Partial merge of the Pandora branch
This commit is contained in:
commit
4138440daa
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue