mirror of
https://github.com/gligli/nulldc-360.git
synced 2025-04-02 11:11:56 -04:00
2028 lines
No EOL
38 KiB
C++
2028 lines
No EOL
38 KiB
C++
#include "sh4_cpu_shil.h"
|
|
#include "emitter/emitter.h"
|
|
#include "dc/mem/sh4_mem.h"
|
|
#include "dc/sh4/sh4_opcode_list.h"
|
|
#include "dc/sh4/sh4_registers.h"
|
|
#include "dc/sh4/shil/shil.h"
|
|
#include "log/logging_interface.h"
|
|
#include <assert.h>
|
|
|
|
#undef sh4op
|
|
|
|
#define SH4_REC
|
|
|
|
shil_stream* ilst;
|
|
|
|
#define handle_stids {if (bb->flags.IsDelaySlot) { bb->flags.SaveTInDelaySlot=true; ilst->LoadT(jcond_flag); } }
|
|
|
|
#define need_rpctmp {if (bb->flags.IsDelaySlot && bb->flags.CouldNeedPCtmp) { /*printf("need_rpctmp\n");*/ bb->flags.NeedPCtmp=true; ilst->mov(reg_pc_temp, reg_pc); } }
|
|
#define handle_rpctmp {if (bb->flags.NeedPCtmp) { /*printf("handle_rpctmp\n");*/ ilst->mov(reg_pc, reg_pc_temp); } }
|
|
|
|
#define shil_interpret(str) { need_rpctmp; handle_stids; ilst->shil_ifb(str,pc); }
|
|
|
|
#undef sh4op
|
|
#undef rsh4op
|
|
#define rsh4op(str) void __fastcall rec_shil_##str (u32 op,u32 pc,BasicBlock* bb)
|
|
#define sh4op(str) void __fastcall rec_shil_##str (u32 op,u32 pc,BasicBlock* bb) { shil_interpret(op); }; void __fastcall kkrec_shil_##str (u32 op,u32 pc,BasicBlock* bb)
|
|
|
|
//#define tmu_underflow 0x0100
|
|
#define iNimp(info) rec_shil_iNimp(pc,op,info)
|
|
|
|
Sh4RegType dyna_reg_id_r[16];
|
|
Sh4RegType dyna_reg_id_r_bank[8];
|
|
|
|
Sh4RegType dyna_reg_id_fr[16];
|
|
Sh4RegType dyna_reg_id_xf[16];
|
|
|
|
Sh4RegType dyna_reg_id_dr[8];
|
|
Sh4RegType dyna_reg_id_xd[8];
|
|
|
|
#define r dyna_reg_id_r
|
|
#define r_bank dyna_reg_id_r_bank
|
|
|
|
#define fr dyna_reg_id_fr
|
|
#define xf dyna_reg_id_xf
|
|
|
|
#define dr dyna_reg_id_dr
|
|
#define xd dyna_reg_id_xd
|
|
|
|
void rec_shil_iNimp(u32 pc,u32 op ,char * text)
|
|
{
|
|
printf("SHIL: Internal fatal error: %s",text);
|
|
|
|
printf("PC 0x%x , OP = 0x%x\n",pc,op);
|
|
|
|
printf("GPR regs : \n"); //dump the useful only
|
|
for(s32 i = 0;i < 16;i++)
|
|
printf("r[%d] : 0x%x,",i,r[i]);
|
|
printf("\nFP regs : \n");
|
|
for(s32 i = 0;i < 16;i++)
|
|
printf("fr[%d] : %f,",i,fr[i]);
|
|
|
|
printf("\nControl regs : \n");
|
|
printf("RM %d DN : %d PR %d SZ %d FR %d PR_SZ %d NIL %d\n",sh4r.fpscr.RM,sh4r.fpscr.DN,sh4r.fpscr.PR,sh4r.fpscr.SZ,sh4r.fpscr.FR,sh4r.fpscr.PR_SZ,sh4r.fpscr.nil);
|
|
printf("finexact %d,",sh4r.fpscr.finexact);
|
|
printf("funderflow %d,",sh4r.fpscr.funderflow);
|
|
printf("foverflow %d,",sh4r.fpscr.foverflow);
|
|
printf("fdivbyzero %d,",sh4r.fpscr.fdivbyzero);
|
|
printf("finvalidop %d,",sh4r.fpscr.finvalidop);
|
|
printf("einexact %d,",sh4r.fpscr.einexact);
|
|
printf("eunderflow %d,",sh4r.fpscr.eunderflow);
|
|
printf("eoverflow %d,",sh4r.fpscr.eoverflow);
|
|
printf("edivbyzero %d,",sh4r.fpscr.edivbyzero);
|
|
printf("einvalidop %d,",sh4r.fpscr.einvalidop);
|
|
printf("cinexact %d,",sh4r.fpscr.cinexact);
|
|
printf("cunderflow %d,",sh4r.fpscr.cunderflow);
|
|
printf("coverflow %d,",sh4r.fpscr.coverflow);
|
|
printf("cdivbyzero %d,",sh4r.fpscr.cdivbyzero);
|
|
printf("cinvalid %d,",sh4r.fpscr.cinvalid);
|
|
printf("cfpuerr %d\n",sh4r.fpscr.cfpuerr);
|
|
|
|
//while(1){}
|
|
die("SHIL: Internal fatal error");
|
|
}
|
|
//************************ TLB/Cache ************************
|
|
//ldtlb
|
|
rsh4op(i0000_0000_0011_1000)
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//ocbi @<REG_N>
|
|
rsh4op(i0000_nnnn_1001_0011)
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//ocbp @<REG_N>
|
|
rsh4op(i0000_nnnn_1010_0011)
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//ocbwb @<REG_N>
|
|
rsh4op(i0000_nnnn_1011_0011)
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//pref @<REG_N>
|
|
rsh4op(i0000_nnnn_1000_0011)
|
|
{
|
|
u32 n = GetN(op);
|
|
ilst->pref(r[n]);
|
|
}
|
|
|
|
//************************ Set/Get T/S ************************
|
|
//sets
|
|
rsh4op(i0000_0000_0101_1000)
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//clrs
|
|
rsh4op(i0000_0000_0100_1000)
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//sett
|
|
rsh4op(i0000_0000_0001_1000)
|
|
{
|
|
ilst->mov(reg_sr_T,1);
|
|
}
|
|
|
|
//clrt
|
|
rsh4op(i0000_0000_0000_1000)
|
|
{
|
|
ilst->mov(reg_sr_T,0);
|
|
}
|
|
|
|
//movt <REG_N>
|
|
rsh4op(i0000_nnnn_0010_1001)
|
|
{
|
|
u32 n = GetN(op);
|
|
ilst->mov(r[n],reg_sr_T);
|
|
}
|
|
|
|
//************************ Reg Compares ************************
|
|
//cmp/pz <REG_N>
|
|
rsh4op(i0100_nnnn_0001_0001)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
ilst->cmp(r[n],(s8)0); //singed compare
|
|
handle_stids; ilst->SaveT(CC_NL);
|
|
}
|
|
|
|
//cmp/pl <REG_N>
|
|
rsh4op(i0100_nnnn_0001_0101)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
ilst->cmp(r[n],(s8)0); //singed compare
|
|
handle_stids; ilst->SaveT(CC_NLE);
|
|
}
|
|
|
|
//cmp/eq #<imm>,R0
|
|
rsh4op(i1000_1000_iiii_iiii)
|
|
{
|
|
ilst->cmp(r[0],GetSImm8(op));
|
|
handle_stids; ilst->SaveT(CC_E);
|
|
}
|
|
|
|
//cmp/eq <REG_M>,<REG_N>
|
|
rsh4op(i0011_nnnn_mmmm_0000)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ilst->cmp(r[n],r[m],ppc_condition_flags[CC_E][2]);
|
|
handle_stids; ilst->SaveT(CC_E);
|
|
}
|
|
|
|
//cmp/hs <REG_M>,<REG_N>
|
|
rsh4op(i0011_nnnn_mmmm_0010)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ilst->cmp(r[n],r[m],ppc_condition_flags[CC_AE][2]);
|
|
handle_stids; ilst->SaveT(CC_AE);
|
|
}
|
|
|
|
//cmp/ge <REG_M>,<REG_N>
|
|
rsh4op(i0011_nnnn_mmmm_0011)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ilst->cmp(r[n],r[m],ppc_condition_flags[CC_GE][2]);
|
|
handle_stids; ilst->SaveT(CC_GE);
|
|
}
|
|
|
|
//cmp/hi <REG_M>,<REG_N>
|
|
rsh4op(i0011_nnnn_mmmm_0110)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ilst->cmp(r[n],r[m],ppc_condition_flags[CC_A][2]);
|
|
handle_stids; ilst->SaveT(CC_A);
|
|
}
|
|
|
|
//cmp/gt <REG_M>,<REG_N>
|
|
rsh4op(i0011_nnnn_mmmm_0111)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ilst->cmp(r[n],r[m],ppc_condition_flags[CC_G][2]);
|
|
handle_stids; ilst->SaveT(CC_G);
|
|
}
|
|
|
|
//cmp/str <REG_M>,<REG_N>
|
|
rsh4op(i0010_nnnn_mmmm_1100)
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//tst #<imm>,R0
|
|
rsh4op(i1100_1000_iiii_iiii)
|
|
{
|
|
ilst->test(r[0],GetImm8(op));
|
|
handle_stids; ilst->SaveT(CC_Z);
|
|
}
|
|
//tst <REG_M>,<REG_N>
|
|
rsh4op(i0010_nnnn_mmmm_1000)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ilst->test(r[n],r[m]);
|
|
handle_stids; ilst->SaveT(CC_Z);
|
|
}
|
|
//************************ mulls! ************************
|
|
//mulu.w <REG_M>,<REG_N>
|
|
rsh4op(i0010_nnnn_mmmm_1110)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ilst->mulu_16_16_32(r[n],r[m]);
|
|
}
|
|
|
|
//muls.w <REG_M>,<REG_N>
|
|
rsh4op(i0010_nnnn_mmmm_1111)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ilst->muls_16_16_32(r[n],r[m]);
|
|
}
|
|
|
|
//dmulu.l <REG_M>,<REG_N>
|
|
rsh4op(i0011_nnnn_mmmm_0101)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ilst->mulu_32_32_64(r[n],r[m]);
|
|
}
|
|
|
|
//dmuls.l <REG_M>,<REG_N>
|
|
rsh4op(i0011_nnnn_mmmm_1101)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ilst->muls_32_32_64(r[n],r[m]);
|
|
}
|
|
|
|
//mac.w @<REG_M>+,@<REG_N>+
|
|
rsh4op(i0100_nnnn_mmmm_1111)
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//mac.l @<REG_M>+,@<REG_N>+
|
|
rsh4op(i0000_nnnn_mmmm_1111)
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//mul.l <REG_M>,<REG_N>
|
|
rsh4op(i0000_nnnn_mmmm_0111)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ilst->muls_32_32_32(r[n],r[m]);
|
|
}
|
|
|
|
//************************ Div ! ************************
|
|
#define MASK_N_M 0xF00F
|
|
#define MASK_N 0xF0FF
|
|
#define MASK_NONE 0xFFFF
|
|
|
|
#define DIV0U_KEY 0x0019
|
|
#define DIV0S_KEY 0x2007
|
|
#define DIV1_KEY 0x3004
|
|
#define ROTCL_KEY 0x4024
|
|
|
|
Sh4RegType div_som_reg1;
|
|
Sh4RegType div_som_reg2;
|
|
Sh4RegType div_som_reg3;
|
|
|
|
u32 MatchDiv32(u32 pc , Sh4RegType ®1,Sh4RegType ®2 , Sh4RegType ®3)
|
|
{
|
|
if (settings.dynarec.Safe)
|
|
return 0;
|
|
|
|
u32 v_pc=pc;
|
|
u32 match=1;
|
|
for (int i=0;i<32;i++)
|
|
{
|
|
u16 opcode=ReadMem16(v_pc);
|
|
v_pc+=2;
|
|
if ((opcode&MASK_N)==ROTCL_KEY)
|
|
{
|
|
if (reg1==NoReg)
|
|
reg1=(Sh4RegType)GetN(opcode);
|
|
else if (reg1!=(Sh4RegType)GetN(opcode))
|
|
break;
|
|
match++;
|
|
}
|
|
else
|
|
break;
|
|
|
|
opcode=ReadMem16(v_pc);
|
|
v_pc+=2;
|
|
if ((opcode&MASK_N_M)==DIV1_KEY)
|
|
{
|
|
if (reg2==NoReg)
|
|
reg2=(Sh4RegType)GetM(opcode);
|
|
else if (reg2!=(Sh4RegType)GetM(opcode))
|
|
break;
|
|
|
|
if (reg2==reg1)
|
|
break;
|
|
|
|
if (reg3==NoReg)
|
|
reg3=(Sh4RegType)GetN(opcode);
|
|
else if (reg3!=(Sh4RegType)GetN(opcode))
|
|
break;
|
|
|
|
if (reg3==reg1)
|
|
break;
|
|
|
|
match++;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
|
|
return match;
|
|
}
|
|
bool __fastcall MatchDiv32u(u32 op,u32 pc)
|
|
{
|
|
div_som_reg1=NoReg;
|
|
div_som_reg2=NoReg;
|
|
div_som_reg3=NoReg;
|
|
|
|
u32 match=MatchDiv32(pc+2,div_som_reg1,div_som_reg2,div_som_reg3);
|
|
|
|
|
|
//dlog("DIV32U matched %d%% @ 0x%X\n",match*100/65,pc);
|
|
if (match==65)
|
|
{
|
|
//DIV32U was perfectly matched :)
|
|
return true;
|
|
}
|
|
else //no match ...
|
|
return false;
|
|
}
|
|
|
|
bool __fastcall MatchDiv32s(u32 op,u32 pc)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
div_som_reg1=NoReg;
|
|
div_som_reg2=(Sh4RegType)m;
|
|
div_som_reg3=(Sh4RegType)n;
|
|
|
|
u32 match=MatchDiv32(pc+2,div_som_reg1,div_som_reg2,div_som_reg3);
|
|
// dlog("DIV32S matched %d%% @ 0x%X\n",match*100/65,pc);
|
|
|
|
if (match==65)
|
|
{
|
|
//DIV32S was perfectly matched :)
|
|
return true;
|
|
}
|
|
else //no match ...
|
|
return false;
|
|
}
|
|
//div0u
|
|
rsh4op(i0000_0000_0001_1001)
|
|
{
|
|
if (MatchDiv32u(op,pc))
|
|
{
|
|
//DIV32U was perfectly matched :)
|
|
bb->flags.SynthOpcode=BLOCK_SOM_SIZE_128;
|
|
ilst->div(div_som_reg1,div_som_reg2,div_som_reg3,FLAG_ZX|FLAG_32);
|
|
// dlog("div32 %d/%d/%d\n",div_som_reg1,div_som_reg2,div_som_reg3);
|
|
}
|
|
else //fallback to interpreter (16b div propably)
|
|
shil_interpret(op);
|
|
}
|
|
//div0s <REG_M>,<REG_N>
|
|
rsh4op(i0010_nnnn_mmmm_0111)
|
|
{
|
|
if (MatchDiv32s(op,pc))
|
|
{
|
|
//DIV32S was perfectly matched :)
|
|
bb->flags.SynthOpcode=BLOCK_SOM_SIZE_128;
|
|
ilst->div(div_som_reg1,div_som_reg2,div_som_reg3,FLAG_SX|FLAG_32);
|
|
// dlog("div32s %d/%d/%d\n",div_som_reg1,div_som_reg2,div_som_reg3);
|
|
//shil_interpret(op);
|
|
}
|
|
else //fallback to interpreter (16b div propably)
|
|
shil_interpret(op);
|
|
|
|
return;
|
|
}
|
|
|
|
//div1 <REG_M>,<REG_N>
|
|
rsh4op(i0011_nnnn_mmmm_0100)
|
|
{
|
|
//u32 n=GetN(op);
|
|
//u32 m=GetM(op);
|
|
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//************************ Simple maths ************************
|
|
//addc <REG_M>,<REG_N>
|
|
rsh4op(i0011_nnnn_mmmm_1110)
|
|
{
|
|
u32 n=GetN(op);
|
|
u32 m=GetM(op);
|
|
|
|
ilst->adc(r[n],r[m]); //add w/ carry
|
|
handle_stids; ilst->SaveT(CC_O);
|
|
}
|
|
|
|
// addv <REG_M>,<REG_N>
|
|
rsh4op(i0011_nnnn_mmmm_1111)
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//subc <REG_M>,<REG_N>
|
|
rsh4op(i0011_nnnn_mmmm_1010)
|
|
{
|
|
//u32 n = GetN(op);
|
|
//u32 m = GetM(op);
|
|
/*
|
|
ilst->neg(r[n]); //dest=-dest
|
|
ilst->LoadT(CF); //load T to carry flag
|
|
ilst->adc(r[n],r[m]); //add w/ carry
|
|
handle_stids; ilst->SaveT(SaveCF);//save CF to T
|
|
*/
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//subv <REG_M>,<REG_N>
|
|
rsh4op(i0011_nnnn_mmmm_1011)
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//dt <REG_N>
|
|
rsh4op(i0100_nnnn_0001_0000)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
ilst->dec(r[n]);
|
|
handle_stids; ilst->SaveT(CC_Z);
|
|
}
|
|
|
|
//negc <REG_M>,<REG_N>
|
|
rsh4op(i0110_nnnn_mmmm_1010)
|
|
{
|
|
//u32 n = GetN(op);
|
|
//u32 m = GetM(op);
|
|
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//neg <REG_M>,<REG_N>
|
|
rsh4op(i0110_nnnn_mmmm_1011)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ilst->mov(r[n],r[m]);
|
|
ilst->neg(r[n]);
|
|
}
|
|
|
|
//not <REG_M>,<REG_N>
|
|
rsh4op(i0110_nnnn_mmmm_0111)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ilst->mov(r[n],r[m]);
|
|
ilst->__not(r[n]);
|
|
}
|
|
|
|
//************************ shifts/rotates ************************
|
|
//shll <REG_N>
|
|
rsh4op(i0100_nnnn_0000_0000)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
ilst->shl(r[n],1,true);
|
|
handle_stids; ilst->SaveT(CC_E);
|
|
}
|
|
|
|
//shal <REG_N>
|
|
rsh4op(i0100_nnnn_0010_0000)
|
|
{
|
|
u32 n=GetN(op);
|
|
|
|
ilst->shl(r[n],1,true);
|
|
handle_stids; ilst->SaveT(CC_E);
|
|
}
|
|
|
|
//shlr <REG_N>
|
|
rsh4op(i0100_nnnn_0000_0001)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
ilst->shr(r[n],1,true);
|
|
handle_stids; ilst->SaveT(CC_E);
|
|
}
|
|
|
|
//shar <REG_N>
|
|
rsh4op(i0100_nnnn_0010_0001)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
ilst->sar(r[n],1,true);
|
|
handle_stids; ilst->SaveT(CC_E);
|
|
}
|
|
|
|
//shad <REG_M>,<REG_N>
|
|
rsh4op(i0100_nnnn_mmmm_1100)
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//shld <REG_M>,<REG_N>
|
|
rsh4op(i0100_nnnn_mmmm_1101)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ilst->shld(r[n],r[m]);
|
|
|
|
//shil_interpret(op);
|
|
}
|
|
|
|
//rotcl <REG_N>
|
|
rsh4op(i0100_nnnn_0010_0100)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
ilst->rcl(r[n]);
|
|
handle_stids; ilst->SaveT(CC_E);
|
|
}
|
|
|
|
//rotl <REG_N>
|
|
rsh4op(i0100_nnnn_0000_0100)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
ilst->rol(r[n]);
|
|
handle_stids; ilst->SaveT(CC_E);
|
|
}
|
|
|
|
//rotcr <REG_N>
|
|
rsh4op(i0100_nnnn_0010_0101)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
ilst->rcr(r[n]);
|
|
handle_stids; ilst->SaveT(CC_E);
|
|
}
|
|
|
|
//rotr <REG_N>
|
|
rsh4op(i0100_nnnn_0000_0101)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
ilst->ror(r[n]);
|
|
handle_stids; ilst->SaveT(CC_E);
|
|
}
|
|
//************************ byte reorder/sign ************************
|
|
//swap.b <REG_M>,<REG_N>
|
|
rsh4op(i0110_nnnn_mmmm_1000)
|
|
{
|
|
u32 m = GetM(op);
|
|
u32 n = GetN(op);
|
|
|
|
ilst->mov(r[n],r[m]);
|
|
ilst->bswap(r[n]);
|
|
}
|
|
|
|
//swap.w <REG_M>,<REG_N>
|
|
rsh4op(i0110_nnnn_mmmm_1001)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ilst->mov(r[n],r[m]);
|
|
ilst->wswap(r[n]);
|
|
}
|
|
|
|
//extu.b <REG_M>,<REG_N>
|
|
rsh4op(i0110_nnnn_mmmm_1100)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ilst->movzxb(r[n],r[m]);
|
|
}
|
|
|
|
//extu.w <REG_M>,<REG_N>
|
|
rsh4op(i0110_nnnn_mmmm_1101)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ilst->movzxw(r[n],r[m]);
|
|
}
|
|
|
|
//exts.b <REG_M>,<REG_N>
|
|
rsh4op(i0110_nnnn_mmmm_1110)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ilst->movsxb(r[n],r[m]);
|
|
}
|
|
|
|
|
|
//exts.w <REG_M>,<REG_N>
|
|
rsh4op(i0110_nnnn_mmmm_1111)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ilst->movsxw(r[n],r[m]);
|
|
}
|
|
|
|
|
|
//xtrct <REG_M>,<REG_N>
|
|
rsh4op(i0010_nnnn_mmmm_1101)
|
|
{
|
|
//u32 n = GetN(op);
|
|
//u32 m = GetM(op);
|
|
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//************************ xxx.b #<imm>,@(R0,GBR) ************************
|
|
//tst.b #<imm>,@(R0,GBR)
|
|
rsh4op(i1100_1100_iiii_iiii)
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//and.b #<imm>,@(R0,GBR)
|
|
rsh4op(i1100_1101_iiii_iiii)
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//xor.b #<imm>,@(R0,GBR)
|
|
rsh4op(i1100_1110_iiii_iiii)
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//or.b #<imm>,@(R0,GBR)
|
|
rsh4op(i1100_1111_iiii_iiii)
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//tas.b @<REG_N>
|
|
rsh4op(i0100_nnnn_0001_1011)
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
|
|
//bah
|
|
//Not implt
|
|
rsh4op(iNotImplemented)
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
|
|
rsh4op(gdrom_hle_op)
|
|
{
|
|
EMUERROR("GDROM HLE NOT SUPPORTED");
|
|
}
|
|
|
|
//all fpu emulation ops :)
|
|
|
|
//fadd <FREG_M>,<FREG_N>
|
|
rsh4op(i1111_nnnn_mmmm_0000)
|
|
{//TODO : CHECK THIS PR FP
|
|
|
|
if (sh4r.fpscr.PR == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
ilst->fadd(fr[n],fr[m]);
|
|
//fr[n] += fr[m];
|
|
//CHECK_FPU_32(fr[n]);
|
|
}
|
|
else
|
|
{
|
|
shil_interpret(op);
|
|
return;
|
|
/*
|
|
u32 n = (op >> 9) & 0x07;
|
|
u32 m = (op >> 5) & 0x07;
|
|
|
|
ilst->fadd(dr[n],dr[m]);
|
|
*/
|
|
//START64();
|
|
//double drn=GetDR(n), drm=GetDR(m);
|
|
//drn += drm;
|
|
//CHECK_FPU_64(drn);
|
|
//SetDR(n,drn);
|
|
//END64();
|
|
}
|
|
}
|
|
|
|
//fsub <FREG_M>,<FREG_N>
|
|
rsh4op(i1111_nnnn_mmmm_0001)
|
|
{
|
|
if (sh4r.fpscr.PR == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ilst->fsub(fr[n],fr[m]);
|
|
//fr[n] -= fr[m];
|
|
//CHECK_FPU_32(fr[n]);
|
|
}
|
|
else
|
|
{
|
|
shil_interpret(op);
|
|
return;
|
|
//u32 n = (op >> 9) & 0x07;
|
|
//u32 m = (op >> 5) & 0x07;
|
|
//
|
|
//ilst->fsub(dr[n],dr[m]);
|
|
//START64();
|
|
//double drn=GetDR(n), drm=GetDR(m);
|
|
//drn-=drm;
|
|
//dr[n] -= dr[m];
|
|
//SetDR(n,drn);
|
|
//END64();
|
|
}
|
|
}
|
|
//fmul <FREG_M>,<FREG_N>
|
|
rsh4op(i1111_nnnn_mmmm_0010)
|
|
{
|
|
if (sh4r.fpscr.PR == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
ilst->fmul(fr[n],fr[m]);
|
|
}
|
|
else
|
|
{
|
|
shil_interpret(op);
|
|
return;
|
|
//u32 n = (op >> 9) & 0x07;
|
|
//u32 m = (op >> 5) & 0x07;
|
|
//START64();
|
|
//double drn=GetDR(n), drm=GetDR(m);
|
|
//drn*=drm;
|
|
//dr[n] *= dr[m];
|
|
//SetDR(n,drn);
|
|
//END64();
|
|
//ilst->fmul(dr[n],dr[m]);
|
|
}
|
|
}
|
|
//fdiv <FREG_M>,<FREG_N>
|
|
rsh4op(i1111_nnnn_mmmm_0011)
|
|
{
|
|
if (sh4r.fpscr.PR == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
ilst->fdiv(fr[n],fr[m]);
|
|
}
|
|
else
|
|
{
|
|
shil_interpret(op);
|
|
return;
|
|
//u32 n = (op >> 9) & 0x07;
|
|
//u32 m = (op >> 5) & 0x07;
|
|
//START64();
|
|
//double drn=GetDR(n), drm=GetDR(m);
|
|
//drn/=drm;
|
|
//SetDR(n,drn);
|
|
//END64();
|
|
//ilst->fdiv(dr[n],dr[m]);
|
|
}
|
|
}
|
|
//fcmp/eq <FREG_M>,<FREG_N>
|
|
rsh4op(i1111_nnnn_mmmm_0100)
|
|
{
|
|
if (sh4r.fpscr.PR == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
//sr.T = (fr[m] == fr[n]) ? 1 : 0;
|
|
ilst->fcmp(fr[n],fr[m]);
|
|
handle_stids; ilst->SaveT(CC_FPU_E);
|
|
}
|
|
else
|
|
{
|
|
shil_interpret(op);
|
|
return;
|
|
//u32 n = (op >> 9) & 0x07;
|
|
//u32 m = (op >> 5) & 0x07;
|
|
//ilst->cmp(dr[n],dr[m]);
|
|
//START64();
|
|
//sr.T = (GetDR(m) == GetDR(n)) ? 1 : 0;
|
|
//END64();
|
|
}
|
|
}
|
|
//fcmp/gt <FREG_M>,<FREG_N>
|
|
rsh4op(i1111_nnnn_mmmm_0101)
|
|
{
|
|
if (sh4r.fpscr.PR == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
/*if (fr[n] > fr[m])
|
|
sr.T = 1;
|
|
else
|
|
sr.T = 0;*/
|
|
ilst->fcmp(fr[n],fr[m]);
|
|
handle_stids; ilst->SaveT(CC_NBE);
|
|
}
|
|
else
|
|
{
|
|
shil_interpret(op);
|
|
return;
|
|
//u32 n = (op >> 9) & 0x07;
|
|
//u32 m = (op >> 5) & 0x07;
|
|
|
|
/*START64();
|
|
if (GetDR(n) > GetDR(m))
|
|
sr.T = 1;
|
|
else
|
|
sr.T = 0;
|
|
END64();*/
|
|
|
|
//ilst->cmp(dr[n],dr[m]);
|
|
}
|
|
}
|
|
//fmov.s @(R0,<REG_M>),<FREG_N>
|
|
rsh4op(i1111_nnnn_mmmm_0110)
|
|
{
|
|
if (sh4r.fpscr.SZ == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
//fr_hex[n] = ReadMem32(r[m] + r[0]);
|
|
ilst->readm32(fr[n],r[0],r[m]);
|
|
}
|
|
else
|
|
{
|
|
//shil_interpret(op);
|
|
//return;
|
|
u32 n = (op >> 8) & 0x0E;
|
|
u32 m = GetM(op);
|
|
if (((op >> 8) & 0x1) == 0)
|
|
{
|
|
//fr_hex[n] = ReadMem32(r[m] + r[0]);
|
|
//fr_hex[n + 1] = ReadMem32(r[m] + r[0] + 4);
|
|
ilst->readm64(dr[n>>1],r[0],r[m]);
|
|
}
|
|
else
|
|
{
|
|
//xf_hex[n] = ReadMem32(r[m] + r[0]);
|
|
//xf_hex[n + 1] = ReadMem32(r[m] + r[0] + 4);
|
|
ilst->readm64(xd[n>>1],r[0],r[m]);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//fmov.s <FREG_M>,@(R0,<REG_N>)
|
|
rsh4op(i1111_nnnn_mmmm_0111)
|
|
{//used
|
|
if (sh4r.fpscr.SZ == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
//WriteMem32(r[0] + r[n], fr_hex[m]);
|
|
ilst->writem32(fr[m],r[0],r[n]);
|
|
}
|
|
else
|
|
{
|
|
//shil_interpret(op);
|
|
//return;
|
|
u32 n = GetN(op);
|
|
u32 m = (op >> 4) & 0x0E;
|
|
if (((op >> 4) & 0x1) == 0)
|
|
{
|
|
//WriteMem32(r[n] + r[0], fr_hex[m]);
|
|
//WriteMem32(r[n] + r[0] + 4, fr_hex[m + 1]);
|
|
ilst->writem64(dr[m>>1],r[0],r[n]);
|
|
}
|
|
else
|
|
{
|
|
//WriteMem32(r[n] + r[0], xf_hex[m]);
|
|
//WriteMem32(r[n] + r[0] + 4, xf_hex[m + 1]);
|
|
ilst->writem64(xd[m>>1],r[0],r[n]);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//fmov.s @<REG_M>,<FREG_N>
|
|
rsh4op(i1111_nnnn_mmmm_1000)
|
|
{//used
|
|
if (sh4r.fpscr.SZ == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
//fr_hex[n] = ReadMem32(r[m]);
|
|
ilst->readm32(fr[n],r[m]);
|
|
}
|
|
else
|
|
{
|
|
//shil_interpret(op);
|
|
//return;
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
if ((n & 0x1) == 0)
|
|
{
|
|
//fr_hex[n] = ReadMem32(r[m]);
|
|
//fr_hex[n + 1] = ReadMem32(r[m] + 4);
|
|
ilst->readm64(dr[n>>1],r[m]);
|
|
//ilst->readm32(fr[n&~1],r[m]);
|
|
//ilst->readm32(fr[n|1],r[m],4);
|
|
}
|
|
else
|
|
{
|
|
//xf_hex[n] = ReadMem32(r[m]);
|
|
//xf_hex[n + 1] = ReadMem32(r[m] + 4);
|
|
ilst->readm64(xd[n>>1],r[m]);
|
|
//ilst->readm32(xf[n&~1],r[m]);
|
|
//ilst->readm32(xf[n|1],r[m],4);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//fmov.s @<REG_M>+,<FREG_N>
|
|
rsh4op(i1111_nnnn_mmmm_1001)
|
|
{
|
|
if (sh4r.fpscr.SZ == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
//fr_hex[n] = ReadMem32(r[m]);
|
|
ilst->readm32(fr[n],r[m]);
|
|
ilst->add(r[m],4);
|
|
//r[m] += 4;
|
|
}
|
|
else
|
|
{
|
|
//shil_interpret(op);
|
|
//return;
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
if ((n & 0x1) == 0)
|
|
{
|
|
//fr_hex[n] = ReadMem32(r[m]);
|
|
//fr_hex[n + 1] = ReadMem32(r[m]+ 4);
|
|
|
|
ilst->readm64(dr[n>>1],r[m]);
|
|
//ilst->readm32(fr[n&~1],r[m]);
|
|
//ilst->readm32(fr[n|1],r[m],4);
|
|
}
|
|
else
|
|
{
|
|
//xf_hex[n] = ReadMem32(r[m] );
|
|
//xf_hex[n + 1] = ReadMem32(r[m]+ 4);
|
|
ilst->readm64(xd[n>>1],r[m]);
|
|
//ilst->readm32(xf[n&~1],r[m]);
|
|
//ilst->readm32(xf[n|1],r[m],4);
|
|
}
|
|
ilst->add(r[m],8);
|
|
//r[m] += 8;
|
|
}
|
|
}
|
|
|
|
|
|
//fmov.s <FREG_M>,@<REG_N>
|
|
rsh4op(i1111_nnnn_mmmm_1010)
|
|
{
|
|
if (sh4r.fpscr.SZ == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
//WriteMem32(r[n], fr_hex[m]);
|
|
ilst->writem32(fr[m],r[n]);
|
|
}
|
|
else
|
|
{
|
|
//shil_interpret(op);
|
|
//return;
|
|
|
|
u32 n = GetN(op);
|
|
u32 m = (op >> 4) & 0x0E;
|
|
|
|
if (((op >> 4) & 0x1) == 0)
|
|
{
|
|
//WriteMem32(r[n], fr_hex[m]);
|
|
//WriteMem32(r[n] + 4, fr_hex[m + 1]);
|
|
ilst->writem64(dr[m>>1],r[n]);
|
|
}
|
|
else
|
|
{
|
|
//WriteMem32(r[n], xf_hex[m]);
|
|
//WriteMem32(r[n] + 4, xf_hex[m + 1]);
|
|
ilst->writem64(xd[m>>1],r[n]);
|
|
}
|
|
}
|
|
}
|
|
|
|
//fmov.s <FREG_M>,@-<REG_N>
|
|
rsh4op(i1111_nnnn_mmmm_1011)
|
|
{//used
|
|
if (sh4r.fpscr.SZ == 0)
|
|
{
|
|
//iNimp("fmov.s <FREG_M>,@-<REG_N>");
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
//r[n] -= 4;
|
|
ilst->sub(r[n],4);
|
|
ilst->writem32(fr[m],r[n]);
|
|
//WriteMem32(r[n], fr_hex[m]);
|
|
}
|
|
else
|
|
{
|
|
//shil_interpret(op);
|
|
//return;
|
|
|
|
u32 n = GetN(op);
|
|
u32 m = (op >> 4) & 0x0E;
|
|
|
|
//r[n] -= 8;
|
|
if (((op >> 4) & 0x1) == 0)
|
|
{
|
|
//WriteMem32(r[n] , fr_hex[m]);
|
|
//WriteMem32(r[n]+ 4, fr_hex[m + 1]);
|
|
ilst->sub(r[n],8);
|
|
ilst->writem64(dr[m>>1],r[n]);
|
|
|
|
}
|
|
else
|
|
{
|
|
//WriteMem32(r[n] , xf_hex[m]);
|
|
//WriteMem32(r[n]+ 4, xf_hex[m + 1]);
|
|
ilst->sub(r[n],8);
|
|
ilst->writem64(xd[m>>1],r[n]);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//fmov <FREG_M>,<FREG_N>
|
|
rsh4op(i1111_nnnn_mmmm_1100)
|
|
{//TODO : checkthis
|
|
if (sh4r.fpscr.SZ == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
//fr[n] = fr[m];
|
|
ilst->mov(fr[n],fr[m]);
|
|
}
|
|
else
|
|
{
|
|
u32 n = (op >> 9) & 0x7;
|
|
u32 m = (op >> 5) & 0x7;
|
|
|
|
switch ((op >> 4) & 0x11)
|
|
{
|
|
case 0x00:
|
|
//dr[n] = dr[m];
|
|
//fr_hex[n] = fr_hex[m];
|
|
//fr_hex[n + 1] = fr_hex[m + 1];
|
|
ilst->mov(dr[n],dr[m]);
|
|
break;
|
|
case 0x01:
|
|
//dr[n] = xf[m];
|
|
//fr_hex[n] = xf_hex[m];
|
|
//fr_hex[n + 1] = xf_hex[m + 1];
|
|
ilst->mov(dr[n],xd[m]);
|
|
break;
|
|
case 0x10:
|
|
//xf[n] = dr[m];
|
|
//xf_hex[n] = fr_hex[m];
|
|
//xf_hex[n + 1] = fr_hex[m + 1];
|
|
ilst->mov(xd[n],dr[m]);
|
|
break;
|
|
case 0x11:
|
|
//xf[n] = xf[m];
|
|
//xf_hex[n] = xf_hex[m];
|
|
//xf_hex[n + 1] = xf_hex[m + 1];
|
|
ilst->mov(xd[n],xd[m]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//fabs <FREG_N>
|
|
rsh4op(i1111_nnnn_0101_1101)
|
|
{
|
|
int n=GetN(op);
|
|
|
|
if (sh4r.fpscr.PR ==0)
|
|
{
|
|
//fr_hex[n]&=0x7FFFFFFF;
|
|
ilst->fabs(fr[n]);
|
|
}
|
|
else
|
|
{
|
|
//fr_hex[(n&0xE)+1]&=0x7FFFFFFF;
|
|
|
|
shil_interpret(op);
|
|
//gli ilst->fabs(dr[n>>1]);
|
|
}
|
|
|
|
}
|
|
|
|
//FSCA FPUL, DRn//F0FD//1111_nnn0_1111_1101
|
|
rsh4op(i1111_nnn0_1111_1101)
|
|
{
|
|
if (sh4r.fpscr.PR==0)
|
|
{
|
|
int n=GetN(op) & 0xE;
|
|
ilst->fsca(fr[n]);
|
|
//shil_interpret(op);
|
|
}
|
|
else
|
|
iNimp("FSCA : Double precision mode");
|
|
|
|
}
|
|
|
|
//FSRRA //1111_nnnn_0111_1101
|
|
rsh4op(i1111_nnnn_0111_1101)
|
|
{
|
|
|
|
// What about double precision?
|
|
if (sh4r.fpscr.PR==0)
|
|
{
|
|
u32 n = GetN(op);
|
|
ilst->fsrra(fr[n]);
|
|
//shil_interpret(op);
|
|
}
|
|
else
|
|
iNimp("FSRRA : Double precision mode");
|
|
|
|
}
|
|
|
|
//fcnvds <DR_N>,FPUL
|
|
rsh4op(i1111_nnnn_1011_1101)
|
|
{
|
|
if (sh4r.fpscr.PR == 1)
|
|
{
|
|
shil_interpret(op);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
iNimp("fcnvds <DR_N>,FPUL,m=0");
|
|
}
|
|
}
|
|
|
|
|
|
//fcnvsd FPUL,<DR_N>
|
|
rsh4op(i1111_nnnn_1010_1101)
|
|
{
|
|
|
|
if (sh4r.fpscr.PR == 1)
|
|
{
|
|
shil_interpret(op);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
iNimp("fcnvsd FPUL,<DR_N>,m=0");
|
|
}
|
|
}
|
|
|
|
//fipr <FV_M>,<FV_N>
|
|
rsh4op(i1111_nnmm_1110_1101)
|
|
{
|
|
int n=GetN(op)&0xC;
|
|
int m=(GetN(op)&0x3)<<2;
|
|
ilst->fipr(fr[n],fr[m]);
|
|
bb->flags.FpuIsVector=true;
|
|
}
|
|
|
|
|
|
//fldi0 <FREG_N>
|
|
rsh4op(i1111_nnnn_1000_1101)
|
|
{
|
|
if (sh4r.fpscr.PR==0)
|
|
{
|
|
//iNimp("fldi0 <FREG_N>");
|
|
u32 n = GetN(op);
|
|
|
|
//fr[n] = 0.0f;
|
|
ilst->mov(fr[n],0);//0.0f is 0x0 , right ?
|
|
}
|
|
else
|
|
{
|
|
iNimp("fldi0 <Dreg_N>");
|
|
}
|
|
}
|
|
|
|
|
|
//fldi1 <FREG_N>
|
|
rsh4op(i1111_nnnn_1001_1101)
|
|
{
|
|
if (sh4r.fpscr.PR==0)
|
|
{
|
|
//iNimp("fldi1 <FREG_N>");
|
|
u32 n = GetN(op);
|
|
|
|
//fr[n] = 1.0f;
|
|
ilst->mov(fr[n],0x3f800000);//1.0f is 0x3f800000 , right ?
|
|
}
|
|
else
|
|
{
|
|
iNimp("fldi1 <Dreg_N>");
|
|
}
|
|
}
|
|
|
|
|
|
//flds <FREG_N>,FPUL
|
|
rsh4op(i1111_nnnn_0001_1101)
|
|
{
|
|
//this seems to be a valid opcode even if double precicion is activated
|
|
//carrier requires this
|
|
//u32 n = GetN(op);
|
|
//fpul = fr_hex[n];
|
|
ilst->mov(reg_fpul,fr[GetN(op)]);
|
|
}
|
|
|
|
|
|
//float FPUL,<FREG_N>
|
|
rsh4op(i1111_nnnn_0010_1101)
|
|
{//TODO : CHECK THIS (FP)
|
|
|
|
if (sh4r.fpscr.PR == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
//fr[n] = (float)(int)fpul;
|
|
ilst->floatfpul(fr[n]);
|
|
//shil_interpret(op);
|
|
}
|
|
else
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
}
|
|
|
|
//ftrc <FREG_N>, FPUL
|
|
rsh4op(i1111_nnnn_0011_1101)
|
|
{
|
|
if (sh4r.fpscr.PR == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
//fpul = (u32)(s32)fr[n];
|
|
ilst->ftrc(fr[n]);
|
|
//shil_interpret(op);
|
|
}
|
|
else
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
}
|
|
|
|
|
|
//fneg <FREG_N>
|
|
rsh4op(i1111_nnnn_0100_1101)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
if (sh4r.fpscr.PR ==0)
|
|
{
|
|
ilst->fneg(fr[n]);
|
|
}
|
|
else
|
|
{
|
|
shil_interpret(op);
|
|
//gli ilst->fneg(dr[n>>1]);
|
|
}
|
|
}
|
|
|
|
|
|
//frchg
|
|
rsh4op(i1111_1011_1111_1101)
|
|
{
|
|
// needed for some obscure reason related to BLOCK_EXITTYPE_FIXED_CSC
|
|
need_rpctmp;
|
|
ilst->mov(reg_pc,pc);
|
|
|
|
ilst->frchg();
|
|
return;
|
|
|
|
//iNimp("frchg");
|
|
//sh4r.fpscr.FR = 1 - sh4r.fpscr.FR;
|
|
|
|
//UpdateFPSCR();
|
|
}
|
|
|
|
|
|
//fschg
|
|
rsh4op(i1111_0011_1111_1101)
|
|
{
|
|
shil_interpret(op);
|
|
return;
|
|
|
|
//iNimp("fschg");
|
|
//sh4r.fpscr.SZ = 1 - sh4r.fpscr.SZ;
|
|
//UpdateFPSCR();//*FixME* prob not needed
|
|
}
|
|
|
|
//fsqrt <FREG_N>
|
|
rsh4op(i1111_nnnn_0110_1101)
|
|
{
|
|
if (sh4r.fpscr.PR == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
//fr[n] = (float)sqrt((double)fr[n]);
|
|
//CHECK_FPU_32(fr[n]);
|
|
ilst->fsqrt(fr[n]);
|
|
}
|
|
else
|
|
{
|
|
//Operation _can_ be done on sh4
|
|
iNimp("fsqrt <DREG_N>");
|
|
}
|
|
}
|
|
|
|
//fsts FPUL,<FREG_N>
|
|
rsh4op(i1111_nnnn_0000_1101)
|
|
{
|
|
//this seems to be a valid opcode even if double precicion is activated
|
|
//carrier requires it
|
|
//u32 n = GetN(op);
|
|
ilst->mov(fr[GetN(op)],reg_fpul);
|
|
|
|
}
|
|
|
|
//fmac <FREG_0>,<FREG_M>,<FREG_N>
|
|
rsh4op(i1111_nnnn_mmmm_1110)
|
|
{
|
|
//iNimp("fmac <FREG_0>,<FREG_M>,<FREG_N>");
|
|
if (sh4r.fpscr.PR==0)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
//fr[n] += fr[0] * fr[m];
|
|
ilst->fmac(fr[n],fr[m]);
|
|
//CHECK_FPU_32(fr[n]);
|
|
}
|
|
else
|
|
{
|
|
iNimp("fmac <DREG_0>,<DREG_M>,<DREG_N>");
|
|
}
|
|
}
|
|
|
|
|
|
//ftrv xmtrx,<FV_N>
|
|
rsh4op(i1111_nn01_1111_1101)
|
|
{
|
|
u32 n=GetN(op)&0xC;
|
|
ilst->ftrv(fr[n]);
|
|
bb->flags.FpuIsVector=true;
|
|
}
|
|
|
|
|
|
rsh4op(icpu_nimp)
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
|
|
|
|
//Branches
|
|
|
|
void DoDslot(u32 pc,BasicBlock* bb, bool CouldNeedPCtmp)
|
|
{
|
|
u16 opcode=ReadMem16(pc+2);
|
|
|
|
if (opcode==0 || opcode==0)
|
|
dlog("0 on delayslot , ingoring it ..\n");
|
|
else{
|
|
bb->flags.IsDelaySlot=true;
|
|
bb->flags.CouldNeedPCtmp=CouldNeedPCtmp;
|
|
bb->flags.NeedPCtmp=false;
|
|
RecOpPtr[opcode](opcode,pc+2,bb);
|
|
bb->flags.IsDelaySlot=false;
|
|
}
|
|
}
|
|
|
|
//braf <REG_N>
|
|
rsh4op(i0000_nnnn_0010_0011)
|
|
{
|
|
need_rpctmp;
|
|
|
|
u32 n = GetN(op);
|
|
/*
|
|
u32 newpc = r[n] + pc + 2;//pc +2 is done after
|
|
ExecuteDelayslot(); //WARN : r[n] can change here
|
|
pc = newpc;
|
|
*/
|
|
|
|
//shil_interpret(op);
|
|
//ilst->add(reg_pc,2);
|
|
//return;
|
|
bb->flags.ExitType = BLOCK_EXITTYPE_DYNAMIC;
|
|
bb->flags.EndAnalyse=true;
|
|
ilst->mov(reg_pc,r[n]);
|
|
ilst->add(reg_pc,pc+4);
|
|
DoDslot(pc,bb,true);
|
|
handle_rpctmp;
|
|
}
|
|
//bsrf <REG_N>
|
|
rsh4op(i0000_nnnn_0000_0011)
|
|
{
|
|
need_rpctmp;
|
|
|
|
u32 n = GetN(op);
|
|
/*
|
|
u32 newpc = r[n] + pc +2;//pc +2 is done after
|
|
pr = pc + 4; //after delayslot
|
|
ExecuteDelayslot(); //WARN : pr and r[n] can change here
|
|
pc = newpc;
|
|
|
|
AddCall(pr-4,pr,pc,0);
|
|
*/
|
|
|
|
//shil_interpret(op);
|
|
//ilst->add(reg_pc,2);
|
|
//return;
|
|
|
|
bb->flags.EndAnalyse=true;
|
|
bb->flags.ExitType=BLOCK_EXITTYPE_DYNAMIC_CALL;
|
|
ilst->mov(reg_pr,pc+4);
|
|
ilst->mov(reg_pc,r[n]);
|
|
ilst->add(reg_pc,pc+4);
|
|
DoDslot(pc,bb,true);
|
|
handle_rpctmp;
|
|
bb->TT_next_addr=pc+4;
|
|
}
|
|
|
|
|
|
//rte
|
|
rsh4op(i0000_0000_0010_1011)
|
|
{
|
|
need_rpctmp;
|
|
|
|
/*
|
|
//iNimp("rte");
|
|
sr.SetFull(ssr);
|
|
u32 newpc = spc;//+2 is added after instruction
|
|
ExecuteDelayslot();
|
|
pc = newpc -2;
|
|
RemoveCall(spc,1);
|
|
UpdateSR();
|
|
*/
|
|
shil_interpret(op);
|
|
ilst->add(reg_pc,2);
|
|
|
|
bb->flags.EndAnalyse=true;
|
|
bb->flags.ExitType=BLOCK_EXITTYPE_DYNAMIC;
|
|
return;
|
|
}
|
|
|
|
|
|
//rts
|
|
rsh4op(i0000_0000_0000_1011)
|
|
{
|
|
need_rpctmp;
|
|
|
|
/*
|
|
//TODO Check new delay slot code [28/1/06]
|
|
u32 newpc=pr;//+2 is added after instruction
|
|
ExecuteDelayslot(); //WARN : pr can change here
|
|
pc=newpc-2;
|
|
RemoveCall(pr,0);
|
|
*/
|
|
//shil_interpret(op);
|
|
//ilst->add(reg_pc,2);
|
|
//return;
|
|
bb->flags.EndAnalyse = true;
|
|
bb->flags.ExitType= BLOCK_EXITTYPE_RET;
|
|
ilst->mov(reg_pc,reg_pr);
|
|
DoDslot(pc,bb,true);
|
|
handle_rpctmp;
|
|
}
|
|
|
|
|
|
// bf <bdisp8>
|
|
rsh4op(i1000_1011_iiii_iiii)
|
|
{//ToDo : Check Me [26/4/05] | Check DELAY SLOT [28/1/06]
|
|
/*
|
|
if (sr.T==0)
|
|
{
|
|
//direct jump
|
|
pc = (u32)((GetSImm8(op))*2 + 4 + pc );
|
|
pc-=2;
|
|
}
|
|
*/
|
|
|
|
bb->TF_next_addr=pc+2;
|
|
bb->TT_next_addr=(u32)((GetSImm8(op))*2 + 4 + pc );
|
|
|
|
bb->flags.EndAnalyse=true;
|
|
bb->flags.ExitType=BLOCK_EXITTYPE_COND;
|
|
}
|
|
|
|
|
|
// bf.s <bdisp8>
|
|
rsh4op(i1000_1111_iiii_iiii)
|
|
{//TODO : Check This [26/4/05] | Check DELAY SLOT [28/1/06]
|
|
/*
|
|
if (sr.T==0)
|
|
{
|
|
//delay 1 instruction
|
|
u32 newpc=(u32) ( (GetSImm8(op)<<1) + pc+2);//pc+2 is done after
|
|
ExecuteDelayslot();
|
|
pc = newpc;
|
|
}
|
|
*/
|
|
//shil_interpret(op);
|
|
//return;
|
|
/*shil_interpret(op);
|
|
ilst->add(reg_pc,2);
|
|
return;*/
|
|
|
|
bb->TF_next_addr=pc+4;
|
|
bb->TT_next_addr=(u32)((GetSImm8(op))*2 + 4 + pc );
|
|
|
|
DoDslot(pc,bb,false);
|
|
bb->flags.EndAnalyse = true;
|
|
bb->flags.ExitType = BLOCK_EXITTYPE_COND;
|
|
}
|
|
|
|
|
|
// bt <bdisp8>
|
|
rsh4op(i1000_1001_iiii_iiii)
|
|
{//TODO : Check This [26/4/05] | Check DELAY SLOT [28/1/06]
|
|
/*
|
|
if (sr.T==1)
|
|
{
|
|
//direct jump
|
|
pc = (u32) ( (GetSImm8(op)<<1) + pc+2);
|
|
}
|
|
*/
|
|
|
|
|
|
bb->TF_next_addr=(u32)((GetSImm8(op))*2 + 4 + pc );
|
|
bb->TT_next_addr=pc+2;
|
|
|
|
bb->flags.EndAnalyse=true;
|
|
bb->flags.ExitType=BLOCK_EXITTYPE_COND;
|
|
}
|
|
|
|
|
|
// bt.s <bdisp8>
|
|
rsh4op(i1000_1101_iiii_iiii)
|
|
{
|
|
/*
|
|
if (sr.T == 1)
|
|
{//TODO : Check This [26/4/05] | Check DELAY SLOT [28/1/06]
|
|
//delay 1 instruction
|
|
u32 newpc=(u32) ( (GetSImm8(op)<<1) + pc+2);//pc+2 is done after
|
|
ExecuteDelayslot();
|
|
pc = newpc;
|
|
}
|
|
*/
|
|
/*shil_interpret(op);
|
|
ilst->add(reg_pc,2);
|
|
return;*/
|
|
|
|
bb->TF_next_addr=(u32)((GetSImm8(op))*2 + 4 + pc );
|
|
bb->TT_next_addr=pc+4;
|
|
|
|
DoDslot(pc,bb,false);
|
|
|
|
bb->flags.EndAnalyse=true;
|
|
bb->flags.ExitType=BLOCK_EXITTYPE_COND;
|
|
}
|
|
|
|
|
|
|
|
// bra <bdisp12>
|
|
rsh4op(i1010_iiii_iiii_iiii)
|
|
{//ToDo : Check Me [26/4/05] | Check ExecuteDelayslot [28/1/06]
|
|
//delay 1 jump imm12
|
|
/*
|
|
u32 newpc =(u32) (( ((s16)((GetImm12(op))<<4)) >>3) + pc + 4);//(s16<<4,>>4(-1*2))
|
|
ExecuteDelayslot();
|
|
pc=newpc-2;
|
|
*/
|
|
|
|
bb->TF_next_addr=(u32) (( ((s16)((GetImm12(op))<<4)) >>3) + pc + 4);
|
|
bb->flags.EndAnalyse=true;
|
|
bb->flags.ExitType=BLOCK_EXITTYPE_FIXED;
|
|
DoDslot(pc,bb,false);
|
|
}
|
|
// bsr <bdisp12>
|
|
rsh4op(i1011_iiii_iiii_iiii)
|
|
{//ToDo : Check Me [26/4/05] | Check new delay slot code [28/1/06]
|
|
/*
|
|
//iNimp("bsr <bdisp12>");
|
|
u32 disp = GetImm12(op);
|
|
pr = pc + 4;
|
|
//delay 1 opcode
|
|
u32 newpc = (u32)((((s16)(disp<<4)) >> 3) + pc + 4);
|
|
AddCall(pc,pr,newpc,0); //WARN : pr can change here
|
|
ExecuteDelayslot();
|
|
pc=newpc-2;*/
|
|
|
|
bb->TF_next_addr=(u32) (( ((s16)((GetImm12(op))<<4)) >>3) + pc + 4);
|
|
bb->flags.EndAnalyse=true;
|
|
bb->flags.ExitType=BLOCK_EXITTYPE_FIXED_CALL;
|
|
|
|
ilst->mov(reg_pr,pc+4);
|
|
DoDslot(pc,bb,false);
|
|
bb->TT_next_addr=pc+4;
|
|
}
|
|
|
|
// trapa #<imm>
|
|
rsh4op(i1100_0011_iiii_iiii)
|
|
{
|
|
need_rpctmp;
|
|
|
|
/*
|
|
CCN_TRA = (GetImm8(op) << 2);
|
|
Do_Exeption(0,0x160,0x100);
|
|
*/
|
|
shil_interpret(op);
|
|
ilst->add(reg_pc,2);
|
|
bb->flags.EndAnalyse=true;
|
|
bb->flags.ExitType=BLOCK_EXITTYPE_DYNAMIC;
|
|
return;
|
|
}
|
|
//jmp @<REG_N>
|
|
rsh4op(i0100_nnnn_0010_1011)
|
|
{ //ToDo : Check Me [26/4/05] | Check new delay slot code [28/1/06]
|
|
need_rpctmp;
|
|
|
|
u32 n = GetN(op);
|
|
/*
|
|
//delay 1 instruction
|
|
u32 newpc=r[n];
|
|
ExecuteDelayslot();
|
|
pc=newpc-2;//+2 is done after
|
|
|
|
*/
|
|
//shil_interpret(op);
|
|
//ilst->add(reg_pc,2);
|
|
//return;
|
|
bb->flags.EndAnalyse=true;
|
|
bb->flags.ExitType=BLOCK_EXITTYPE_DYNAMIC;
|
|
ilst->mov(reg_pc,r[n]);
|
|
DoDslot(pc,bb,true);
|
|
handle_rpctmp;
|
|
}
|
|
|
|
|
|
//jsr @<REG_N>
|
|
rsh4op(i0100_nnnn_0000_1011)
|
|
{//ToDo : Check This [26/4/05] | Check new delay slot code [28/1/06]
|
|
need_rpctmp;
|
|
|
|
u32 n = GetN(op);
|
|
|
|
|
|
bb->flags.EndAnalyse=true;
|
|
bb->flags.ExitType=BLOCK_EXITTYPE_DYNAMIC_CALL;
|
|
ilst->mov(reg_pr,pc+4);
|
|
ilst->mov(reg_pc,r[n]);
|
|
DoDslot(pc,bb,true);
|
|
handle_rpctmp;
|
|
bb->TT_next_addr=pc+4;
|
|
}
|
|
|
|
|
|
|
|
//sh4_bpt_op => breakpoint opcode
|
|
rsh4op(sh4_bpt_op)
|
|
{
|
|
shil_interpret(op);
|
|
}
|
|
//sleep
|
|
rsh4op(i0000_0000_0001_1011)
|
|
{
|
|
need_rpctmp;
|
|
|
|
shil_interpret(op);
|
|
ilst->add(reg_pc,2);
|
|
bb->flags.EndAnalyse=true;
|
|
bb->flags.ExitType=BLOCK_EXITTYPE_DYNAMIC;
|
|
return;
|
|
}
|
|
|
|
bool __fastcall Scanner_FindSOM(u32 opcode,u32 pc,u32* SOM)
|
|
{
|
|
if (opcode ==0x0019)
|
|
{
|
|
//possible div0u
|
|
//i0000_0000_0001_1001
|
|
*SOM=128;
|
|
return MatchDiv32u(opcode,pc);
|
|
}
|
|
else if ((opcode & 0xF00F)==0x2007)
|
|
{
|
|
//possible div0s
|
|
//i0010_nnnn_mmmm_0111
|
|
*SOM=128;
|
|
return MatchDiv32s(opcode,pc);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
#define notshit
|
|
#ifdef notshit
|
|
//ok , all the opcodes to here are hand writen for the rec
|
|
//time for the compiler fun
|
|
//>:D
|
|
|
|
#undef r
|
|
#undef r_bank
|
|
|
|
struct shil_RecRegType
|
|
{
|
|
Sh4RegType regid;
|
|
//SUB
|
|
void operator-=(const u32 constv)
|
|
{
|
|
ilst->sub(regid,constv);
|
|
};
|
|
void operator-=(const shil_RecRegType& reg)
|
|
{
|
|
ilst->sub(regid,reg.regid);
|
|
}
|
|
|
|
void operator--(int wtf)
|
|
{
|
|
(*this)-=1;
|
|
}
|
|
//ADD
|
|
void operator+=(const u32 constv)
|
|
{
|
|
ilst->add(regid,constv);
|
|
};
|
|
void operator+=(const shil_RecRegType& reg)
|
|
{
|
|
ilst->add(regid,reg.regid);
|
|
}
|
|
void operator++(int wtf)
|
|
{
|
|
(*this)+=1;
|
|
}
|
|
//MOVS
|
|
void operator=(const u32 constv)
|
|
{
|
|
ilst->mov(regid,constv);
|
|
}
|
|
void operator=(const s32 constv)
|
|
{
|
|
(*this)=(u32)constv;
|
|
}
|
|
void operator=(const shil_RecRegType& reg)
|
|
{
|
|
ilst->mov(regid,reg.regid);
|
|
}
|
|
//AND
|
|
void operator&=(const u32 constv)
|
|
{
|
|
ilst->__and(regid,constv);
|
|
};
|
|
void operator&=(const shil_RecRegType& reg)
|
|
{
|
|
ilst->__and(regid,reg.regid);
|
|
};
|
|
//OR
|
|
void operator|=(const u32 constv)
|
|
{
|
|
ilst->__or(regid,constv);
|
|
};
|
|
void operator|=(const shil_RecRegType& reg)
|
|
{
|
|
ilst->__or(regid,reg.regid);
|
|
};
|
|
//XOR
|
|
void operator^=(const u32 constv)
|
|
{
|
|
ilst->__xor(regid,constv);
|
|
};
|
|
void operator^=(const shil_RecRegType& reg)
|
|
{
|
|
ilst->__xor(regid,reg.regid);
|
|
};
|
|
//SHIFT RIGHT
|
|
void operator>>=(const u32 constv)
|
|
{
|
|
ilst->shr(regid,(u8)constv,false);
|
|
};
|
|
|
|
//SHIFT LEFT
|
|
void operator<<=(const u32 constv)
|
|
{
|
|
ilst->shl(regid,(u8)constv,false);
|
|
};
|
|
};
|
|
|
|
|
|
//Read Mem macros
|
|
#define ReadMemU32(to,addr) ReadMemRec(to,addr,0,4)//to=ReadMem32(addr)
|
|
#define ReadMemS16(to,addr) ReadMemRecS(to,addr,0,2)// to=(u32)(s32)(s16)ReadMem16(addr)
|
|
#define ReadMemS8(to,addr) ReadMemRecS(to,addr,0,1)//to=(u32)(s32)(s8)ReadMem8(addr)
|
|
|
|
//Base,offset format
|
|
#define ReadMemBOU32(to,addr,offset) ReadMemRec(to,addr,offset,4)//ReadMemU32(to,addr+offset)
|
|
#define ReadMemBOS16(to,addr,offset) ReadMemRecS(to,addr,offset,2)//ReadMemS16(to,addr+offset)
|
|
#define ReadMemBOS8(to,addr,offset) ReadMemRecS(to,addr,offset,1)//ReadMemS8(to,addr+offset)
|
|
|
|
//Write Mem Macros
|
|
#define WriteMemU32(addr,data) WriteMemRec(addr,0,data,4)//WriteMem32(addr,(u32)data)
|
|
#define WriteMemU16(addr,data) WriteMemRec(addr,0,data,2)//WriteMem16(addr,(u16)data)
|
|
#define WriteMemU8(addr,data) WriteMemRec(addr,0,data,1)//WriteMem8(addr,(u8)data)
|
|
|
|
//Base,offset format
|
|
#define WriteMemBOU32(addr,offset,data) WriteMemRec(addr,offset,data,4)//WriteMemU32(addr+offset,data)
|
|
#define WriteMemBOU16(addr,offset,data) WriteMemRec(addr,offset,data,2)//WriteMemU16(addr+offset,data)
|
|
#define WriteMemBOU8(addr,offset,data) WriteMemRec(addr,offset,data,1)//WriteMemU8(addr+offset,data)
|
|
|
|
|
|
void ReadMemRec(shil_RecRegType &to,u32 addr,u32 offset,u32 sz)
|
|
{
|
|
assert(sz==4);
|
|
ilst->readm32(to.regid,addr+offset);
|
|
}
|
|
|
|
void ReadMemRec(shil_RecRegType &to,shil_RecRegType& addr,u32 offset,u32 sz)
|
|
{
|
|
assert(sz==4);
|
|
ilst->readm32(to.regid,addr.regid,offset);
|
|
}
|
|
|
|
|
|
void ReadMemRec(shil_RecRegType &to,shil_RecRegType& addr,shil_RecRegType& offset,u32 sz)
|
|
{
|
|
assert(sz==4);
|
|
ilst->readm32(to.regid,addr.regid,offset.regid);
|
|
}
|
|
|
|
//signed
|
|
void ReadMemRecS(shil_RecRegType &to,u32 addr,u32 offset,u32 sz)
|
|
{
|
|
assert(sz!=4);
|
|
if (sz==1)
|
|
ilst->readm8(to.regid,addr+offset);
|
|
else
|
|
ilst->readm16(to.regid,addr+offset);
|
|
|
|
}
|
|
void ReadMemRecS(shil_RecRegType &to,shil_RecRegType& addr,u32 offset,u32 sz)
|
|
{
|
|
assert(sz!=4);
|
|
if (sz==1)
|
|
ilst->readm8(to.regid,addr.regid,offset);
|
|
else
|
|
ilst->readm16(to.regid,addr.regid,offset);
|
|
}
|
|
|
|
|
|
void ReadMemRecS(shil_RecRegType &to,shil_RecRegType& addr,shil_RecRegType& offset,u32 sz)
|
|
{
|
|
assert(sz!=4);
|
|
if (sz==1)
|
|
ilst->readm8(to.regid,addr.regid,offset.regid);
|
|
else
|
|
ilst->readm16(to.regid,addr.regid,offset.regid);
|
|
}
|
|
//WriteMem(u32 addr,u32 data,u32 sz)
|
|
void WriteMemRec(shil_RecRegType& addr,u32 offset,shil_RecRegType &data,u32 sz)
|
|
{
|
|
if (sz==1)
|
|
ilst->writem8(data.regid,addr.regid,offset);
|
|
else if (sz==2)
|
|
ilst->writem16(data.regid,addr.regid,offset);
|
|
else
|
|
ilst->writem32(data.regid,addr.regid,offset);
|
|
}
|
|
void WriteMemRec(shil_RecRegType& addr,shil_RecRegType& offset,shil_RecRegType &data,u32 sz)
|
|
{
|
|
if (sz==1)
|
|
ilst->writem8(data.regid,addr.regid,offset.regid);
|
|
else if (sz==2)
|
|
ilst->writem16(data.regid,addr.regid,offset.regid);
|
|
else
|
|
ilst->writem32(data.regid,addr.regid,offset.regid);
|
|
}
|
|
|
|
|
|
|
|
|
|
shil_RecRegType shil_rec_r[16];
|
|
shil_RecRegType shil_rec_r_bank[8];
|
|
|
|
shil_RecRegType shil_rec_gbr,shil_rec_ssr,shil_rec_spc,shil_rec_sgr,shil_rec_dbr,shil_rec_vbr;
|
|
shil_RecRegType shil_rec_pr,shil_rec_fpul;
|
|
|
|
struct shil_rec_mac_s
|
|
{
|
|
shil_RecRegType l;
|
|
shil_RecRegType h;
|
|
}shil_rec_mac;
|
|
|
|
|
|
void shil_DynarecInit()
|
|
{
|
|
for (int i=0;i<8;i++)
|
|
{
|
|
dyna_reg_id_fr[i]=(Sh4RegType)(fr_0+i);
|
|
dyna_reg_id_xf[i]=(Sh4RegType)(xf_0+i);
|
|
dyna_reg_id_dr[i]=(Sh4RegType)(dr_0+i);
|
|
dyna_reg_id_xd[i]=(Sh4RegType)(xd_0+i);
|
|
|
|
shil_rec_r[i].regid=dyna_reg_id_r[i]=(Sh4RegType)(r0+i);
|
|
shil_rec_r_bank[i].regid=dyna_reg_id_r_bank[i]=(Sh4RegType)(r0_Bank+i);
|
|
}
|
|
|
|
for (int i=8;i<16;i++)
|
|
{
|
|
dyna_reg_id_fr[i]=(Sh4RegType)(fr_0+i);
|
|
dyna_reg_id_xf[i]=(Sh4RegType)(xf_0+i);
|
|
|
|
shil_rec_r[i].regid=dyna_reg_id_r[i]=(Sh4RegType)(r0+i);
|
|
}
|
|
|
|
shil_rec_gbr.regid=reg_gbr;
|
|
shil_rec_ssr.regid=reg_ssr;
|
|
shil_rec_spc.regid=reg_spc;
|
|
shil_rec_sgr.regid=reg_sgr;
|
|
shil_rec_dbr.regid=reg_dbr;
|
|
shil_rec_vbr.regid=reg_vbr;
|
|
|
|
shil_rec_mac.h.regid=reg_mach;
|
|
shil_rec_mac.l.regid=reg_macl;
|
|
shil_rec_pr.regid=reg_pr;
|
|
shil_rec_fpul.regid=reg_fpul;
|
|
}
|
|
//rename shit
|
|
|
|
#define UpdateFPSCR rec_UpdateFPSCR
|
|
#define UpdateSR rec_UpdateSR
|
|
|
|
#define r shil_rec_r
|
|
#define r_bank shil_rec_r_bank
|
|
#define gbr shil_rec_gbr
|
|
#define ssr shil_rec_ssr
|
|
#define spc shil_rec_spc
|
|
#define sgr shil_rec_sgr
|
|
#define dbr shil_rec_dbr
|
|
#define vbr shil_rec_vbr
|
|
#define mac shil_rec_mac
|
|
|
|
#define pr shil_rec_pr
|
|
#define fpul shil_rec_fpul
|
|
|
|
//nice names ehh ? make us sure we don't use em :)
|
|
#define sr a_not_defined_name_has_to_be_rec_sr
|
|
#define fpscr a_not_defined_name_has_to_be_rec_fpscr
|
|
|
|
#undef iNimp
|
|
#define iNimp(op,info) rec_shil_iNimp(pc,op,info)
|
|
|
|
#include "dc/sh4/sh4_cpu_loadstore.h"
|
|
#include "dc/sh4/sh4_cpu_movs.h"
|
|
#include "dc/sh4/sh4_cpu_arith.h"
|
|
#include "dc/sh4/sh4_cpu_branch.h"
|
|
#include "dc/sh4/sh4_cpu_logic.h"
|
|
#endif |