diff --git a/core/libs/prx/libc/src/MathExact.cpp b/core/libs/prx/libc/src/MathExact.cpp index bbfe5114ef..e6f7d3849f 100644 --- a/core/libs/prx/libc/src/MathExact.cpp +++ b/core/libs/prx/libc/src/MathExact.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "prx/libc/include/General.hpp" @@ -179,25 +180,13 @@ long double APS5_VABI fmal_nid_postfix(long double x, long double y, long double double APS5_VABI rint_nid_postfix(double x) { return std::isnan(x) ? x + x : std::rint(x); } float APS5_VABI rintf_nid_postfix(float x) { return std::isnan(x) ? x + x : std::rint(x); } -std::int64_t APS5_VABI lrint_nid_postfix(double x) { - ErrnoGuard guard; - return std::llrint(x); -} +std::int64_t APS5_VABI lrint_nid_postfix(double x) { return _mm_cvtsd_si64(_mm_set_sd(x)); } -std::int64_t APS5_VABI lrintf_nid_postfix(float x) { - ErrnoGuard guard; - return std::llrint(x); -} +std::int64_t APS5_VABI lrintf_nid_postfix(float x) { return _mm_cvtss_si64(_mm_set_ss(x)); } -long long APS5_VABI llrint_nid_postfix(double x) { - ErrnoGuard guard; - return std::llrint(x); -} +long long APS5_VABI llrint_nid_postfix(double x) { return _mm_cvtsd_si64(_mm_set_sd(x)); } -long long APS5_VABI llrintf_nid_postfix(float x) { - ErrnoGuard guard; - return std::llrint(x); -} +long long APS5_VABI llrintf_nid_postfix(float x) { return _mm_cvtss_si64(_mm_set_ss(x)); } double APS5_VABI drem_nid_postfix(double x, double y) { return Remainder(x, y); diff --git a/core/libs/tests/GuestMathExact.cpp b/core/libs/tests/GuestMathExact.cpp index 5db64f610d..53b41df063 100644 --- a/core/libs/tests/GuestMathExact.cpp +++ b/core/libs/tests/GuestMathExact.cpp @@ -103,6 +103,11 @@ static void CheckConsoleQuirks() { Require(scalblnl_nid_postfix(1.0L, INT64_C(0x100000001)) == 2.0L && scalblnl_nid_postfix(1.0L, INT64_MAX) == 0.5L); Require(scalbln_nid_postfix(1.0, INT64_C(0x100000001)) == INFINITY && scalbln_nid_postfix(1.0, INT64_MIN) == 0.0); Require(lrint_nid_postfix(0x1p40) == INT64_C(0x10000000000)); + for (const double outside : {0x1p63, -0x1p64, 1e300, static_cast(INFINITY), -static_cast(INFINITY), static_cast(NAN)}) { + Require(lrint_nid_postfix(outside) == INT64_MIN && llrint_nid_postfix(outside) == LLONG_MIN); + Require(lrintf_nid_postfix(static_cast(outside)) == INT64_MIN && llrintf_nid_postfix(static_cast(outside)) == LLONG_MIN); + } + Require(lrint_nid_postfix(-0x1p63) == INT64_MIN && lrintf_nid_postfix(0x1.fffffep62f) == INT64_C(0x7fffff8000000000)); const long double product = Extended(0x4000, 0xe000000000000000ull) * Extended(0x4001, 0xda76b022816f6a94ull); Require(SameBits(fmal_nid_postfix(Extended(0x4000, 0xe000000000000000ull), Extended(0x4001, 0xda76b022816f6a94ull), Extended(0x9b45, 0xd3b49eac84283c95ull)), product)); Require(finite_nid_postfix(1.0) == 1 && finite_nid_postfix(INFINITY) == 0);