From ff7faafda68f697b38270569031f71f151d2dc0f Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Fri, 4 Jun 2021 18:25:30 +0200 Subject: [PATCH] msvcrt: Import log1pf implementation from musl. Signed-off-by: Piotr Caban Signed-off-by: Alexandre Julliard --- configure | 1 - configure.ac | 1 - dlls/msvcrt/math.c | 66 +++++++++++++++++++++++++++++++++++++++++-- dlls/msvcrt/unixlib.c | 13 --------- dlls/msvcrt/unixlib.h | 1 - include/config.h.in | 3 -- 6 files changed, 63 insertions(+), 22 deletions(-) diff --git a/configure b/configure index e91b319c705..e73670fc110 100755 --- a/configure +++ b/configure @@ -19622,7 +19622,6 @@ for ac_func in \ fmaf \ lgamma \ lgammaf \ - log1pf \ log2 \ log2f \ tgamma \ diff --git a/configure.ac b/configure.ac index accdbaf6216..b13c2ad3182 100644 --- a/configure.ac +++ b/configure.ac @@ -2661,7 +2661,6 @@ AC_CHECK_FUNCS(\ fmaf \ lgamma \ lgammaf \ - log1pf \ log2 \ log2f \ tgamma \ diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index fbc97aedce4..5702131cec9 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -6972,12 +6972,72 @@ double CDECL log1p(double x) /********************************************************************* * log1pf (MSVCR120.@) + * + * Copied from musl: src/math/log1pf.c */ float CDECL log1pf(float x) { - if (x < -1) *_errno() = EDOM; - else if (x == -1) *_errno() = ERANGE; - return unix_funcs->log1pf( x ); + static const float ln2_hi = 6.9313812256e-01, + ln2_lo = 9.0580006145e-06, + Lg1 = 0xaaaaaa.0p-24, + Lg2 = 0xccce13.0p-25, + Lg3 = 0x91e9ee.0p-25, + Lg4 = 0xf89e26.0p-26; + + union {float f; UINT32 i;} u = {x}; + float hfsq, f, c, s, z, R, w, t1, t2, dk; + UINT32 ix, iu; + int k; + + ix = u.i; + k = 1; + if (ix < 0x3ed413d0 || ix >> 31) { /* 1+x < sqrt(2)+ */ + if (ix >= 0xbf800000) { /* x <= -1.0 */ + if (x == -1) { + *_errno() = ERANGE; + return x / 0.0f; /* log1p(-1)=+inf */ + } + *_errno() = EDOM; + return (x - x) / 0.0f; /* log1p(x<-1)=NaN */ + } + if (ix<<1 < 0x33800000<<1) { /* |x| < 2**-24 */ + /* underflow if subnormal */ + if ((ix & 0x7f800000) == 0) + fp_barrierf(x * x); + return x; + } + if (ix <= 0xbe95f619) { /* sqrt(2)/2- <= 1+x < sqrt(2)+ */ + k = 0; + c = 0; + f = x; + } + } else if (ix >= 0x7f800000) + return x; + if (k) { + u.f = 1 + x; + iu = u.i; + iu += 0x3f800000 - 0x3f3504f3; + k = (int)(iu >> 23) - 0x7f; + /* correction term ~ log(1+x)-log(u), avoid underflow in c/u */ + if (k < 25) { + c = k >= 2 ? 1 - (u.f - x) : x - (u.f - 1); + c /= u.f; + } else + c = 0; + /* reduce u into [sqrt(2)/2, sqrt(2)] */ + iu = (iu & 0x007fffff) + 0x3f3504f3; + u.i = iu; + f = u.f - 1; + } + s = f / (2.0f + f); + z = s * s; + w = z * z; + t1= w * (Lg2 + w * Lg4); + t2= z * (Lg1 + w * Lg3); + R = t2 + t1; + hfsq = 0.5f * f * f; + dk = k; + return s * (hfsq + R) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi; } /********************************************************************* diff --git a/dlls/msvcrt/unixlib.c b/dlls/msvcrt/unixlib.c index f98d08e4909..3b003a846c8 100644 --- a/dlls/msvcrt/unixlib.c +++ b/dlls/msvcrt/unixlib.c @@ -136,18 +136,6 @@ static float CDECL unix_log10f( float x ) return log10f( x ); } -/********************************************************************* - * log1pf - */ -static float CDECL unix_log1pf(float x) -{ -#ifdef HAVE_LOG1PF - return log1pf(x); -#else - return log(1 + x); -#endif -} - /********************************************************************* * log2 */ @@ -225,7 +213,6 @@ static const struct unix_funcs funcs = unix_lgammaf, unix_log10, unix_log10f, - unix_log1pf, unix_log2, unix_log2f, unix_pow, diff --git a/dlls/msvcrt/unixlib.h b/dlls/msvcrt/unixlib.h index 285deb22bc2..7e976949e04 100644 --- a/dlls/msvcrt/unixlib.h +++ b/dlls/msvcrt/unixlib.h @@ -32,7 +32,6 @@ struct unix_funcs float (CDECL *lgammaf)(float x); double (CDECL *log10)(double x); float (CDECL *log10f)(float x); - float (CDECL *log1pf)(float x); double (CDECL *log2)(double x); float (CDECL *log2f)(float x); double (CDECL *pow)(double x, double y); diff --git a/include/config.h.in b/include/config.h.in index 7e6d36112d3..1b308f3d34c 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -408,9 +408,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_VIDEODEV2_H -/* Define to 1 if you have the `log1pf' function. */ -#undef HAVE_LOG1PF - /* Define to 1 if you have the `log2' function. */ #undef HAVE_LOG2