Commit 8252be56 authored by Alexandre Julliard's avatar Alexandre Julliard

msvcrt: Use the nexttoward()/nexttowardf() implementation from the bundled musl library.

Rename the musl functions to avoid compiler warnings about the signature mismatch (double vs. long double).
parent 85e65544
...@@ -2303,9 +2303,9 @@ ...@@ -2303,9 +2303,9 @@
@ cdecl nextafter(double double) @ cdecl nextafter(double double)
@ cdecl nextafterf(float float) @ cdecl nextafterf(float float)
@ cdecl nextafterl(double double) nextafter @ cdecl nextafterl(double double) nextafter
@ cdecl nexttoward(double double) MSVCRT_nexttoward @ cdecl nexttoward(double double) __nexttoward
@ cdecl nexttowardf(float double) MSVCRT_nexttowardf @ cdecl nexttowardf(float double) __nexttowardf
@ cdecl nexttowardl(double double) MSVCRT_nexttoward @ cdecl nexttowardl(double double) __nexttoward
@ stub norm @ stub norm
@ stub normf @ stub normf
@ stub norml @ stub norml
......
...@@ -4076,59 +4076,6 @@ float CDECL nearbyintf(float x) ...@@ -4076,59 +4076,6 @@ float CDECL nearbyintf(float x)
return x; return x;
} }
/*********************************************************************
* nexttoward (MSVCR120.@)
*/
double CDECL MSVCRT_nexttoward(double num, double next)
{
return nextafter(num, next);
}
/*********************************************************************
* nexttowardf (MSVCR120.@)
*
* Copied from musl: src/math/nexttowardf.c
*/
float CDECL MSVCRT_nexttowardf(float x, double y)
{
unsigned int ix = *(unsigned int*)&x;
unsigned int e;
float ret;
if (isnan(x) || isnan(y))
return x + y;
if (x == y)
return y;
if (x == 0) {
ix = 1;
if (signbit(y))
ix |= 0x80000000;
} else if (x < y) {
if (signbit(x))
ix--;
else
ix++;
} else {
if (signbit(x))
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;
}
ret = *(float*)&ix;
/* raise underflow if ret is subnormal or zero */
if (e == 0) {
fp_barrierf(x * x + ret * ret);
*_errno() = ERANGE;
}
return ret;
}
#endif /* _MSVCR_VER>=120 */ #endif /* _MSVCR_VER>=120 */
/********************************************************************* /*********************************************************************
......
...@@ -1733,9 +1733,9 @@ ...@@ -1733,9 +1733,9 @@
@ cdecl _o_nextafter(double double) nextafter @ cdecl _o_nextafter(double double) nextafter
@ cdecl _o_nextafterf(float float) nextafterf @ cdecl _o_nextafterf(float float) nextafterf
@ cdecl _o_nextafterl(double double) nextafter @ cdecl _o_nextafterl(double double) nextafter
@ cdecl _o_nexttoward(double double) MSVCRT_nexttoward @ cdecl _o_nexttoward(double double) __nexttoward
@ cdecl _o_nexttowardf(float double) MSVCRT_nexttowardf @ cdecl _o_nexttowardf(float double) __nexttowardf
@ cdecl _o_nexttowardl(double double) MSVCRT_nexttoward @ cdecl _o_nexttowardl(double double) __nexttoward
@ cdecl _o_pow(double double) pow @ cdecl _o_pow(double double) pow
@ cdecl -arch=!i386 _o_powf(float float) powf @ cdecl -arch=!i386 _o_powf(float float) powf
@ cdecl _o_putc(long ptr) putc @ cdecl _o_putc(long ptr) putc
...@@ -2441,9 +2441,9 @@ ...@@ -2441,9 +2441,9 @@
@ cdecl nextafter(double double) @ cdecl nextafter(double double)
@ cdecl nextafterf(float float) @ cdecl nextafterf(float float)
@ cdecl nextafterl(double double) nextafter @ cdecl nextafterl(double double) nextafter
@ cdecl nexttoward(double double) MSVCRT_nexttoward @ cdecl nexttoward(double double) __nexttoward
@ cdecl nexttowardf(float double) MSVCRT_nexttowardf @ cdecl nexttowardf(float double) __nexttowardf
@ cdecl nexttowardl(double double) MSVCRT_nexttoward @ cdecl nexttowardl(double double) __nexttoward
@ stub norm @ stub norm
@ stub normf @ stub normf
@ stub norml @ stub norml
......
#include "libm.h" #include "libm.h"
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
double __cdecl nexttoward(double x, long double y) double __cdecl __nexttoward(double x, double y)
{ {
return nextafter(x, y); return nextafter(x, y);
} }
......
#include "libm.h" #include "libm.h"
float __cdecl nexttowardf(float x, long double y) float __cdecl __nexttowardf(float x, double y)
{ {
union {float f; uint32_t i;} ux = {x}; union {float f; uint32_t i;} ux = {x};
uint32_t e; uint32_t e;
...@@ -26,10 +26,14 @@ float __cdecl nexttowardf(float x, long double y) ...@@ -26,10 +26,14 @@ float __cdecl nexttowardf(float x, long double y)
} }
e = ux.i & 0x7f800000; e = ux.i & 0x7f800000;
/* raise overflow if ux.f is infinite and x is finite */ /* raise overflow if ux.f is infinite and x is finite */
if (e == 0x7f800000) if (e == 0x7f800000) {
FORCE_EVAL(x+x); FORCE_EVAL(x+x);
errno = ERANGE;
}
/* raise underflow if ux.f is subnormal or zero */ /* raise underflow if ux.f is subnormal or zero */
if (e == 0) if (e == 0) {
FORCE_EVAL(x*x + ux.f*ux.f); FORCE_EVAL(x*x + ux.f*ux.f);
errno = ERANGE;
}
return ux.f; return ux.f;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment