mirror of
https://github.com/azahar-emu/dynarmic
synced 2025-11-06 15:10:00 +01:00
fp: Fix FPToFixed for borderline values
This commit is contained in:
parent
f3af94bc7c
commit
4f3ef50d5c
@ -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…
x
Reference in New Issue
Block a user