diff --git a/core/libs/prx/libc/src/MathExact.cpp b/core/libs/prx/libc/src/MathExact.cpp index bbfe5114eff4..fa9cc266432f 100644 --- a/core/libs/prx/libc/src/MathExact.cpp +++ b/core/libs/prx/libc/src/MathExact.cpp @@ -42,8 +42,8 @@ short TestExtended(const ExtendedBits& bits) { const int exponent = bits.signExponent & 0x7fff; const std::uint64_t fraction = bits.mantissa & 0x7fffffffffffffffull; if (exponent == 0x7fff) return fraction != 0 ? NotANumber : Infinite; - if (exponent != 0 || (bits.mantissa >> 63) != 0) return Finite; - return bits.mantissa != 0 ? Denormal : Zero; + if ((bits.mantissa >> 63) != 0) return Finite; + return exponent != 0 || bits.mantissa != 0 ? Denormal : Zero; } template @@ -242,8 +242,9 @@ int APS5_VABI finitef_nid_postfix(float x) { return std::isfinite(x) ? 1 : 0; } int APS5_VABI __fpclassifyl_nid_postfix(long double x) { const ExtendedBits bits = Bits(x); - if ((bits.signExponent & 0x7fff) != 0 || bits.mantissa == 0) return TestExtended(bits); - return Denormal; + const int exponent = bits.signExponent & 0x7fff; + if (exponent == 0) return bits.mantissa != 0 ? Denormal : Zero; + return exponent != 0x7fff ? Finite : TestExtended(bits); } int APS5_VABI __isinfl_nid_postfix(long double x) { return TestExtended(Bits(x)) == Infinite ? 1 : 0; } int APS5_VABI __isnanl_nid_postfix(long double x) { return TestExtended(Bits(x)) == NotANumber ? 1 : 0; } diff --git a/core/libs/tests/GuestMathExact.cpp b/core/libs/tests/GuestMathExact.cpp index 5db64f610dd5..35d1e587dba9 100644 --- a/core/libs/tests/GuestMathExact.cpp +++ b/core/libs/tests/GuestMathExact.cpp @@ -130,6 +130,10 @@ static void CheckRoundingModes() { static void CheckClassification() { const long double pseudoDenormal = Extended(0x0000, 0x8000000000000000ull); Require(_LDtest_nid_postfix(&pseudoDenormal) == -1 && __fpclassifyl_nid_postfix(pseudoDenormal) == -2); + for (const long double unnormal : {Extended(0x3fff, 0x4000000000000000ull), Extended(0x8001, 0), Extended(0x7ffe, 0x7fffffffffffffffull)}) { + Require(_LDtest_nid_postfix(&unnormal) == -2 && _LDclass_nid_postfix(unnormal) == -2); + Require(__fpclassifyl_nid_postfix(unnormal) == -1 && __isnormall_nid_postfix(unnormal) == 1); + } const long double zero = 0.0L, infinity = INFINITY, nan = NAN, denormal = Extended(0, 1); Require(_LDtest_nid_postfix(&zero) == 0 && _LDtest_nid_postfix(&infinity) == 1 && _LDtest_nid_postfix(&nan) == 2 && _LDtest_nid_postfix(&denormal) == -2); Require(__fpclassifyl_nid_postfix(1.0L) == -1 && __fpclassifyl_nid_postfix(0.0L) == 0 && __fpclassifyl_nid_postfix(INFINITY) == 1);