VFPv4: Implement VFMA, VFMS

This commit is contained in:
MerryMage 2020-05-10 14:18:06 +01:00
parent 8e97b10acb
commit 010fab9a0e
4 changed files with 53 additions and 3 deletions

View file

@ -10,8 +10,8 @@ INST(vfp_VSUB, "VSUB", "cccc11100D11nnnndddd101zN
INST(vfp_VDIV, "VDIV", "cccc11101D00nnnndddd101zN0M0mmmm") // VFPv2
INST(vfp_VFNMS, "VFNMS", "cccc11101D01nnnndddd101zN0M0mmmm") // VFPv4
INST(vfp_VFNMA, "VFNMA", "cccc11101D01nnnndddd101zN1M0mmmm") // VFPv4
//INST(vfp_VFMA, "VFMA", "cccc11101D10nnnndddd101zN0M0mmmm") // VFPv4
//INST(vfp_VFMS, "VFMS", "cccc11101D10nnnndddd101zN1M0mmmm") // VFPv4
INST(vfp_VFMA, "VFMA", "cccc11101D10nnnndddd101zN0M0mmmm") // VFPv4
INST(vfp_VFMS, "VFMS", "cccc11101D10nnnndddd101zN1M0mmmm") // VFPv4
// Other floating-point data-processing instructions
//INST(vfp_VMOV_imm, "VMOV (immediate)", "cccc11101D11vvvvdddd101z0000vvvv") // VFPv3

View file

@ -1221,7 +1221,15 @@ public:
}
std::string vfp_VFNMA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
return fmt::format("vfmna{}.{} {}, {}, {}", CondToString(cond), sz ? "f64" : "f32", FPRegStr(sz, Vd, D), FPRegStr(sz, Vn, N), FPRegStr(sz, Vm, M));
return fmt::format("vfnma{}.{} {}, {}, {}", CondToString(cond), sz ? "f64" : "f32", FPRegStr(sz, Vd, D), FPRegStr(sz, Vn, N), FPRegStr(sz, Vm, M));
}
std::string vfp_VFMS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
return fmt::format("vfms{}.{} {}, {}, {}", CondToString(cond), sz ? "f64" : "f32", FPRegStr(sz, Vd, D), FPRegStr(sz, Vn, N), FPRegStr(sz, Vm, M));
}
std::string vfp_VFMA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
return fmt::format("vfma{}.{} {}, {}, {}", CondToString(cond), sz ? "f64" : "f32", FPRegStr(sz, Vd, D), FPRegStr(sz, Vn, N), FPRegStr(sz, Vm, M));
}
std::string vfp_VMOV_u32_f64(Cond cond, size_t Vd, Reg t, bool D){

View file

@ -373,6 +373,8 @@ struct ArmTranslatorVisitor final {
bool vfp_VDIV(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm);
bool vfp_VFNMS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm);
bool vfp_VFNMA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm);
bool vfp_VFMA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm);
bool vfp_VFMS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm);
// Floating-point move instructions
bool vfp_VMOV_u32_f64(Cond cond, size_t Vd, Reg t, bool D);

View file

@ -304,6 +304,46 @@ bool ArmTranslatorVisitor::vfp_VFNMA(Cond cond, bool D, size_t Vn, size_t Vd, bo
});
}
// VFMA<c>.F64 <Dd>, <Dn>, <Dm>
// VFMA<c>.F32 <Sd>, <Sn>, <Sm>
bool ArmTranslatorVisitor::vfp_VFMA(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(reg_d, reg_n, reg_m, true);
ir.SetExtendedRegister(d, result);
});
}
// VFMS<c>.F64 <Dd>, <Dn>, <Dm>
// VFMS<c>.F32 <Sd>, <Sn>, <Sm>
bool ArmTranslatorVisitor::vfp_VFMS(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(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) {