A32: Implement VFPv5 VRINT{R,Z}

This commit is contained in:
MerryMage 2020-06-22 19:35:32 +01:00
parent 47bc99ad9f
commit 52b8039367
4 changed files with 46 additions and 0 deletions

View file

@ -26,6 +26,8 @@ INST(vfp_VCVTB, "VCVTB", "cccc11101D11001odddd101z0
INST(vfp_VCVTT, "VCVTT", "cccc11101D11001odddd101z11M0mmmm") // VFPv3HP INST(vfp_VCVTT, "VCVTT", "cccc11101D11001odddd101z11M0mmmm") // VFPv3HP
INST(vfp_VCMP, "VCMP", "cccc11101D110100dddd101zE1M0mmmm") // VFPv2 INST(vfp_VCMP, "VCMP", "cccc11101D110100dddd101zE1M0mmmm") // VFPv2
INST(vfp_VCMP_zero, "VCMP (with zero)", "cccc11101D110101dddd101zE1000000") // VFPv2 INST(vfp_VCMP_zero, "VCMP (with zero)", "cccc11101D110101dddd101zE1000000") // VFPv2
INST(vfp_VRINTR, "VRINTR", "cccc11101D110110dddd101z01M0mmmm") // VFPv5
INST(vfp_VRINTZ, "VRINTZ", "cccc11101D110110dddd101z11M0mmmm") // VFPv5
INST(vfp_VCVT_f_to_f, "VCVT (f32<->f64)", "cccc11101D110111dddd101z11M0mmmm") // VFPv2 INST(vfp_VCVT_f_to_f, "VCVT (f32<->f64)", "cccc11101D110111dddd101z11M0mmmm") // VFPv2
INST(vfp_VCVT_from_int, "VCVT (from int)", "cccc11101D111000dddd101zs1M0mmmm") // VFPv2 INST(vfp_VCVT_from_int, "VCVT (from int)", "cccc11101D111000dddd101zs1M0mmmm") // VFPv2
//INST(vfp_VCVT_from_fixed, "VCVT (from fixed)", "cccc11101D11101Udddd101zx1i0vvvv") // VFPv3 //INST(vfp_VCVT_from_fixed, "VCVT (from fixed)", "cccc11101D11101Udddd101zx1i0vvvv") // VFPv3

View file

@ -1420,6 +1420,14 @@ public:
return fmt::format("vcmp{}{}.{} {}, #0.0", E ? "e" : "", CondToString(cond), sz ? "f64" : "f32", FPRegStr(sz, Vd, D)); return fmt::format("vcmp{}{}.{} {}, #0.0", E ? "e" : "", CondToString(cond), sz ? "f64" : "f32", FPRegStr(sz, Vd, D));
} }
std::string vfp_VRINTR(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
return fmt::format("vrintr{} {}, {}", CondToString(cond), FPRegStr(sz, Vd, D), FPRegStr(sz, Vm, M));
}
std::string vfp_VRINTZ(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
return fmt::format("vrintz{} {}, {}", CondToString(cond), FPRegStr(sz, Vd, D), FPRegStr(sz, Vm, M));
}
std::string vfp_VCVT_f_to_f(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) { std::string vfp_VCVT_f_to_f(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
return fmt::format("vcvt{}.{}.{} {}, {}", CondToString(cond), !sz ? "f64" : "f32", sz ? "f64" : "f32", FPRegStr(!sz, Vd, D), FPRegStr(sz, Vm, M)); return fmt::format("vcvt{}.{}.{} {}, {}", CondToString(cond), !sz ? "f64" : "f32", sz ? "f64" : "f32", FPRegStr(!sz, Vd, D), FPRegStr(sz, Vm, M));
} }

View file

@ -423,6 +423,8 @@ struct ArmTranslatorVisitor final {
bool vfp_VCVTT(Cond cond, bool D, bool op, size_t Vd, bool sz, bool M, size_t Vm); bool vfp_VCVTT(Cond cond, bool D, bool op, size_t Vd, bool sz, bool M, size_t Vm);
bool vfp_VCMP(Cond cond, bool D, size_t Vd, bool sz, bool E, bool M, size_t Vm); bool vfp_VCMP(Cond cond, bool D, size_t Vd, bool sz, bool E, bool M, size_t Vm);
bool vfp_VCMP_zero(Cond cond, bool D, size_t Vd, bool sz, bool E); bool vfp_VCMP_zero(Cond cond, bool D, size_t Vd, bool sz, bool E);
bool vfp_VRINTR(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm);
bool vfp_VRINTZ(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm);
bool vfp_VCVT_f_to_f(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm); bool vfp_VCVT_f_to_f(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm);
bool vfp_VCVT_from_int(Cond cond, bool D, size_t Vd, bool sz, bool is_signed, bool M, size_t Vm); bool vfp_VCVT_from_int(Cond cond, bool D, size_t Vd, bool sz, bool is_signed, bool M, size_t Vm);
bool vfp_VCVT_to_u32(Cond cond, bool D, size_t Vd, bool sz, bool round_towards_zero, bool M, size_t Vm); bool vfp_VCVT_to_u32(Cond cond, bool D, size_t Vd, bool sz, bool round_towards_zero, bool M, size_t Vm);

View file

@ -882,6 +882,40 @@ bool ArmTranslatorVisitor::vfp_VCMP_zero(Cond cond, bool D, size_t Vd, bool sz,
return true; return true;
} }
// VRINTR.{F16,F32} <Sd>, <Sm>
// VRINTR.F64 <Dd>, <Dm>
bool ArmTranslatorVisitor::vfp_VRINTR(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!ConditionPassed(cond)) {
return true;
}
const auto d = ToExtReg(sz, Vd, D);
const auto m = ToExtReg(sz, Vm, M);
const auto reg_m = ir.GetExtendedRegister(m);
const auto rounding_mode = ir.current_location.FPSCR().RMode();
const auto result = ir.FPRoundInt(reg_m, rounding_mode, false);
ir.SetExtendedRegister(d, result);
return true;
}
// VRINTZ.{F16,F32} <Sd>, <Sm>
// VRINTZ.F64 <Dd>, <Dm>
bool ArmTranslatorVisitor::vfp_VRINTZ(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!ConditionPassed(cond)) {
return true;
}
const auto d = ToExtReg(sz, Vd, D);
const auto m = ToExtReg(sz, Vm, M);
const auto reg_m = ir.GetExtendedRegister(m);
const auto rounding_mode = FP::RoundingMode::TowardsZero;
const auto result = ir.FPRoundInt(reg_m, rounding_mode, false);
ir.SetExtendedRegister(d, result);
return true;
}
// VCVT<c>.F64.F32 <Dd>, <Sm> // VCVT<c>.F64.F32 <Dd>, <Sm>
// VCVT<c>.F32.F64 <Sd>, <Dm> // VCVT<c>.F32.F64 <Sd>, <Dm>
bool ArmTranslatorVisitor::vfp_VCVT_f_to_f(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) { bool ArmTranslatorVisitor::vfp_VCVT_f_to_f(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {