DYNAREC: Attempt to add a few more opcode to dynarec

This commit is contained in:
ptitSeb 2013-12-29 13:29:33 +01:00
parent 8f694405ff
commit a604988944
4 changed files with 229 additions and 22 deletions

61
newdc/arm_emitter/E_DataOp.h Normal file → Executable file
View File

@ -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&15)<<7;
EMIT_I;
}
EAPI ADD(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
{
ADD(Rd,Rn,Rm,false,CC);
@ -285,7 +298,20 @@ 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;
EMIT_I;
}
EAPI AND(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
{
DECL_Id(0x00000000);
@ -358,7 +384,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);
@ -486,7 +530,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;
}

27
newdc/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
newdc/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

149
newdc/rec-ARM/arm_dyna.cpp Normal file → Executable file
View File

@ -1371,6 +1371,56 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging,
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\n",reg.mapg(op->rd),reg.mapg(op->rs1),reg.mapg(op->rs2), reg.mapg(op->rs3));
{
MOV(reg.mapg(op->rd2), 0);
SUB(r1, reg.mapg(op->rd2), reg.mapg(op->rs3)); // create a carry
SBC(reg.mapg(op->rd), reg.mapg(op->rs1), reg.mapg(op->rs2));
ADC(reg.mapg(op->rd2), reg.mapg(op->rd2), 0);
}
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));
{
TST(reg.mapg(op->rs2), 0x80000000); //sign
B(4*4-8, CC_NE); // Label1
AND(r2, reg.mapg(op->rs2), 0x1F);
LSL(r1, reg.mapg(op->rs1), r2);
B(6*4-8, CC_AL); // Label2
//Label1:
NEG(r2, reg.mapg(op->rs2));
AND(r2, r2, 0x1F);
CMP(r2, 0x0);
LSR(r1, reg.mapg(op->rs1), r2, CC_NE);
MOV(r1, 0, CC_EQ);
// Label2:
MOV(reg.mapg(op->rd), r1);
}
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));
{
TST(reg.mapg(op->rs2), 0x80000000); //sign
B(6*4-8, CC_NE); // Label1
AND(r2, reg.mapg(op->rs2), 0x1F);
TST(reg.mapg(op->rs1), 0x80000000); //sign
LSL(r1, reg.mapg(op->rs1), r2);
ORR(r1, r1, 0x80000000, CC_NE); // restaure sign
B(6*4-8, CC_AL); // Label2
//Label1:
NEG(r2, reg.mapg(op->rs2));
AND(r2, r2, 0x1F);
CMP(r2, 0x0);
MOVW(r2, 31, CC_EQ);
ASR(r1, reg.mapg(op->rs1), r2);
// Label2:
MOV(reg.mapg(op->rd), r1);
}
break;
case shop_sync_sr:
{
@ -1398,7 +1448,6 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging,
{
verify(op->rd._reg!=op->rs1._reg);
verify(op->rs2.is_imm() || op->rd._reg!=op->rs2._reg);
//rd is always NOT a source !
MOVW(reg.mapg(op->rd),0);
@ -1443,14 +1492,40 @@ 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(reg.mapg(op->rd), reg.mapg(op->rd), reg.mapg(op->rd));
EOR(r1, reg.mapg(op->rs1), reg.mapg(op->rs2));
TST(r1, 0xFF000000);
MOVW(reg.mapg(op->rd), 1, CC_EQ);
TST(r1, 0x00FF0000);
MOVW(reg.mapg(op->rd), 1, CC_EQ);
TST(r1, 0x0000FF00);
MOVW(reg.mapg(op->rd), 1, CC_EQ);
TST(r1, 0x000000FF);
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};
@ -1459,7 +1534,42 @@ 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));
{
EOR(reg.mapg(op->rd2), reg.mapg(op->rd2), reg.mapg(op->rd2));
MOV(reg.mapg(op->rd), reg.mapg(op->rd2));
MOVS(r2, reg.mapg(op->rs2));
B(11*4-8, CC_EQ); // Divide by zero, Label1:
MOV(reg.mapg(op->rd2), reg.mapg(op->rs1));
CLZ(reg.mapg(op->rd), r2);
LSL(reg.mapg(op->rd), reg.mapg(op->rd), r2);
ORR(reg.mapg(op->rd), reg.mapg(op->rd), 1<<31);
LSR(reg.mapg(op->rd), reg.mapg(op->rd), reg.mapg(op->rd));
// Label2:
CMP(reg.mapg(op->rd2), r2);
SUB(reg.mapg(op->rd2), reg.mapg(op->rd2), r2, CC_CS);
ADC(reg.mapg(op->rd), reg.mapg(op->rd), reg.mapg(op->rd), true, CC_AL);
LSR(r2, r2, 1, CC_AL);
B(-4*4-8, CC_CC); // Label2:
// Labe1:
MOV(r0,r0);
}
break;*/
case shop_pref:
{
if (op->flags != 0x1337)
@ -1601,9 +1711,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);
}
@ -1630,7 +1741,7 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging,
_r2=q1;
}
#if 1
#if !defined(TARGET_PANDORA)
//VFP
eFSReg fs2=_r2==q0?f0:f4;
@ -1660,7 +1771,7 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging,
SUB(r0,r8,op->rd.reg_aofs());
}
#if 1
#if !defined(TARGET_PANDORA)
//f0,f1,f2,f3 : vin
//f4,f5,f6,f7 : out
//f8,f9,f10,f11 : mtx temp
@ -1736,7 +1847,7 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging,
//4 mul
//4 mla
//1 add
*/
*/
#endif
}
@ -1774,10 +1885,20 @@ 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:
//printf("CFB %d\n",op->op);
printf("CFB %d\n",op->op);/*SEB*/
shil_chf[op->op](op);
break;