#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 #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 @ rsh4op(i0000_nnnn_1001_0011) { shil_interpret(op); } //ocbp @ rsh4op(i0000_nnnn_1010_0011) { shil_interpret(op); } //ocbwb @ rsh4op(i0000_nnnn_1011_0011) { shil_interpret(op); } //pref @ 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 rsh4op(i0000_nnnn_0010_1001) { u32 n = GetN(op); ilst->mov(r[n],reg_sr_T); } //************************ Reg Compares ************************ //cmp/pz 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 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 #,R0 rsh4op(i1000_1000_iiii_iiii) { ilst->cmp(r[0],GetSImm8(op)); handle_stids; ilst->SaveT(CC_E); } //cmp/eq , 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 , 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 , 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 , 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 , 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 , rsh4op(i0010_nnnn_mmmm_1100) { shil_interpret(op); } //tst #,R0 rsh4op(i1100_1000_iiii_iiii) { ilst->test(r[0],GetImm8(op)); handle_stids; ilst->SaveT(CC_Z); } //tst , 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 , rsh4op(i0010_nnnn_mmmm_1110) { u32 n = GetN(op); u32 m = GetM(op); ilst->mulu_16_16_32(r[n],r[m]); } //muls.w , rsh4op(i0010_nnnn_mmmm_1111) { u32 n = GetN(op); u32 m = GetM(op); ilst->muls_16_16_32(r[n],r[m]); } //dmulu.l , rsh4op(i0011_nnnn_mmmm_0101) { u32 n = GetN(op); u32 m = GetM(op); ilst->mulu_32_32_64(r[n],r[m]); } //dmuls.l , rsh4op(i0011_nnnn_mmmm_1101) { u32 n = GetN(op); u32 m = GetM(op); ilst->muls_32_32_64(r[n],r[m]); } //mac.w @+,@+ rsh4op(i0100_nnnn_mmmm_1111) { shil_interpret(op); } //mac.l @+,@+ rsh4op(i0000_nnnn_mmmm_1111) { shil_interpret(op); } //mul.l , 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 , 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 , rsh4op(i0011_nnnn_mmmm_0100) { //u32 n=GetN(op); //u32 m=GetM(op); shil_interpret(op); } //************************ Simple maths ************************ //addc , 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 , rsh4op(i0011_nnnn_mmmm_1111) { shil_interpret(op); } //subc , 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 , rsh4op(i0011_nnnn_mmmm_1011) { shil_interpret(op); } //dt rsh4op(i0100_nnnn_0001_0000) { u32 n = GetN(op); ilst->dec(r[n]); handle_stids; ilst->SaveT(CC_Z); } //negc , rsh4op(i0110_nnnn_mmmm_1010) { //u32 n = GetN(op); //u32 m = GetM(op); shil_interpret(op); } //neg , rsh4op(i0110_nnnn_mmmm_1011) { u32 n = GetN(op); u32 m = GetM(op); ilst->mov(r[n],r[m]); ilst->neg(r[n]); } //not , 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 rsh4op(i0100_nnnn_0000_0000) { u32 n = GetN(op); ilst->shl(r[n],1,true); handle_stids; ilst->SaveT(CC_E); } //shal rsh4op(i0100_nnnn_0010_0000) { u32 n=GetN(op); ilst->shl(r[n],1,true); handle_stids; ilst->SaveT(CC_E); } //shlr rsh4op(i0100_nnnn_0000_0001) { u32 n = GetN(op); ilst->shr(r[n],1,true); handle_stids; ilst->SaveT(CC_E); } //shar rsh4op(i0100_nnnn_0010_0001) { u32 n = GetN(op); ilst->sar(r[n],1,true); handle_stids; ilst->SaveT(CC_E); } //shad , rsh4op(i0100_nnnn_mmmm_1100) { shil_interpret(op); } //shld , rsh4op(i0100_nnnn_mmmm_1101) { u32 n = GetN(op); u32 m = GetM(op); ilst->shld(r[n],r[m]); //shil_interpret(op); } //rotcl rsh4op(i0100_nnnn_0010_0100) { u32 n = GetN(op); ilst->rcl(r[n]); handle_stids; ilst->SaveT(CC_E); } //rotl rsh4op(i0100_nnnn_0000_0100) { u32 n = GetN(op); ilst->rol(r[n]); handle_stids; ilst->SaveT(CC_E); } //rotcr rsh4op(i0100_nnnn_0010_0101) { u32 n = GetN(op); ilst->rcr(r[n]); handle_stids; ilst->SaveT(CC_E); } //rotr rsh4op(i0100_nnnn_0000_0101) { u32 n = GetN(op); ilst->ror(r[n]); handle_stids; ilst->SaveT(CC_E); } //************************ byte reorder/sign ************************ //swap.b , 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 , 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 , rsh4op(i0110_nnnn_mmmm_1100) { u32 n = GetN(op); u32 m = GetM(op); ilst->movzxb(r[n],r[m]); } //extu.w , rsh4op(i0110_nnnn_mmmm_1101) { u32 n = GetN(op); u32 m = GetM(op); ilst->movzxw(r[n],r[m]); } //exts.b , rsh4op(i0110_nnnn_mmmm_1110) { u32 n = GetN(op); u32 m = GetM(op); ilst->movsxb(r[n],r[m]); } //exts.w , rsh4op(i0110_nnnn_mmmm_1111) { u32 n = GetN(op); u32 m = GetM(op); ilst->movsxw(r[n],r[m]); } //xtrct , rsh4op(i0010_nnnn_mmmm_1101) { //u32 n = GetN(op); //u32 m = GetM(op); shil_interpret(op); } //************************ xxx.b #,@(R0,GBR) ************************ //tst.b #,@(R0,GBR) rsh4op(i1100_1100_iiii_iiii) { shil_interpret(op); } //and.b #,@(R0,GBR) rsh4op(i1100_1101_iiii_iiii) { shil_interpret(op); } //xor.b #,@(R0,GBR) rsh4op(i1100_1110_iiii_iiii) { shil_interpret(op); } //or.b #,@(R0,GBR) rsh4op(i1100_1111_iiii_iiii) { shil_interpret(op); } //tas.b @ 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 , 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 , 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 , 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 , 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 , 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 , 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,), 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 ,@(R0,) 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 @, 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 @+, 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 ,@ 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 ,@- rsh4op(i1111_nnnn_mmmm_1011) {//used if (sh4r.fpscr.SZ == 0) { //iNimp("fmov.s ,@-"); 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 , 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 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 ,FPUL rsh4op(i1111_nnnn_1011_1101) { if (sh4r.fpscr.PR == 1) { shil_interpret(op); return; } else { iNimp("fcnvds ,FPUL,m=0"); } } //fcnvsd FPUL, rsh4op(i1111_nnnn_1010_1101) { if (sh4r.fpscr.PR == 1) { shil_interpret(op); return; } else { iNimp("fcnvsd FPUL,,m=0"); } } //fipr , 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 rsh4op(i1111_nnnn_1000_1101) { if (sh4r.fpscr.PR==0) { //iNimp("fldi0 "); u32 n = GetN(op); //fr[n] = 0.0f; ilst->mov(fr[n],0);//0.0f is 0x0 , right ? } else { iNimp("fldi0 "); } } //fldi1 rsh4op(i1111_nnnn_1001_1101) { if (sh4r.fpscr.PR==0) { //iNimp("fldi1 "); u32 n = GetN(op); //fr[n] = 1.0f; ilst->mov(fr[n],0x3f800000);//1.0f is 0x3f800000 , right ? } else { iNimp("fldi1 "); } } //flds ,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, 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 , 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 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 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 "); } } //fsts FPUL, 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 ,, rsh4op(i1111_nnnn_mmmm_1110) { //iNimp("fmac ,,"); 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 ,,"); } } //ftrv xmtrx, 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 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 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 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 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 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 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 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 rsh4op(i1011_iiii_iiii_iiii) {//ToDo : Check Me [26/4/05] | Check new delay slot code [28/1/06] /* //iNimp("bsr "); 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 # 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 @ 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 @ 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