Module: wine Branch: master Commit: 4ffb1199e37ddb96c7b361bb97767a74ef5e2902 URL: https://gitlab.winehq.org/wine/wine/-/commit/4ffb1199e37ddb96c7b361bb97767a7...
Author: Alexandre Julliard julliard@winehq.org Date: Fri Mar 31 16:53:49 2023 +0200
msvcrt: Use the atanh()/atanhf() implementation from the bundled musl library.
---
dlls/msvcr120/msvcr120.spec | 6 ++--- dlls/msvcrt/math.c | 61 +++++++-------------------------------------- dlls/ucrtbase/ucrtbase.spec | 12 ++++----- libs/musl/src/math/atanh.c | 2 ++ libs/musl/src/math/atanhf.c | 2 ++ 5 files changed, 22 insertions(+), 61 deletions(-)
diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index f536aba9ba3..cfc81d75804 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -2026,9 +2026,9 @@ @ cdecl -arch=!i386 atanf(float) @ cdecl atan2(double double) @ cdecl -arch=!i386 atan2f(float float) -@ cdecl atanh(double) -@ cdecl atanhf(float) -@ cdecl atanhl(double) atanh +@ cdecl atanh(double) MSVCRT_atanh +@ cdecl atanhf(float) MSVCRT_atanhf +@ cdecl atanhl(double) MSVCRT_atanh @ cdecl -private atexit(ptr) MSVCRT_atexit # not imported to avoid conflicts with Mingw @ cdecl atof(str) @ cdecl atoi(str) diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index 4f95a4747a9..bc138845dce 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -78,7 +78,7 @@ void msvcrt_init_math( void *module ) }
/* Copied from musl: src/internal/libm.h */ -#if !defined(__i386__) || _MSVCR_VER>=120 +#ifndef __i386__ static inline float fp_barrierf(float x) { volatile float y = x; @@ -3377,73 +3377,30 @@ float CDECL MSVCRT_acoshf(float x)
/********************************************************************* * atanh (MSVCR120.@) - * - * Copied from musl: src/math/atanh.c */ -double CDECL atanh(double x) +double CDECL MSVCRT_atanh(double x) { - UINT64 ux = *(UINT64*)&x; - int e = ux >> 52 & 0x7ff; - int s = ux >> 63; - - /* |x| */ - ux &= (UINT64)-1 / 2; - x = *(double*)&ux; - - if (x > 1) { + if (fabs(x) > 1) + { *_errno() = EDOM; feraiseexcept(FE_INVALID); return NAN; } - - if (e < 0x3ff - 1) { - if (e < 0x3ff - 32) { - fp_barrier(x + 0x1p120f); - if (e == 0) /* handle underflow */ - fp_barrier(x * x); - } else { /* |x| < 0.5, up to 1.7ulp error */ - x = 0.5 * log1p(2 * x + 2 * x * x / (1 - x)); - } - } else { /* avoid overflow */ - x = 0.5 * log1p(2 * (x / (1 - x))); - if (isinf(x)) *_errno() = ERANGE; - } - return s ? -x : x; + return atanh( x ); }
/********************************************************************* * atanhf (MSVCR120.@) - * - * Copied from musl: src/math/atanhf.c */ -float CDECL atanhf(float x) +float CDECL MSVCRT_atanhf(float x) { - UINT32 ux = *(UINT32*)&x; - int s = ux >> 31; - - /* |x| */ - ux &= 0x7fffffff; - x = *(float*)&ux; - - if (x > 1) { + if (fabs(x) > 1) + { *_errno() = EDOM; feraiseexcept(FE_INVALID); return NAN; } - - if (ux < 0x3f800000 - (1 << 23)) { - if (ux < 0x3f800000 - (32 << 23)) { - fp_barrierf(x + 0x1p120f); - if (ux < (1 << 23)) /* handle underflow */ - fp_barrierf(x * x); - } else { /* |x| < 0.5, up to 1.7ulp error */ - x = 0.5f * log1pf(2 * x + 2 * x * x / (1 - x)); - } - } else { /* avoid overflow */ - x = 0.5f * log1pf(2 * (x / (1 - x))); - if (isinf(x)) *_errno() = ERANGE; - } - return s ? -x : x; + return atanhf( x ); }
#endif /* _MSVCR_VER>=120 */ diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index 5bea04dad62..258a1aa945a 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -1576,9 +1576,9 @@ @ cdecl _o_atan2(double double) atan2 @ cdecl -arch=!i386 _o_atan2f(float float) atan2f @ cdecl -arch=!i386 _o_atanf(float) atanf -@ cdecl _o_atanh(double) atanh -@ cdecl _o_atanhf(float) atanhf -@ cdecl _o_atanhl(double) atanh +@ cdecl _o_atanh(double) MSVCRT_atanh +@ cdecl _o_atanhf(float) MSVCRT_atanhf +@ cdecl _o_atanhl(double) MSVCRT_atanh @ cdecl _o_atof(str) atof @ cdecl _o_atoi(str) atoi @ cdecl _o_atol(str) atol @@ -2170,9 +2170,9 @@ @ cdecl atan2(double double) @ cdecl -arch=!i386 atan2f(float float) @ cdecl -arch=!i386 atanf(float) -@ cdecl atanh(double) -@ cdecl atanhf(float) -@ cdecl atanhl(double) atanh +@ cdecl atanh(double) MSVCRT_atanh +@ cdecl atanhf(float) MSVCRT_atanhf +@ cdecl atanhl(double) MSVCRT_atanh @ cdecl atof(str) @ cdecl atoi(str) @ cdecl atol(str) diff --git a/libs/musl/src/math/atanh.c b/libs/musl/src/math/atanh.c index b50e4922a10..08776e97f03 100644 --- a/libs/musl/src/math/atanh.c +++ b/libs/musl/src/math/atanh.c @@ -14,6 +14,7 @@ double __cdecl atanh(double x)
if (e < 0x3ff - 1) { if (e < 0x3ff - 32) { + fp_barrier(y + 0x1p120f); /* handle underflow */ if (e == 0) FORCE_EVAL((float)y); @@ -24,6 +25,7 @@ double __cdecl atanh(double x) } else { /* avoid overflow */ y = 0.5*log1p(2*(y/(1-y))); + if (isinf(y)) errno = ERANGE; } return s ? -y : y; } diff --git a/libs/musl/src/math/atanhf.c b/libs/musl/src/math/atanhf.c index cbb425ce908..74533fb11b8 100644 --- a/libs/musl/src/math/atanhf.c +++ b/libs/musl/src/math/atanhf.c @@ -13,6 +13,7 @@ float __cdecl atanhf(float x)
if (u.i < 0x3f800000 - (1<<23)) { if (u.i < 0x3f800000 - (32<<23)) { + fp_barrierf(y + 0x1p120f); /* handle underflow */ if (u.i < (1<<23)) FORCE_EVAL((float)(y*y)); @@ -23,6 +24,7 @@ float __cdecl atanhf(float x) } else { /* avoid overflow */ y = 0.5f*log1pf(2*(y/(1-y))); + if (isinf(y)) errno = ERANGE; } return s ? -y : y; }