From ed48a9d7d57bedc35907765a42a644837436b103 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Wed, 24 Jun 2020 22:31:58 +0100 Subject: [PATCH] A32: Implement VFPv5 VRINTX --- src/frontend/A32/decoder/vfp.inc | 1 + .../A32/disassembler/disassembler_arm.cpp | 4 ++++ src/frontend/A32/translate/impl/translate_arm.h | 1 + src/frontend/A32/translate/impl/vfp.cpp | 17 +++++++++++++++++ 4 files changed, 23 insertions(+) diff --git a/src/frontend/A32/decoder/vfp.inc b/src/frontend/A32/decoder/vfp.inc index 36283634..21c9b78d 100644 --- a/src/frontend/A32/decoder/vfp.inc +++ b/src/frontend/A32/decoder/vfp.inc @@ -28,6 +28,7 @@ INST(vfp_VCMP, "VCMP", "cccc11101D110100dddd101zE INST(vfp_VCMP_zero, "VCMP (with zero)", "cccc11101D110101dddd101zE1000000") // VFPv2 INST(vfp_VRINTR, "VRINTR", "cccc11101D110110dddd101z01M0mmmm") // VFPv5 INST(vfp_VRINTZ, "VRINTZ", "cccc11101D110110dddd101z11M0mmmm") // VFPv5 +INST(vfp_VRINTX, "VRINTX", "cccc11101D110111dddd101z01M0mmmm") // VFPv5 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_fixed, "VCVT (from fixed)", "cccc11101D11101Udddd101zx1i0vvvv") // VFPv3 diff --git a/src/frontend/A32/disassembler/disassembler_arm.cpp b/src/frontend/A32/disassembler/disassembler_arm.cpp index 3a693303..f7b4329c 100644 --- a/src/frontend/A32/disassembler/disassembler_arm.cpp +++ b/src/frontend/A32/disassembler/disassembler_arm.cpp @@ -1428,6 +1428,10 @@ public: return fmt::format("vrintz{} {}, {}", CondToString(cond), FPRegStr(sz, Vd, D), FPRegStr(sz, Vm, M)); } + std::string vfp_VRINTX(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) { + return fmt::format("vrintx{} {}, {}", 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) { return fmt::format("vcvt{}.{}.{} {}, {}", CondToString(cond), !sz ? "f64" : "f32", sz ? "f64" : "f32", FPRegStr(!sz, Vd, D), FPRegStr(sz, Vm, M)); } diff --git a/src/frontend/A32/translate/impl/translate_arm.h b/src/frontend/A32/translate/impl/translate_arm.h index ed7e2630..3f469f61 100644 --- a/src/frontend/A32/translate/impl/translate_arm.h +++ b/src/frontend/A32/translate/impl/translate_arm.h @@ -425,6 +425,7 @@ struct ArmTranslatorVisitor final { 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_VRINTX(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_fixed(Cond cond, bool D, bool U, size_t Vd, bool sz, bool sx, Imm<1> i, Imm<4> imm4); diff --git a/src/frontend/A32/translate/impl/vfp.cpp b/src/frontend/A32/translate/impl/vfp.cpp index 8ef34d38..3bb939d5 100644 --- a/src/frontend/A32/translate/impl/vfp.cpp +++ b/src/frontend/A32/translate/impl/vfp.cpp @@ -916,6 +916,23 @@ bool ArmTranslatorVisitor::vfp_VRINTZ(Cond cond, bool D, size_t Vd, bool sz, boo return true; } +// VRINTX.{F16,F32} , +// VRINTX.F64
, +bool ArmTranslatorVisitor::vfp_VRINTX(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, true); + ir.SetExtendedRegister(d, result); + return true; +} + // VCVT.F64.F32
, // VCVT.F32.F64 , bool ArmTranslatorVisitor::vfp_VCVT_f_to_f(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {