Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #10959 from JosJuice/frsp-subnormal
Interpreter: Fix rounding edge case in frsp
  • Loading branch information
lioncash committed Aug 9, 2022
2 parents e9e2c74 + c5d9514 commit c2dd58c
Showing 1 changed file with 19 additions and 0 deletions.
19 changes: 19 additions & 0 deletions Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h
Expand Up @@ -52,6 +52,25 @@ inline void SetFPException(UReg_FPSCR* fpscr, u32 mask)

inline float ForceSingle(const UReg_FPSCR& fpscr, double value)
{
if (fpscr.NI)
{
// Emulate a rounding quirk. If the conversion result before rounding is a subnormal single,
// it's always flushed to zero, even if rounding would have caused it to become normal.

constexpr u64 smallest_normal_single = 0x3810000000000000;
const u64 value_without_sign =
Common::BitCast<u64>(value) & (Common::DOUBLE_EXP | Common::DOUBLE_FRAC);

if (value_without_sign < smallest_normal_single)
{
const u64 flushed_double = Common::BitCast<u64>(value) & Common::DOUBLE_SIGN;
const u32 flushed_single = static_cast<u32>(flushed_double >> 32);
return Common::BitCast<float>(flushed_single);
}
}

// Emulate standard conversion to single precision.

float x = static_cast<float>(value);
if (!cpu_info.bFlushToZero && fpscr.NI)
{
Expand Down

0 comments on commit c2dd58c

Please sign in to comment.