fp: Fix FPToFixed for borderline values
This commit is contained in:
parent
f3af94bc7c
commit
4f3ef50d5c
2 changed files with 19 additions and 1 deletions
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "dynarmic/common/fp/op/FPToFixed.h"
|
#include "dynarmic/common/fp/op/FPToFixed.h"
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
#include <mcl/assert.hpp>
|
#include <mcl/assert.hpp>
|
||||||
#include <mcl/bit/bit_count.hpp>
|
#include <mcl/bit/bit_count.hpp>
|
||||||
#include <mcl/bit/bit_field.hpp>
|
#include <mcl/bit/bit_field.hpp>
|
||||||
|
@ -75,7 +76,7 @@ u64 FPToFixed(size_t ibits, FPT op, size_t fbits, bool unsigned_, FPCR fpcr, Rou
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detect Overflow
|
// Detect Overflow
|
||||||
const int min_exponent_for_overflow = static_cast<int>(ibits) - static_cast<int>(mcl::bit::highest_set_bit(value.mantissa + (round_up ? 1 : 0))) - (unsigned_ ? 0 : 1);
|
const int min_exponent_for_overflow = static_cast<int>(ibits) - static_cast<int>(mcl::bit::highest_set_bit(value.mantissa + (round_up ? Safe::LogicalShiftRight<u64>(1, exponent) : 0))) - (unsigned_ ? 0 : 1);
|
||||||
if (exponent >= min_exponent_for_overflow) {
|
if (exponent >= min_exponent_for_overflow) {
|
||||||
// Positive overflow
|
// Positive overflow
|
||||||
if (unsigned_ || !sign) {
|
if (unsigned_ || !sign) {
|
||||||
|
|
|
@ -38,3 +38,20 @@ TEST_CASE("FPToFixed", "[fp]") {
|
||||||
REQUIRE(fpsr.Value() == expected_fpsr);
|
REQUIRE(fpsr.Value() == expected_fpsr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("FPToFixed edge cases", "[fp]") {
|
||||||
|
const std::vector<std::tuple<u64, u64, bool, FP::RoundingMode>> test_cases{
|
||||||
|
{0x41dffffffffffffe, 0x7fffffff, false, FP::RoundingMode::ToNearest_TieEven},
|
||||||
|
{0x41dffffffffffffe, 0x7fffffff, false, FP::RoundingMode::TowardsPlusInfinity},
|
||||||
|
{0x41dffffffffffffe, 0x7fffffff, false, FP::RoundingMode::TowardsMinusInfinity},
|
||||||
|
{0x41dffffffffffffe, 0x7fffffff, false, FP::RoundingMode::TowardsZero},
|
||||||
|
{0x41dffffffffffffe, 0x7fffffff, false, FP::RoundingMode::ToNearest_TieAwayFromZero},
|
||||||
|
};
|
||||||
|
|
||||||
|
const FPCR fpcr;
|
||||||
|
FPSR fpsr;
|
||||||
|
for (auto [input, expected_output, unsigned_, rounding_mode] : test_cases) {
|
||||||
|
const u64 output = FPToFixed<u64>(32, input, 0, unsigned_, fpcr, rounding_mode, fpsr);
|
||||||
|
REQUIRE(output == expected_output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue