feat(libc): export isnanf and __signbitl

This commit is contained in:
MarcZX100 2026-10-11 14:35:01 +00:00
parent a11c8f7f70
commit e7c20b3033
2 changed files with 23 additions and 0 deletions

View File

@ -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;

View File

@ -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<const float*>(&_FNan_nid_postfix)) == 2);
}
static void CheckMissingClassificationExports() {
const float infinity = std::numeric_limits<float>::infinity();
const float nan = std::numeric_limits<float>::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<long double>::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<long double>::infinity()) == 0);
Require(__signbitl_nid_postfix(-std::numeric_limits<long double>::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;