From 85e655445bb0d8aa5951f9c53eebaf3c4c37897a Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 4 Apr 2023 16:48:53 +0200 Subject: [PATCH] msvcrt: Use the nextafter()/nextafterf() implementation from the bundled musl library. --- dlls/crtdll/crtdll.spec | 2 +- dlls/msvcr100/msvcr100.spec | 4 +- dlls/msvcr110/msvcr110.spec | 4 +- dlls/msvcr120/msvcr120.spec | 10 ++-- dlls/msvcr70/msvcr70.spec | 2 +- dlls/msvcr71/msvcr71.spec | 2 +- dlls/msvcr80/msvcr80.spec | 4 +- dlls/msvcr90/msvcr90.spec | 4 +- dlls/msvcrt/math.c | 89 +-------------------------------- dlls/msvcrt/msvcrt.spec | 4 +- dlls/msvcrtd/msvcrtd.spec | 2 +- dlls/ucrtbase/ucrtbase.spec | 20 ++++---- libs/musl/src/math/nextafter.c | 14 ++++-- libs/musl/src/math/nextafterf.c | 14 ++++-- 14 files changed, 52 insertions(+), 123 deletions(-) diff --git a/dlls/crtdll/crtdll.spec b/dlls/crtdll/crtdll.spec index 3a90ad7ef74..0e863362f77 100644 --- a/dlls/crtdll/crtdll.spec +++ b/dlls/crtdll/crtdll.spec @@ -241,7 +241,7 @@ @ cdecl _mkdir(str) @ cdecl _mktemp(str) @ cdecl _msize(ptr) -@ cdecl _nextafter(double double) +@ cdecl _nextafter(double double) nextafter @ cdecl _onexit(ptr) @ varargs _open(str long) @ cdecl _open_osfhandle(long long) diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index 1b9abbfdec2..abae3f4b301 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -1215,8 +1215,8 @@ @ cdecl _mktime32(ptr) @ cdecl _mktime64(ptr) @ cdecl _msize(ptr) -@ cdecl _nextafter(double double) -@ cdecl -arch=x86_64 _nextafterf(float float) +@ cdecl _nextafter(double double) nextafter +@ cdecl -arch=x86_64 _nextafterf(float float) nextafterf @ cdecl _onexit(ptr) @ varargs _open(str long) @ cdecl _open_osfhandle(long long) diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec index bba1222a44e..e83ce328928 100644 --- a/dlls/msvcr110/msvcr110.spec +++ b/dlls/msvcr110/msvcr110.spec @@ -1572,8 +1572,8 @@ @ cdecl _mktime32(ptr) @ cdecl _mktime64(ptr) @ cdecl _msize(ptr) -@ cdecl _nextafter(double double) -@ cdecl -arch=x86_64 _nextafterf(float float) +@ cdecl _nextafter(double double) nextafter +@ cdecl -arch=x86_64 _nextafterf(float float) nextafterf @ cdecl _onexit(ptr) @ varargs _open(str long) @ cdecl _open_osfhandle(long long) diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index 654fb4071f8..cdd5848f7e9 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -1583,8 +1583,8 @@ @ cdecl _mktime32(ptr) @ cdecl _mktime64(ptr) @ cdecl _msize(ptr) -@ cdecl _nextafter(double double) -@ cdecl -arch=x86_64 _nextafterf(float float) +@ cdecl _nextafter(double double) nextafter +@ cdecl -arch=x86_64 _nextafterf(float float) nextafterf @ cdecl _onexit(ptr) @ varargs _open(str long) @ cdecl _open_osfhandle(long long) @@ -2300,9 +2300,9 @@ @ cdecl nearbyint(double) @ cdecl nearbyintf(float) @ cdecl nearbyintl(double) nearbyint -@ cdecl nextafter(double double) _nextafter -@ cdecl nextafterf(float float) _nextafterf -@ cdecl nextafterl(double double) _nextafter +@ cdecl nextafter(double double) +@ cdecl nextafterf(float float) +@ cdecl nextafterl(double double) nextafter @ cdecl nexttoward(double double) MSVCRT_nexttoward @ cdecl nexttowardf(float double) MSVCRT_nexttowardf @ cdecl nexttowardl(double double) MSVCRT_nexttoward diff --git a/dlls/msvcr70/msvcr70.spec b/dlls/msvcr70/msvcr70.spec index 1e02dc95d2d..3300cf36bf3 100644 --- a/dlls/msvcr70/msvcr70.spec +++ b/dlls/msvcr70/msvcr70.spec @@ -479,7 +479,7 @@ @ cdecl _mktemp(str) @ cdecl _mktime64(ptr) @ cdecl _msize(ptr) -@ cdecl _nextafter(double double) +@ cdecl _nextafter(double double) nextafter @ cdecl _onexit(ptr) @ varargs _open(str long) @ cdecl _open_osfhandle(long long) diff --git a/dlls/msvcr71/msvcr71.spec b/dlls/msvcr71/msvcr71.spec index 1a075986ddd..5b68d3217af 100644 --- a/dlls/msvcr71/msvcr71.spec +++ b/dlls/msvcr71/msvcr71.spec @@ -474,7 +474,7 @@ @ cdecl _mktemp(str) @ cdecl _mktime64(ptr) @ cdecl _msize(ptr) -@ cdecl _nextafter(double double) +@ cdecl _nextafter(double double) nextafter @ cdecl _onexit(ptr) @ varargs _open(str long) @ cdecl _open_osfhandle(long long) diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index 2ea91c0ce8a..7c7c2f8bcdb 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -887,8 +887,8 @@ @ cdecl _mktime32(ptr) @ cdecl _mktime64(ptr) @ cdecl _msize(ptr) -@ cdecl _nextafter(double double) -@ cdecl -arch=x86_64 _nextafterf(float float) +@ cdecl _nextafter(double double) nextafter +@ cdecl -arch=x86_64 _nextafterf(float float) nextafterf @ cdecl _onexit(ptr) @ varargs _open(str long) @ cdecl _open_osfhandle(long long) diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index fb274878d39..c1e4a406265 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -865,8 +865,8 @@ @ cdecl _mktime32(ptr) @ cdecl _mktime64(ptr) @ cdecl _msize(ptr) -@ cdecl _nextafter(double double) -@ cdecl -arch=x86_64 _nextafterf(float float) +@ cdecl _nextafter(double double) nextafter +@ cdecl -arch=x86_64 _nextafterf(float float) nextafterf @ cdecl _onexit(ptr) @ varargs _open(str long) @ cdecl _open_osfhandle(long long) diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index d8563873562..dbd9bde4d32 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -216,49 +216,6 @@ float CDECL _chgsignf( float num ) return u.f; } -/********************************************************************* - * _nextafterf (MSVCRT.@) - * - * Copied from musl: src/math/nextafterf.c - */ -float CDECL _nextafterf( float x, float y ) -{ - unsigned int ix = *(unsigned int*)&x; - unsigned int iy = *(unsigned int*)&y; - unsigned int ax, ay, e; - - if (isnan(x) || isnan(y)) - return x + y; - if (x == y) { - if (_fpclassf(y) & (_FPCLASS_ND | _FPCLASS_PD | _FPCLASS_NZ | _FPCLASS_PZ )) - *_errno() = ERANGE; - return y; - } - ax = ix & 0x7fffffff; - ay = iy & 0x7fffffff; - if (ax == 0) { - if (ay == 0) - return y; - ix = (iy & 0x80000000) | 1; - } else if (ax > ay || ((ix ^ iy) & 0x80000000)) - ix--; - else - ix++; - e = ix & 0x7f800000; - /* raise overflow if ix is infinite and x is finite */ - if (e == 0x7f800000) { - fp_barrierf(x + x); - *_errno() = ERANGE; - } - /* raise underflow if ix is subnormal or zero */ - y = *(float*)&ix; - if (e == 0) { - fp_barrierf(x * x + y * y); - *_errno() = ERANGE; - } - return y; -} - #endif /* Copied from musl: src/math/__rem_pio2_large.c */ @@ -4124,7 +4081,7 @@ float CDECL nearbyintf(float x) */ double CDECL MSVCRT_nexttoward(double num, double next) { - return _nextafter(num, next); + return nextafter(num, next); } /********************************************************************* @@ -4174,50 +4131,6 @@ float CDECL MSVCRT_nexttowardf(float x, double y) #endif /* _MSVCR_VER>=120 */ -/********************************************************************* - * _nextafter (MSVCRT.@) - * - * Copied from musl: src/math/nextafter.c - */ -double CDECL _nextafter(double x, double y) -{ - ULONGLONG llx = *(ULONGLONG*)&x; - ULONGLONG lly = *(ULONGLONG*)&y; - ULONGLONG ax, ay; - int e; - - if (isnan(x) || isnan(y)) - return x + y; - if (llx == lly) { - if (_fpclass(y) & (_FPCLASS_ND | _FPCLASS_PD | _FPCLASS_NZ | _FPCLASS_PZ )) - *_errno() = ERANGE; - return y; - } - ax = llx & -1ULL / 2; - ay = lly & -1ULL / 2; - if (ax == 0) { - if (ay == 0) - return y; - llx = (lly & 1ULL << 63) | 1; - } else if (ax > ay || ((llx ^ lly) & 1ULL << 63)) - llx--; - else - llx++; - e = llx >> 52 & 0x7ff; - /* raise overflow if llx is infinite and x is finite */ - if (e == 0x7ff) { - fp_barrier(x + x); - *_errno() = ERANGE; - } - /* raise underflow if llx is subnormal or zero */ - y = *(double*)&llx; - if (e == 0) { - fp_barrier(x * x + y * y); - *_errno() = ERANGE; - } - return y; -} - /********************************************************************* * _ecvt (MSVCRT.@) */ diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 4d4228cc819..0b88ba97135 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -840,8 +840,8 @@ @ cdecl _msize(ptr) # stub -arch=win32 _msize_debug(ptr long) # stub -arch=win64 _msize_dbg(ptr long) -@ cdecl _nextafter(double double) -@ cdecl -arch=x86_64 _nextafterf(float float) +@ cdecl _nextafter(double double) nextafter +@ cdecl -arch=x86_64 _nextafterf(float float) nextafterf @ cdecl _onexit(ptr) @ varargs _open(str long) @ cdecl _open_osfhandle(long long) diff --git a/dlls/msvcrtd/msvcrtd.spec b/dlls/msvcrtd/msvcrtd.spec index 68fa80d532f..2c3f4912a03 100644 --- a/dlls/msvcrtd/msvcrtd.spec +++ b/dlls/msvcrtd/msvcrtd.spec @@ -457,7 +457,7 @@ @ cdecl _mktemp(str) @ cdecl _msize(ptr) @ cdecl _msize_dbg(ptr) _msize -@ cdecl _nextafter(double double) +@ cdecl _nextafter(double double) nextafter @ cdecl _onexit(ptr) @ varargs _open(str long) @ cdecl _open_osfhandle(long long) diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index 51137681f14..a6db1a60c5d 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -731,8 +731,8 @@ @ cdecl _mktime32(ptr) @ cdecl _mktime64(ptr) @ cdecl _msize(ptr) -@ cdecl _nextafter(double double) -@ cdecl -arch=x86_64 _nextafterf(float float) +@ cdecl _nextafter(double double) nextafter +@ cdecl -arch=x86_64 _nextafterf(float float) nextafterf @ cdecl -arch=i386 _o__CIacos() _CIacos @ cdecl -arch=i386 _o__CIasin() _CIasin @ cdecl -arch=i386 _o__CIatan() _CIatan @@ -1299,8 +1299,8 @@ @ cdecl _o__mktime32(ptr) _mktime32 @ cdecl _o__mktime64(ptr) _mktime64 @ cdecl _o__msize(ptr) _msize -@ cdecl _o__nextafter(double double) _nextafter -@ cdecl -arch=x86_64 _o__nextafterf(float float) _nextafterf +@ cdecl _o__nextafter(double double) nextafter +@ cdecl -arch=x86_64 _o__nextafterf(float float) nextafterf @ cdecl _o__open_osfhandle(long long) _open_osfhandle @ cdecl _o__pclose(ptr) _pclose @ cdecl _o__pipe(ptr long long) _pipe @@ -1730,9 +1730,9 @@ @ cdecl _o_nearbyint(double) nearbyint @ cdecl _o_nearbyintf(float) nearbyintf @ cdecl _o_nearbyintl(double) nearbyint -@ cdecl _o_nextafter(double double) _nextafter -@ cdecl _o_nextafterf(float float) _nextafterf -@ cdecl _o_nextafterl(double double) _nextafter +@ cdecl _o_nextafter(double double) nextafter +@ cdecl _o_nextafterf(float float) nextafterf +@ cdecl _o_nextafterl(double double) nextafter @ cdecl _o_nexttoward(double double) MSVCRT_nexttoward @ cdecl _o_nexttowardf(float double) MSVCRT_nexttowardf @ cdecl _o_nexttowardl(double double) MSVCRT_nexttoward @@ -2438,9 +2438,9 @@ @ cdecl nearbyint(double) @ cdecl nearbyintf(float) @ cdecl nearbyintl(double) nearbyint -@ cdecl nextafter(double double) _nextafter -@ cdecl nextafterf(float float) _nextafterf -@ cdecl nextafterl(double double) _nextafter +@ cdecl nextafter(double double) +@ cdecl nextafterf(float float) +@ cdecl nextafterl(double double) nextafter @ cdecl nexttoward(double double) MSVCRT_nexttoward @ cdecl nexttowardf(float double) MSVCRT_nexttowardf @ cdecl nexttowardl(double double) MSVCRT_nexttoward diff --git a/libs/musl/src/math/nextafter.c b/libs/musl/src/math/nextafter.c index 232042355a3..95f71439558 100644 --- a/libs/musl/src/math/nextafter.c +++ b/libs/musl/src/math/nextafter.c @@ -8,8 +8,12 @@ double __cdecl nextafter(double x, double y) if (isnan(x) || isnan(y)) return x + y; - if (ux.i == uy.i) + if (ux.i == uy.i) { + e = ux.i >> 52 & 0x7ff; + if (!e) + errno = ERANGE; return y; + } ax = ux.i & -1ULL/2; ay = uy.i & -1ULL/2; if (ax == 0) { @@ -22,10 +26,14 @@ double __cdecl nextafter(double x, double y) ux.i++; e = ux.i >> 52 & 0x7ff; /* raise overflow if ux.f is infinite and x is finite */ - if (e == 0x7ff) + if (e == 0x7ff) { FORCE_EVAL(x+x); + errno = ERANGE; + } /* raise underflow if ux.f is subnormal or zero */ - if (e == 0) + if (e == 0) { FORCE_EVAL(x*x + ux.f*ux.f); + errno = ERANGE; + } return ux.f; } diff --git a/libs/musl/src/math/nextafterf.c b/libs/musl/src/math/nextafterf.c index 8da11a0f33e..3b044d3f28a 100644 --- a/libs/musl/src/math/nextafterf.c +++ b/libs/musl/src/math/nextafterf.c @@ -7,8 +7,12 @@ float __cdecl nextafterf(float x, float y) if (isnan(x) || isnan(y)) return x + y; - if (ux.i == uy.i) + if (ux.i == uy.i) { + e = ux.i & 0x7f800000; + if (!e) + errno = ERANGE; return y; + } ax = ux.i & 0x7fffffff; ay = uy.i & 0x7fffffff; if (ax == 0) { @@ -21,10 +25,14 @@ float __cdecl nextafterf(float x, float y) ux.i++; e = ux.i & 0x7f800000; /* raise overflow if ux.f is infinite and x is finite */ - if (e == 0x7f800000) + if (e == 0x7f800000) { FORCE_EVAL(x+x); + errno = ERANGE; + } /* raise underflow if ux.f is subnormal or zero */ - if (e == 0) + if (e == 0) { FORCE_EVAL(x*x + ux.f*ux.f); + errno = ERANGE; + } return ux.f; }