From: Alexandre Julliard julliard@winehq.org
--- dlls/crtdll/crtdll.spec | 2 +- dlls/msvcr100/msvcr100.spec | 4 +- dlls/msvcr110/msvcr110.spec | 4 +- dlls/msvcr120/msvcr120.spec | 4 +- dlls/msvcr70/msvcr70.spec | 2 +- dlls/msvcr71/msvcr71.spec | 2 +- dlls/msvcr80/msvcr80.spec | 4 +- dlls/msvcr90/msvcr90.spec | 4 +- dlls/msvcrt/math.c | 117 +++++++----------------------------- dlls/msvcrt/msvcrt.spec | 4 +- dlls/msvcrtd/msvcrtd.spec | 2 +- libs/musl/src/math/tanh.c | 9 ++- libs/musl/src/math/tanhf.c | 9 ++- 13 files changed, 51 insertions(+), 116 deletions(-)
diff --git a/dlls/crtdll/crtdll.spec b/dlls/crtdll/crtdll.spec index b870eef8845..98d729b9eb1 100644 --- a/dlls/crtdll/crtdll.spec +++ b/dlls/crtdll/crtdll.spec @@ -496,7 +496,7 @@ @ varargs swscanf(wstr wstr) @ cdecl system(str) @ cdecl tan(double) -@ cdecl tanh(double) +@ cdecl tanh(double) MSVCRT_tanh @ cdecl -arch=win32 time(ptr) _time32 @ cdecl -arch=win64 time(ptr) _time64 @ cdecl tmpfile() diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index 16ece69f1a4..6ef7befa344 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -1829,8 +1829,8 @@ @ cdecl system(str) @ cdecl tan(double) @ cdecl -arch=!i386 tanf(float) -@ cdecl tanh(double) -@ cdecl -arch=!i386 tanhf(float) +@ cdecl tanh(double) MSVCRT_tanh +@ cdecl -arch=!i386 tanhf(float) MSVCRT_tanhf @ cdecl tmpfile() @ cdecl tmpfile_s(ptr) @ cdecl tmpnam(ptr) diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec index d4d696f512e..bd44b4476cd 100644 --- a/dlls/msvcr110/msvcr110.spec +++ b/dlls/msvcr110/msvcr110.spec @@ -2187,8 +2187,8 @@ @ cdecl system(str) @ cdecl tan(double) @ cdecl -arch=!i386 tanf(float) -@ cdecl tanh(double) -@ cdecl -arch=!i386 tanhf(float) +@ cdecl tanh(double) MSVCRT_tanh +@ cdecl -arch=!i386 tanhf(float) MSVCRT_tanhf @ cdecl tmpfile() @ cdecl tmpfile_s(ptr) @ cdecl tmpnam(ptr) diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index cfc81d75804..618fc3acbba 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -2404,8 +2404,8 @@ @ cdecl system(str) @ cdecl tan(double) @ cdecl -arch=!i386 tanf(float) -@ cdecl tanh(double) -@ cdecl -arch=!i386 tanhf(float) +@ cdecl tanh(double) MSVCRT_tanh +@ cdecl -arch=!i386 tanhf(float) MSVCRT_tanhf @ cdecl tgamma(double) @ cdecl tgammaf(float) @ cdecl tgammal(double) tgamma diff --git a/dlls/msvcr70/msvcr70.spec b/dlls/msvcr70/msvcr70.spec index cf2a57c5578..fe281841198 100644 --- a/dlls/msvcr70/msvcr70.spec +++ b/dlls/msvcr70/msvcr70.spec @@ -844,7 +844,7 @@ @ varargs swscanf(wstr wstr) @ cdecl system(str) @ cdecl tan(double) -@ cdecl tanh(double) +@ cdecl tanh(double) MSVCRT_tanh @ cdecl -arch=win32 time(ptr) _time32 @ cdecl -arch=win64 time(ptr) _time64 @ cdecl tmpfile() diff --git a/dlls/msvcr71/msvcr71.spec b/dlls/msvcr71/msvcr71.spec index 1ef2ec942e4..ed9de904884 100644 --- a/dlls/msvcr71/msvcr71.spec +++ b/dlls/msvcr71/msvcr71.spec @@ -839,7 +839,7 @@ @ varargs swscanf(wstr wstr) @ cdecl system(str) @ cdecl tan(double) -@ cdecl tanh(double) +@ cdecl tanh(double) MSVCRT_tanh @ cdecl -arch=win32 time(ptr) _time32 @ cdecl -arch=win64 time(ptr) _time64 @ cdecl tmpfile() diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index 88c4a32d52f..a1273d7d995 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -1510,8 +1510,8 @@ @ cdecl system(str) @ cdecl tan(double) @ cdecl -arch=!i386 tanf(float) -@ cdecl tanh(double) -@ cdecl -arch=!i386 tanhf(float) +@ cdecl tanh(double) MSVCRT_tanh +@ cdecl -arch=!i386 tanhf(float) MSVCRT_tanhf @ cdecl tmpfile() @ cdecl tmpfile_s(ptr) @ cdecl tmpnam(ptr) diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index bd5b3126f30..e199475aa30 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -1482,8 +1482,8 @@ @ cdecl system(str) @ cdecl tan(double) @ cdecl -arch=!i386 tanf(float) -@ cdecl tanh(double) -@ cdecl -arch=!i386 tanhf(float) +@ cdecl tanh(double) MSVCRT_tanh +@ cdecl -arch=!i386 tanhf(float) MSVCRT_tanhf @ cdecl tmpfile() @ cdecl tmpfile_s(ptr) @ cdecl tmpnam(ptr) diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index bc138845dce..2acfe23278d 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -78,19 +78,13 @@ void msvcrt_init_math( void *module ) }
/* Copied from musl: src/internal/libm.h */ -#ifndef __i386__ -static inline float fp_barrierf(float x) -{ - volatile float y = x; - return y; -} -#endif - +#if _MSVCR_VER >= 120 static inline double fp_barrier(double x) { volatile double y = x; return y; } +#endif
static inline double ret_nan( BOOL update_sw ) { @@ -399,49 +393,17 @@ float CDECL sqrtf( float x ) /********************************************************************* * tanhf (MSVCRT.@) */ -float CDECL tanhf( float x ) +#if _MSVCR_VER < 140 /* other versions call tanhf() directly */ +float CDECL MSVCRT_tanhf( float x ) { - UINT32 ui = *(UINT32*)&x; - UINT32 sign = ui & 0x80000000; - float t; - - /* x = |x| */ - ui &= 0x7fffffff; - x = *(float*)&ui; - - if (ui > 0x3f0c9f54) { - /* |x| > log(3)/2 ~= 0.5493 or nan */ - if (ui > 0x41200000) { - if (ui > 0x7f800000) { - *(UINT32*)&x = ui | sign | 0x400000; -#if _MSVCR_VER < 140 - return math_error(_DOMAIN, "tanhf", x, 0, x); -#else - return x; -#endif - } - /* |x| > 10 */ - fp_barrierf(x + 0x1p120f); - t = 1 + 0 / x; - } else { - t = expm1f(2 * x); - t = 1 - 2 / (t + 2); - } - } else if (ui > 0x3e82c578) { - /* |x| > log(5/3)/2 ~= 0.2554 */ - t = expm1f(2 * x); - t = t / (t + 2); - } else if (ui >= 0x00800000) { - /* |x| >= 0x1p-126 */ - t = expm1f(-2 * x); - t = -t / (t + 2); - } else { - /* |x| is subnormal */ - fp_barrierf(x * x); - t = x; - } - return sign ? -t : t; + if (isnan( x )) + { + *(UINT32*)&x |= 0x400000; + return math_error(_DOMAIN, "tanhf", x, 0, x); + } + return tanhf( x ); } +#endif
#endif
@@ -675,54 +637,17 @@ double CDECL sqrt( double x ) /********************************************************************* * tanh (MSVCRT.@) */ -double CDECL tanh( double x ) -{ - UINT64 ui = *(UINT64*)&x; - UINT64 sign = ui & 0x8000000000000000ULL; - UINT32 w; - double t; - - /* x = |x| */ - ui &= (UINT64)-1 / 2; - x = *(double*)&ui; - w = ui >> 32; - - if (w > 0x3fe193ea) { - /* |x| > log(3)/2 ~= 0.5493 or nan */ - if (w > 0x40340000) { - if (ui > 0x7ff0000000000000ULL) { - *(UINT64*)&x = ui | sign | 0x0008000000000000ULL; -#if _MSVCR_VER < 140 - return math_error(_DOMAIN, "tanh", x, 0, x); -#else - return x; -#endif - } - /* |x| > 20 */ - /* note: this branch avoids raising overflow */ - fp_barrier(x + 0x1p120f); - t = 1 - 0 / x; - } else { - t = expm1(2 * x); - t = 1 - 2 / (t + 2); - } - } else if (w > 0x3fd058ae) { - /* |x| > log(5/3)/2 ~= 0.2554 */ - t = expm1(2 * x); - t = t / (t + 2); - } else if (w >= 0x00100000) { - /* |x| >= 0x1p-1022, up to 2ulp error in [0.1,0.2554] */ - t = expm1(-2 * x); - t = -t / (t + 2); - } else { - /* |x| is subnormal */ - /* note: the branch above would not raise underflow in [0x1p-1023,0x1p-1022) */ - fp_barrier((float)x); - t = x; - } - return sign ? -t : t; +#if _MSVCR_VER < 140 /* other versions call tanh() directly */ +double CDECL MSVCRT_tanh( double x ) +{ + if (isnan( x )) + { + *(UINT64*)&x |= 0x0008000000000000ULL; + return math_error(_DOMAIN, "tanh", x, 0, x); + } + return tanh( x ); } - +#endif
#if (defined(__GNUC__) || defined(__clang__)) && defined(__i386__)
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index c7facd39df1..3566e1e4728 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -1461,9 +1461,9 @@ @ varargs swscanf_s(wstr wstr) @ cdecl system(str) @ cdecl tan(double) -@ cdecl tanh(double) +@ cdecl tanh(double) MSVCRT_tanh @ cdecl -arch=!i386 tanf(float) -@ cdecl -arch=!i386 tanhf(float) +@ cdecl -arch=!i386 tanhf(float) MSVCRT_tanhf @ cdecl -arch=win32 time(ptr) _time32 @ cdecl -arch=win64 time(ptr) _time64 @ cdecl tmpfile() diff --git a/dlls/msvcrtd/msvcrtd.spec b/dlls/msvcrtd/msvcrtd.spec index 09c0a947683..e1f9e0a6cf3 100644 --- a/dlls/msvcrtd/msvcrtd.spec +++ b/dlls/msvcrtd/msvcrtd.spec @@ -797,7 +797,7 @@ @ varargs swscanf(wstr wstr) @ cdecl system(str) @ cdecl tan(double) -@ cdecl tanh(double) +@ cdecl tanh(double) MSVCRT_tanh @ cdecl -arch=win32 time(ptr) _time32 @ cdecl -arch=win64 time(ptr) _time64 @ cdecl tmpfile() diff --git a/libs/musl/src/math/tanh.c b/libs/musl/src/math/tanh.c index 160baedab77..0f29ac90811 100644 --- a/libs/musl/src/math/tanh.c +++ b/libs/musl/src/math/tanh.c @@ -8,11 +8,11 @@ double __cdecl tanh(double x) { union {double f; uint64_t i;} u = {.f = x}; uint32_t w; - int sign; + uint64_t sign; double_t t;
/* x = |x| */ - sign = u.i >> 63; + sign = u.i & 0x8000000000000000ULL; u.i &= (uint64_t)-1/2; x = u.f; w = u.i >> 32; @@ -20,8 +20,13 @@ double __cdecl tanh(double x) if (w > 0x3fe193ea) { /* |x| > log(3)/2 ~= 0.5493 or nan */ if (w > 0x40340000) { + if (w > 0x7ff00000) { + u.i |= sign | 0x0008000000000000ULL; + return u.f; + } /* |x| > 20 or nan */ /* note: this branch avoids raising overflow */ + fp_barrier(x + 0x1p120f); t = 1 - 0/x; } else { t = expm1(2*x); diff --git a/libs/musl/src/math/tanhf.c b/libs/musl/src/math/tanhf.c index 350cb01b44f..bb72d45de03 100644 --- a/libs/musl/src/math/tanhf.c +++ b/libs/musl/src/math/tanhf.c @@ -4,11 +4,11 @@ float __cdecl tanhf(float x) { union {float f; uint32_t i;} u = {.f = x}; uint32_t w; - int sign; + uint32_t sign; float t;
/* x = |x| */ - sign = u.i >> 31; + sign = u.i & 0x80000000; u.i &= 0x7fffffff; x = u.f; w = u.i; @@ -16,7 +16,12 @@ float __cdecl tanhf(float x) if (w > 0x3f0c9f54) { /* |x| > log(3)/2 ~= 0.5493 or nan */ if (w > 0x41200000) { + if (w > 0x7f800000) { + u.i |= sign | 0x400000; + return u.f; + } /* |x| > 10 */ + fp_barrierf(x + 0x1p120f); t = 1 + 0/x; } else { t = expm1f(2*x);