From 805428e35eee0111340a1175cffb349f65de0162 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Mon, 23 Jul 2018 11:52:37 +0100 Subject: [PATCH] fp: Remove MantissaT --- src/common/fp/mantissa_util.h | 11 +++++------ src/common/fp/op/FPRoundInt.cpp | 2 +- src/common/fp/unpacked.cpp | 24 ++++++++++++------------ src/common/fp/unpacked.h | 24 +++++++++++------------- tests/fp/mantissa_util_tests.cpp | 4 ++-- tests/fp/unpacked_tests.cpp | 4 ++-- 6 files changed, 33 insertions(+), 36 deletions(-) diff --git a/src/common/fp/mantissa_util.h b/src/common/fp/mantissa_util.h index 2551c40c..7f2c3110 100644 --- a/src/common/fp/mantissa_util.h +++ b/src/common/fp/mantissa_util.h @@ -18,20 +18,19 @@ enum class ResidualError { GreaterThanHalf, }; -template -ResidualError ResidualErrorOnRightShift(MantissaT mantissa, int shift_amount) { +inline ResidualError ResidualErrorOnRightShift(u64 mantissa, int shift_amount) { if (shift_amount <= 0 || mantissa == 0) { return ResidualError::Zero; } - if (shift_amount > static_cast(Common::BitSize())) { + if (shift_amount > static_cast(Common::BitSize())) { return Common::MostSignificantBit(mantissa) ? ResidualError::GreaterThanHalf : ResidualError::LessThanHalf; } const size_t half_bit_position = static_cast(shift_amount - 1); - const MantissaT half = static_cast(1) << half_bit_position; - const MantissaT error_mask = Common::Ones(static_cast(shift_amount)); - const MantissaT error = mantissa & error_mask; + const u64 half = static_cast(1) << half_bit_position; + const u64 error_mask = Common::Ones(static_cast(shift_amount)); + const u64 error = mantissa & error_mask; if (error == 0) { return ResidualError::Zero; diff --git a/src/common/fp/op/FPRoundInt.cpp b/src/common/fp/op/FPRoundInt.cpp index 2d10b69e..a14c21ca 100644 --- a/src/common/fp/op/FPRoundInt.cpp +++ b/src/common/fp/op/FPRoundInt.cpp @@ -77,7 +77,7 @@ u64 FPRoundInt(FPT op, FPCR fpcr, RoundingMode rounding, bool exact, FPSR& fpsr) const FPT result = int_result == 0 ? FPInfo::Zero(sign) - : FPRound(FPUnpacked{new_sign, 0, abs_int_result}, fpcr, RoundingMode::TowardsZero, fpsr); + : FPRound(FPUnpacked{new_sign, 0, abs_int_result}, fpcr, RoundingMode::TowardsZero, fpsr); if (error != ResidualError::Zero && exact) { FPProcessException(FPExc::Inexact, fpcr, fpsr); diff --git a/src/common/fp/unpacked.cpp b/src/common/fp/unpacked.cpp index 55fe21f0..0cd478b4 100644 --- a/src/common/fp/unpacked.cpp +++ b/src/common/fp/unpacked.cpp @@ -14,7 +14,7 @@ namespace Dynarmic::FP { template -std::tuple> FPUnpack(FPT op, FPCR fpcr, FPSR& fpsr) { +std::tuple FPUnpack(FPT op, FPCR fpcr, FPSR& fpsr) { constexpr size_t sign_bit = FPInfo::exponent_width + FPInfo::explicit_mantissa_width; constexpr size_t exponent_high_bit = FPInfo::exponent_width + FPInfo::explicit_mantissa_width - 1; constexpr size_t exponent_low_bit = FPInfo::explicit_mantissa_width; @@ -51,21 +51,21 @@ std::tuple> FPUnpack(FPT op, FPCR fpcr, FPSR& fpsr return {FPType::Nonzero, sign, {sign, exp, frac}}; } -template std::tuple> FPUnpack(u32 op, FPCR fpcr, FPSR& fpsr); -template std::tuple> FPUnpack(u64 op, FPCR fpcr, FPSR& fpsr); +template std::tuple FPUnpack(u32 op, FPCR fpcr, FPSR& fpsr); +template std::tuple FPUnpack(u64 op, FPCR fpcr, FPSR& fpsr); -template -std::tuple Normalize(FPUnpacked op) { +template +std::tuple Normalize(FPUnpacked op) { const int highest_set_bit = Common::HighestSetBit(op.mantissa); const int shift_amount = highest_set_bit - static_cast(F); - const MantissaT mantissa = Safe::LogicalShiftRight(op.mantissa, shift_amount); - const MantissaT error = Safe::LogicalShiftRightDouble(op.mantissa, static_cast(0), shift_amount); + const u64 mantissa = Safe::LogicalShiftRight(op.mantissa, shift_amount); + const u64 error = Safe::LogicalShiftRightDouble(op.mantissa, static_cast(0), shift_amount); const int exponent = op.exponent + highest_set_bit; return std::make_tuple(op.sign, exponent, mantissa, error); } -template -FPT FPRoundBase(FPUnpacked op, FPCR fpcr, RoundingMode rounding, FPSR& fpsr) { +template +FPT FPRoundBase(FPUnpacked op, FPCR fpcr, RoundingMode rounding, FPSR& fpsr) { ASSERT(op.mantissa != 0); ASSERT(rounding != RoundingMode::ToNearest_TieAwayFromZero); @@ -94,7 +94,7 @@ FPT FPRoundBase(FPUnpacked op, FPCR fpcr, RoundingMode rounding, FPSR bool round_up = false, overflow_to_inf = false; switch (rounding) { case RoundingMode::ToNearest_TieEven: { - constexpr MantissaT half = static_cast(1) << (Common::BitSize() - 1); + constexpr u64 half = static_cast(1) << (Common::BitSize() - 1); round_up = (error > half) || (error == half && Common::Bit<0>(mantissa)); overflow_to_inf = true; break; @@ -175,7 +175,7 @@ FPT FPRoundBase(FPUnpacked op, FPCR fpcr, RoundingMode rounding, FPSR return result; } -template u32 FPRoundBase(FPUnpacked op, FPCR fpcr, RoundingMode rounding, FPSR& fpsr); -template u64 FPRoundBase(FPUnpacked op, FPCR fpcr, RoundingMode rounding, FPSR& fpsr); +template u32 FPRoundBase(FPUnpacked op, FPCR fpcr, RoundingMode rounding, FPSR& fpsr); +template u64 FPRoundBase(FPUnpacked op, FPCR fpcr, RoundingMode rounding, FPSR& fpsr); } // namespace Dynarmic::FP diff --git a/src/common/fp/unpacked.h b/src/common/fp/unpacked.h index 067058c8..a0961bd7 100644 --- a/src/common/fp/unpacked.h +++ b/src/common/fp/unpacked.h @@ -25,33 +25,31 @@ enum class FPType { }; /// value = (sign ? -1 : +1) * mantissa * 2^exponent -template struct FPUnpacked { bool sign; int exponent; - MantissaT mantissa; + u64 mantissa; }; -template -inline bool operator==(const FPUnpacked& a, const FPUnpacked& b) { +inline bool operator==(const FPUnpacked& a, const FPUnpacked& b) { return std::tie(a.sign, a.exponent, a.mantissa) == std::tie(b.sign, b.exponent, b.mantissa); } template -std::tuple> FPUnpack(FPT op, FPCR fpcr, FPSR& fpsr); +std::tuple FPUnpack(FPT op, FPCR fpcr, FPSR& fpsr); -template -FPT FPRoundBase(FPUnpacked op, FPCR fpcr, RoundingMode rounding, FPSR& fpsr); +template +FPT FPRoundBase(FPUnpacked op, FPCR fpcr, RoundingMode rounding, FPSR& fpsr); -template -FPT FPRound(FPUnpacked op, FPCR fpcr, RoundingMode rounding, FPSR& fpsr) { +template +FPT FPRound(FPUnpacked op, FPCR fpcr, RoundingMode rounding, FPSR& fpsr) { fpcr.AHP(false); - return FPRoundBase(op, fpcr, rounding, fpsr); + return FPRoundBase(op, fpcr, rounding, fpsr); } -template -FPT FPRound(FPUnpacked op, FPCR fpcr, FPSR& fpsr) { - return FPRound(op, fpcr, fpcr.RMode(), fpsr); +template +FPT FPRound(FPUnpacked op, FPCR fpcr, FPSR& fpsr) { + return FPRound(op, fpcr, fpcr.RMode(), fpsr); } } // namespace Dynarmic::FP diff --git a/tests/fp/mantissa_util_tests.cpp b/tests/fp/mantissa_util_tests.cpp index 732d35f7..89e9e700 100644 --- a/tests/fp/mantissa_util_tests.cpp +++ b/tests/fp/mantissa_util_tests.cpp @@ -38,12 +38,12 @@ TEST_CASE("ResidualErrorOnRightShift", "[fp]") { TEST_CASE("ResidualErrorOnRightShift Randomized", "[fp]") { for (size_t test = 0; test < 100000; test++) { - const u32 mantissa = RandInt(0, 0xFFFFFFFF); + const u64 mantissa = Common::SignExtend<32, u64>(RandInt(0, 0xFFFFFFFF)); const int shift = RandInt(-60, 60); const ResidualError result = ResidualErrorOnRightShift(mantissa, shift); - const u64 calculated_error = Safe::ArithmeticShiftRightDouble(Common::SignExtend<32, u64>(mantissa), u64(0), shift); + const u64 calculated_error = Safe::ArithmeticShiftRightDouble(mantissa, u64(0), shift); const ResidualError expected_result = [&]{ constexpr u64 half_error = 0x8000'0000'0000'0000ull; if (calculated_error == 0) { diff --git a/tests/fp/unpacked_tests.cpp b/tests/fp/unpacked_tests.cpp index bdc54172..2b50b396 100644 --- a/tests/fp/unpacked_tests.cpp +++ b/tests/fp/unpacked_tests.cpp @@ -19,7 +19,7 @@ using namespace Dynarmic; using namespace Dynarmic::FP; TEST_CASE("FPUnpack Tests", "[fp]") { - const static std::vector>, u32>> test_cases { + const static std::vector, u32>> test_cases { {0x00000000, {FPType::Zero, false, {false, 0, 0}}, 0}, {0x7F800000, {FPType::Infinity, false, {false, 1000000, 1}}, 0}, {0xFF800000, {FPType::Infinity, true, {true, 1000000, 1}}, 0}, @@ -43,7 +43,7 @@ TEST_CASE("FPUnpack Tests", "[fp]") { } TEST_CASE("FPRound Tests", "[fp]") { - const static std::vector>, u32>> test_cases { + const static std::vector, u32>> test_cases { {0x7F800000, {FPType::Infinity, false, {false, 1000000, 1}}, 0x14}, {0xFF800000, {FPType::Infinity, true, {true, 1000000, 1}}, 0x14}, {0x00000001, {FPType::Nonzero, false, {false, -149, 1}}, 0}, // Smallest single precision denormal is 2^-149.