Update ArmEmitter with Sonic1's new NEON emitters. Thanks!

This commit is contained in:
Henrik Rydgård 2013-11-13 11:34:47 +01:00
parent a0c6b18134
commit ddf5b695ac
2 changed files with 1085 additions and 23 deletions

File diff suppressed because it is too large Load Diff

View File

@ -346,9 +346,36 @@ struct LiteralPool
typedef const u8* JumpTarget; typedef const u8* JumpTarget;
// XXX: Stop polluting the global namespace
const u32 I_8 = (1 << 0);
const u32 I_16 = (1 << 1);
const u32 I_32 = (1 << 2);
const u32 I_64 = (1 << 3);
const u32 I_SIGNED = (1 << 4);
const u32 I_UNSIGNED = (1 << 5);
const u32 F_32 = (1 << 6);
const u32 I_POLYNOMIAL = (1 << 7); // Only used in VMUL/VMULL
u32 EncodeVd(ARMReg Vd);
u32 EncodeVn(ARMReg Vn);
u32 EncodeVm(ARMReg Vm);
// Subtracts the base from the register to give us the real one
ARMReg SubBase(ARMReg Reg);
enum NEONAlignment {
ALIGN_NONE = 0,
ALIGN_64 = 1,
ALIGN_128 = 2,
ALIGN_256 = 3
};
class NEONXEmitter;
class ARMXEmitter class ARMXEmitter
{ {
friend struct OpArg; // for Write8 etc friend struct OpArg; // for Write8 etc
friend class NEONXEmitter;
private: private:
u8 *code, *startcode; u8 *code, *startcode;
u8 *lastCacheFlushEnd; u8 *lastCacheFlushEnd;
@ -361,9 +388,6 @@ private:
void WriteShiftedDataOp(u32 op, bool SetFlags, ARMReg dest, ARMReg src, Operand2 op2); void WriteShiftedDataOp(u32 op, bool SetFlags, ARMReg dest, ARMReg src, Operand2 op2);
void WriteSignedMultiply(u32 Op, u32 Op2, u32 Op3, ARMReg dest, ARMReg r1, ARMReg r2); void WriteSignedMultiply(u32 Op, u32 Op2, u32 Op3, ARMReg dest, ARMReg r1, ARMReg r2);
u32 EncodeVd(ARMReg Vd);
u32 EncodeVn(ARMReg Vn);
u32 EncodeVm(ARMReg Vm);
void WriteVFPDataOp(u32 Op, ARMReg Vd, ARMReg Vn, ARMReg Vm); void WriteVFPDataOp(u32 Op, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void Write4OpMultiply(u32 op, ARMReg destLo, ARMReg destHi, ARMReg rn, ARMReg rm); void Write4OpMultiply(u32 op, ARMReg destLo, ARMReg destHi, ARMReg rn, ARMReg rm);
@ -449,7 +473,6 @@ public:
void ADDS(ARMReg dest, ARMReg src, Operand2 op2); void ADDS(ARMReg dest, ARMReg src, Operand2 op2);
void ADC (ARMReg dest, ARMReg src, Operand2 op2); void ADC (ARMReg dest, ARMReg src, Operand2 op2);
void ADCS(ARMReg dest, ARMReg src, Operand2 op2); void ADCS(ARMReg dest, ARMReg src, Operand2 op2);
void LSL (ARMReg dest, ARMReg src, Operand2 op2); void LSL (ARMReg dest, ARMReg src, Operand2 op2);
void LSL (ARMReg dest, ARMReg src, ARMReg op2); void LSL (ARMReg dest, ARMReg src, ARMReg op2);
void LSLS(ARMReg dest, ARMReg src, Operand2 op2); void LSLS(ARMReg dest, ARMReg src, Operand2 op2);
@ -543,12 +566,10 @@ public:
// is deprecating conditional execution of ASIMD instructions. // is deprecating conditional execution of ASIMD instructions.
// ASIMD instructions don't even have a conditional encoding. // ASIMD instructions don't even have a conditional encoding.
// Subtracts the base from the register to give us the real one
ARMReg SubBase(ARMReg Reg);
// NEON Only // NEON Only
void VABD(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm); void VABD(IntegerSize size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VADD(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm); void VADD(IntegerSize size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VSUB(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm); void VSUB(IntegerSize size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
// VFP Only // VFP Only
void VLDR(ARMReg Dest, ARMReg Base, s16 offset); void VLDR(ARMReg Dest, ARMReg Base, s16 offset);
@ -582,6 +603,100 @@ public:
void VCVTF32F16(ARMReg Dest, ARMReg Src); void VCVTF32F16(ARMReg Dest, ARMReg Src);
void VCVTF16F32(ARMReg Dest, ARMReg Src); void VCVTF16F32(ARMReg Dest, ARMReg Src);
void VABA(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VABAL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VABD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VABDL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VABS(u32 Size, ARMReg Vd, ARMReg Vm);
void VACGE(ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VACGT(ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VACLE(ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VACLT(ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VADDHN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VADDL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VADDW(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VAND(ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VBIC(ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VBIF(ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VBIT(ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VBSL(ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VCEQ(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VCEQ(u32 Size, ARMReg Vd, ARMReg Vm);
void VCGE(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VCGE(u32 Size, ARMReg Vd, ARMReg Vm);
void VCGT(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VCGT(u32 Size, ARMReg Vd, ARMReg Vm);
void VCLE(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VCLE(u32 Size, ARMReg Vd, ARMReg Vm);
void VCLS(u32 Size, ARMReg Vd, ARMReg Vm);
void VCLT(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VCLT(u32 Size, ARMReg Vd, ARMReg Vm);
void VCLZ(u32 Size, ARMReg Vd, ARMReg Vm);
void VCNT(u32 Size, ARMReg Vd, ARMReg Vm);
void VDUP(u32 Size, ARMReg Vd, ARMReg Vm, u8 index);
void VDUP(u32 Size, ARMReg Vd, ARMReg Rt);
void VEOR(ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VEXT(ARMReg Vd, ARMReg Vn, ARMReg Vm, u8 index);
void VFMA(ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VFMS(ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VHADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VHSUB(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VMAX(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VMIN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VMLA(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VMLS(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VMLAL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VMLSL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VMUL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VMULL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VNEG(u32 Size, ARMReg Vd, ARMReg Vm);
void VORN(ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VORR(ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VPADAL(u32 Size, ARMReg Vd, ARMReg Vm);
void VPADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VPADDL(u32 Size, ARMReg Vd, ARMReg Vm);
void VPMAX(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VPMIN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VQABS(u32 Size, ARMReg Vd, ARMReg Vm);
void VQADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VQDMLAL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VQDMLSL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VQDMULH(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VQDMULL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VQNEG(u32 Size, ARMReg Vd, ARMReg Vm);
void VQRDMULH(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VQRSHL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VQSHL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VQSUB(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VRADDHN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VRECPE(u32 Size, ARMReg Vd, ARMReg Vm);
void VRECPS(ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VRHADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VRSHL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VRSQRTE(u32 Size, ARMReg Vd, ARMReg Vm);
void VRSQRTS(ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VRSUBHN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VSHL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VSUB(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VSUBHN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VSUBL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VSUBW(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VSWP(ARMReg Vd, ARMReg Vm);
void VTRN(u32 Size, ARMReg Vd, ARMReg Vm);
void VTST(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void VUZP(u32 Size, ARMReg Vd, ARMReg Vm);
void VZIP(u32 Size, ARMReg Vd, ARMReg Vm);
void VREVX(u32 size, u32 Size, ARMReg Vd, ARMReg Vm);
void VREV64(u32 Size, ARMReg Vd, ARMReg Vm);
void VREV32(u32 Size, ARMReg Vd, ARMReg Vm);
void VREV16(u32 Size, ARMReg Vd, ARMReg Vm);
void VLD1(u32 Size, ARMReg Vd, ARMReg Rn, NEONAlignment align = ALIGN_NONE, ARMReg Rm = _PC);
void VLD2(u32 Size, ARMReg Vd, ARMReg Rn, NEONAlignment align = ALIGN_NONE, ARMReg Rm = _PC);
void VST1(u32 Size, ARMReg Vd, ARMReg Rn, NEONAlignment align = ALIGN_NONE, ARMReg Rm = _PC);
void VMRS_APSR(); void VMRS_APSR();
void VMRS(ARMReg Rt); void VMRS(ARMReg Rt);
void VMSR(ARMReg Rt); void VMSR(ARMReg Rt);
@ -598,6 +713,20 @@ public:
void TSTI2R(ARMReg rs, u32 val, ARMReg scratch); void TSTI2R(ARMReg rs, u32 val, ARMReg scratch);
void ORI2R(ARMReg rd, ARMReg rs, u32 val, ARMReg scratch); void ORI2R(ARMReg rd, ARMReg rs, u32 val, ARMReg scratch);
inline u32 encodedSize(u32 value)
{
if (value & I_8)
return 0;
else if (value & I_16)
return 1;
else if ((value & I_32) || (value & F_32))
return 2;
else if (value & I_64)
return 3;
else
_dbg_assert_msg_(JIT, false, "Passed invalid size to integer NEON instruction");
return 0;
}
}; // class ARMXEmitter }; // class ARMXEmitter