From 617ca0adf007e862f4f1f50751a4aaa07900ef90 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 30 Jun 2018 11:36:46 +0100 Subject: [PATCH] floating_point_conversion_integer: Refactor implementation of FCVTZS_float_int and FCVTZU_float_int --- .../floating_point_conversion_integer.cpp | 73 +++++++++++-------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/src/frontend/A64/translate/impl/floating_point_conversion_integer.cpp b/src/frontend/A64/translate/impl/floating_point_conversion_integer.cpp index 009744bd..98143f86 100644 --- a/src/frontend/A64/translate/impl/floating_point_conversion_integer.cpp +++ b/src/frontend/A64/translate/impl/floating_point_conversion_integer.cpp @@ -6,6 +6,7 @@ #include +#include "common/fp/rounding_mode.h" #include "frontend/A64/translate/impl/impl.h" namespace Dynarmic::A64 { @@ -135,58 +136,66 @@ bool TranslatorVisitor::FMOV_float_gen(bool sf, Imm<2> type, Imm<1> rmode_0, Imm return true; } -bool TranslatorVisitor::FCVTZS_float_int(bool sf, Imm<2> type, Vec Vn, Reg Rd) { +static bool FloaingPointConvertSignedInteger(TranslatorVisitor& v, bool sf, Imm<2> type, Vec Vn, Reg Rd, FP::RoundingMode rounding_mode) { const size_t intsize = sf ? 64 : 32; const auto fltsize = GetDataSize(type); if (!fltsize || *fltsize == 16) { - return UnallocatedEncoding(); + return v.UnallocatedEncoding(); } - const IR::U32U64 fltval = V_scalar(*fltsize, Vn); + const IR::U32U64 fltval = v.V_scalar(*fltsize, Vn); IR::U32U64 intval; if (intsize == 32 && *fltsize == 32) { - intval = ir.FPSingleToFixedS32(fltval, 0, FP::RoundingMode::TowardsZero); + intval = v.ir.FPSingleToFixedS32(fltval, 0, rounding_mode); } else if (intsize == 32 && *fltsize == 64) { - intval = ir.FPDoubleToFixedS32(fltval, 0, FP::RoundingMode::TowardsZero); + intval = v.ir.FPDoubleToFixedS32(fltval, 0, rounding_mode); } else if (intsize == 64 && *fltsize == 32) { - intval = ir.FPSingleToFixedS64(fltval, 0, FP::RoundingMode::TowardsZero); + intval = v.ir.FPSingleToFixedS64(fltval, 0, rounding_mode); } else if (intsize == 64 && *fltsize == 64) { - intval = ir.FPDoubleToFixedS64(fltval, 0, FP::RoundingMode::TowardsZero); + intval = v.ir.FPDoubleToFixedS64(fltval, 0, rounding_mode); } else { UNREACHABLE(); } - X(intsize, Rd, intval); + v.X(intsize, Rd, intval); return true; } +static bool FloaingPointConvertUnsignedInteger(TranslatorVisitor& v, bool sf, Imm<2> type, Vec Vn, Reg Rd, FP::RoundingMode rounding_mode) { + const size_t intsize = sf ? 64 : 32; + const auto fltsize = GetDataSize(type); + if (!fltsize || *fltsize == 16) { + return v.UnallocatedEncoding(); + } + + const IR::U32U64 fltval = v.V_scalar(*fltsize, Vn); + IR::U32U64 intval; + + if (intsize == 32 && *fltsize == 32) { + intval = v.ir.FPSingleToFixedU32(fltval, 0, rounding_mode); + } else if (intsize == 32 && *fltsize == 64) { + intval = v.ir.FPDoubleToFixedU32(fltval, 0, rounding_mode); + } else if (intsize == 64 && *fltsize == 32) { + intval = v.ir.FPSingleToFixedU64(fltval, 0, rounding_mode); + } else if (intsize == 64 && *fltsize == 64) { + intval = v.ir.FPDoubleToFixedU64(fltval, 0, rounding_mode); + } else { + UNREACHABLE(); + } + + v.X(intsize, Rd, intval); + + return true; +} + +bool TranslatorVisitor::FCVTZS_float_int(bool sf, Imm<2> type, Vec Vn, Reg Rd) { + return FloaingPointConvertSignedInteger(*this, sf, type, Vn, Rd, FP::RoundingMode::TowardsZero); +} + bool TranslatorVisitor::FCVTZU_float_int(bool sf, Imm<2> type, Vec Vn, Reg Rd) { - const size_t intsize = sf ? 64 : 32; - const auto fltsize = GetDataSize(type); - if (!fltsize || *fltsize == 16) { - return UnallocatedEncoding(); - } - - const IR::U32U64 fltval = V_scalar(*fltsize, Vn); - IR::U32U64 intval; - - if (intsize == 32 && *fltsize == 32) { - intval = ir.FPSingleToFixedU32(fltval, 0, FP::RoundingMode::TowardsZero); - } else if (intsize == 32 && *fltsize == 64) { - intval = ir.FPDoubleToFixedU32(fltval, 0, FP::RoundingMode::TowardsZero); - } else if (intsize == 64 && *fltsize == 32) { - intval = ir.FPSingleToFixedU64(fltval, 0, FP::RoundingMode::TowardsZero); - } else if (intsize == 64 && *fltsize == 64) { - intval = ir.FPDoubleToFixedU64(fltval, 0, FP::RoundingMode::TowardsZero); - } else { - UNREACHABLE(); - } - - X(intsize, Rd, intval); - - return true; + return FloaingPointConvertUnsignedInteger(*this, sf, type, Vn, Rd, FP::RoundingMode::TowardsZero); } } // namespace Dynarmic::A64