VFPv5: Implement VCVT{A,N,P,M}

This commit is contained in:
MerryMage 2020-06-19 20:31:16 +01:00
parent 6a965b80d6
commit ad96b2b18d
4 changed files with 28 additions and 1 deletions

View file

@ -33,7 +33,7 @@ INST(vfp_VCVT_to_u32, "VCVT (to u32)", "cccc11101D111100dddd101zr
INST(vfp_VCVT_to_s32, "VCVT (to s32)", "cccc11101D111101dddd101zr1M0mmmm") // VFPv2 INST(vfp_VCVT_to_s32, "VCVT (to s32)", "cccc11101D111101dddd101zr1M0mmmm") // VFPv2
//INST(vfp_VCVT_to_fixed, "VCVT (to fixed)", "cccc11101D11111Udddd101zx1i0vvvv") // VFPv3 //INST(vfp_VCVT_to_fixed, "VCVT (to fixed)", "cccc11101D11111Udddd101zx1i0vvvv") // VFPv3
INST(vfp_VRINT_rm, "VRINT{A,N,P,M}", "111111101D1110mmdddd101z01M0mmmm") // VFPv5 INST(vfp_VRINT_rm, "VRINT{A,N,P,M}", "111111101D1110mmdddd101z01M0mmmm") // VFPv5
//INST(vfp_VCVT_rm, "VCVT{A,N,P,M}", "111111101D1111mmdddd101zU1M0mmmm") // VFPv5 INST(vfp_VCVT_rm, "VCVT{A,N,P,M}", "111111101D1111mmdddd101zU1M0mmmm") // VFPv5
// Floating-point move instructions // Floating-point move instructions
INST(vfp_VMOV_u32_f64, "VMOV (core to f64)", "cccc11100000ddddtttt1011D0010000") // VFPv2 INST(vfp_VMOV_u32_f64, "VMOV (core to f64)", "cccc11100000ddddtttt1011D0010000") // VFPv2

View file

@ -1395,6 +1395,10 @@ public:
return fmt::format("vrint{}.{} {}, {}", "anpm"[rm], sz ? "f64" : "f32", FPRegStr(sz, Vd, D), FPRegStr(sz, Vm, M)); return fmt::format("vrint{}.{} {}, {}", "anpm"[rm], sz ? "f64" : "f32", FPRegStr(sz, Vd, D), FPRegStr(sz, Vm, M));
} }
std::string vfp_VCVT_rm(bool D, size_t rm, size_t Vd, bool sz, bool U, bool M, size_t Vm) {
return fmt::format("vcvt{}.{}.{} {}, {}", "anpm"[rm], U ? "u32" : "s32", sz ? "f64" : "f32", FPRegStr(false, Vd, D), FPRegStr(sz, Vm, M));
}
std::string vfp_VMSR(Cond cond, Reg t) { std::string vfp_VMSR(Cond cond, Reg t) {
return fmt::format("vmsr{} fpscr, {}", CondToString(cond), t); return fmt::format("vmsr{} fpscr, {}", CondToString(cond), t);
} }

View file

@ -421,6 +421,7 @@ struct ArmTranslatorVisitor final {
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);
bool vfp_VCVT_to_s32(Cond cond, bool D, size_t Vd, bool sz, bool round_towards_zero, bool M, size_t Vm); bool vfp_VCVT_to_s32(Cond cond, bool D, size_t Vd, bool sz, bool round_towards_zero, bool M, size_t Vm);
bool vfp_VRINT_rm(bool D, size_t rm, size_t Vd, bool sz, bool M, size_t Vm); bool vfp_VRINT_rm(bool D, size_t rm, size_t Vd, bool sz, bool M, size_t Vm);
bool vfp_VCVT_rm(bool D, size_t rm, size_t Vd, bool sz, bool U, bool M, size_t Vm);
// Floating-point system register access // Floating-point system register access
bool vfp_VMSR(Cond cond, Reg t); bool vfp_VMSR(Cond cond, Reg t);

View file

@ -826,6 +826,28 @@ bool ArmTranslatorVisitor::vfp_VRINT_rm(bool D, size_t rm, size_t Vd, bool sz, b
}); });
} }
// VCVT{A,N,P,M}.F32 <Sd>, <Sm>
// VCVT{A,N,P,M}.F64 <Sd>, <Dm>
bool ArmTranslatorVisitor::vfp_VCVT_rm(bool D, size_t rm, size_t Vd, bool sz, bool U, bool M, size_t Vm) {
const std::array rm_lookup{
FP::RoundingMode::ToNearest_TieAwayFromZero,
FP::RoundingMode::ToNearest_TieEven,
FP::RoundingMode::TowardsPlusInfinity,
FP::RoundingMode::TowardsMinusInfinity,
};
const FP::RoundingMode rounding_mode = rm_lookup[rm];
const bool unsigned_ = !U;
const auto d = ToExtReg(false, Vd, D);
const auto m = ToExtReg(sz, Vm, M);
return EmitVfpVectorOperation(sz, d, m, [this, rounding_mode, unsigned_](ExtReg d, ExtReg m) {
const auto reg_m = ir.GetExtendedRegister(m);
const auto result = unsigned_ ? ir.FPToFixedU32(reg_m, 0, rounding_mode) : ir.FPToFixedS32(reg_m, 0, rounding_mode);
ir.SetExtendedRegister(d, result);
});
}
// VMSR FPSCR, <Rt> // VMSR FPSCR, <Rt>
bool ArmTranslatorVisitor::vfp_VMSR(Cond cond, Reg t) { bool ArmTranslatorVisitor::vfp_VMSR(Cond cond, Reg t) {
if (t == Reg::PC) { if (t == Reg::PC) {