dyna: implement missing ops: ldc/stc sr/fpscr, tas, div1

add dynarec implementations for missing ldc and stc ops with sr and
fpscr
add dynarec implementation for tas.b
canonical implementation for div1
delete unused reg_old_sr_status and reg_sr
This commit is contained in:
Flyinghead 2022-12-17 11:09:51 +01:00
parent 51758b965e
commit ce674a872a
10 changed files with 142 additions and 116 deletions

View File

@ -115,7 +115,7 @@ static void dec_End(u32 dst, BlockEndType flags, bool delaySlot)
verify(state.JumpAddr != NullAddress);
}
#define SR_STATUS_MASK 0x700083F2
#define SR_STATUS_MASK STATUS_MASK
#define SR_T_MASK 1
static u32 dec_jump_simm8(u32 op)
@ -237,33 +237,70 @@ sh4dec(i0000_0000_0001_1011)
dec_End(NullAddress, BET_DynamicJump, false);
}
//ldc.l @<REG_N>+,SR
/*
sh4dec(i0100_nnnn_0000_0111)
{
u32 sr_t;
ReadMemU32(sr_t,r[n]);
if (sh4_exept_raised)
return;
sr.SetFull(sr_t);
r[n] += 4;
if (UpdateSR())
{
//FIXME only if interrupts got on .. :P
UpdateINTC();
}
dec_End(NullAddress,BET_StaticIntr,false);
}
*/
//ldc <REG_N>,SR
sh4dec(i0100_nnnn_0000_1110)
{
u32 n = GetN(op);
dec_write_sr((Sh4RegType)(reg_r0+n));
dec_write_sr((Sh4RegType)(reg_r0 + GetN(op)));
Emit(shop_sync_sr);
dec_End(NullAddress, BET_StaticIntr, false);
if (!state.cpu.is_delayslot)
dec_End(state.cpu.rpc + 2, BET_StaticIntr, false);
}
//ldc.l @<REG_N>+,SR
sh4dec(i0100_nnnn_0000_0111)
{
shil_param rn = mk_regi(reg_r0 + GetN(op));
state.info.has_readm = true;
Emit(shop_readm, reg_temp, rn, shil_param(), 4);
Emit(shop_add, rn, rn, mk_imm(4));
dec_write_sr(reg_temp);
Emit(shop_sync_sr);
if (!state.cpu.is_delayslot)
dec_End(state.cpu.rpc + 2, BET_StaticIntr, false);
}
//ldc.l <REG_N>,FPSCR
sh4dec(i0100_nnnn_0110_1010)
{
Emit(shop_mov32, reg_fpscr, mk_regi(reg_r0 + GetN(op)));
Emit(shop_sync_fpscr);
if (!state.cpu.is_delayslot)
dec_End(state.cpu.rpc + 2, BET_StaticJump, false);
}
//ldc.l @<REG_N>+,FPSCR
sh4dec(i0100_nnnn_0110_0110)
{
shil_param rn = mk_regi(reg_r0 + GetN(op));
state.info.has_readm = true;
Emit(shop_readm, reg_fpscr, rn, shil_param(), 4);
Emit(shop_add, rn, rn, mk_imm(4));
Emit(shop_sync_fpscr);
if (!state.cpu.is_delayslot)
dec_End(state.cpu.rpc + 2, BET_StaticJump, false);
}
//stc.l SR,@-<REG_N>
sh4dec(i0100_nnnn_0000_0011)
{
Emit(shop_mov32, reg_temp, reg_sr_status);
Emit(shop_or, reg_temp, reg_temp, reg_sr_T);
shil_param rn = mk_regi(reg_r0 + GetN(op));
state.info.has_writem = true;
Emit(shop_writem, shil_param(), rn, reg_temp, 4, mk_imm(-4));
Emit(shop_add, rn, rn, mk_imm(-4));
}
// tas.b <REG_N>
sh4dec(i0100_nnnn_0001_1011)
{
shil_param rn = mk_regi(reg_r0 + GetN(op));
state.info.has_readm = true;
state.info.has_writem = true;
Emit(shop_readm, reg_temp, rn, shil_param(), 1);
Emit(shop_seteq, reg_sr_T, reg_temp, mk_imm(0));
Emit(shop_or, reg_temp, reg_temp, mk_imm(0x80));
Emit(shop_writem, shil_param(), rn, reg_temp, 1);
}
//nop !
@ -329,7 +366,7 @@ static const Sh4RegType SREGS[] =
static const Sh4RegType CREGS[] =
{
reg_sr,
reg_sr_status,
reg_gbr,
reg_vbr,
reg_ssr,
@ -616,21 +653,6 @@ static bool MatchDiv32s(u32 op,u32 pc)
return match == 65;
}
/*
//This ended up too rare (and too hard to match)
bool MatchDiv0S_0(u32 pc)
{
if (IReadMem16(pc+0)==0x233A && //XOR r3,r3
IReadMem16(pc+2)==0x2137 && //DIV0S r3,r1
IReadMem16(pc+4)==0x322A && //SUBC r2,r2
IReadMem16(pc+6)==0x313A && //SUBC r3,r1
(IReadMem16(pc+8)&0xF00F)==0x2007) //DIV0S x,x
return true;
else
return false;
}
*/
static bool dec_generic(u32 op)
{
DecMode mode;DecParam d;DecParam s;shilop natop;u32 e;
@ -649,8 +671,8 @@ static bool dec_generic(u32 op)
if (op>=0xF000)
{
state.info.has_fpu=true;
//return false;//FPU off for now
if (state.cpu.FPR64 /*|| state.cpu.FSZ64*/)
if (state.cpu.FPR64)
// fallback to interpreter for double float ops
return false;
if (state.cpu.FSZ64 && (d==PRM_FRN_SZ || d==PRM_FRM_SZ || s==PRM_FRN_SZ || s==PRM_FRM_SZ))

View File

@ -19,7 +19,7 @@ sh4dec(i0000_0000_0000_1011);
sh4dec(i0000_0000_0010_1011);
sh4dec(i1100_0011_iiii_iiii);
sh4dec(i0000_0000_0001_1011);
//sh4dec(i0100_nnnn_0000_0111);
sh4dec(i0100_nnnn_0000_0111);
sh4dec(i0100_nnnn_0000_1110);
sh4dec(i0011_nnnn_mmmm_1000);
sh4dec(i0011_nnnn_mmmm_1100);
@ -29,3 +29,7 @@ sh4dec(i1111_0011_1111_1101);
sh4dec(i1111_1011_1111_1101);
sh4dec(i0100_nnnn_0010_0100);
sh4dec(i0100_nnnn_0010_0101);
sh4dec(i0100_nnnn_0110_1010);
sh4dec(i0100_nnnn_0110_0110);
sh4dec(i0100_nnnn_0001_1011);
sh4dec(i0100_nnnn_0000_0011);

View File

@ -75,12 +75,12 @@ std::string name_reg(Sh4RegType reg)
case reg_old_fpscr:
ss << "old_fpscr";
break;
case reg_old_sr_status:
ss << "old_sr_status";
break;
case reg_ssr:
ss << "ssr";
break;
case reg_temp:
ss << "temp";
break;
default:
ss << "s" << reg;
break;

View File

@ -651,6 +651,32 @@ shil_compile
shil_opc_end()
//shop_div1
shil_opc(div1)
shil_canonical
(
u64,f1,(u32 a, s32 b, u32 T),
bool qxm = sr.Q ^ sr.M;
sr.Q = (int)a < 0;
a = (a << 1) | T;
u32 oldA = a;
a += (qxm ? 1 : -1) * b; // b if sr.Q != sr.M, -b otherwise
sr.Q ^= sr.M ^ (qxm ? a < oldA : a > oldA);
T = !(sr.Q ^ sr.M);
return a | ((u64)T << 32);
)
shil_compile
(
shil_cf_arg_u32(rs3);
shil_cf_arg_u32(rs2);
shil_cf_arg_u32(rs1);
shil_cf(f1);
shil_cf_rv_u64(rd);
)
shil_opc_end()
//debug_3
shil_opc(debug_3)
shil_canonical

View File

@ -182,13 +182,24 @@ private:
for (auto it = constprop_values.begin(); it != constprop_values.end(); )
{
Sh4RegType reg = it->first.get_reg();
if (reg == reg_sr_status || reg == reg_old_sr_status || (reg >= reg_r0 && reg <= reg_r7)
if (reg == reg_sr_status || (reg >= reg_r0 && reg <= reg_r7)
|| (reg >= reg_r0_Bank && reg <= reg_r7_Bank))
it = constprop_values.erase(it);
else
it++;
}
}
else if (op.op == shop_div1)
{
for (auto it = constprop_values.begin(); it != constprop_values.end(); )
{
Sh4RegType reg = it->first.get_reg();
if (reg == reg_sr_status)
it = constprop_values.erase(it);
else
it++;
}
}
else if (op.op == shop_sync_fpscr)
{
for (auto it = constprop_values.begin(); it != constprop_values.end(); )
@ -355,13 +366,15 @@ private:
{
last_versions[reg_sr_T] = -1;
last_versions[reg_sr_status] = -1;
last_versions[reg_old_sr_status] = -1;
for (int i = reg_r0; i <= reg_r7; i++)
last_versions[i] = -1;
for (int i = reg_r0_Bank; i <= reg_r7_Bank; i++)
last_versions[i] = -1;
continue;
}
if (op.op == shop_div1)
last_versions[reg_sr_status] = -1;
if (op.op == shop_sync_fpscr)
{
last_versions[reg_fpscr] = -1;

View File

@ -65,7 +65,6 @@ public:
{
//FlushReg(reg_sr_T, true);
FlushReg(reg_sr_status, true);
FlushReg(reg_old_sr_status, true);
for (int i = reg_r0; i <= reg_r7; i++)
FlushReg((Sh4RegType)i, true);
for (int i = reg_r0_Bank; i <= reg_r7_Bank; i++)
@ -403,11 +402,13 @@ private:
// TODO we could look at the ifb op to optimize what to flush
if (op->op == shop_ifb || (mmu_enabled() && (op->op == shop_readm || op->op == shop_writem || op->op == shop_pref)))
return true;
if (op->op == shop_sync_sr && (/*reg == reg_sr_T ||*/ reg == reg_sr_status || reg == reg_old_sr_status || (reg >= reg_r0 && reg <= reg_r7)
if (op->op == shop_sync_sr && (/*reg == reg_sr_T ||*/ reg == reg_sr_status || (reg >= reg_r0 && reg <= reg_r7)
|| (reg >= reg_r0_Bank && reg <= reg_r7_Bank)))
return true;
if (op->op == shop_sync_fpscr && (reg == reg_fpscr || reg == reg_old_fpscr || (reg >= reg_fr_0 && reg <= reg_xf_15)))
return true;
if (op->op == shop_div1 && reg == reg_sr_status)
return true;
// if reg is used by a subsequent vector op that doesn't use reg allocation
if (UsesReg(op, reg, version, true))
return true;

View File

@ -206,10 +206,6 @@ static u32* Sh4_int_GetRegisterPtr(Sh4RegType reg)
return &next_pc;
break;
case reg_old_sr_status :
return &old_sr.status;
break;
case reg_sr_status :
return &sr.status;
break;

View File

@ -80,8 +80,6 @@ enum Sh4RegType
reg_pr,
reg_fpul,
reg_nextpc,
reg_sr, //Includes T (combined on read/separated on write)
reg_old_sr_status, //Only the status bits
reg_sr_status, //Only the status bits
reg_sr_T, //Only T
reg_old_fpscr,

View File

@ -18,10 +18,6 @@ enum OpcodeType
WritesFPSCR = 16, // Writes to FPSCR , and UpdateSR needs to be called
Invalid = 128, // Invalid
NO_FP = 256,
NO_GP = 512,
NO_SP = 1024,
UsesFPU = 2048, // Floating point op
FWritesFPSCR = UsesFPU | WritesFPSCR,

View File

@ -9,63 +9,49 @@
OpCallFP* OpPtr[0x10000];
sh4_opcodelistentry* OpDesc[0x10000];
//XR_N,XR_M,FR_M,FR_N,GPR_N,GPR_M,EREAD,EWRITE
//
//IMM8,IMM4,IMM12
#define Mask_n_m 0xF00F
#define Mask_n_m_imm4 0xF000
#define Mask_n 0xF0FF
#define Mask_none 0xFFFF
#define Mask_imm8 0xFF00
#define Mask_imm12 0xF000
#define Mask_n_imm8 0xF000
#define Mask_n_ml3bit 0xF08F
#define Mask_nh3bit 0xF1FF
#define Mask_nh2bit 0xF3FF
//,DEC_D_RN|DEC_S_RM|DEC_OP(shop_and)
u64 dec_Fill(DecMode mode,DecParam d,DecParam s,shilop op,u32 extra=0)
static u64 dec_Fill(DecMode mode,DecParam d,DecParam s,shilop op,u32 extra=0)
{
return (((u64)extra)<<32)|(mode<<24)|(d<<16)|(s<<8)|op;
}
u64 dec_Un_rNrN(shilop op)
{
return dec_Fill(DM_UnaryOp,PRM_RN,PRM_RN,op);
}
u64 dec_Un_rNrM(shilop op)
static u64 dec_Un_rNrM(shilop op)
{
return dec_Fill(DM_UnaryOp,PRM_RN,PRM_RM,op);
}
u64 dec_Un_frNfrN(shilop op)
static u64 dec_Un_frNfrN(shilop op)
{
return dec_Fill(DM_UnaryOp,PRM_FRN,PRM_FRN,op);
}
u64 dec_Un_frNfrM(shilop op)
{
return dec_Fill(DM_UnaryOp,PRM_FRN,PRM_FRM,op);
}
u64 dec_Bin_frNfrM(shilop op, u32 haswrite=1)
static u64 dec_Bin_frNfrM(shilop op, u32 haswrite=1)
{
return dec_Fill(DM_BinaryOp,PRM_FRN,PRM_FRM,op,haswrite);
}
u64 dec_Bin_rNrM(shilop op, u32 haswrite=1)
static u64 dec_Bin_rNrM(shilop op, u32 haswrite=1)
{
return dec_Fill(DM_BinaryOp,PRM_RN,PRM_RM,op,haswrite);
}
u64 dec_mul(u32 type)
static u64 dec_mul(u32 type)
{
//return 0;
return dec_Fill(DM_MUL,PRM_RN,PRM_RM,shop_mul_s16,type);
}
u64 dec_Bin_S8R(shilop op, u32 haswrite=1)
static u64 dec_Bin_S8R(shilop op, u32 haswrite=1)
{
return dec_Fill(DM_BinaryOp,PRM_RN,PRM_SIMM8,op,haswrite);
}
u64 dec_Bin_r0u8(shilop op, u32 haswrite=1)
static u64 dec_Bin_r0u8(shilop op, u32 haswrite=1)
{
return dec_Fill(DM_BinaryOp,PRM_R0,PRM_UIMM8,op,haswrite);
}
u64 dec_shft(s32 offs,bool arithm)
static u64 dec_shft(s32 offs,bool arithm)
{
if (offs>0)
{
@ -76,42 +62,26 @@ u64 dec_shft(s32 offs,bool arithm)
{
return dec_Fill(DM_Shift,PRM_RN,PRM_RN,arithm?shop_sar:shop_shr,-offs);
}
}
u64 dec_cmp(shilop op, DecParam s1,DecParam s2)
static u64 dec_cmp(shilop op, DecParam s1,DecParam s2)
{
return dec_Fill(DM_WriteTOp,s1,s2,op);
}
u64 dec_LD(DecParam d) { return dec_Fill(DM_UnaryOp,d,PRM_RN,shop_mov32); }
u64 dec_LDM(DecParam d) { return dec_Fill(DM_ReadM,d,PRM_RN,shop_readm,-4); }
u64 dec_ST(DecParam d) { return dec_Fill(DM_UnaryOp,PRM_RN,d,shop_mov32); }
u64 dec_STSRF(DecParam d) { return dec_Fill(DM_ReadSRF,PRM_RN,d,shop_mov32); }
u64 dec_STM(DecParam d) { return dec_Fill(DM_WriteM,PRM_RN,d,shop_writem,-4); }
static u64 dec_LD(DecParam d) { return dec_Fill(DM_UnaryOp,d,PRM_RN,shop_mov32); }
static u64 dec_LDM(DecParam d) { return dec_Fill(DM_ReadM,d,PRM_RN,shop_readm,-4); }
static u64 dec_ST(DecParam d) { return dec_Fill(DM_UnaryOp,PRM_RN,d,shop_mov32); }
static u64 dec_STSRF(DecParam d) { return dec_Fill(DM_ReadSRF,PRM_RN,d,shop_mov32); }
static u64 dec_STM(DecParam d) { return dec_Fill(DM_WriteM,PRM_RN,d,shop_writem,-4); }
//d=reg to read into
u64 dec_MRd(DecParam d,DecParam s,u32 sz) { return dec_Fill(DM_ReadM,d,s,shop_readm,sz); }
static u64 dec_MRd(DecParam d,DecParam s,u32 sz) { return dec_Fill(DM_ReadM,d,s,shop_readm,sz); }
//d= reg to read from
u64 dec_MWt(DecParam d,DecParam s,u32 sz) { return dec_Fill(DM_WriteM,d,s,shop_writem,sz); }
//use this to disable opcodes :p
u64 dec_rz(...) { return 0; }
//jump for now..
//how bout a decoded switch list ? could that _much_ faster ?
static u64 dec_MWt(DecParam d,DecParam s,u32 sz) { return dec_Fill(DM_WriteM,d,s,shop_writem,sz); }
sh4_opcodelistentry missing_opcode = {0,iNotImplemented,0,0,ReadWritePC,"missing",0,0,CO,fix_none };
#define R_GP (NO_SP|NO_FP) //only general
#define R_FP (NO_SP|NO_GP) //only float
#define R_SP (NO_GP|NO_FP) //only special
#define R_GSP (NO_FP) //general + special
#define R_GFP (NO_SP) //general + float
#define R_NON (NO_SP|NO_GP|NO_FP) //no registers at all (...)
#define R_MMR (R_NON) //Memory mapped registers
#define R_ALL (0)
sh4_opcodelistentry opcodes[]=
{
//HLE
@ -125,7 +95,7 @@ sh4_opcodelistentry opcodes[]=
{dec_i0000_0000_0000_1001 ,i0000_nnnn_1011_0011 ,Mask_n ,0x00B3 ,Normal ,"ocbwb @<REG_N>" ,1,2,MA,fix_none}, //ocbwb @<REG_N>
{0 ,i0000_nnnn_1000_0011 ,Mask_n ,0x0083 ,Normal ,"pref @<REG_N>" ,1,2,LS,fix_none ,dec_Fill(DM_UnaryOp,PRM_RN,PRM_ONE,shop_pref,1)}, //pref @<REG_N>
{0 ,i0000_nnnn_mmmm_0111 ,Mask_n_m ,0x0007 ,Normal ,"mul.l <REG_M>,<REG_N>" ,2,4,CO,fix_none ,dec_mul(-32)}, //mul.l <REG_M>,<REG_N>
{0 ,i0000_0000_0010_1000 ,Mask_none ,0x0028 ,Normal | R_SP,"clrmac" ,1,3,LS,fix_none}, //clrmac
{0 ,i0000_0000_0010_1000 ,Mask_none ,0x0028 ,Normal ,"clrmac" ,1,3,LS,fix_none}, //clrmac
{0 ,i0000_0000_0100_1000 ,Mask_none ,0x0048 ,Normal ,"clrs" ,1,1,CO,fix_none ,dec_Fill(DM_BinaryOp, PRM_SR_STATUS, PRM_TWO_INV, shop_and, 1) }, //clrs
{0 ,i0000_0000_0000_1000 ,Mask_none ,0x0008 ,Normal ,"clrt" ,1,1,MT,fix_none ,dec_Fill(DM_UnaryOp,PRM_SR_T,PRM_ZERO,shop_mov32)}, //clrt
{0 ,i0000_0000_0011_1000 ,Mask_none ,0x0038 ,Normal ,"ldtlb" ,1,1,CO,fix_none} ,//ldtlb
@ -149,14 +119,14 @@ sh4_opcodelistentry opcodes[]=
{0 ,i0010_nnnn_mmmm_1001 ,Mask_n_m ,0x2009 ,Normal ,"and <REG_M>,<REG_N>" ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_and)}, //and <REG_M>,<REG_N>
{0 ,i0010_nnnn_mmmm_1010 ,Mask_n_m ,0x200A ,Normal ,"xor <REG_M>,<REG_N>" ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_xor)}, //xor <REG_M>,<REG_N>
{0 ,i0010_nnnn_mmmm_1011 ,Mask_n_m ,0x200B ,Normal ,"or <REG_M>,<REG_N>" ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_or)}, //or <REG_M>,<REG_N>
{0 ,i0010_nnnn_mmmm_1100 ,Mask_n_m ,0x200C ,Normal |NO_FP,"cmp/str <REG_M>,<REG_N>" ,1,1,MT,fix_none ,dec_cmp(shop_setpeq,PRM_RN,PRM_RM)}, //cmp/str <REG_M>,<REG_N>
{0 ,i0010_nnnn_mmmm_1101 ,Mask_n_m ,0x200D ,Normal |NO_FP,"xtrct <REG_M>,<REG_N>" ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_xtrct)}, //xtrct <REG_M>,<REG_N>
{0 ,i0010_nnnn_mmmm_1100 ,Mask_n_m ,0x200C ,Normal ,"cmp/str <REG_M>,<REG_N>" ,1,1,MT,fix_none ,dec_cmp(shop_setpeq,PRM_RN,PRM_RM)}, //cmp/str <REG_M>,<REG_N>
{0 ,i0010_nnnn_mmmm_1101 ,Mask_n_m ,0x200D ,Normal ,"xtrct <REG_M>,<REG_N>" ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_xtrct)}, //xtrct <REG_M>,<REG_N>
{0 ,i0010_nnnn_mmmm_1110 ,Mask_n_m ,0x200E ,Normal ,"mulu.w <REG_M>,<REG_N>" ,1,4,CO,fix_none ,dec_mul(16)}, //mulu.w <REG_M>,<REG_N>
{0 ,i0010_nnnn_mmmm_1111 ,Mask_n_m ,0x200F ,Normal ,"muls.w <REG_M>,<REG_N>" ,1,4,CO,fix_none ,dec_mul(-16)}, //muls.w <REG_M>,<REG_N>
{0 ,i0011_nnnn_mmmm_0000 ,Mask_n_m ,0x3000 ,Normal ,"cmp/eq <REG_M>,<REG_N>" ,1,1,MT,fix_none ,dec_cmp(shop_seteq,PRM_RN,PRM_RM)}, // cmp/eq <REG_M>,<REG_N>
{0 ,i0011_nnnn_mmmm_0010 ,Mask_n_m ,0x3002 ,Normal ,"cmp/hs <REG_M>,<REG_N>" ,1,1,MT,fix_none ,dec_cmp(shop_setae,PRM_RN,PRM_RM)}, // cmp/hs <REG_M>,<REG_N>
{0 ,i0011_nnnn_mmmm_0011 ,Mask_n_m ,0x3003 ,Normal ,"cmp/ge <REG_M>,<REG_N>" ,1,1,MT,fix_none ,dec_cmp(shop_setge,PRM_RN,PRM_RM)}, //cmp/ge <REG_M>,<REG_N>
{0 ,i0011_nnnn_mmmm_0100 ,Mask_n_m ,0x3004 ,Normal ,"div1 <REG_M>,<REG_N>" ,1,1,EX,fix_none}, //div1 <REG_M>,<REG_N>
{0 ,i0011_nnnn_mmmm_0100 ,Mask_n_m ,0x3004 ,Normal ,"div1 <REG_M>,<REG_N>" ,1,1,EX,fix_none ,dec_Fill(DM_ADC,PRM_RN,PRM_RM,shop_div1,0)}, //div1 <REG_M>,<REG_N>
{0 ,i0011_nnnn_mmmm_0101 ,Mask_n_m ,0x3005 ,Normal ,"dmulu.l <REG_M>,<REG_N>" ,2,4,CO,fix_none ,dec_mul(64)}, //dmulu.l <REG_M>,<REG_N>
{0 ,i0011_nnnn_mmmm_0110 ,Mask_n_m ,0x3006 ,Normal ,"cmp/hi <REG_M>,<REG_N>" ,1,1,MT,fix_none ,dec_cmp(shop_setab,PRM_RN,PRM_RM)}, // cmp/hi <REG_M>,<REG_N>
{0 ,i0011_nnnn_mmmm_0111 ,Mask_n_m ,0x3007 ,Normal ,"cmp/gt <REG_M>,<REG_N>" ,1,1,MT,fix_none ,dec_cmp(shop_setgt,PRM_RN,PRM_RM)}, //cmp/gt <REG_M>,<REG_N>
@ -222,7 +192,7 @@ sh4_opcodelistentry opcodes[]=
{0 ,i0100_nnnn_0011_0010 ,Mask_n ,0x4032 ,Normal ,"stc.l SGR,@-<REG_N>" ,3,3,CO,rn_4 ,dec_STM(PRM_SREG)}, //sts.l SGR,@-<REG_N>
//stc : @-rn
{0 ,i0100_nnnn_0000_0011 ,Mask_n ,0x4003 ,Normal ,"stc.l SR,@-<REG_N>" ,1,1,CO,rn_4}, //stc.l SR,@-<REG_N>
{dec_i0100_nnnn_0000_0011 ,i0100_nnnn_0000_0011 ,Mask_n ,0x4003 ,Normal ,"stc.l SR,@-<REG_N>" ,1,1,CO,rn_4}, //stc.l SR,@-<REG_N>
{0 ,i0100_nnnn_0001_0011 ,Mask_n ,0x4013 ,Normal ,"stc.l GBR,@-<REG_N>" ,1,1,CO,rn_4 ,dec_STM(PRM_CREG)}, //stc.l GBR,@-<REG_N>
{0 ,i0100_nnnn_0010_0011 ,Mask_n ,0x4023 ,Normal ,"stc.l VBR,@-<REG_N>" ,1,1,CO,rn_4 ,dec_STM(PRM_CREG)}, //stc.l VBR,@-<REG_N>
{0 ,i0100_nnnn_0011_0011 ,Mask_n ,0x4033 ,Normal ,"stc.l SSR,@-<REG_N>" ,1,1,CO,rn_4 ,dec_STM(PRM_CREG)}, //stc.l SSR,@-<REG_N>
@ -235,11 +205,11 @@ sh4_opcodelistentry opcodes[]=
{0 ,i0100_nnnn_0010_0110 ,Mask_n ,0x4026 ,Normal ,"lds.l @<REG_N>+,PR" ,1,2,CO,fix_none ,dec_LDM(PRM_SREG)}, //lds.l @<REG_N>+,PR
{0 ,i0100_nnnn_0011_0110 ,Mask_n ,0x4036 ,Normal ,"ldc.l @<REG_N>+,SGR" ,3,3,CO,fix_none ,dec_LDM(PRM_SREG)}, //lds.l @<REG_N>+,SGR
{0 ,i0100_nnnn_0101_0110 ,Mask_n ,0x4056 ,UsesFPU ,"lds.l @<REG_N>+,FPUL" ,1,1,CO,fix_none ,dec_LDM(PRM_SREG)}, //lds.l @<REG_N>+,FPUL
{0 ,i0100_nnnn_0110_0110 ,Mask_n ,0x4066 ,FWritesFPSCR ,"lds.l @<REG_N>+,FPSCR" ,1,1,CO,fix_none}, //lds.l @<REG_N>+,FPSCR
{dec_i0100_nnnn_0110_0110 ,i0100_nnnn_0110_0110 ,Mask_n ,0x4066 ,FWritesFPSCR ,"lds.l @<REG_N>+,FPSCR" ,1,1,CO,fix_none}, //lds.l @<REG_N>+,FPSCR
{0 ,i0100_nnnn_1111_0110 ,Mask_n ,0x40F6 ,Normal ,"ldc.l @<REG_N>+,DBR" ,1,3,CO,fix_none ,dec_LDM(PRM_SREG)}, //lds.l @<REG_N>+,DBR
//ldc : @rn+
{0 ,i0100_nnnn_0000_0111 ,Mask_n ,0x4007 ,WritesSRRWPC ,"ldc.l @<REG_N>+,SR" ,1,1,CO,fix_none}, //ldc.l @<REG_N>+,SR
{dec_i0100_nnnn_0000_0111 ,i0100_nnnn_0000_0111 ,Mask_n ,0x4007 ,WritesSRRWPC ,"ldc.l @<REG_N>+,SR" ,1,1,CO,fix_none}, //ldc.l @<REG_N>+,SR
{0 ,i0100_nnnn_0001_0111 ,Mask_n ,0x4017 ,Normal ,"ldc.l @<REG_N>+,GBR" ,1,1,CO,fix_none ,dec_LDM(PRM_CREG)}, //ldc.l @<REG_N>+,GBR
{0 ,i0100_nnnn_0010_0111 ,Mask_n ,0x4027 ,Normal ,"ldc.l @<REG_N>+,VBR" ,1,1,CO,fix_none ,dec_LDM(PRM_CREG)}, //ldc.l @<REG_N>+,VBR
{0 ,i0100_nnnn_0011_0111 ,Mask_n ,0x4037 ,Normal ,"ldc.l @<REG_N>+,SSR" ,1,1,CO,fix_none ,dec_LDM(PRM_CREG)}, //ldc.l @<REG_N>+,SSR
@ -270,7 +240,7 @@ sh4_opcodelistentry opcodes[]=
{0 ,i0100_nnnn_0010_1010 ,Mask_n ,0x402A ,Normal ,"lds <REG_N>,PR" ,1,2,CO,fix_none ,dec_LD(PRM_SREG)}, //lds <REG_N>,PR
{0 ,i0100_nnnn_0011_1010 ,Mask_n ,0x403A ,Normal ,"ldc <REG_N>,SGR" ,3,3,CO,fix_none ,dec_LD(PRM_SREG)}, //lds <REG_N>,SGR
{0 ,i0100_nnnn_0101_1010 ,Mask_n ,0x405A ,UsesFPU ,"lds <REG_N>,FPUL" ,1,1,CO,fix_none ,dec_LD(PRM_SREG)}, //lds <REG_N>,FPUL
{0 ,i0100_nnnn_0110_1010 ,Mask_n ,0x406A ,FWritesFPSCR ,"lds <REG_N>,FPSCR" ,1,1,CO,fix_none}, //lds <REG_N>,FPSCR
{dec_i0100_nnnn_0110_1010 ,i0100_nnnn_0110_1010 ,Mask_n ,0x406A ,FWritesFPSCR ,"lds <REG_N>,FPSCR" ,1,1,CO,fix_none}, //lds <REG_N>,FPSCR
{0 ,i0100_nnnn_1111_1010 ,Mask_n ,0x40FA ,Normal ,"ldc <REG_N>,DBR" ,1,1,CO,fix_none ,dec_LD(PRM_SREG)}, //lds <REG_N>,DBR
//ldc : rn
@ -301,7 +271,7 @@ sh4_opcodelistentry opcodes[]=
{0 ,i0100_nnnn_0010_1001 ,Mask_n ,0x4029 ,Normal ,"shlr16 <REG_N>" ,1,1,EX,fix_none ,dec_shft(-16,false)}, //shlr16 <REG_N>
{dec_i0100_nnnn_0010_1011 ,i0100_nnnn_0010_1011 ,Mask_n ,0x402B ,Branch_dir_d ,"jmp @<REG_N>" ,2,3,CO,fix_none}, //jmp @<REG_N>
{dec_i0100_nnnn_0000_1011 ,i0100_nnnn_0000_1011 ,Mask_n ,0x400B ,Branch_dir_d ,"jsr @<REG_N>" ,2,3,CO,fix_none}, //jsr @<REG_N>
{0 ,i0100_nnnn_0001_1011 ,Mask_n ,0x401B ,Normal ,"tas.b @<REG_N>" ,5,5,CO,fix_none}, //tas.b @<REG_N>
{dec_i0100_nnnn_0001_1011 ,i0100_nnnn_0001_1011 ,Mask_n ,0x401B ,Normal ,"tas.b @<REG_N>" ,5,5,CO,fix_none}, //tas.b @<REG_N>
{0 ,i0100_nnnn_mmmm_1100 ,Mask_n_m ,0x400C ,Normal ,"shad <REG_M>,<REG_N>" ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_shad)}, //shad <REG_M>,<REG_N>
{0 ,i0100_nnnn_mmmm_1101 ,Mask_n_m ,0x400D ,Normal ,"shld <REG_M>,<REG_N>" ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_shld)}, //shld <REG_M>,<REG_N>
{0 ,i0100_nnnn_mmmm_1111 ,Mask_n_m ,0x400F ,Normal ,"mac.w @<REG_M>+,@<REG_N>+" ,2,3,CO,fix_none}, //mac.w @<REG_M>+,@<REG_N>+