From da55a453d1422d37b5684ea3ddaf7ef95bf6d7a3 Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Tue, 25 May 2021 15:21:15 +0200 Subject: [PATCH] msvcrt: Import asinh implementation from musl. Signed-off-by: Piotr Caban Signed-off-by: Alexandre Julliard --- configure | 1 - configure.ac | 1 - dlls/msvcrt/math.c | 20 +++++++++++++++++++- dlls/msvcrt/unixlib.c | 18 ------------------ dlls/msvcrt/unixlib.h | 1 - include/config.h.in | 3 --- 6 files changed, 19 insertions(+), 25 deletions(-) diff --git a/configure b/configure index d7b558784fd..9b41d4ff072 100755 --- a/configure +++ b/configure @@ -19616,7 +19616,6 @@ $as_echo "#define HAVE_ISNAN 1" >>confdefs.h fi for ac_func in \ - asinh \ atanh \ atanhf \ exp2 \ diff --git a/configure.ac b/configure.ac index 73afcc9c6d0..6674e0d15df 100644 --- a/configure.ac +++ b/configure.ac @@ -2656,7 +2656,6 @@ then fi AC_CHECK_FUNCS(\ - asinh \ atanh \ atanhf \ exp2 \ diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index 65d01105a45..8d4ca7bb3fb 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -6569,10 +6569,28 @@ double CDECL fmin(double x, double y) /********************************************************************* * asinh (MSVCR120.@) + * + * Copied from musl: src/math/asinh.c */ double CDECL asinh(double x) { - return unix_funcs->asinh( x ); + UINT64 ux = *(UINT64*)&x; + int e = ux >> 52 & 0x7ff; + int s = ux >> 63; + + /* |x| */ + ux &= (UINT64)-1 / 2; + x = *(double*)&ux; + + if (e >= 0x3ff + 26) /* |x| >= 0x1p26 or inf or nan */ + x = log(x) + 0.693147180559945309417232121458176568; + else if (e >= 0x3ff + 1) /* |x| >= 2 */ + x = log(2 * x + 1 / (sqrt(x * x + 1) + x)); + else if (e >= 0x3ff - 26) /* |x| >= 0x1p-26 */ + x = log1p(x + x * x / (sqrt(x * x + 1) + 1)); + else /* |x| < 0x1p-26, raise inexact if x != 0 */ + fp_barrier(x + 0x1p120f); + return s ? -x : x; } /********************************************************************* diff --git a/dlls/msvcrt/unixlib.c b/dlls/msvcrt/unixlib.c index f937ee5e65e..ce055c8ea03 100644 --- a/dlls/msvcrt/unixlib.c +++ b/dlls/msvcrt/unixlib.c @@ -42,23 +42,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt); -/********************************************************************* - * asinh - */ -static double CDECL unix_asinh(double x) -{ -#ifdef HAVE_ASINH - return asinh(x); -#else - if (!isfinite(x*x+1)) - { - if (x > 0) return log(2) + log(x); - else return -log(2) - log(-x); - } - return log(x + sqrt(x*x+1)); -#endif -} - /********************************************************************* * atanh */ @@ -410,7 +393,6 @@ static float CDECL unix_tgammaf(float x) static const struct unix_funcs funcs = { - unix_asinh, unix_atanh, unix_atanhf, unix_cosh, diff --git a/dlls/msvcrt/unixlib.h b/dlls/msvcrt/unixlib.h index 6a3732234a2..f915f2f92d0 100644 --- a/dlls/msvcrt/unixlib.h +++ b/dlls/msvcrt/unixlib.h @@ -23,7 +23,6 @@ struct unix_funcs { - double (CDECL *asinh)(double x); double (CDECL *atanh)(double x); float (CDECL *atanhf)(float x); double (CDECL *cosh)(double x); diff --git a/include/config.h.in b/include/config.h.in index f44f72c459d..bca2d843e58 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -25,9 +25,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_ARPA_NAMESER_H -/* Define to 1 if you have the `asinh' function. */ -#undef HAVE_ASINH - /* Define to 1 if you have the header file. */ #undef HAVE_ASM_TYPES_H