From e7c20b30331e2c5be96c34586849b8b4e4bfc640 Mon Sep 17 00:00:00 2001 From: MarcZX100 Date: Sun, 11 Oct 2026 14:35:01 +0000 Subject: [PATCH] feat(libc): export isnanf and __signbitl --- core/libs/prx/libc/src/Math.cpp | 5 +++++ core/libs/tests/GuestMath.cpp | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/core/libs/prx/libc/src/Math.cpp b/core/libs/prx/libc/src/Math.cpp index 9d6a8aebd..ba60360b1 100644 --- a/core/libs/prx/libc/src/Math.cpp +++ b/core/libs/prx/libc/src/Math.cpp @@ -169,6 +169,7 @@ short APS5_VABI _FDtest_nid_postfix(const float* value) { return Finite; } int APS5_VABI __isnanf_nid_postfix(float x) { return std::isnan(x) ? 1 : 0; } +int APS5_VABI isnanf_nid_postfix(float x) { return __isnanf_nid_postfix(x); } int APS5_VABI __fpclassifyf_nid_postfix(float x) { constexpr int Infinite = 0x01, NotANumber = 0x02, Normal = 0x04, Subnormal = 0x08, Zero = 0x10; std::uint32_t bits; @@ -180,6 +181,10 @@ int APS5_VABI __fpclassifyf_nid_postfix(float x) { return Normal; } int APS5_VABI __signbitf_nid_postfix(float x) { return std::signbit(x) ? 1 : 0; } +int APS5_VABI __signbitl_nid_postfix(long double x) { + static_assert(sizeof(long double) == 16, "guest long double requires x87 extended precision storage"); + return std::signbit(x) ? 1 : 0; +} static std::mutex g_randLock; static std::uint32_t g_randState = 1; diff --git a/core/libs/tests/GuestMath.cpp b/core/libs/tests/GuestMath.cpp index 6d56671b5..01fdbd1f8 100644 --- a/core/libs/tests/GuestMath.cpp +++ b/core/libs/tests/GuestMath.cpp @@ -37,6 +37,8 @@ extern LibcFloatConstant _FInf_nid_postfix; extern LibcFloatConstant _FNan_nid_postfix; short APS5_VABI _FDtest_nid_postfix(const float*); int APS5_VABI __fpclassifyf_nid_postfix(float); +int APS5_VABI isnanf_nid_postfix(float); +int APS5_VABI __signbitl_nid_postfix(long double); float APS5_VABI fmodf_nid_postfix(float, float); float APS5_VABI asinf_nid_postfix(float); float APS5_VABI acosf_nid_postfix(float); @@ -328,6 +330,21 @@ static void CheckFloatClassification() { Require(_FDtest_nid_postfix(reinterpret_cast(&_FNan_nid_postfix)) == 2); } +static void CheckMissingClassificationExports() { + const float infinity = std::numeric_limits::infinity(); + const float nan = std::numeric_limits::quiet_NaN(); + Require(isnanf_nid_postfix(nan) == 1); + Require(isnanf_nid_postfix(infinity) == 0 && isnanf_nid_postfix(-infinity) == 0); + Require(isnanf_nid_postfix(0.f) == 0 && isnanf_nid_postfix(-1.f) == 0); + + const long double negativeNan = std::copysign(std::numeric_limits::quiet_NaN(), -1.L); + Require(__signbitl_nid_postfix(0.L) == 0 && __signbitl_nid_postfix(-0.L) == 1); + Require(__signbitl_nid_postfix(1.L) == 0 && __signbitl_nid_postfix(-1.L) == 1); + Require(__signbitl_nid_postfix(std::numeric_limits::infinity()) == 0); + Require(__signbitl_nid_postfix(-std::numeric_limits::infinity()) == 1); + Require(__signbitl_nid_postfix(negativeNan) == 1); +} + static void CheckDoubleRounding(double value, std::int64_t expected, bool invalid) { for (const bool useLlround : {false, true}) { std::feclearexcept(FE_ALL_EXCEPT); @@ -352,6 +369,7 @@ static void CheckFloatRounding(float value, std::int64_t expected, bool invalid) int main() { CheckFloatClassification(); + CheckMissingClassificationExports(); CheckIntegerConversions(); Require(atof_nid_postfix(" -12.5tail") == -12.5); char* end = nullptr;