[ARM] Fix VSQRT/VCMP/VCMPE/VCMPE0/VCMP0 emitters when using the high 16 double registers.

This commit is contained in:
Ryan Houdek 2013-09-17 22:06:30 +00:00
parent ec9c395f4f
commit 06062d5744
2 changed files with 24 additions and 7 deletions

View file

@ -972,10 +972,10 @@ u32 ARMXEmitter::EncodeVm(ARMReg Vm)
ARMReg Reg = SubBase(Vm);
if (quad_reg)
return ((Reg & 0x10) << 2) | (Reg & 0xF);
return ((Reg & 0x10) << 1) | (Reg & 0xF);
else
if (double_reg)
return ((Reg & 0x10) << 2) | (Reg & 0xF);
return ((Reg & 0x10) << 1) | (Reg & 0xF);
else
return ((Reg & 0x1) << 5) | (Reg >> 1);
}
@ -995,6 +995,22 @@ void ARMXEmitter::WriteVFPDataOp(u32 Op, ARMReg Vd, ARMReg Vn, ARMReg Vm)
Write32(cond | (enc.opc1 << 20) | VnEnc | VdEnc | (enc.opc2 << 4) | (quad_reg << 6) | (double_reg << 8) | VmEnc);
}
void ARMXEmitter::WriteVFPDataOp6bit(u32 Op, ARMReg Vd, ARMReg Vn, ARMReg Vm, u32 bit6)
{
bool quad_reg = Vd >= Q0;
bool double_reg = Vd >= D0 && Vd < Q0;
VFPEnc enc = VFPOps[Op][quad_reg];
if (enc.opc1 == -1 && enc.opc2 == -1)
_dbg_assert_msg_(DYNA_REC, false, "%s does not support %s", VFPOpNames[Op], quad_reg ? "NEON" : "VFP");
u32 VdEnc = EncodeVd(Vd);
u32 VnEnc = EncodeVn(Vn);
u32 VmEnc = EncodeVm(Vm);
u32 cond = quad_reg ? (0xF << 28) : condition;
Write32(cond | (enc.opc1 << 20) | VnEnc | VdEnc | (enc.opc2 << 4) | (bit6 << 6) | (double_reg << 8) | VmEnc);
}
void ARMXEmitter::VMLA(ARMReg Vd, ARMReg Vn, ARMReg Vm){ WriteVFPDataOp(0, Vd, Vn, Vm); }
void ARMXEmitter::VNMLA(ARMReg Vd, ARMReg Vn, ARMReg Vm){ WriteVFPDataOp(1, Vd, Vn, Vm); }
void ARMXEmitter::VMLS(ARMReg Vd, ARMReg Vn, ARMReg Vm){ WriteVFPDataOp(2, Vd, Vn, Vm); }
@ -1006,11 +1022,11 @@ void ARMXEmitter::VNMUL(ARMReg Vd, ARMReg Vn, ARMReg Vm){ WriteVFPDataOp(7, Vd,
void ARMXEmitter::VABS(ARMReg Vd, ARMReg Vm){ WriteVFPDataOp(8, Vd, D0, Vm); }
void ARMXEmitter::VDIV(ARMReg Vd, ARMReg Vn, ARMReg Vm){ WriteVFPDataOp(9, Vd, Vn, Vm); }
void ARMXEmitter::VNEG(ARMReg Vd, ARMReg Vm){ WriteVFPDataOp(10, Vd, D1, Vm); }
void ARMXEmitter::VSQRT(ARMReg Vd, ARMReg Vm){ WriteVFPDataOp(11, Vd, D1, Vm); }
void ARMXEmitter::VCMP(ARMReg Vd, ARMReg Vm){ WriteVFPDataOp(12, Vd, D4, Vm); }
void ARMXEmitter::VCMPE(ARMReg Vd, ARMReg Vm){ WriteVFPDataOp(13, Vd, D4, Vm); }
void ARMXEmitter::VCMP(ARMReg Vd){ WriteVFPDataOp(12, Vd, D5, D0); }
void ARMXEmitter::VCMPE(ARMReg Vd){ WriteVFPDataOp(13, Vd, D5, D0); }
void ARMXEmitter::VSQRT(ARMReg Vd, ARMReg Vm){ WriteVFPDataOp6bit(11, Vd, D1, Vm, 3); }
void ARMXEmitter::VCMP(ARMReg Vd, ARMReg Vm){ WriteVFPDataOp6bit(12, Vd, D4, Vm, 1); }
void ARMXEmitter::VCMPE(ARMReg Vd, ARMReg Vm){ WriteVFPDataOp6bit(13, Vd, D4, Vm, 1); }
void ARMXEmitter::VCMP(ARMReg Vd){ WriteVFPDataOp6bit(12, Vd, D5, D0, 1); }
void ARMXEmitter::VCMPE(ARMReg Vd){ WriteVFPDataOp6bit(13, Vd, D5, D0, 1); }
void ARMXEmitter::VLDR(ARMReg Dest, ARMReg Base, s16 offset)
{

View file

@ -359,6 +359,7 @@ private:
u32 EncodeVn(ARMReg Vn);
u32 EncodeVm(ARMReg Vm);
void WriteVFPDataOp(u32 Op, ARMReg Vd, ARMReg Vn, ARMReg Vm);
void WriteVFPDataOp6bit(u32 Op, ARMReg Vd, ARMReg Vn, ARMReg Vm, u32 bit6);
void Write4OpMultiply(u32 op, ARMReg destLo, ARMReg destHi, ARMReg rn, ARMReg rm);