Commit 4ffb1199 authored by Alexandre Julliard's avatar Alexandre Julliard

msvcrt: Use the atanh()/atanhf() implementation from the bundled musl library.

parent e2924faf
...@@ -2026,9 +2026,9 @@ ...@@ -2026,9 +2026,9 @@
@ cdecl -arch=!i386 atanf(float) @ cdecl -arch=!i386 atanf(float)
@ cdecl atan2(double double) @ cdecl atan2(double double)
@ cdecl -arch=!i386 atan2f(float float) @ cdecl -arch=!i386 atan2f(float float)
@ cdecl atanh(double) @ cdecl atanh(double) MSVCRT_atanh
@ cdecl atanhf(float) @ cdecl atanhf(float) MSVCRT_atanhf
@ cdecl atanhl(double) atanh @ cdecl atanhl(double) MSVCRT_atanh
@ cdecl -private atexit(ptr) MSVCRT_atexit # not imported to avoid conflicts with Mingw @ cdecl -private atexit(ptr) MSVCRT_atexit # not imported to avoid conflicts with Mingw
@ cdecl atof(str) @ cdecl atof(str)
@ cdecl atoi(str) @ cdecl atoi(str)
......
...@@ -78,7 +78,7 @@ void msvcrt_init_math( void *module ) ...@@ -78,7 +78,7 @@ void msvcrt_init_math( void *module )
} }
/* Copied from musl: src/internal/libm.h */ /* Copied from musl: src/internal/libm.h */
#if !defined(__i386__) || _MSVCR_VER>=120 #ifndef __i386__
static inline float fp_barrierf(float x) static inline float fp_barrierf(float x)
{ {
volatile float y = x; volatile float y = x;
...@@ -3377,73 +3377,30 @@ float CDECL MSVCRT_acoshf(float x) ...@@ -3377,73 +3377,30 @@ float CDECL MSVCRT_acoshf(float x)
/********************************************************************* /*********************************************************************
* atanh (MSVCR120.@) * atanh (MSVCR120.@)
*
* Copied from musl: src/math/atanh.c
*/ */
double CDECL atanh(double x) double CDECL MSVCRT_atanh(double x)
{ {
UINT64 ux = *(UINT64*)&x; if (fabs(x) > 1)
int e = ux >> 52 & 0x7ff; {
int s = ux >> 63;
/* |x| */
ux &= (UINT64)-1 / 2;
x = *(double*)&ux;
if (x > 1) {
*_errno() = EDOM; *_errno() = EDOM;
feraiseexcept(FE_INVALID); feraiseexcept(FE_INVALID);
return NAN; return NAN;
} }
return atanh( x );
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;
} }
/********************************************************************* /*********************************************************************
* atanhf (MSVCR120.@) * atanhf (MSVCR120.@)
*
* Copied from musl: src/math/atanhf.c
*/ */
float CDECL atanhf(float x) float CDECL MSVCRT_atanhf(float x)
{ {
UINT32 ux = *(UINT32*)&x; if (fabs(x) > 1)
int s = ux >> 31; {
/* |x| */
ux &= 0x7fffffff;
x = *(float*)&ux;
if (x > 1) {
*_errno() = EDOM; *_errno() = EDOM;
feraiseexcept(FE_INVALID); feraiseexcept(FE_INVALID);
return NAN; return NAN;
} }
return atanhf( x );
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;
} }
#endif /* _MSVCR_VER>=120 */ #endif /* _MSVCR_VER>=120 */
......
...@@ -1576,9 +1576,9 @@ ...@@ -1576,9 +1576,9 @@
@ cdecl _o_atan2(double double) atan2 @ cdecl _o_atan2(double double) atan2
@ cdecl -arch=!i386 _o_atan2f(float float) atan2f @ cdecl -arch=!i386 _o_atan2f(float float) atan2f
@ cdecl -arch=!i386 _o_atanf(float) atanf @ cdecl -arch=!i386 _o_atanf(float) atanf
@ cdecl _o_atanh(double) atanh @ cdecl _o_atanh(double) MSVCRT_atanh
@ cdecl _o_atanhf(float) atanhf @ cdecl _o_atanhf(float) MSVCRT_atanhf
@ cdecl _o_atanhl(double) atanh @ cdecl _o_atanhl(double) MSVCRT_atanh
@ cdecl _o_atof(str) atof @ cdecl _o_atof(str) atof
@ cdecl _o_atoi(str) atoi @ cdecl _o_atoi(str) atoi
@ cdecl _o_atol(str) atol @ cdecl _o_atol(str) atol
...@@ -2170,9 +2170,9 @@ ...@@ -2170,9 +2170,9 @@
@ cdecl atan2(double double) @ cdecl atan2(double double)
@ cdecl -arch=!i386 atan2f(float float) @ cdecl -arch=!i386 atan2f(float float)
@ cdecl -arch=!i386 atanf(float) @ cdecl -arch=!i386 atanf(float)
@ cdecl atanh(double) @ cdecl atanh(double) MSVCRT_atanh
@ cdecl atanhf(float) @ cdecl atanhf(float) MSVCRT_atanhf
@ cdecl atanhl(double) atanh @ cdecl atanhl(double) MSVCRT_atanh
@ cdecl atof(str) @ cdecl atof(str)
@ cdecl atoi(str) @ cdecl atoi(str)
@ cdecl atol(str) @ cdecl atol(str)
......
...@@ -14,6 +14,7 @@ double __cdecl atanh(double x) ...@@ -14,6 +14,7 @@ double __cdecl atanh(double x)
if (e < 0x3ff - 1) { if (e < 0x3ff - 1) {
if (e < 0x3ff - 32) { if (e < 0x3ff - 32) {
fp_barrier(y + 0x1p120f);
/* handle underflow */ /* handle underflow */
if (e == 0) if (e == 0)
FORCE_EVAL((float)y); FORCE_EVAL((float)y);
...@@ -24,6 +25,7 @@ double __cdecl atanh(double x) ...@@ -24,6 +25,7 @@ double __cdecl atanh(double x)
} else { } else {
/* avoid overflow */ /* avoid overflow */
y = 0.5*log1p(2*(y/(1-y))); y = 0.5*log1p(2*(y/(1-y)));
if (isinf(y)) errno = ERANGE;
} }
return s ? -y : y; return s ? -y : y;
} }
...@@ -13,6 +13,7 @@ float __cdecl atanhf(float x) ...@@ -13,6 +13,7 @@ float __cdecl atanhf(float x)
if (u.i < 0x3f800000 - (1<<23)) { if (u.i < 0x3f800000 - (1<<23)) {
if (u.i < 0x3f800000 - (32<<23)) { if (u.i < 0x3f800000 - (32<<23)) {
fp_barrierf(y + 0x1p120f);
/* handle underflow */ /* handle underflow */
if (u.i < (1<<23)) if (u.i < (1<<23))
FORCE_EVAL((float)(y*y)); FORCE_EVAL((float)(y*y));
...@@ -23,6 +24,7 @@ float __cdecl atanhf(float x) ...@@ -23,6 +24,7 @@ float __cdecl atanhf(float x)
} else { } else {
/* avoid overflow */ /* avoid overflow */
y = 0.5f*log1pf(2*(y/(1-y))); y = 0.5f*log1pf(2*(y/(1-y)));
if (isinf(y)) errno = ERANGE;
} }
return s ? -y : y; return s ? -y : y;
} }
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