From 3415828fb4f8dc6b7396444966572d2df3bcda7b Mon Sep 17 00:00:00 2001 From: MerryMage Date: Wed, 5 Sep 2018 20:12:37 +0100 Subject: [PATCH] IR: Simplify FP{Single,Double}ToFixed{U,S}{32,64} --- .../A32/translate/translate_arm/vfp2.cpp | 8 +--- .../floating_point_conversion_fixed_point.cpp | 32 +++++---------- .../floating_point_conversion_integer.cpp | 24 ++++------- .../impl/simd_scalar_shift_by_immediate.cpp | 16 +++----- .../impl/simd_scalar_two_register_misc.cpp | 16 +++----- src/frontend/ir/ir_emitter.cpp | 40 ++++++------------- src/frontend/ir/ir_emitter.h | 12 ++---- 7 files changed, 48 insertions(+), 100 deletions(-) diff --git a/src/frontend/A32/translate/translate_arm/vfp2.cpp b/src/frontend/A32/translate/translate_arm/vfp2.cpp index 898a8418..69939ff5 100644 --- a/src/frontend/A32/translate/translate_arm/vfp2.cpp +++ b/src/frontend/A32/translate/translate_arm/vfp2.cpp @@ -441,9 +441,7 @@ bool ArmTranslatorVisitor::vfp2_VCVT_to_u32(Cond cond, bool D, size_t Vd, bool s // VCVT{,R}.U32.F64 , if (ConditionPassed(cond)) { auto reg_m = ir.GetExtendedRegister(m); - auto result = sz - ? ir.FPDoubleToFixedU32(reg_m, 0, round_towards_zero ? FP::RoundingMode::TowardsZero : ir.current_location.FPSCR().RMode()) - : ir.FPSingleToFixedU32(reg_m, 0, round_towards_zero ? FP::RoundingMode::TowardsZero : ir.current_location.FPSCR().RMode()); + auto result = ir.FPToFixedU32(reg_m, 0, round_towards_zero ? FP::RoundingMode::TowardsZero : ir.current_location.FPSCR().RMode()); ir.SetExtendedRegister(d, result); } return true; @@ -456,9 +454,7 @@ bool ArmTranslatorVisitor::vfp2_VCVT_to_s32(Cond cond, bool D, size_t Vd, bool s // VCVT{,R}.S32.F64 , if (ConditionPassed(cond)) { auto reg_m = ir.GetExtendedRegister(m); - auto result = sz - ? ir.FPDoubleToFixedS32(reg_m, 0, round_towards_zero ? FP::RoundingMode::TowardsZero : ir.current_location.FPSCR().RMode()) - : ir.FPSingleToFixedS32(reg_m, 0, round_towards_zero ? FP::RoundingMode::TowardsZero : ir.current_location.FPSCR().RMode()); + auto result = ir.FPToFixedS32(reg_m, 0, round_towards_zero ? FP::RoundingMode::TowardsZero : ir.current_location.FPSCR().RMode()); ir.SetExtendedRegister(d, result); } return true; diff --git a/src/frontend/A64/translate/impl/floating_point_conversion_fixed_point.cpp b/src/frontend/A64/translate/impl/floating_point_conversion_fixed_point.cpp index b346dbd8..4d3b9011 100644 --- a/src/frontend/A64/translate/impl/floating_point_conversion_fixed_point.cpp +++ b/src/frontend/A64/translate/impl/floating_point_conversion_fixed_point.cpp @@ -21,18 +21,12 @@ bool TranslatorVisitor::FCVTZS_float_fix(bool sf, Imm<2> type, Imm<6> scale, Vec } const u8 fracbits = 64 - scale.ZeroExtend(); - const IR::U32U64 fltscale = I(*fltsize, u64(fracbits + (*fltsize == 32 ? 127 : 1023)) << (*fltsize == 32 ? 23 : 52)); - const IR::U32U64 fltval = ir.FPMul(V_scalar(*fltsize, Vn), fltscale, true); - + const IR::U32U64 fltval = V_scalar(*fltsize, Vn); IR::U32U64 intval; - if (intsize == 32 && *fltsize == 32) { - intval = ir.FPSingleToFixedS32(fltval, 0, FP::RoundingMode::TowardsZero); - } else if (intsize == 32 && *fltsize == 64) { - intval = ir.FPDoubleToFixedS32(fltval, 0, FP::RoundingMode::TowardsZero); - } else if (intsize == 64 && *fltsize == 32) { - intval = ir.FPSingleToFixedS64(fltval, 0, FP::RoundingMode::TowardsZero); - } else if (intsize == 64 && *fltsize == 64) { - intval = ir.FPDoubleToFixedS64(fltval, 0, FP::RoundingMode::TowardsZero); + if (intsize == 32) { + intval = ir.FPToFixedS32(fltval, fracbits, FP::RoundingMode::TowardsZero); + } else if (intsize == 64) { + intval = ir.FPToFixedS64(fltval, fracbits, FP::RoundingMode::TowardsZero); } else { UNREACHABLE(); } @@ -52,18 +46,12 @@ bool TranslatorVisitor::FCVTZU_float_fix(bool sf, Imm<2> type, Imm<6> scale, Vec } const u8 fracbits = 64 - scale.ZeroExtend(); - const IR::U32U64 fltscale = I(*fltsize, u64(fracbits + (*fltsize == 32 ? 127 : 1023)) << (*fltsize == 32 ? 23 : 52)); - const IR::U32U64 fltval = ir.FPMul(V_scalar(*fltsize, Vn), fltscale, true); - + 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); + if (intsize == 32) { + intval = ir.FPToFixedU32(fltval, fracbits, FP::RoundingMode::TowardsZero); + } else if (intsize == 64) { + intval = ir.FPToFixedU64(fltval, fracbits, FP::RoundingMode::TowardsZero); } else { UNREACHABLE(); } 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 35f03411..97be8ca9 100644 --- a/src/frontend/A64/translate/impl/floating_point_conversion_integer.cpp +++ b/src/frontend/A64/translate/impl/floating_point_conversion_integer.cpp @@ -134,14 +134,10 @@ static bool FloaingPointConvertSignedInteger(TranslatorVisitor& v, bool sf, Imm< const IR::U32U64 fltval = v.V_scalar(*fltsize, Vn); IR::U32U64 intval; - if (intsize == 32 && *fltsize == 32) { - intval = v.ir.FPSingleToFixedS32(fltval, 0, rounding_mode); - } else if (intsize == 32 && *fltsize == 64) { - intval = v.ir.FPDoubleToFixedS32(fltval, 0, rounding_mode); - } else if (intsize == 64 && *fltsize == 32) { - intval = v.ir.FPSingleToFixedS64(fltval, 0, rounding_mode); - } else if (intsize == 64 && *fltsize == 64) { - intval = v.ir.FPDoubleToFixedS64(fltval, 0, rounding_mode); + if (intsize == 32) { + intval = v.ir.FPToFixedS32(fltval, 0, rounding_mode); + } else if (intsize == 64) { + intval = v.ir.FPToFixedS64(fltval, 0, rounding_mode); } else { UNREACHABLE(); } @@ -161,14 +157,10 @@ static bool FloaingPointConvertUnsignedInteger(TranslatorVisitor& v, bool sf, Im 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); + if (intsize == 32) { + intval = v.ir.FPToFixedU32(fltval, 0, rounding_mode); + } else if (intsize == 64) { + intval = v.ir.FPToFixedU64(fltval, 0, rounding_mode); } else { UNREACHABLE(); } diff --git a/src/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp b/src/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp index 700980f5..867b2601 100644 --- a/src/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp +++ b/src/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp @@ -140,18 +140,14 @@ bool ScalarFPConvertWithRound(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Ve const IR::U32U64 operand = v.V_scalar(esize, Vn); const IR::U32U64 result = [&]() -> IR::U32U64 { if (esize == 64) { - if (sign == Signedness::Signed) { - return v.ir.FPDoubleToFixedS64(operand, fbits, FP::RoundingMode::TowardsZero); - } - - return v.ir.FPDoubleToFixedU64(operand, fbits, FP::RoundingMode::TowardsZero); + return sign == Signedness::Signed + ? v.ir.FPToFixedS64(operand, fbits, FP::RoundingMode::TowardsZero) + : v.ir.FPToFixedU64(operand, fbits, FP::RoundingMode::TowardsZero); } - if (sign == Signedness::Signed) { - return v.ir.FPSingleToFixedS32(operand, fbits, FP::RoundingMode::TowardsZero); - } - - return v.ir.FPSingleToFixedU32(operand, fbits, FP::RoundingMode::TowardsZero); + return sign == Signedness::Signed + ? v.ir.FPToFixedS32(operand, fbits, FP::RoundingMode::TowardsZero) + : v.ir.FPToFixedU32(operand, fbits, FP::RoundingMode::TowardsZero); }(); v.V_scalar(esize, Vd, result); diff --git a/src/frontend/A64/translate/impl/simd_scalar_two_register_misc.cpp b/src/frontend/A64/translate/impl/simd_scalar_two_register_misc.cpp index d3d5b585..e5890b2a 100644 --- a/src/frontend/A64/translate/impl/simd_scalar_two_register_misc.cpp +++ b/src/frontend/A64/translate/impl/simd_scalar_two_register_misc.cpp @@ -56,18 +56,14 @@ bool ScalarFPConvertWithRound(TranslatorVisitor& v, bool sz, Vec Vn, Vec Vd, const IR::U32U64 operand = v.V_scalar(esize, Vn); const IR::U32U64 result = [&]() -> IR::U32U64 { if (sz) { - if (sign == Signedness::Signed) { - return v.ir.FPDoubleToFixedS64(operand, 0, rmode); - } - - return v.ir.FPDoubleToFixedU64(operand, 0, rmode); + return sign == Signedness::Signed + ? v.ir.FPToFixedS64(operand, 0, rmode) + : v.ir.FPToFixedU64(operand, 0, rmode); } - if (sign == Signedness::Signed) { - return v.ir.FPSingleToFixedS32(operand, 0, rmode); - } - - return v.ir.FPSingleToFixedU32(operand, 0, rmode); + return sign == Signedness::Signed + ? v.ir.FPToFixedS32(operand, 0, rmode) + : v.ir.FPToFixedU32(operand, 0, rmode); }(); v.V_scalar(esize, Vd, result); diff --git a/src/frontend/ir/ir_emitter.cpp b/src/frontend/ir/ir_emitter.cpp index b9a9424c..6d65b477 100644 --- a/src/frontend/ir/ir_emitter.cpp +++ b/src/frontend/ir/ir_emitter.cpp @@ -1774,44 +1774,28 @@ U64 IREmitter::FPSingleToDouble(const U32& a, bool fpcr_controlled) { return Inst(Opcode::FPSingleToDouble, a); } -U32 IREmitter::FPDoubleToFixedS32(const U64& a, size_t fbits, FP::RoundingMode rounding) { +U32 IREmitter::FPToFixedS32(const U32U64& a, size_t fbits, FP::RoundingMode rounding) { ASSERT(fbits <= 32); - return Inst(Opcode::FPDoubleToFixedS32, a, Imm8(static_cast(fbits)), Imm8(static_cast(rounding))); + const Opcode opcode = a.GetType() == Type::U32 ? Opcode::FPSingleToFixedS32 : Opcode::FPDoubleToFixedS32; + return Inst(opcode, a, Imm8(static_cast(fbits)), Imm8(static_cast(rounding))); } -U64 IREmitter::FPDoubleToFixedS64(const U64& a, size_t fbits, FP::RoundingMode rounding) { +U64 IREmitter::FPToFixedS64(const U32U64& a, size_t fbits, FP::RoundingMode rounding) { ASSERT(fbits <= 64); - return Inst(Opcode::FPDoubleToFixedS64, a, Imm8(static_cast(fbits)), Imm8(static_cast(rounding))); + const Opcode opcode = a.GetType() == Type::U32 ? Opcode::FPSingleToFixedS64 : Opcode::FPDoubleToFixedS64; + return Inst(opcode, a, Imm8(static_cast(fbits)), Imm8(static_cast(rounding))); } -U32 IREmitter::FPDoubleToFixedU32(const U64& a, size_t fbits, FP::RoundingMode rounding) { +U32 IREmitter::FPToFixedU32(const U32U64& a, size_t fbits, FP::RoundingMode rounding) { ASSERT(fbits <= 32); - return Inst(Opcode::FPDoubleToFixedU32, a, Imm8(static_cast(fbits)), Imm8(static_cast(rounding))); + const Opcode opcode = a.GetType() == Type::U32 ? Opcode::FPSingleToFixedU32 : Opcode::FPDoubleToFixedU32; + return Inst(opcode, a, Imm8(static_cast(fbits)), Imm8(static_cast(rounding))); } -U64 IREmitter::FPDoubleToFixedU64(const U64& a, size_t fbits, FP::RoundingMode rounding) { +U64 IREmitter::FPToFixedU64(const U32U64& a, size_t fbits, FP::RoundingMode rounding) { ASSERT(fbits <= 64); - return Inst(Opcode::FPDoubleToFixedU64, a, Imm8(static_cast(fbits)), Imm8(static_cast(rounding))); -} - -U32 IREmitter::FPSingleToFixedS32(const U32& a, size_t fbits, FP::RoundingMode rounding) { - ASSERT(fbits <= 32); - return Inst(Opcode::FPSingleToFixedS32, a, Imm8(static_cast(fbits)), Imm8(static_cast(rounding))); -} - -U64 IREmitter::FPSingleToFixedS64(const U32& a, size_t fbits, FP::RoundingMode rounding) { - ASSERT(fbits <= 64); - return Inst(Opcode::FPSingleToFixedS64, a, Imm8(static_cast(fbits)), Imm8(static_cast(rounding))); -} - -U32 IREmitter::FPSingleToFixedU32(const U32& a, size_t fbits, FP::RoundingMode rounding) { - ASSERT(fbits <= 32); - return Inst(Opcode::FPSingleToFixedU32, a, Imm8(static_cast(fbits)), Imm8(static_cast(rounding))); -} - -U64 IREmitter::FPSingleToFixedU64(const U32& a, size_t fbits, FP::RoundingMode rounding) { - ASSERT(fbits <= 64); - return Inst(Opcode::FPSingleToFixedU64, a, Imm8(static_cast(fbits)), Imm8(static_cast(rounding))); + const Opcode opcode = a.GetType() == Type::U32 ? Opcode::FPSingleToFixedU64 : Opcode::FPDoubleToFixedU64; + return Inst(opcode, a, Imm8(static_cast(fbits)), Imm8(static_cast(rounding))); } U32 IREmitter::FPS32ToSingle(const U32& a, bool round_to_nearest, bool fpcr_controlled) { diff --git a/src/frontend/ir/ir_emitter.h b/src/frontend/ir/ir_emitter.h index 6fa6af4f..1f3c4d89 100644 --- a/src/frontend/ir/ir_emitter.h +++ b/src/frontend/ir/ir_emitter.h @@ -295,14 +295,10 @@ public: U32U64 FPSub(const U32U64& a, const U32U64& b, bool fpcr_controlled); U32 FPDoubleToSingle(const U64& a, bool fpcr_controlled); U64 FPSingleToDouble(const U32& a, bool fpcr_controlled); - U32 FPDoubleToFixedS32(const U64& a, size_t fbits, FP::RoundingMode rounding); - U64 FPDoubleToFixedS64(const U64& a, size_t fbits, FP::RoundingMode rounding); - U32 FPDoubleToFixedU32(const U64& a, size_t fbits, FP::RoundingMode rounding); - U64 FPDoubleToFixedU64(const U64& a, size_t fbits, FP::RoundingMode rounding); - U32 FPSingleToFixedS32(const U32& a, size_t fbits, FP::RoundingMode rounding); - U64 FPSingleToFixedS64(const U32& a, size_t fbits, FP::RoundingMode rounding); - U32 FPSingleToFixedU32(const U32& a, size_t fbits, FP::RoundingMode rounding); - U64 FPSingleToFixedU64(const U32& a, size_t fbits, FP::RoundingMode rounding); + U32 FPToFixedS32(const U32U64& a, size_t fbits, FP::RoundingMode rounding); + U64 FPToFixedS64(const U32U64& a, size_t fbits, FP::RoundingMode rounding); + U32 FPToFixedU32(const U32U64& a, size_t fbits, FP::RoundingMode rounding); + U64 FPToFixedU64(const U32U64& a, size_t fbits, FP::RoundingMode rounding); U32 FPS32ToSingle(const U32& a, bool round_to_nearest, bool fpcr_controlled); U32 FPU32ToSingle(const U32& a, bool round_to_nearest, bool fpcr_controlled); U64 FPS32ToDouble(const U32& a, bool round_to_nearest, bool fpcr_controlled);