diff --git a/core/arm_emitter/E_DataOp.h b/core/arm_emitter/E_DataOp.h old mode 100644 new mode 100755 index 4fd79c5f8..0bf896c32 --- a/core/arm_emitter/E_DataOp.h +++ b/core/arm_emitter/E_DataOp.h @@ -120,7 +120,7 @@ ADD.SP.REG 0x008D0000 EAPI RSC DP_PARAMS { DP_COMMON; DP_OPCODE(DP_RSC); EMIT_I; } EAPI TST DP_PARAMS { DP_COMMON; DP_OPCODE(DP_TST); EMIT_I; } EAPI TEQ DP_PARAMS { DP_COMMON; DP_OPCODE(DP_TEQ); EMIT_I; } - EAPI CMP DP_PARAMS { DP_COMMON; DP_OPCODE(DP_CMP); EMIT_I; } +// EAPI CMP DP_PARAMS { DP_COMMON; DP_OPCODE(DP_CMP); EMIT_I; } EAPI CMN DP_PARAMS { DP_COMMON; DP_OPCODE(DP_CMN); EMIT_I; } EAPI ORR DP_PARAMS { DP_COMMON; DP_OPCODE(DP_ORR); EMIT_I; } EAPI MOV DP_PARAMS { DP_COMMON; DP_OPCODE(DP_MOV); EMIT_I; } @@ -194,6 +194,19 @@ ADD.SP.REG 0x008D0000 ADD(Rd,Rn,Rm,0,S,CC); } + EAPI ADD(eReg Rd, eReg Rn, eReg Rm, ShiftOp Shift, u32 Imm8, ConditionCode CC=AL) + { + DECL_Id(0x00800000); + + SET_CC; + I |= (Rn&15)<<16; + I |= (Rd&15)<<12; + I |= (Rm&15); + I |= Shift<<5; + I |= (Imm8&31)<<7; + EMIT_I; + } + EAPI ADD(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL) { ADD(Rd,Rn,Rm,false,CC); @@ -241,7 +254,23 @@ ADD.SP.REG 0x008D0000 EMIT_I; } - + EAPI ADC(eReg Rd, eReg Rn, eReg Rm, bool S, ShiftOp Shift, u32 Imm8, ConditionCode CC=AL) + { + DECL_Id(0x00A00000); + + if (S) + I |= 1<<20; + + SET_CC; + I |= (Rn&15)<<16; + I |= (Rd&15)<<12; + I |= (Rm&15); + I |= Shift<<5; + I |= (Imm8&31)<<7; + EMIT_I; + } + + EAPI ADR(eReg Rd, s32 Imm8, ConditionCode CC=AL) { @@ -285,6 +314,50 @@ ADD.SP.REG 0x008D0000 I |= ARMImmid8r4(Imm8); // * 12b imm is 8b imm 4b rot. spec, add rot support! EMIT_I; } + + EAPI ORR(eReg Rd, eReg Rn, eReg Rm, ShiftOp Shift, eReg Rs, ConditionCode CC=AL) + { + DECL_Id(0x01800000); + + SET_CC; + I |= (Rn&15)<<16; + I |= (Rd&15)<<12; + I |= (Rm&15); + I |= Shift<<5; + I |= (Rs&15)<<8; + I |= 1<<4; + EMIT_I; + } + + EAPI ORR(eReg Rd, eReg Rn, eReg Rm, bool S, ShiftOp Shift, u32 Imm8, ConditionCode CC=AL) + { + DECL_Id(0x01800000); + + if (S) + I |= 1<<20; + + SET_CC; + I |= (Rn&15)<<16; + I |= (Rd&15)<<12; + I |= (Rm&15); + I |= Shift<<5; + I |= (Imm8&31)<<7; + EMIT_I; + } + + EAPI AND(eReg Rd, eReg Rn, eReg Rm, bool S, ConditionCode CC=AL) + { + DECL_Id(0x00000000); + + if (S) + I |= 1<<20; + + SET_CC; + I |= (Rn&15)<<16; + I |= (Rd&15)<<12; + I |= (Rm&15); + EMIT_I; + } EAPI AND(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL) { @@ -308,6 +381,20 @@ ADD.SP.REG 0x008D0000 EMIT_I; } + EAPI AND(eReg Rd, eReg Rn, s32 Imm8, bool S, ConditionCode CC=AL) + { + DECL_Id(0x02000000); + + if (S) + I |= 1<<20; + + SET_CC; + I |= (Rn&15)<<16; + I |= (Rd&15)<<12; + I |= ARMImmid8r4(Imm8); // * 12b imm is 8b imm 4b rot. spec, add rot support! + EMIT_I; + } + EAPI EOR(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL) { @@ -320,6 +407,20 @@ ADD.SP.REG 0x008D0000 EMIT_I; } + EAPI EOR(eReg Rd, eReg Rn, eReg Rm, bool S, ConditionCode CC=AL) + { + DECL_Id(0x00200000); + + if (S) + I |= 1<<20; + + SET_CC; + I |= (Rn&15)<<16; + I |= (Rd&15)<<12; + I |= (Rm&15); + EMIT_I; + } + EAPI EOR(eReg Rd, eReg Rn, s32 Imm8, ConditionCode CC=AL) { DECL_Id(0x02200000); @@ -358,7 +459,25 @@ ADD.SP.REG 0x008D0000 } EAPI SUB(eReg Rd, eReg Rn, s32 Imm8, ConditionCode CC=AL) { SUB(Rd,Rn,Imm8,false,CC); } - + EAPI SBC(eReg Rd, eReg Rn, eReg Rm, bool S, ConditionCode CC=AL) + { + DECL_Id(0x00C00000); + + if (S) + I |= 1<<20; + + SET_CC; + I |= (Rn&15)<<16; + I |= (Rd&15)<<12; + I |= (Rm&15); + EMIT_I; + } + + EAPI SBC(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL) + { + SBC(Rd,Rn,Rm,false,CC); + } + EAPI RSB(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL) { DECL_Id(0x00600000); @@ -382,6 +501,20 @@ ADD.SP.REG 0x008D0000 EMIT_I; } + EAPI RSB(eReg Rd, eReg Rn, s32 Imm8, bool S, ConditionCode CC=AL) + { + DECL_Id(0x02600000); + + if (S) + I |= 1<<20; + + SET_CC; + I |= (Rn&15)<<16; + I |= (Rd&15)<<12; + I |= ARMImmid8r4(Imm8); // * 12b imm is 8b imm 4b rot. spec, add rot support! + EMIT_I; + } + EAPI MVN(eReg Rd, eReg Rm, ConditionCode CC=AL) { @@ -465,6 +598,44 @@ ADD.SP.REG 0x008D0000 EMIT_I; } + EAPI MOV(eReg Rd, eReg Rm, bool S, ConditionCode CC=AL) + { + DECL_Id(0x01A00000); + + if (S) + I |= 1<<20; + + SET_CC; + I |= (Rd&15)<<12; + I |= (Rm&15); + EMIT_I; + } + + EAPI MOV(eReg Rd, eReg Rm, ShiftOp Shift, u32 Imm8, ConditionCode CC=AL) + { + DECL_Id(0x01A00000); + + SET_CC; + I |= (Rd&15)<<12; + I |= (Rm&15); + I |= Shift<<5; + I |= (Imm8&31)<<7; + EMIT_I; + } + + EAPI MOV(eReg Rd, eReg Rm, ShiftOp Shift, eReg Rs, ConditionCode CC=AL) + { + DECL_Id(0x01A00000); + + SET_CC; + I |= (Rd&15)<<12; + I |= (Rm&15); + I |= Shift<<5; + I |= (Rs&15)<<8; + I |= 1<<4; + EMIT_I; + } + EAPI MOVW(eReg Rd, u32 Imm16, ConditionCode CC=AL) { DECL_Id(0x03000000); @@ -486,7 +657,18 @@ ADD.SP.REG 0x008D0000 I |= (Imm16&0x0FFF); EMIT_I; } - + + EAPI MOV(eReg Rd, s32 Imm8, ConditionCode CC=AL) + { + DECL_Id(0x03A00000); + + SET_CC; + I |= (Rd&15)<<12; + I |= ARMImmid8r4(Imm8); // * 12b imm is 8b imm 4b rot. spec, add rot support! + EMIT_I; + } + + @@ -511,9 +693,31 @@ ADD.SP.REG 0x008D0000 EMIT_I; } - - - + EAPI CMP(eReg Rd, eReg Rm, ShiftOp Shift, eReg Rs, ConditionCode CC=AL) + { + DECL_Id(0x01500000); + + SET_CC; + I |= (Rd&15)<<12; + I |= (Rm&15); + I |= Shift<<5; + I |= (Rs&15)<<8; + I |= 1<<4; + EMIT_I; + } + + EAPI CMP(eReg Rd, eReg Rm, ShiftOp Shift, u32 Imm8, ConditionCode CC=AL) + { + DECL_Id(0x01500000); + + SET_CC; + I |= (Rd&15)<<12; + I |= (Rm&15); + I |= Shift<<5; + I |= (Imm8&31)<<7; + EMIT_I; + } + EAPI LSL(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL) { DECL_Id(0x01A00010); diff --git a/core/arm_emitter/E_Multiply.h b/core/arm_emitter/E_Multiply.h old mode 100644 new mode 100755 index c83edf5db..e50a38366 --- a/core/arm_emitter/E_Multiply.h +++ b/core/arm_emitter/E_Multiply.h @@ -32,8 +32,31 @@ namespace ARM EMIT_I; } - - + EAPI UMULL(eReg Rdhi, eReg Rdlo, eReg Rs, eReg Rm, ConditionCode CC=AL) // *FIXME* S + { + DECL_Id(0x00800090); + + SET_CC; + I |= (Rdhi&15)<<16; + I |= (Rdlo&15)<<12; + I |= (Rs&15)<<8; + I |= (Rm&15); + EMIT_I; + } + + EAPI SMULL(eReg Rdhi, eReg Rdlo, eReg Rs, eReg Rm, ConditionCode CC=AL) // *FIXME* S + { + DECL_Id(0x00C00090); + + SET_CC; + I |= (Rdhi&15)<<16; + I |= (Rdlo&15)<<12; + I |= (Rs&15)<<8; + I |= (Rm&15); + EMIT_I; + } + + diff --git a/core/arm_emitter/E_VDataOp.h b/core/arm_emitter/E_VDataOp.h old mode 100644 new mode 100755 index e91ceaccd..f33ebc743 --- a/core/arm_emitter/E_VDataOp.h +++ b/core/arm_emitter/E_VDataOp.h @@ -234,8 +234,15 @@ namespace ARM // VAC{COND} { DECL_Id(0xF3000E10); SET_Vdnm; EMIT_I; } // VCEQ { DECL_Id(0xF3000810); SET_Vdnm; EMIT_I; } .F32 { DECL_Id(0xF2000E00); SET_Vdnm; EMIT_I; } + VdpInstrI(CEQ, 0xF3200810) +// VdpInstrF(CEQ, 0xF2000e00) // VCGE { DECL_Id(0xF2000310); SET_Vdnm; EMIT_I; } .F32 { DECL_Id(0xF3000E00); SET_Vdnm; EMIT_I; } + VdpInstrI(CGE, 0xF2200310) +// VdpInstrF(CGE, 0xF3000e00) // VCGT { DECL_Id(0xF2000300); SET_Vdnm; EMIT_I; } .F32 { DECL_Id(0xF3200E00); SET_Vdnm; EMIT_I; } + //*SEB* 0xF220030 for S32, 0xF3200300 for U32, 0xF2000300 is for S8. + VdpInstrI(CGT, 0xF2200300) + //VdpInstrF(CGT, 0xF3200e00) // VCLE { DECL_Id(0xF3B10180); SET_Vdnm; EMIT_I; } // R is VCGE w/ operands reversed // VCLT { DECL_Id(0xF3B10200); SET_Vdnm; EMIT_I; } // R is VCGT w/ operands reversed // VTST { DECL_Id(0xF2000810); SET_Vdnm; EMIT_I; } @@ -325,7 +332,7 @@ namespace ARM I |= 1<<8; //SET_F SET_Dm; - I |= 0x1<<24; //SET_Q not compitable + I |= 0x1<<24; //SET_Q not compatible I |= 2<<20; //size to 32 @@ -348,7 +355,7 @@ namespace ARM I |= 1<<8; //SET_F SET_Dm; - I |= 0x1<<24; //SET_Q not compitable + I |= 0x1<<24; //SET_Q not compatible I |= 2<<20; //size to 32 @@ -592,7 +599,8 @@ namespace ARM EAPI VCVT_to_S32_VFP (eFSReg Sd, eFSReg Sm, ConditionCode CC=CC_AL) { DECL_Id(0x0EBD0AC0); SET_CC; SET_Sd; SET_Sm; EMIT_I; } // VfpInstrS(ABS, 0x0EB00AC0) ** {D,S}dm - //EAPI VCVT_from_S32_VFP (eFSReg Sd, eFSReg Sm) { DECL_Id(0x0EB80A40); SET_CC; SET_Sd; SET_Sm; EMIT_I; } // VfpInstrS(ABS, 0x0EB00AC0) ** {D,S}dm + // 0x0EB80A40 is to_U32. to_S32 is 0x0EB80AC0 + EAPI VCVT_from_S32_VFP (eFSReg Sd, eFSReg Sm, ConditionCode CC=CC_AL) { DECL_Id(0x0EB80AC0); SET_CC; SET_Sd; SET_Sm; EMIT_I; } // VfpInstrS(ABS, 0x0EB00AC0) ** {D,S}dm EAPI VABS_VFP (eFSReg Sd, eFSReg Sm, ConditionCode CC=CC_AL) { DECL_Id(0x0EB00AC0); SET_CC; SET_Sd; SET_Sm; EMIT_I; } // VfpInstrS(ABS, 0x0EB00AC0) ** {D,S}dm EAPI VNEG_VFP (eFSReg Sd, eFSReg Sm, ConditionCode CC=CC_AL) { DECL_Id(0x0EB10A40); SET_CC; SET_Sd; SET_Sm; EMIT_I; } // VfpInstrS(NEG, 0x0EB10A40) ** {D,S}dm diff --git a/core/arm_emitter/arm_disasm.h b/core/arm_emitter/arm_disasm.h old mode 100644 new mode 100755 index 6675bc02f..e34dbda64 --- a/core/arm_emitter/arm_disasm.h +++ b/core/arm_emitter/arm_disasm.h @@ -79,6 +79,7 @@ namespace ARM u32 uSB = ((op>>20) & 0x01) ; // Sign Change Bit + /* if (uCC == UC) { printf ("DBG armdis has UC instruction %X\n", op); @@ -93,7 +94,6 @@ namespace ARM } - if (uO1 == 0) { @@ -181,8 +181,55 @@ namespace ARM sprintf (disbuf, "INVALID INSTRUCTION"); } - - + */ + if (!uC1 && uO1==5) { + //B + char tmp[20]; + tmp[0]='\0'; + armdis_cc(uCC, tmp); + sprintf(disbuf, "B%s %08X", tmp, (op&0xffffff)<<2); + } else { + armdis_dp(uC1, disbuf); + char tmp[20]; + tmp[0]='\0'; + armdis_cc(uCC, tmp); + if (tmp[0]) { + strcat(disbuf, ".\0"); + strcat(disbuf, tmp); + } + if (uSB) strcat(disbuf, ".S\0"); + bool shifter=false; + switch (uO1) { + case 0: + // reg_reg + sprintf(tmp,"\tr%d, r%d", (op>>12)&0x0f, (op)&0x0f); + shifter=true; + break; + case 1: + // reg_imm + sprintf(tmp,"\tr%d, %04X", (op>>16)&0x0f, (op)&0xffff); + break; + default: + shifter=true; + sprintf(tmp, " 0x%0X", uO1); + } + strcat(disbuf, tmp); + char* ShiftOpStr[]={"LSL","LSR","ASR","ROR"}; + u32 shiftop=(op>>5)&0x3; + u32 shiftoptype=(op>>4)&0x1; + u32 shiftopreg=(op>>8)&0xf; + u32 shiftopimm=(op>>7)&0x1f; + if (shifter) { + if (!shiftop && !shiftoptype && !shiftopimm) + { + //nothing + } else { + if ((shiftop==1) || (shiftop==2)) if (!shiftoptype) if (!shiftopimm) shiftopimm=32; + sprintf(tmp, " ,%s %s%d", ShiftOpStr[shiftop], (shiftoptype)?" r":" #", (shiftoptype)?shiftopreg:shiftopimm); + strcat(disbuf, tmp); + } + } + } } diff --git a/core/hw/sh4/sh4_sched.cpp b/core/hw/sh4/sh4_sched.cpp old mode 100644 new mode 100755 index a80c60cd0..1fa6e0c82 --- a/core/hw/sh4/sh4_sched.cpp +++ b/core/hw/sh4/sh4_sched.cpp @@ -71,7 +71,7 @@ void sh4_sched_ffts() } else { - Sh4cntx.sh4_sched_next=200*1000*1000; + Sh4cntx.sh4_sched_next=SH4_MAIN_CLOCK; } sh4_sched_ffb+=Sh4cntx.sh4_sched_next; diff --git a/core/rec-ARM/arm_dyna.cpp b/core/rec-ARM/arm_dyna.cpp old mode 100644 new mode 100755 index 6b8829461..61eb30078 --- a/core/rec-ARM/arm_dyna.cpp +++ b/core/rec-ARM/arm_dyna.cpp @@ -979,6 +979,11 @@ EAPI NEG(eReg Rd,eReg Rs) RSB(Rd,Rs,0); } +EAPI NEG(eReg Rd,eReg Rs, bool S, ConditionCode cond = CC_AL) +{ + RSB(Rd,Rs,0, S, cond); +} + eReg GenMemAddr(shil_opcode* op,eReg raddr=r0) { if (op->rs3.is_imm()) @@ -1386,9 +1391,9 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, ADC(reg.mapg(op->rd2),r1,0); #else - LSR(reg.mapg(op->rd2),reg.mapg(op->rs3),1,true); //C=rs3, rd2=0 + LSR(r0,reg.mapg(op->rs3),1,true); //C=rs3, r0=0 ADC(reg.mapg(op->rd),reg.mapg(op->rs1),reg.mapg(op->rs2),true); //(C,rd)=rs1+rs2+rs3(C) - ADC(reg.mapg(op->rd2),reg.mapg(op->rd2),0); //rd2=C, (or MOVCS rd2, 1) + ADC(reg.mapg(op->rd2),r0,0); //rd2=C, (or MOVCS rd2, 1) #endif } break; @@ -1396,19 +1401,64 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, case shop_rocr: { - LSR(reg.mapg(op->rd2),reg.mapg(op->rs2),1,true); //C=rs2, rd2=0 - AND(reg.mapg(op->rd2),reg.mapg(op->rs1),1); //get new carry + if (reg.mapg(op->rd2)!=reg.mapg(op->rs1)) { + LSR(reg.mapg(op->rd2),reg.mapg(op->rs2),1,true); //C=rs2, rd2=0 + AND(reg.mapg(op->rd2),reg.mapg(op->rs1),1); //get new carry + } else { + LSR(r0,reg.mapg(op->rs2),1,true); //C=rs2, rd2=0 + ADD(r0, reg.mapg(op->rs1),1); + } RRX(reg.mapg(op->rd),reg.mapg(op->rs1)); //RRX w/ carry :) + if (reg.mapg(op->rd2)==reg.mapg(op->rs1)) + MOV(reg.mapg(op->rd2), r0); + } break; case shop_rocl: { - ADD(reg.mapg(op->rd),reg.mapg(op->rs2),reg.mapg(op->rs1),1,true); //(C,rd)= rs1<<1 + (|) rs2 + //ADD(reg.mapg(op->rd),reg.mapg(op->rs2),reg.mapg(op->rs1),1,true); //(C,rd)= rs1<<1 + (|) rs2 + ORR(reg.mapg(op->rd),reg.mapg(op->rs2),reg.mapg(op->rs1),true, S_LSL, 1); //(C,rd)= rs1<<1 + (|) rs2 MOVW(reg.mapg(op->rd2),0); //clear rd2 (for ADC/MOVCS) ADC(reg.mapg(op->rd2),reg.mapg(op->rd2),0); //rd2=C (or MOVCS rd2, 1) } break; + + case shop_sbc: + //printf("sbc: r%d r%d r%d r%d r%d\n",reg.mapg(op->rd),reg.mapg(op->rd2),reg.mapg(op->rs1),reg.mapg(op->rs2), reg.mapg(op->rs3)); + { + EOR(reg.mapg(op->rd2),reg.mapg(op->rs3),1); + LSR(reg.mapg(op->rd2),reg.mapg(op->rd2),1,true); //C=rs3, rd2=0 + SBC(reg.mapg(op->rd), reg.mapg(op->rs1), reg.mapg(op->rs2), true); + MOV(reg.mapg(op->rd2), 1, CC_CC); + } + break; + + case shop_shld: + //printf("shld: r%d r%d r%d\n",reg.mapg(op->rd),reg.mapg(op->rs1),reg.mapg(op->rs2)); + { + verify(!op->rs2.is_imm()); + AND(r0, reg.mapg(op->rs2), 0x8000001F, true); + RSB(r0, r0, 0x80000020, CC_MI); + LSR(reg.mapg(op->rd), reg.mapg(op->rs1), r0, CC_MI); + LSL(reg.mapg(op->rd), reg.mapg(op->rs1), r0, CC_PL); + //MOV(reg.mapg(op->rd), reg.mapg(op->rs1), S_LSL, r0, CC_PL); + //MOV(reg.mapg(op->rd), reg.mapg(op->rs1), S_LSR, r0, CC_MI); + } + break; + + case shop_shad: + //printf("shad: r%d r%d r%d\n",reg.mapg(op->rd),reg.mapg(op->rs1),reg.mapg(op->rs2)); + { + verify(!op->rs2.is_imm()); + AND(r0, reg.mapg(op->rs2), 0x8000001F, true); + RSB(r0, r0, 0x80000020, CC_MI); + ASR(reg.mapg(op->rd), reg.mapg(op->rs1), r0, CC_MI); + LSL(reg.mapg(op->rd), reg.mapg(op->rs1), r0, CC_PL); + //MOV(reg.mapg(op->rd), reg.mapg(op->rs1), S_LSL, r0, CC_PL); + //MOV(reg.mapg(op->rd), reg.mapg(op->rs1), S_ASR, r0, CC_MI); + } + break; case shop_sync_sr: { @@ -1481,14 +1531,37 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, MOVW(reg.mapg(op->rd),1,opcls2[op->op-shop_test]); break; } - + + case shop_setpeq: + { + EOR(r1, reg.mapg(op->rs1), reg.mapg(op->rs2)); + MOVW(reg.mapg(op->rd), 0); + + TST(r1, 0xFF000000); + TST(r1, 0x00FF0000, CC_NE); + TST(r1, 0x0000FF00, CC_NE); + TST(r1, 0x000000FF, CC_NE); + MOVW(reg.mapg(op->rd), 1, CC_EQ); + } + break; + //UXTH for zero extention and/or more mul forms (for 16 and 64 bits) -// case shop_mul_u16: -// case shop_mul_s16: + case shop_mul_u16: + { + UXTH(r1, reg.mapg(op->rs1)); + UXTH(r2, reg.mapg(op->rs2)); + MUL(reg.mapg(op->rd),r1,r2); + } + break; + case shop_mul_s16: + { + SXTH(r1, reg.mapg(op->rs1)); + SXTH(r2, reg.mapg(op->rs2)); + MUL(reg.mapg(op->rd),r1,r2); + } + break; case shop_mul_i32: -// case shop_mul_u64: -// case shop_mul_s64: { //x86_opcode_class opdt[]={op_movzx16to32,op_movsx16to32,op_mov32,op_mov32,op_mov32}; //x86_opcode_class opmt[]={op_mul32,op_mul32,op_mul32,op_mul32,op_imul32}; @@ -1497,7 +1570,73 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, MUL(reg.mapg(op->rd),reg.mapg(op->rs1),reg.mapg(op->rs2)); } break; - + case shop_mul_u64: + { + UMULL(reg.mapg(op->rd2), reg.mapg(op->rd), reg.mapg(op->rs1), reg.mapg(op->rs2)); + } + break; + case shop_mul_s64: + { + SMULL(reg.mapg(op->rd2), reg.mapg(op->rd), reg.mapg(op->rs1), reg.mapg(op->rs2)); + } + break; + +/* case shop_div32u: + // Doesn't work + // algo from new arm dynarec from mupen64plus + //printf("div32u: r%d r%d r%d r%d\n",reg.mapg(op->rd2),reg.mapg(op->rd),reg.mapg(op->rs1),reg.mapg(op->rs2)); + { + // remainder = r0, quotient = r1, HOST_TEMPREG = r2, copy de rs1 = r3, copy de rs2 = r4 + MOV(r3, reg.mapg(op->rs1)); + MOV(r4, reg.mapg(op->rs2), true); + MOV(r0, reg.mapg(op->rs1)); // dividend = d1 , divisor = d2 + MVN(r1, 0); + B(10*4-8, CC_EQ); + CLZ(r2, r4); + MOV(r1, 1<<31); + LSL(r4, r4, r2); + LSR(r1, r1, r2); + CMP(r0, r4); + SUB(r0, r0, r4, CC_CS); + ADC(r1, r1, r1, true); + MOV(r4, r4, S_LSR, 1, CC_CC); + B(-4*4-8, CC_CC); + MOV(reg.mapg(op->rd), r1); + MOV(reg.mapg(op->rd2), r0); + } + break;*/ +/* case shop_div32s: + //printf("div32s r%d, r%d, r%d, r%d\n", reg.mapg(op->rd2),reg.mapg(op->rd),reg.mapg(op->rs1),reg.mapg(op->rs2)); + // algo from dynarec from pcsxrearmed + // remainder = r0, quotient = r1, HOST_TEMPREG = r2, copy de rs1 = r3, copy de rs2 = r4 + { + MOV(r3, reg.mapg(op->rs1)); + MOV(r4, reg.mapg(op->rs2)); + MOV(r0, reg.mapg(op->rs1), true); + MVN(r1, 0); + RSB(r1, r1, 0, CC_MI); // .. quotient and .. + RSB(r0, r0, 0, CC_MI); // .. remainder for div0 case (will be negated back after jump) + MOV(r2, reg.mapg(op->rs2), true); + B(14*4-8, CC_EQ); // Division by zero + RSB(r2, r2, 0, true, CC_MI); + CLZ(r1, r2); + LSL(r2, r2, r1); + ORR(r1, r1, 1<<31); + LSR(r1, r1, r1); + CMP(r0, r2); + SUB(r0, r0, r2, CC_CS); + ADC(r1, r1, r1, true); + MOV(r2, r2, S_LSR, 1); + B(-4*4-8, CC_CC); // -4 + TEQ(r3, r4, S_LSL, CC_AL); + RSB(r1, r1, 0, CC_MI); + TST(r3, r3); + RSB(r0, r0, 0, CC_MI); + MOV(reg.mapg(op->rd2), r0); + MOV(reg.mapg(op->rd), r1); + } + break;*/ + case shop_pref: { if (op->flags != 0x1337) @@ -1639,9 +1778,10 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, VLDR(d0,r0); */ - LSL(r0,r0,3); - ADD(r0,r1,r0); //EMITTER: Todo, add with shifted ! - + //LSL(r0,r0,3); + //ADD(r0,r1,r0); //EMITTER: Todo, add with shifted ! + ADD(r0,r1,r0, S_LSL, 3); + VLDR(/*reg.mapf(op->rd,0)*/d0,r0,0); VSTR(d0,r8,op->rd.reg_nofs()/4); } @@ -1774,7 +1914,6 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, //4 mul //4 mla //1 add - */ */ #endif } @@ -1812,6 +1951,16 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, VMOV(reg.mapg(op->rd),f0); //shil_chf[op->op](op); break; + + case shop_cvt_i2f_n: // may be some difference should be made ? + case shop_cvt_i2f_z: + + //printf("i2f: f%d r%d\n",reg.mapf(op->rd),reg.mapg(op->rs1)); + //BKPT(); + VMOV(f0, reg.mapg(op->rs1)); + VCVT_from_S32_VFP(reg.mapfs(op->rd),f0); + //shil_chf[op->op](op); + break; #endif default: