VFP: Implement VMLA, VMLS, VNMLA, VNMLS

This commit is contained in:
MerryMage
2016-08-07 11:38:30 +01:00
parent 3f1345a1a5
commit da33af5abe
4 changed files with 112 additions and 9 deletions

View File

@@ -74,6 +74,46 @@ bool ArmTranslatorVisitor::vfp2_VMUL(Cond cond, bool D, size_t Vn, size_t Vd, bo
return true;
}
bool ArmTranslatorVisitor::vfp2_VMLA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (ir.current_location.FPSCR_Len() != 1 || ir.current_location.FPSCR_Stride() != 1)
return InterpretThisInstruction(); // TODO: Vectorised floating point instructions
ExtReg d = ToExtReg(sz, Vd, D);
ExtReg n = ToExtReg(sz, Vn, N);
ExtReg m = ToExtReg(sz, Vm, M);
// VMLA.{F32,F64} <{S,D}d>, <{S,D}n>, <{S,D}m>
if (ConditionPassed(cond)) {
auto a = ir.GetExtendedRegister(n);
auto b = ir.GetExtendedRegister(m);
auto c = ir.GetExtendedRegister(d);
auto result = sz
? ir.FPAdd64(c, ir.FPMul64(a, b, true), true)
: ir.FPAdd32(c, ir.FPMul32(a, b, true), true);
ir.SetExtendedRegister(d, result);
}
return true;
}
bool ArmTranslatorVisitor::vfp2_VMLS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (ir.current_location.FPSCR_Len() != 1 || ir.current_location.FPSCR_Stride() != 1)
return InterpretThisInstruction(); // TODO: Vectorised floating point instructions
ExtReg d = ToExtReg(sz, Vd, D);
ExtReg n = ToExtReg(sz, Vn, N);
ExtReg m = ToExtReg(sz, Vm, M);
// VMLS.{F32,F64} <{S,D}d>, <{S,D}n>, <{S,D}m>
if (ConditionPassed(cond)) {
auto a = ir.GetExtendedRegister(n);
auto b = ir.GetExtendedRegister(m);
auto c = ir.GetExtendedRegister(d);
auto result = sz
? ir.FPAdd64(c, ir.FPNeg64(ir.FPMul64(a, b, true)), true)
: ir.FPAdd32(c, ir.FPNeg32(ir.FPMul32(a, b, true)), true);
ir.SetExtendedRegister(d, result);
}
return true;
}
bool ArmTranslatorVisitor::vfp2_VNMUL(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (ir.current_location.FPSCR_Len() != 1 || ir.current_location.FPSCR_Stride() != 1)
return InterpretThisInstruction(); // TODO: Vectorised floating point instructions
@@ -93,6 +133,46 @@ bool ArmTranslatorVisitor::vfp2_VNMUL(Cond cond, bool D, size_t Vn, size_t Vd, b
return true;
}
bool ArmTranslatorVisitor::vfp2_VNMLA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (ir.current_location.FPSCR_Len() != 1 || ir.current_location.FPSCR_Stride() != 1)
return InterpretThisInstruction(); // TODO: Vectorised floating point instructions
ExtReg d = ToExtReg(sz, Vd, D);
ExtReg n = ToExtReg(sz, Vn, N);
ExtReg m = ToExtReg(sz, Vm, M);
// VNMLA.{F32,F64} <{S,D}d>, <{S,D}n>, <{S,D}m>
if (ConditionPassed(cond)) {
auto a = ir.GetExtendedRegister(n);
auto b = ir.GetExtendedRegister(m);
auto c = ir.GetExtendedRegister(d);
auto result = sz
? ir.FPAdd64(ir.FPNeg64(c), ir.FPNeg64(ir.FPMul64(a, b, true)), true)
: ir.FPAdd32(ir.FPNeg32(c), ir.FPNeg32(ir.FPMul32(a, b, true)), true);
ir.SetExtendedRegister(d, result);
}
return true;
}
bool ArmTranslatorVisitor::vfp2_VNMLS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (ir.current_location.FPSCR_Len() != 1 || ir.current_location.FPSCR_Stride() != 1)
return InterpretThisInstruction(); // TODO: Vectorised floating point instructions
ExtReg d = ToExtReg(sz, Vd, D);
ExtReg n = ToExtReg(sz, Vn, N);
ExtReg m = ToExtReg(sz, Vm, M);
// VNMLS.{F32,F64} <{S,D}d>, <{S,D}n>, <{S,D}m>
if (ConditionPassed(cond)) {
auto a = ir.GetExtendedRegister(n);
auto b = ir.GetExtendedRegister(m);
auto c = ir.GetExtendedRegister(d);
auto result = sz
? ir.FPAdd64(ir.FPNeg64(c), ir.FPMul64(a, b, true), true)
: ir.FPAdd32(ir.FPNeg32(c), ir.FPMul32(a, b, true), true);
ir.SetExtendedRegister(d, result);
}
return true;
}
bool ArmTranslatorVisitor::vfp2_VDIV(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (ir.current_location.FPSCR_Len() != 1 || ir.current_location.FPSCR_Stride() != 1)
return InterpretThisInstruction(); // TODO: Vectorised floating point instructions