Partial merge of the Pandora branch

This commit is contained in:
Stefanos Kornilios Mitsis Poiitidis 2014-01-21 02:02:12 +02:00
commit 4138440daa
6 changed files with 462 additions and 31 deletions

218
core/arm_emitter/E_DataOp.h Normal file → Executable file
View File

@ -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);

27
core/arm_emitter/E_Multiply.h Normal file → Executable file
View File

@ -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;
}

14
core/arm_emitter/E_VDataOp.h Normal file → Executable file
View File

@ -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

53
core/arm_emitter/arm_disasm.h Normal file → Executable file
View File

@ -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);
}
}
}
}

2
core/hw/sh4/sh4_sched.cpp Normal file → Executable file
View File

@ -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;

179
core/rec-ARM/arm_dyna.cpp Normal file → Executable file
View File

@ -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: