[ARM] Fix VSQRT/VCMP/VCMPE/VCMPE0/VCMP0 emitters when using the high 16 double registers.
This commit is contained in:
parent
ec9c395f4f
commit
06062d5744
|
@ -972,10 +972,10 @@ u32 ARMXEmitter::EncodeVm(ARMReg Vm)
|
||||||
ARMReg Reg = SubBase(Vm);
|
ARMReg Reg = SubBase(Vm);
|
||||||
|
|
||||||
if (quad_reg)
|
if (quad_reg)
|
||||||
return ((Reg & 0x10) << 2) | (Reg & 0xF);
|
return ((Reg & 0x10) << 1) | (Reg & 0xF);
|
||||||
else
|
else
|
||||||
if (double_reg)
|
if (double_reg)
|
||||||
return ((Reg & 0x10) << 2) | (Reg & 0xF);
|
return ((Reg & 0x10) << 1) | (Reg & 0xF);
|
||||||
else
|
else
|
||||||
return ((Reg & 0x1) << 5) | (Reg >> 1);
|
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);
|
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::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::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); }
|
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::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::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::VNEG(ARMReg Vd, ARMReg Vm){ WriteVFPDataOp(10, Vd, D1, Vm); }
|
||||||
void ARMXEmitter::VSQRT(ARMReg Vd, ARMReg Vm){ WriteVFPDataOp(11, Vd, D1, Vm); }
|
void ARMXEmitter::VSQRT(ARMReg Vd, ARMReg Vm){ WriteVFPDataOp6bit(11, Vd, D1, Vm, 3); }
|
||||||
void ARMXEmitter::VCMP(ARMReg Vd, ARMReg Vm){ WriteVFPDataOp(12, Vd, D4, Vm); }
|
void ARMXEmitter::VCMP(ARMReg Vd, ARMReg Vm){ WriteVFPDataOp6bit(12, Vd, D4, Vm, 1); }
|
||||||
void ARMXEmitter::VCMPE(ARMReg Vd, ARMReg Vm){ WriteVFPDataOp(13, Vd, D4, Vm); }
|
void ARMXEmitter::VCMPE(ARMReg Vd, ARMReg Vm){ WriteVFPDataOp6bit(13, Vd, D4, Vm, 1); }
|
||||||
void ARMXEmitter::VCMP(ARMReg Vd){ WriteVFPDataOp(12, Vd, D5, D0); }
|
void ARMXEmitter::VCMP(ARMReg Vd){ WriteVFPDataOp6bit(12, Vd, D5, D0, 1); }
|
||||||
void ARMXEmitter::VCMPE(ARMReg Vd){ WriteVFPDataOp(13, Vd, D5, D0); }
|
void ARMXEmitter::VCMPE(ARMReg Vd){ WriteVFPDataOp6bit(13, Vd, D5, D0, 1); }
|
||||||
|
|
||||||
void ARMXEmitter::VLDR(ARMReg Dest, ARMReg Base, s16 offset)
|
void ARMXEmitter::VLDR(ARMReg Dest, ARMReg Base, s16 offset)
|
||||||
{
|
{
|
||||||
|
|
|
@ -359,6 +359,7 @@ private:
|
||||||
u32 EncodeVn(ARMReg Vn);
|
u32 EncodeVn(ARMReg Vn);
|
||||||
u32 EncodeVm(ARMReg Vm);
|
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 WriteVFPDataOp6bit(u32 Op, ARMReg Vd, ARMReg Vn, ARMReg Vm, u32 bit6);
|
||||||
|
|
||||||
void Write4OpMultiply(u32 op, ARMReg destLo, ARMReg destHi, ARMReg rn, ARMReg rm);
|
void Write4OpMultiply(u32 op, ARMReg destLo, ARMReg destHi, ARMReg rn, ARMReg rm);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue