Piotr Caban : msvcrt: Import nextafterf implementation from musl.
Alexandre Julliard
julliard at winehq.org
Fri May 14 15:47:05 CDT 2021
Module: wine
Branch: master
Commit: 1dc3aa808fc65347fb12d32b05194c05748110be
URL: https://source.winehq.org/git/wine.git/?a=commit;h=1dc3aa808fc65347fb12d32b05194c05748110be
Author: Piotr Caban <piotr at codeweavers.com>
Date: Fri May 14 16:11:55 2021 +0200
msvcrt: Import nextafterf implementation from musl.
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/msvcrt/math.c | 40 +++++++++++++++++++++++++++++++++++++---
dlls/msvcrt/unixlib.c | 9 ---------
dlls/msvcrt/unixlib.h | 1 -
3 files changed, 37 insertions(+), 13 deletions(-)
diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c
index b682e72ab76..77018e27cf5 100644
--- a/dlls/msvcrt/math.c
+++ b/dlls/msvcrt/math.c
@@ -234,11 +234,45 @@ float CDECL _copysignf( float x, float y )
/*********************************************************************
* _nextafterf (MSVCRT.@)
+ *
+ * Copied from musl: src/math/nextafterf.c
*/
-float CDECL _nextafterf( float num, float next )
+float CDECL _nextafterf( float x, float y )
{
- if (!isfinite(num) || !isfinite(next)) *_errno() = EDOM;
- return unix_funcs->nextafterf( num, next );
+ 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;
}
/*********************************************************************
diff --git a/dlls/msvcrt/unixlib.c b/dlls/msvcrt/unixlib.c
index 931c8a2412b..c36d5a2caad 100644
--- a/dlls/msvcrt/unixlib.c
+++ b/dlls/msvcrt/unixlib.c
@@ -547,14 +547,6 @@ static float CDECL unix_modff( float x, float *iptr )
return modff( x, iptr );
}
-/*********************************************************************
- * nextafterf
- */
-static float CDECL unix_nextafterf(float num, float next)
-{
- return nextafterf(num,next);
-}
-
/*********************************************************************
* nexttoward
*/
@@ -814,7 +806,6 @@ static const struct unix_funcs funcs =
unix_logbf,
unix_modf,
unix_modff,
- unix_nextafterf,
unix_nexttoward,
unix_nexttowardf,
unix_pow,
diff --git a/dlls/msvcrt/unixlib.h b/dlls/msvcrt/unixlib.h
index 1c43253f746..1a8807b8495 100644
--- a/dlls/msvcrt/unixlib.h
+++ b/dlls/msvcrt/unixlib.h
@@ -72,7 +72,6 @@ struct unix_funcs
float (CDECL *logbf)(float x);
double (CDECL *modf)(double x, double *iptr);
float (CDECL *modff)(float x, float *iptr);
- float (CDECL *nextafterf)(float x, float y);
double (CDECL *nexttoward)(double x, double y);
float (CDECL *nexttowardf)(float x, double y);
double (CDECL *pow)(double x, double y);
More information about the wine-cvs
mailing list