VFPv4: Implement VFNMS, VFNMA

This commit is contained in:
MerryMage
2020-05-10 14:14:03 +01:00
parent 6df660c889
commit 8e97b10acb
4 changed files with 52 additions and 2 deletions

View File

@@ -264,6 +264,46 @@ bool ArmTranslatorVisitor::vfp_VDIV(Cond cond, bool D, size_t Vn, size_t Vd, boo
});
}
// VFNMS<c>.F64 <Dd>, <Dn>, <Dm>
// VFNMS<c>.F32 <Sd>, <Sn>, <Sm>
bool ArmTranslatorVisitor::vfp_VFNMS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!ConditionPassed(cond)) {
return true;
}
const auto d = ToExtReg(sz, Vd, D);
const auto n = ToExtReg(sz, Vn, N);
const auto m = ToExtReg(sz, Vm, M);
return EmitVfpVectorOperation(sz, d, n, m, [this](ExtReg d, ExtReg n, ExtReg m) {
const auto reg_n = ir.GetExtendedRegister(n);
const auto reg_m = ir.GetExtendedRegister(m);
const auto reg_d = ir.GetExtendedRegister(d);
const auto result = ir.FPMulAdd(ir.FPNeg(reg_d), reg_n, reg_m, true);
ir.SetExtendedRegister(d, result);
});
}
// VFNMA<c>.F64 <Dd>, <Dn>, <Dm>
// VFNMA<c>.F32 <Sd>, <Sn>, <Sm>
bool ArmTranslatorVisitor::vfp_VFNMA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!ConditionPassed(cond)) {
return true;
}
const auto d = ToExtReg(sz, Vd, D);
const auto n = ToExtReg(sz, Vn, N);
const auto m = ToExtReg(sz, Vm, M);
return EmitVfpVectorOperation(sz, d, n, m, [this](ExtReg d, ExtReg n, ExtReg m) {
const auto reg_n = ir.GetExtendedRegister(n);
const auto reg_m = ir.GetExtendedRegister(m);
const auto reg_d = ir.GetExtendedRegister(d);
const auto result = ir.FPMulAdd(ir.FPNeg(reg_d), ir.FPNeg(reg_n), reg_m, true);
ir.SetExtendedRegister(d, result);
});
}
// VMOV<c>.32 <Dd[0]>, <Rt>
bool ArmTranslatorVisitor::vfp_VMOV_u32_f64(Cond cond, size_t Vd, Reg t, bool D) {
if (t == Reg::PC) {