From: Alexandre Julliard julliard@winehq.org
--- dlls/msvcr120/msvcr120.spec | 4 +- dlls/msvcrt/math.c | 79 ++++++++++--------------------------- dlls/ucrtbase/ucrtbase.spec | 8 ++-- libs/musl/src/math/rint.c | 4 +- libs/musl/src/math/rintf.c | 4 +- 5 files changed, 30 insertions(+), 69 deletions(-)
diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index 102d6319f47..ec1fd48dce5 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -2334,9 +2334,9 @@ @ cdecl remquol(double double ptr) remquo @ cdecl rename(str str) @ cdecl rewind(ptr) -@ cdecl rint(double) +@ cdecl rint(double) MSVCRT_rint @ cdecl rintf(float) -@ cdecl rintl(double) rint +@ cdecl rintl(double) MSVCRT_rint @ cdecl round(double) @ cdecl roundf(float) @ cdecl roundl(double) round diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index 1e67ced4360..b1cdb6efb64 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -953,37 +953,6 @@ double CDECL atan( double x ) return sign ? -z : z; }
-/********************************************************************* - * rint (MSVCR120.@) - * - * Copied from musl: src/math/rint.c - */ -double CDECL rint(double x) -{ - static const double toint = 1 / DBL_EPSILON; - - ULONGLONG llx = *(ULONGLONG*)&x; - int e = llx >> 52 & 0x7ff; - int s = llx >> 63; - unsigned cw; - double y; - - if (e >= 0x3ff+52) - return x; - cw = _controlfp(0, 0); - if ((cw & _MCW_PC) != _PC_53) - _controlfp(_PC_53, _MCW_PC); - if (s) - y = fp_barrier(x - toint) + toint; - else - y = fp_barrier(x + toint) - toint; - if ((cw & _MCW_PC) != _PC_53) - _controlfp(cw, _MCW_PC); - if (y == 0) - return s ? -0.0 : 0; - return y; -} - /* Copied from musl: src/math/exp_data.c */ static const UINT64 exp_T[] = { 0x0ULL, 0x3ff0000000000000ULL, @@ -2567,6 +2536,23 @@ int CDECL _isnan(double num)
#if _MSVCR_VER>=120
+/********************************************************************* + * rint (MSVCR120.@) + */ +double CDECL MSVCRT_rint(double x) +{ + unsigned cw; + double y; + + cw = _controlfp(0, 0); + if ((cw & _MCW_PC) != _PC_53) + _controlfp(_PC_53, _MCW_PC); + y = rint(x); + if ((cw & _MCW_PC) != _PC_53) + _controlfp(cw, _MCW_PC); + return y; +} + /********************************************************************* * _nearbyint (MSVCR120.@) * @@ -2585,7 +2571,7 @@ double CDECL nearbyint(double x) cw |= _EM_INEXACT; _setfp(&cw, _EM_INEXACT, NULL, 0); } - x = rint(x); + x = MSVCRT_rint(x); if (update_cw || update_sw) { sw = 0; @@ -3511,31 +3497,6 @@ void __cdecl __libm_sse2_sqrt_precise(void)
#if _MSVCR_VER>=120
-/********************************************************************* - * rintf (MSVCR120.@) - * - * Copied from musl: src/math/rintf.c - */ -float CDECL rintf(float x) -{ - static const float toint = 1 / FLT_EPSILON; - - unsigned int ix = *(unsigned int*)&x; - int e = ix >> 23 & 0xff; - int s = ix >> 31; - float y; - - if (e >= 0x7f + 23) - return x; - if (s) - y = fp_barrierf(x - toint) + toint; - else - y = fp_barrierf(x + toint) - toint; - if (y == 0) - return s ? -0.0f : 0.0f; - return y; -} - /********************************************************************* * lrint (MSVCR120.@) */ @@ -3543,7 +3504,7 @@ __msvcrt_long CDECL lrint(double x) { double d;
- d = rint(x); + d = MSVCRT_rint(x); if ((d < 0 && d != (double)(__msvcrt_long)d) || (d >= 0 && d != (double)(__msvcrt_ulong)d)) { *_errno() = EDOM; @@ -3575,7 +3536,7 @@ __int64 CDECL llrint(double x) { double d;
- d = rint(x); + d = MSVCRT_rint(x); if ((d < 0 && d != (double)(__int64)d) || (d >= 0 && d != (double)(unsigned __int64)d)) { *_errno() = EDOM; diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index a476681fc43..a05023b9f3e 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -1758,9 +1758,9 @@ @ cdecl _o_remquol(double double ptr) remquo @ cdecl _o_rename(str str) rename @ cdecl _o_rewind(ptr) rewind -@ cdecl _o_rint(double) rint +@ cdecl _o_rint(double) MSVCRT_rint @ cdecl _o_rintf(float) rintf -@ cdecl _o_rintl(double) rint +@ cdecl _o_rintl(double) MSVCRT_rint @ cdecl _o_round(double) round @ cdecl _o_roundf(float) roundf @ cdecl _o_roundl(double) round @@ -2471,9 +2471,9 @@ @ cdecl remquol(double double ptr) remquo @ cdecl rename(str str) @ cdecl rewind(ptr) -@ cdecl rint(double) +@ cdecl rint(double) MSVCRT_rint @ cdecl rintf(float) -@ cdecl rintl(double) rint +@ cdecl rintl(double) MSVCRT_rint @ cdecl round(double) @ cdecl roundf(float) @ cdecl roundl(double) round diff --git a/libs/musl/src/math/rint.c b/libs/musl/src/math/rint.c index 2de4ff0a99e..ad35201b266 100644 --- a/libs/musl/src/math/rint.c +++ b/libs/musl/src/math/rint.c @@ -20,9 +20,9 @@ double __cdecl rint(double x) if (e >= 0x3ff+52) return x; if (s) - y = x - toint + toint; + y = fp_barrier(x - toint) + toint; else - y = x + toint - toint; + y = fp_barrier(x + toint) - toint; if (y == 0) return s ? -0.0 : 0; return y; diff --git a/libs/musl/src/math/rintf.c b/libs/musl/src/math/rintf.c index 9e03461404d..455f9e3980f 100644 --- a/libs/musl/src/math/rintf.c +++ b/libs/musl/src/math/rintf.c @@ -22,9 +22,9 @@ float __cdecl rintf(float x) if (e >= 0x7f+23) return x; if (s) - y = x - toint + toint; + y = fp_barrierf(x - toint) + toint; else - y = x + toint - toint; + y = fp_barrierf(x + toint) - toint; if (y == 0) return s ? -0.0f : 0.0f; return y;
From: Alexandre Julliard julliard@winehq.org
--- dlls/msvcrt/math.c | 64 --------------------------------------- libs/musl/src/math/expf.c | 15 +++------ 2 files changed, 4 insertions(+), 75 deletions(-)
diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index b1cdb6efb64..ca95f51873a 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -218,19 +218,6 @@ float CDECL _chgsignf( float num )
#endif
-#ifndef __i386__ -static const UINT64 exp2f_T[] = { - 0x3ff0000000000000ULL, 0x3fefd9b0d3158574ULL, 0x3fefb5586cf9890fULL, 0x3fef9301d0125b51ULL, - 0x3fef72b83c7d517bULL, 0x3fef54873168b9aaULL, 0x3fef387a6e756238ULL, 0x3fef1e9df51fdee1ULL, - 0x3fef06fe0a31b715ULL, 0x3feef1a7373aa9cbULL, 0x3feedea64c123422ULL, 0x3feece086061892dULL, - 0x3feebfdad5362a27ULL, 0x3feeb42b569d4f82ULL, 0x3feeab07dd485429ULL, 0x3feea47eb03a5585ULL, - 0x3feea09e667f3bcdULL, 0x3fee9f75e8ec5f74ULL, 0x3feea11473eb0187ULL, 0x3feea589994cce13ULL, - 0x3feeace5422aa0dbULL, 0x3feeb737b0cdc5e5ULL, 0x3feec49182a3f090ULL, 0x3feed503b23e255dULL, - 0x3feee89f995ad3adULL, 0x3feeff76f2fb5e47ULL, 0x3fef199bdd85529cULL, 0x3fef3720dcef9069ULL, - 0x3fef5818dcfba487ULL, 0x3fef7c97337b9b5fULL, 0x3fefa4afa2a490daULL, 0x3fefd0765b6e4540ULL -}; -#endif - /********************************************************************* * _fdclass (MSVCR120.@) * @@ -489,57 +476,6 @@ float CDECL atanf( float x ) return sign ? -z : z; }
-/********************************************************************* - * expf (MSVCRT.@) - */ -float CDECL expf( float x ) -{ - static const double C[] = { - 0x1.c6af84b912394p-5 / (1 << 5) / (1 << 5) / (1 << 5), - 0x1.ebfce50fac4f3p-3 / (1 << 5) / (1 << 5), - 0x1.62e42ff0c52d6p-1 / (1 << 5) - }; - static const double invln2n = 0x1.71547652b82fep+0 * (1 << 5); - - double kd, z, r, r2, y, s; - UINT32 abstop; - UINT64 ki, t; - - abstop = (*(UINT32*)&x >> 20) & 0x7ff; - if (abstop >= 0x42b) { - /* |x| >= 88 or x is nan. */ - if (*(UINT32*)&x == 0xff800000) - return 0.0f; - if (abstop >= 0x7f8) - return x + x; - if (x > 0x1.62e42ep6f) /* x > log(0x1p128) ~= 88.72 */ - return math_error(_OVERFLOW, "expf", x, 0, x * FLT_MAX); - if (x < -0x1.9fe368p6f) /* x < log(0x1p-150) ~= -103.97 */ - return math_error(_UNDERFLOW, "expf", x, 0, fp_barrierf(FLT_MIN) * FLT_MIN); - } - - /* x*N/Ln2 = k + r with r in [-1/2, 1/2] and int k. */ - z = invln2n * x; - - /* Round and convert z to int, the result is in [-150*N, 128*N] and - ideally ties-to-even rule is used, otherwise the magnitude of r - can be bigger which gives larger approximation error. */ - kd = round(z); - ki = (INT64)kd; - r = z - kd; - - /* exp(x) = 2^(k/N) * 2^(r/N) ~= s * (C0*r^3 + C1*r^2 + C2*r + 1) */ - t = exp2f_T[ki % (1 << 5)]; - t += ki << (52 - 5); - s = *(double*)&t; - z = C[0] * r + C[1]; - r2 = r * r; - y = C[2] * r + 1; - y = z * r2 + y; - y = y * s; - return y; -} - static BOOL sqrtf_validate( float *x ) { short c = _fdclass(*x); diff --git a/libs/musl/src/math/expf.c b/libs/musl/src/math/expf.c index 6cf118b119e..ee40977baaa 100644 --- a/libs/musl/src/math/expf.c +++ b/libs/musl/src/math/expf.c @@ -45,9 +45,9 @@ float __cdecl expf(float x) if (abstop >= top12(INFINITY)) return x + x; if (x > 0x1.62e42ep6f) /* x > log(0x1p128) ~= 88.72 */ - return __math_oflowf(0); + return math_error(_OVERFLOW, "expf", x, 0, x * FLT_MAX); if (x < -0x1.9fe368p6f) /* x < log(0x1p-150) ~= -103.97 */ - return __math_uflowf(0); + return math_error(_UNDERFLOW, "expf", x, 0, fp_barrierf(FLT_MIN) * FLT_MIN); }
/* x*N/Ln2 = k + r with r in [-1/2, 1/2] and int k. */ @@ -56,15 +56,8 @@ float __cdecl expf(float x) /* Round and convert z to int, the result is in [-150*N, 128*N] and ideally ties-to-even rule is used, otherwise the magnitude of r can be bigger which gives larger approximation error. */ -#if TOINT_INTRINSICS - kd = roundtoint(z); - ki = converttoint(z); -#else -# define SHIFT __exp2f_data.shift - kd = eval_as_double(z + SHIFT); - ki = asuint64(kd); - kd -= SHIFT; -#endif + kd = round(z); + ki = (int64_t)kd; r = z - kd;
/* exp(x) = 2^(k/N) * 2^(r/N) ~= s * (C0*r^3 + C1*r^2 + C2*r + 1) */
From: Alexandre Julliard julliard@winehq.org
With the changes from 9c8f8e715f4fd3a35924e4e9d32eb42fa8b56a18. --- dlls/msvcrt/math.c | 47 -------------------------------------- libs/musl/src/math/acosf.c | 21 +++++++++-------- 2 files changed, 11 insertions(+), 57 deletions(-)
diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index ca95f51873a..b8a3fae663f 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -305,53 +305,6 @@ static float asinf_R(float z) return p / q; }
-/********************************************************************* - * acosf (MSVCRT.@) - * - * Copied from musl: src/math/acosf.c - */ -float CDECL acosf( float x ) -{ - static const double pio2_lo = 6.12323399573676603587e-17; - static const double pio2_hi = 1.57079632679489655800e+00; - - float z, w, s, c, df; - unsigned int hx, ix; - - hx = *(unsigned int*)&x; - ix = hx & 0x7fffffff; - /* |x| >= 1 or nan */ - if (ix >= 0x3f800000) { - if (ix == 0x3f800000) { - if (hx >> 31) - return M_PI; - return 0; - } - if (isnan(x)) return x; - return math_error(_DOMAIN, "acosf", x, 0, 0 / (x - x)); - } - /* |x| < 0.5 */ - if (ix < 0x3f000000) { - if (ix <= 0x32800000) /* |x| < 2**-26 */ - return M_PI_2; - return pio2_hi - (x - (pio2_lo - x * asinf_R(x * x))); - } - /* x < -0.5 */ - if (hx >> 31) { - z = (1 + x) * 0.5f; - s = sqrtf(z); - return 2*(pio2_hi - (s + (asinf_R(z) * s - pio2_lo))); - } - /* x > 0.5 */ - z = (1 - x) * 0.5f; - s = sqrtf(z); - hx = *(unsigned int*)&s & 0xffff0000; - df = *(float*)&hx; - c = (z - df * df) / (s + df); - w = asinf_R(z) * s + c; - return 2 * (df + w); -} - /********************************************************************* * asinf (MSVCRT.@) * diff --git a/libs/musl/src/math/acosf.c b/libs/musl/src/math/acosf.c index 0da275bf459..bf37332ab52 100644 --- a/libs/musl/src/math/acosf.c +++ b/libs/musl/src/math/acosf.c @@ -18,15 +18,16 @@ static const float pio2_hi = 1.5707962513e+00, /* 0x3fc90fda */ pio2_lo = 7.5497894159e-08, /* 0x33a22168 */ -pS0 = 1.6666586697e-01, -pS1 = -4.2743422091e-02, -pS2 = -8.6563630030e-03, -qS1 = -7.0662963390e-01; +pS0 = 1.66666672e-01, +pS1 = -5.11644611e-02, +pS2 = -1.21124933e-02, +pS3 = -3.58742251e-03, +qS1 = -7.56982703e-01;
static float R(float z) { float_t p, q; - p = z*(pS0+z*(pS1+z*pS2)); + p = z*(pS0+z*(pS1+z*(pS2+z*pS3))); q = 1.0f+z*qS1; return p/q; } @@ -42,23 +43,23 @@ float __cdecl acosf(float x) if (ix >= 0x3f800000) { if (ix == 0x3f800000) { if (hx >> 31) - return 2*pio2_hi + 0x1p-120f; + return M_PI; return 0; } - return 0/(x-x); + if (isnan(x)) return x; + return math_error(_DOMAIN, "acosf", x, 0, 0 / (x - x)); } /* |x| < 0.5 */ if (ix < 0x3f000000) { if (ix <= 0x32800000) /* |x| < 2**-26 */ - return pio2_hi + 0x1p-120f; + return M_PI_2; return pio2_hi - (x - (pio2_lo-x*R(x*x))); } /* x < -0.5 */ if (hx >> 31) { z = (1+x)*0.5f; s = sqrtf(z); - w = R(z)*s-pio2_lo; - return 2*(pio2_hi - (s+w)); + return 2*(pio2_hi - (s + (R(z)*s-pio2_lo))); } /* x > 0.5 */ z = (1-x)*0.5f;
From: Alexandre Julliard julliard@winehq.org
With the changes from 0b8db612713d6a92109396951d6ac53fd23d6039. --- dlls/msvcrt/math.c | 55 -------------------------------------- libs/musl/src/math/asinf.c | 26 +++++++++++------- 2 files changed, 16 insertions(+), 65 deletions(-)
diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index b8a3fae663f..d8eab014e42 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -290,61 +290,6 @@ int CDECL _isnanf( float num ) return (u.i & 0x7fffffff) > 0x7f800000; }
-static float asinf_R(float z) -{ - /* coefficients for R(x^2) */ - static const float p1 = 1.66666672e-01, - p2 = -5.11644611e-02, - p3 = -1.21124933e-02, - p4 = -3.58742251e-03, - q1 = -7.56982703e-01; - - float p, q; - p = z * (p1 + z * (p2 + z * (p3 + z * p4))); - q = 1.0f + z * q1; - return p / q; -} - -/********************************************************************* - * asinf (MSVCRT.@) - * - * Copied from musl: src/math/asinf.c - */ -float CDECL asinf( float x ) -{ - static const double pio2 = 1.570796326794896558e+00; - static const float pio4_hi = 0.785398125648; - static const float pio2_lo = 7.54978941586e-08; - - float s, z, f, c; - unsigned int hx, ix; - - hx = *(unsigned int*)&x; - ix = hx & 0x7fffffff; - if (ix >= 0x3f800000) { /* |x| >= 1 */ - if (ix == 0x3f800000) /* |x| == 1 */ - return x * pio2 + 7.5231638453e-37; /* asin(+-1) = +-pi/2 with inexact */ - if (isnan(x)) return x; - return math_error(_DOMAIN, "asinf", x, 0, 0 / (x - x)); - } - if (ix < 0x3f000000) { /* |x| < 0.5 */ - /* if 0x1p-126 <= |x| < 0x1p-12, avoid raising underflow */ - if (ix < 0x39800000 && ix >= 0x00800000) - return x; - return x + x * asinf_R(x * x); - } - /* 1 > |x| >= 0.5 */ - z = (1 - fabsf(x)) * 0.5f; - s = sqrtf(z); - /* f+c = sqrt(z) */ - *(unsigned int*)&f = *(unsigned int*)&s & 0xffff0000; - c = (z - f * f) / (s + f); - x = pio4_hi - (2 * s * asinf_R(z) - (pio2_lo - 2 * c) - (pio4_hi - 2 * f)); - if (hx >> 31) - return -x; - return x; -} - /********************************************************************* * atanf (MSVCRT.@) * diff --git a/libs/musl/src/math/asinf.c b/libs/musl/src/math/asinf.c index b13f80307a5..d4a312e90a3 100644 --- a/libs/musl/src/math/asinf.c +++ b/libs/musl/src/math/asinf.c @@ -18,24 +18,26 @@ static const double pio2 = 1.570796326794896558e+00;
static const float +pio4_hi = 0.785398125648, +pio2_lo = 7.54978941586e-08, /* coefficients for R(x^2) */ -pS0 = 1.6666586697e-01, -pS1 = -4.2743422091e-02, -pS2 = -8.6563630030e-03, -qS1 = -7.0662963390e-01; +pS0 = 1.66666672e-01, +pS1 = -5.11644611e-02, +pS2 = -1.21124933e-02, +pS3 = -3.58742251e-03, +qS1 = -7.56982703e-01;
static float R(float z) { float_t p, q; - p = z*(pS0+z*(pS1+z*pS2)); + p = z*(pS0+z*(pS1+z*(pS2+z*pS3))); q = 1.0f+z*qS1; return p/q; }
float __cdecl asinf(float x) { - double s; - float z; + float s, z, f, c; uint32_t hx,ix;
GET_FLOAT_WORD(hx, x); @@ -43,7 +45,8 @@ float __cdecl asinf(float x) if (ix >= 0x3f800000) { /* |x| >= 1 */ if (ix == 0x3f800000) /* |x| == 1 */ return x*pio2 + 0x1p-120f; /* asin(+-1) = +-pi/2 with inexact */ - return 0/(x-x); /* asin(|x|>1) is NaN */ + if (isnan(x)) return x; + return math_error(_DOMAIN, "asinf", x, 0, 0 / (x - x)); } if (ix < 0x3f000000) { /* |x| < 0.5 */ /* if 0x1p-126 <= |x| < 0x1p-12, avoid raising underflow */ @@ -53,8 +56,11 @@ float __cdecl asinf(float x) } /* 1 > |x| >= 0.5 */ z = (1 - fabsf(x))*0.5f; - s = sqrt(z); - x = pio2 - 2*(s+s*R(z)); + s = sqrtf(z); + /* f+c = sqrt(z) */ + *(unsigned int*)&f = *(unsigned int*)&s & 0xffff0000; + c = (z - f * f) / (s + f); + x = pio4_hi - (2*s*R(z) - (pio2_lo - 2*c) - (pio4_hi - 2*f)); if (hx >> 31) return -x; return x;
From: Alexandre Julliard julliard@winehq.org
--- dlls/msvcrt/math.c | 81 ++--------------------------------------- dlls/msvcrt/msvcrt.spec | 2 +- 2 files changed, 5 insertions(+), 78 deletions(-)
diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index d8eab014e42..b44bc051453 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -292,87 +292,14 @@ int CDECL _isnanf( float num )
/********************************************************************* * atanf (MSVCRT.@) - * - * Copied from musl: src/math/atanf.c */ -float CDECL atanf( float x ) +#if _MSVCR_VER == 0 /* other versions call atanf() directly */ +float CDECL MSVCRT_atanf( float x ) { - static const float atanhi[] = { - 4.6364760399e-01, - 7.8539812565e-01, - 9.8279368877e-01, - 1.5707962513e+00, - }; - static const float atanlo[] = { - 5.0121582440e-09, - 3.7748947079e-08, - 3.4473217170e-08, - 7.5497894159e-08, - }; - static const float aT[] = { - 3.3333328366e-01, - -1.9999158382e-01, - 1.4253635705e-01, - -1.0648017377e-01, - 6.1687607318e-02, - }; - - float w, s1, s2, z; - unsigned int ix, sign; - int id; - -#if _MSVCR_VER == 0 if (isnan(x)) return math_error(_DOMAIN, "atanf", x, 0, x); -#endif - - ix = *(unsigned int*)&x; - sign = ix >> 31; - ix &= 0x7fffffff; - if (ix >= 0x4c800000) { /* if |x| >= 2**26 */ - if (isnan(x)) - return x; - z = atanhi[3] + 7.5231638453e-37; - return sign ? -z : z; - } - if (ix < 0x3ee00000) { /* |x| < 0.4375 */ - if (ix < 0x39800000) { /* |x| < 2**-12 */ - if (ix < 0x00800000) - /* raise underflow for subnormal x */ - fp_barrierf(x*x); - return x; - } - id = -1; - } else { - x = fabsf(x); - if (ix < 0x3f980000) { /* |x| < 1.1875 */ - if (ix < 0x3f300000) { /* 7/16 <= |x| < 11/16 */ - id = 0; - x = (2.0f * x - 1.0f) / (2.0f + x); - } else { /* 11/16 <= |x| < 19/16 */ - id = 1; - x = (x - 1.0f) / (x + 1.0f); - } - } else { - if (ix < 0x401c0000) { /* |x| < 2.4375 */ - id = 2; - x = (x - 1.5f) / (1.0f + 1.5f * x); - } else { /* 2.4375 <= |x| < 2**26 */ - id = 3; - x = -1.0f / x; - } - } - } - /* end of argument reduction */ - z = x * x; - w = z * z; - /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ - s1 = z * (aT[0] + w * (aT[2] + w * aT[4])); - s2 = w * (aT[1] + w * aT[3]); - if (id < 0) - return x - x * (s1 + s2); - z = atanhi[id] - ((x * (s1 + s2) - atanlo[id]) - x); - return sign ? -z : z; + return atanf( x ); } +#endif
static BOOL sqrtf_validate( float *x ) { diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 0b88ba97135..8bf1c87d73c 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -1257,7 +1257,7 @@ @ cdecl atan(double) @ cdecl atan2(double double) @ cdecl -arch=!i386 asinf(float) -@ cdecl -arch=!i386 atanf(float) +@ cdecl -arch=!i386 atanf(float) MSVCRT_atanf @ cdecl -arch=!i386 atan2f(float float) @ cdecl -private atexit(ptr) MSVCRT_atexit # not imported to avoid conflicts with Mingw @ cdecl atof(str)
From: Alexandre Julliard julliard@winehq.org
--- dlls/msvcrt/math.c | 245 +-------------------------------------- dlls/msvcrt/msvcrt.spec | 2 +- libs/musl/src/math/exp.c | 28 ++--- 3 files changed, 16 insertions(+), 259 deletions(-)
diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index b44bc051453..ba89c8446ba 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -714,251 +714,16 @@ double CDECL atan( double x ) return sign ? -z : z; }
-/* Copied from musl: src/math/exp_data.c */ -static const UINT64 exp_T[] = { - 0x0ULL, 0x3ff0000000000000ULL, - 0x3c9b3b4f1a88bf6eULL, 0x3feff63da9fb3335ULL, - 0xbc7160139cd8dc5dULL, 0x3fefec9a3e778061ULL, - 0xbc905e7a108766d1ULL, 0x3fefe315e86e7f85ULL, - 0x3c8cd2523567f613ULL, 0x3fefd9b0d3158574ULL, - 0xbc8bce8023f98efaULL, 0x3fefd06b29ddf6deULL, - 0x3c60f74e61e6c861ULL, 0x3fefc74518759bc8ULL, - 0x3c90a3e45b33d399ULL, 0x3fefbe3ecac6f383ULL, - 0x3c979aa65d837b6dULL, 0x3fefb5586cf9890fULL, - 0x3c8eb51a92fdeffcULL, 0x3fefac922b7247f7ULL, - 0x3c3ebe3d702f9cd1ULL, 0x3fefa3ec32d3d1a2ULL, - 0xbc6a033489906e0bULL, 0x3fef9b66affed31bULL, - 0xbc9556522a2fbd0eULL, 0x3fef9301d0125b51ULL, - 0xbc5080ef8c4eea55ULL, 0x3fef8abdc06c31ccULL, - 0xbc91c923b9d5f416ULL, 0x3fef829aaea92de0ULL, - 0x3c80d3e3e95c55afULL, 0x3fef7a98c8a58e51ULL, - 0xbc801b15eaa59348ULL, 0x3fef72b83c7d517bULL, - 0xbc8f1ff055de323dULL, 0x3fef6af9388c8deaULL, - 0x3c8b898c3f1353bfULL, 0x3fef635beb6fcb75ULL, - 0xbc96d99c7611eb26ULL, 0x3fef5be084045cd4ULL, - 0x3c9aecf73e3a2f60ULL, 0x3fef54873168b9aaULL, - 0xbc8fe782cb86389dULL, 0x3fef4d5022fcd91dULL, - 0x3c8a6f4144a6c38dULL, 0x3fef463b88628cd6ULL, - 0x3c807a05b0e4047dULL, 0x3fef3f49917ddc96ULL, - 0x3c968efde3a8a894ULL, 0x3fef387a6e756238ULL, - 0x3c875e18f274487dULL, 0x3fef31ce4fb2a63fULL, - 0x3c80472b981fe7f2ULL, 0x3fef2b4565e27cddULL, - 0xbc96b87b3f71085eULL, 0x3fef24dfe1f56381ULL, - 0x3c82f7e16d09ab31ULL, 0x3fef1e9df51fdee1ULL, - 0xbc3d219b1a6fbffaULL, 0x3fef187fd0dad990ULL, - 0x3c8b3782720c0ab4ULL, 0x3fef1285a6e4030bULL, - 0x3c6e149289cecb8fULL, 0x3fef0cafa93e2f56ULL, - 0x3c834d754db0abb6ULL, 0x3fef06fe0a31b715ULL, - 0x3c864201e2ac744cULL, 0x3fef0170fc4cd831ULL, - 0x3c8fdd395dd3f84aULL, 0x3feefc08b26416ffULL, - 0xbc86a3803b8e5b04ULL, 0x3feef6c55f929ff1ULL, - 0xbc924aedcc4b5068ULL, 0x3feef1a7373aa9cbULL, - 0xbc9907f81b512d8eULL, 0x3feeecae6d05d866ULL, - 0xbc71d1e83e9436d2ULL, 0x3feee7db34e59ff7ULL, - 0xbc991919b3ce1b15ULL, 0x3feee32dc313a8e5ULL, - 0x3c859f48a72a4c6dULL, 0x3feedea64c123422ULL, - 0xbc9312607a28698aULL, 0x3feeda4504ac801cULL, - 0xbc58a78f4817895bULL, 0x3feed60a21f72e2aULL, - 0xbc7c2c9b67499a1bULL, 0x3feed1f5d950a897ULL, - 0x3c4363ed60c2ac11ULL, 0x3feece086061892dULL, - 0x3c9666093b0664efULL, 0x3feeca41ed1d0057ULL, - 0x3c6ecce1daa10379ULL, 0x3feec6a2b5c13cd0ULL, - 0x3c93ff8e3f0f1230ULL, 0x3feec32af0d7d3deULL, - 0x3c7690cebb7aafb0ULL, 0x3feebfdad5362a27ULL, - 0x3c931dbdeb54e077ULL, 0x3feebcb299fddd0dULL, - 0xbc8f94340071a38eULL, 0x3feeb9b2769d2ca7ULL, - 0xbc87deccdc93a349ULL, 0x3feeb6daa2cf6642ULL, - 0xbc78dec6bd0f385fULL, 0x3feeb42b569d4f82ULL, - 0xbc861246ec7b5cf6ULL, 0x3feeb1a4ca5d920fULL, - 0x3c93350518fdd78eULL, 0x3feeaf4736b527daULL, - 0x3c7b98b72f8a9b05ULL, 0x3feead12d497c7fdULL, - 0x3c9063e1e21c5409ULL, 0x3feeab07dd485429ULL, - 0x3c34c7855019c6eaULL, 0x3feea9268a5946b7ULL, - 0x3c9432e62b64c035ULL, 0x3feea76f15ad2148ULL, - 0xbc8ce44a6199769fULL, 0x3feea5e1b976dc09ULL, - 0xbc8c33c53bef4da8ULL, 0x3feea47eb03a5585ULL, - 0xbc845378892be9aeULL, 0x3feea34634ccc320ULL, - 0xbc93cedd78565858ULL, 0x3feea23882552225ULL, - 0x3c5710aa807e1964ULL, 0x3feea155d44ca973ULL, - 0xbc93b3efbf5e2228ULL, 0x3feea09e667f3bcdULL, - 0xbc6a12ad8734b982ULL, 0x3feea012750bdabfULL, - 0xbc6367efb86da9eeULL, 0x3fee9fb23c651a2fULL, - 0xbc80dc3d54e08851ULL, 0x3fee9f7df9519484ULL, - 0xbc781f647e5a3ecfULL, 0x3fee9f75e8ec5f74ULL, - 0xbc86ee4ac08b7db0ULL, 0x3fee9f9a48a58174ULL, - 0xbc8619321e55e68aULL, 0x3fee9feb564267c9ULL, - 0x3c909ccb5e09d4d3ULL, 0x3feea0694fde5d3fULL, - 0xbc7b32dcb94da51dULL, 0x3feea11473eb0187ULL, - 0x3c94ecfd5467c06bULL, 0x3feea1ed0130c132ULL, - 0x3c65ebe1abd66c55ULL, 0x3feea2f336cf4e62ULL, - 0xbc88a1c52fb3cf42ULL, 0x3feea427543e1a12ULL, - 0xbc9369b6f13b3734ULL, 0x3feea589994cce13ULL, - 0xbc805e843a19ff1eULL, 0x3feea71a4623c7adULL, - 0xbc94d450d872576eULL, 0x3feea8d99b4492edULL, - 0x3c90ad675b0e8a00ULL, 0x3feeaac7d98a6699ULL, - 0x3c8db72fc1f0eab4ULL, 0x3feeace5422aa0dbULL, - 0xbc65b6609cc5e7ffULL, 0x3feeaf3216b5448cULL, - 0x3c7bf68359f35f44ULL, 0x3feeb1ae99157736ULL, - 0xbc93091fa71e3d83ULL, 0x3feeb45b0b91ffc6ULL, - 0xbc5da9b88b6c1e29ULL, 0x3feeb737b0cdc5e5ULL, - 0xbc6c23f97c90b959ULL, 0x3feeba44cbc8520fULL, - 0xbc92434322f4f9aaULL, 0x3feebd829fde4e50ULL, - 0xbc85ca6cd7668e4bULL, 0x3feec0f170ca07baULL, - 0x3c71affc2b91ce27ULL, 0x3feec49182a3f090ULL, - 0x3c6dd235e10a73bbULL, 0x3feec86319e32323ULL, - 0xbc87c50422622263ULL, 0x3feecc667b5de565ULL, - 0x3c8b1c86e3e231d5ULL, 0x3feed09bec4a2d33ULL, - 0xbc91bbd1d3bcbb15ULL, 0x3feed503b23e255dULL, - 0x3c90cc319cee31d2ULL, 0x3feed99e1330b358ULL, - 0x3c8469846e735ab3ULL, 0x3feede6b5579fdbfULL, - 0xbc82dfcd978e9db4ULL, 0x3feee36bbfd3f37aULL, - 0x3c8c1a7792cb3387ULL, 0x3feee89f995ad3adULL, - 0xbc907b8f4ad1d9faULL, 0x3feeee07298db666ULL, - 0xbc55c3d956dcaebaULL, 0x3feef3a2b84f15fbULL, - 0xbc90a40e3da6f640ULL, 0x3feef9728de5593aULL, - 0xbc68d6f438ad9334ULL, 0x3feeff76f2fb5e47ULL, - 0xbc91eee26b588a35ULL, 0x3fef05b030a1064aULL, - 0x3c74ffd70a5fddcdULL, 0x3fef0c1e904bc1d2ULL, - 0xbc91bdfbfa9298acULL, 0x3fef12c25bd71e09ULL, - 0x3c736eae30af0cb3ULL, 0x3fef199bdd85529cULL, - 0x3c8ee3325c9ffd94ULL, 0x3fef20ab5fffd07aULL, - 0x3c84e08fd10959acULL, 0x3fef27f12e57d14bULL, - 0x3c63cdaf384e1a67ULL, 0x3fef2f6d9406e7b5ULL, - 0x3c676b2c6c921968ULL, 0x3fef3720dcef9069ULL, - 0xbc808a1883ccb5d2ULL, 0x3fef3f0b555dc3faULL, - 0xbc8fad5d3ffffa6fULL, 0x3fef472d4a07897cULL, - 0xbc900dae3875a949ULL, 0x3fef4f87080d89f2ULL, - 0x3c74a385a63d07a7ULL, 0x3fef5818dcfba487ULL, - 0xbc82919e2040220fULL, 0x3fef60e316c98398ULL, - 0x3c8e5a50d5c192acULL, 0x3fef69e603db3285ULL, - 0x3c843a59ac016b4bULL, 0x3fef7321f301b460ULL, - 0xbc82d52107b43e1fULL, 0x3fef7c97337b9b5fULL, - 0xbc892ab93b470dc9ULL, 0x3fef864614f5a129ULL, - 0x3c74b604603a88d3ULL, 0x3fef902ee78b3ff6ULL, - 0x3c83c5ec519d7271ULL, 0x3fef9a51fbc74c83ULL, - 0xbc8ff7128fd391f0ULL, 0x3fefa4afa2a490daULL, - 0xbc8dae98e223747dULL, 0x3fefaf482d8e67f1ULL, - 0x3c8ec3bc41aa2008ULL, 0x3fefba1bee615a27ULL, - 0x3c842b94c3a9eb32ULL, 0x3fefc52b376bba97ULL, - 0x3c8a64a931d185eeULL, 0x3fefd0765b6e4540ULL, - 0xbc8e37bae43be3edULL, 0x3fefdbfdad9cbe14ULL, - 0x3c77893b4d91cd9dULL, 0x3fefe7c1819e90d8ULL, - 0x3c5305c14160cc89ULL, 0x3feff3c22b8f71f1ULL -}; - /********************************************************************* * exp (MSVCRT.@) - * - * Copied from musl: src/math/exp.c */ -double CDECL exp( double x ) +#if _MSVCR_VER == 0 /* other versions call exp() directly */ +double CDECL MSVCRT_exp( double x ) { - static const double C[] = { - 0x1.ffffffffffdbdp-2, - 0x1.555555555543cp-3, - 0x1.55555cf172b91p-5, - 0x1.1111167a4d017p-7 - }; - static const double invln2N = 0x1.71547652b82fep0 * (1 << 7), - negln2hiN = -0x1.62e42fefa0000p-8, - negln2loN = -0x1.cf79abc9e3b3ap-47; - - UINT32 abstop; - UINT64 ki, idx, top, sbits; - double kd, z, r, r2, scale, tail, tmp; - - abstop = (*(UINT64*)&x >> 52) & 0x7ff; - if (abstop - 0x3c9 >= 0x408 - 0x3c9) { - if (abstop - 0x3c9 >= 0x80000000) - /* Avoid spurious underflow for tiny x. */ - /* Note: 0 is common input. */ - return 1.0 + x; - if (abstop >= 0x409) { - if (*(UINT64*)&x == 0xfff0000000000000ULL) - return 0.0; -#if _MSVCR_VER == 0 - if (*(UINT64*)&x > 0x7ff0000000000000ULL) - return math_error(_DOMAIN, "exp", x, 0, 1.0 + x); -#endif - if (abstop >= 0x7ff) - return 1.0 + x; - if (*(UINT64*)&x >> 63) - return math_error(_UNDERFLOW, "exp", x, 0, fp_barrier(DBL_MIN) * DBL_MIN); - else - return math_error(_OVERFLOW, "exp", x, 0, fp_barrier(DBL_MAX) * DBL_MAX); - } - /* Large x is special cased below. */ - abstop = 0; - } - - /* exp(x) = 2^(k/N) * exp(r), with exp(r) in [2^(-1/2N),2^(1/2N)]. */ - /* x = ln2/N*k + r, with int k and r in [-ln2/2N, ln2/2N]. */ - z = invln2N * x; - kd = round(z); - ki = (INT64)kd; - - r = x + kd * negln2hiN + kd * negln2loN; - /* 2^(k/N) ~= scale * (1 + tail). */ - idx = 2 * (ki % (1 << 7)); - top = ki << (52 - 7); - tail = *(double*)&exp_T[idx]; - /* This is only a valid scale when -1023*N < k < 1024*N. */ - sbits = exp_T[idx + 1] + top; - /* exp(x) = 2^(k/N) * exp(r) ~= scale + scale * (tail + exp(r) - 1). */ - /* Evaluation is optimized assuming superscalar pipelined execution. */ - r2 = r * r; - /* Without fma the worst case error is 0.25/N ulp larger. */ - /* Worst case error is less than 0.5+1.11/N+(abs poly error * 2^53) ulp. */ - tmp = tail + r + r2 * (C[0] + r * C[1]) + r2 * r2 * (C[2] + r * C[3]); - if (abstop == 0) { - /* Handle cases that may overflow or underflow when computing the result that - is scale*(1+TMP) without intermediate rounding. The bit representation of - scale is in SBITS, however it has a computed exponent that may have - overflown into the sign bit so that needs to be adjusted before using it as - a double. (int32_t)KI is the k used in the argument reduction and exponent - adjustment of scale, positive k here means the result may overflow and - negative k means the result may underflow. */ - double scale, y; - - if ((ki & 0x80000000) == 0) { - /* k > 0, the exponent of scale might have overflowed by <= 460. */ - sbits -= 1009ull << 52; - scale = *(double*)&sbits; - y = 0x1p1009 * (scale + scale * tmp); - if (isinf(y)) - return math_error(_OVERFLOW, "exp", x, 0, y); - return y; - } - /* k < 0, need special care in the subnormal range. */ - sbits += 1022ull << 52; - scale = *(double*)&sbits; - y = scale + scale * tmp; - if (y < 1.0) { - /* Round y to the right precision before scaling it into the subnormal - range to avoid double rounding that can cause 0.5+E/2 ulp error where - E is the worst-case ulp error outside the subnormal range. So this - is only useful if the goal is better than 1 ulp worst-case error. */ - double hi, lo; - lo = scale - y + scale * tmp; - hi = 1.0 + y; - lo = 1.0 - hi + y + lo; - y = hi + lo - 1.0; - /* Avoid -0.0 with downward rounding. */ - if (y == 0.0) - y = 0.0; - /* The underflow exception needs to be signaled explicitly. */ - fp_barrier(fp_barrier(0x1p-1022) * 0x1p-1022); - y = 0x1p-1022 * y; - return math_error(_UNDERFLOW, "exp", x, 0, y); - } - y = 0x1p-1022 * y; - return y; - } - scale = *(double*)&sbits; - /* Note: tmp == 0 or |tmp| > 2^-200 and scale > 2^-739, so there - is no spurious underflow here even without fma. */ - return scale + scale * tmp; + if (isnan( x )) return math_error(_DOMAIN, "exp", x, 0, 1.0 + x); + return exp( x ); } +#endif
static BOOL sqrt_validate( double *x, BOOL update_sw ) { diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 8bf1c87d73c..aaca212c63c 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -1282,7 +1282,7 @@ @ cdecl -arch=win64 difftime(long long) _difftime64 @ cdecl -ret64 div(long long) @ cdecl exit(long) -@ cdecl exp(double) +@ cdecl exp(double) MSVCRT_exp @ cdecl -arch=!i386 expf(float) @ cdecl fabs(double) @ cdecl -arch=arm,arm64 fabsf(float) diff --git a/libs/musl/src/math/exp.c b/libs/musl/src/math/exp.c index cb5c077ee37..db67213b7d3 100644 --- a/libs/musl/src/math/exp.c +++ b/libs/musl/src/math/exp.c @@ -28,7 +28,7 @@ a double. (int32_t)KI is the k used in the argument reduction and exponent adjustment of scale, positive k here means the result may overflow and negative k means the result may underflow. */ -static inline double specialcase(double_t tmp, uint64_t sbits, uint64_t ki) +static inline double specialcase(double x, double_t tmp, uint64_t sbits, uint64_t ki) { double_t scale, y;
@@ -37,6 +37,8 @@ static inline double specialcase(double_t tmp, uint64_t sbits, uint64_t ki) sbits -= 1009ull << 52; scale = asdouble(sbits); y = 0x1p1009 * (scale + scale * tmp); + if (isinf(y)) + return math_error(_OVERFLOW, "exp", x, 0, y); return eval_as_double(y); } /* k < 0, need special care in the subnormal range. */ @@ -58,6 +60,8 @@ static inline double specialcase(double_t tmp, uint64_t sbits, uint64_t ki) y = 0.0; /* The underflow exception needs to be signaled explicitly. */ fp_force_eval(fp_barrier(0x1p-1022) * 0x1p-1022); + y = 0x1p-1022 * y; + return math_error(_UNDERFLOW, "exp", x, 0, y); } y = 0x1p-1022 * y; return eval_as_double(y); @@ -87,9 +91,9 @@ double __cdecl exp(double x) if (abstop >= top12(INFINITY)) return 1.0 + x; if (asuint64(x) >> 63) - return __math_uflow(0); + return math_error(_UNDERFLOW, "exp", x, 0, fp_barrier(DBL_MIN) * DBL_MIN); else - return __math_oflow(0); + return math_error(_OVERFLOW, "exp", x, 0, fp_barrier(DBL_MAX) * DBL_MAX); } /* Large x is special cased below. */ abstop = 0; @@ -98,20 +102,8 @@ double __cdecl exp(double x) /* exp(x) = 2^(k/N) * exp(r), with exp(r) in [2^(-1/2N),2^(1/2N)]. */ /* x = ln2/N*k + r, with int k and r in [-ln2/2N, ln2/2N]. */ z = InvLn2N * x; -#if TOINT_INTRINSICS - kd = roundtoint(z); - ki = converttoint(z); -#elif EXP_USE_TOINT_NARROW - /* z - kd is in [-0.5-2^-16, 0.5] in all rounding modes. */ - kd = eval_as_double(z + Shift); - ki = asuint64(kd) >> 16; - kd = (double_t)(int32_t)ki; -#else - /* z - kd is in [-1, 1] in non-nearest rounding modes. */ - kd = eval_as_double(z + Shift); - ki = asuint64(kd); - kd -= Shift; -#endif + kd = round(z); + ki = (int64_t)kd; r = x + kd * NegLn2hiN + kd * NegLn2loN; /* 2^(k/N) ~= scale * (1 + tail). */ idx = 2 * (ki % N); @@ -126,7 +118,7 @@ double __cdecl exp(double x) /* Worst case error is less than 0.5+1.11/N+(abs poly error * 2^53) ulp. */ tmp = tail + r + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5); if (predict_false(abstop == 0)) - return specialcase(tmp, sbits, ki); + return specialcase(x, tmp, sbits, ki); scale = asdouble(sbits); /* Note: tmp == 0 or |tmp| > 2^-200 and scale > 2^-739, so there is no spurious underflow here even without fma. */
From: Alexandre Julliard julliard@winehq.org
--- dlls/msvcrt/math.c | 73 --------------------------------------- libs/musl/src/math/acos.c | 3 +- 2 files changed, 2 insertions(+), 74 deletions(-)
diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index ba89c8446ba..32ee44fa246 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -443,79 +443,6 @@ float CDECL tanhf( float x )
#endif
-/********************************************************************* - * acos (MSVCRT.@) - * - * Copied from musl: src/math/acos.c - */ -static double acos_R(double z) -{ - static const double pS0 = 1.66666666666666657415e-01, - pS1 = -3.25565818622400915405e-01, - pS2 = 2.01212532134862925881e-01, - pS3 = -4.00555345006794114027e-02, - pS4 = 7.91534994289814532176e-04, - pS5 = 3.47933107596021167570e-05, - qS1 = -2.40339491173441421878e+00, - qS2 = 2.02094576023350569471e+00, - qS3 = -6.88283971605453293030e-01, - qS4 = 7.70381505559019352791e-02; - - double p, q; - p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5))))); - q = 1.0 + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4))); - return p/q; -} - -double CDECL acos( double x ) -{ - static const double pio2_hi = 1.57079632679489655800e+00, - pio2_lo = 6.12323399573676603587e-17; - - double z, w, s, c, df; - unsigned int hx, ix; - ULONGLONG llx; - - hx = *(ULONGLONG*)&x >> 32; - ix = hx & 0x7fffffff; - /* |x| >= 1 or nan */ - if (ix >= 0x3ff00000) { - unsigned int lx; - - lx = *(ULONGLONG*)&x; - if (((ix - 0x3ff00000) | lx) == 0) { - /* acos(1)=0, acos(-1)=pi */ - if (hx >> 31) - return 2 * pio2_hi + 7.5231638452626401e-37; - return 0; - } - if (isnan(x)) return x; - return math_error(_DOMAIN, "acos", x, 0, 0 / (x - x)); - } - /* |x| < 0.5 */ - if (ix < 0x3fe00000) { - if (ix <= 0x3c600000) /* |x| < 2**-57 */ - return pio2_hi + 7.5231638452626401e-37; - return pio2_hi - (x - (pio2_lo - x * acos_R(x * x))); - } - /* x < -0.5 */ - if (hx >> 31) { - z = (1.0 + x) * 0.5; - s = sqrt(z); - w = acos_R(z) * s - pio2_lo; - return 2 * (pio2_hi - (s + w)); - } - /* x > 0.5 */ - z = (1.0 - x) * 0.5; - s = sqrt(z); - df = s; - llx = (*(ULONGLONG*)&df >> 32) << 32; - df = *(double*)&llx; - c = (z - df * df) / (s + df); - w = acos_R(z) * s + c; - return 2 * (df + w); -} - /********************************************************************* * asin (MSVCRT.@) * diff --git a/libs/musl/src/math/acos.c b/libs/musl/src/math/acos.c index 950fe8e816c..405599e3bbd 100644 --- a/libs/musl/src/math/acos.c +++ b/libs/musl/src/math/acos.c @@ -75,7 +75,8 @@ double __cdecl acos(double x) return 2*pio2_hi + 0x1p-120f; return 0; } - return 0/(x-x); + if (isnan(x)) return x; + return math_error(_DOMAIN, "acos", x, 0, 0 / (x - x)); } /* |x| < 0.5 */ if (ix < 0x3fe00000) {
From: Alexandre Julliard julliard@winehq.org
--- dlls/crtdll/crtdll.spec | 2 +- dlls/msvcr100/msvcr100.spec | 2 +- dlls/msvcr110/msvcr110.spec | 2 +- dlls/msvcr120/msvcr120.spec | 2 +- dlls/msvcr70/msvcr70.spec | 2 +- dlls/msvcr71/msvcr71.spec | 2 +- dlls/msvcr80/msvcr80.spec | 2 +- dlls/msvcr90/msvcr90.spec | 2 +- dlls/msvcrt/math.c | 92 ++++++------------------------------- dlls/msvcrt/msvcrt.spec | 2 +- dlls/msvcrtd/msvcrtd.spec | 2 +- dlls/ucrtbase/ucrtbase.spec | 4 +- libs/musl/src/math/asin.c | 2 +- 13 files changed, 27 insertions(+), 91 deletions(-)
diff --git a/dlls/crtdll/crtdll.spec b/dlls/crtdll/crtdll.spec index 0e863362f77..b870eef8845 100644 --- a/dlls/crtdll/crtdll.spec +++ b/dlls/crtdll/crtdll.spec @@ -346,7 +346,7 @@ @ cdecl abs(long) @ cdecl acos(double) @ cdecl asctime(ptr) -@ cdecl asin(double) +@ cdecl asin(double) MSVCRT_asin @ cdecl atan(double) @ cdecl atan2(double double) @ cdecl -private atexit(ptr) MSVCRT_atexit diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index abae3f4b301..16ece69f1a4 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -1630,7 +1630,7 @@ @ cdecl -arch=!i386 acosf(float) @ cdecl asctime(ptr) @ cdecl asctime_s(ptr long ptr) -@ cdecl asin(double) +@ cdecl asin(double) MSVCRT_asin @ cdecl -arch=!i386 asinf(float) @ cdecl atan(double) @ cdecl -arch=!i386 atanf(float) diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec index e83ce328928..d4d696f512e 100644 --- a/dlls/msvcr110/msvcr110.spec +++ b/dlls/msvcr110/msvcr110.spec @@ -1987,7 +1987,7 @@ @ cdecl -arch=!i386 acosf(float) @ cdecl asctime(ptr) @ cdecl asctime_s(ptr long ptr) -@ cdecl asin(double) +@ cdecl asin(double) MSVCRT_asin @ cdecl -arch=!i386 asinf(float) @ cdecl atan(double) @ cdecl -arch=!i386 atanf(float) diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index ec1fd48dce5..33bd6efb73e 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -2017,7 +2017,7 @@ @ cdecl acoshl(double) acosh @ cdecl asctime(ptr) @ cdecl asctime_s(ptr long ptr) -@ cdecl asin(double) +@ cdecl asin(double) MSVCRT_asin @ cdecl -arch=!i386 asinf(float) @ cdecl asinh(double) @ cdecl asinhf(float) diff --git a/dlls/msvcr70/msvcr70.spec b/dlls/msvcr70/msvcr70.spec index 3300cf36bf3..cf2a57c5578 100644 --- a/dlls/msvcr70/msvcr70.spec +++ b/dlls/msvcr70/msvcr70.spec @@ -688,7 +688,7 @@ @ cdecl abs(long) @ cdecl acos(double) @ cdecl asctime(ptr) -@ cdecl asin(double) +@ cdecl asin(double) MSVCRT_asin @ cdecl atan(double) @ cdecl atan2(double double) @ cdecl -private atexit(ptr) MSVCRT_atexit # not imported to avoid conflicts with Mingw diff --git a/dlls/msvcr71/msvcr71.spec b/dlls/msvcr71/msvcr71.spec index 5b68d3217af..1ef2ec942e4 100644 --- a/dlls/msvcr71/msvcr71.spec +++ b/dlls/msvcr71/msvcr71.spec @@ -684,7 +684,7 @@ @ cdecl abs(long) @ cdecl acos(double) @ cdecl asctime(ptr) -@ cdecl asin(double) +@ cdecl asin(double) MSVCRT_asin @ cdecl atan(double) @ cdecl atan2(double double) @ cdecl -private atexit(ptr) MSVCRT_atexit # not imported to avoid conflicts with Mingw diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index 7c7c2f8bcdb..88c4a32d52f 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -1313,7 +1313,7 @@ @ cdecl -arch=!i386 acosf(float) @ cdecl asctime(ptr) @ cdecl asctime_s(ptr long ptr) -@ cdecl asin(double) +@ cdecl asin(double) MSVCRT_asin @ cdecl -arch=!i386 asinf(float) @ cdecl atan(double) @ cdecl -arch=!i386 atanf(float) diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index c1e4a406265..bd5b3126f30 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -1285,7 +1285,7 @@ @ cdecl -arch=!i386 acosf(float) @ cdecl asctime(ptr) @ cdecl asctime_s(ptr long ptr) -@ cdecl asin(double) +@ cdecl asin(double) MSVCRT_asin @ cdecl atan(double) @ cdecl atan2(double double) @ cdecl -arch=!i386 asinf(float) diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index 32ee44fa246..69dfca332af 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -445,29 +445,7 @@ float CDECL tanhf( float x )
/********************************************************************* * asin (MSVCRT.@) - * - * Copied from musl: src/math/asin.c */ -static double asin_R(double z) -{ - /* coefficients for R(x^2) */ - static const double pS0 = 1.66666666666666657415e-01, - pS1 = -3.25565818622400915405e-01, - pS2 = 2.01212532134862925881e-01, - pS3 = -4.00555345006794114027e-02, - pS4 = 7.91534994289814532176e-04, - pS5 = 3.47933107596021167570e-05, - qS1 = -2.40339491173441421878e+00, - qS2 = 2.02094576023350569471e+00, - qS3 = -6.88283971605453293030e-01, - qS4 = 7.70381505559019352791e-02; - - double p, q; - p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5))))); - q = 1.0 + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4))); - return p / q; -} - #ifdef __i386__ double CDECL x87_asin(double); __ASM_GLOBAL_FUNC( x87_asin, @@ -485,70 +463,28 @@ __ASM_GLOBAL_FUNC( x87_asin, "ret" ) #endif
-double CDECL asin( double x ) +double CDECL MSVCRT_asin( double x ) { - static const double pio2_hi = 1.57079632679489655800e+00, - pio2_lo = 6.12323399573676603587e-17; - - double z, r, s; - unsigned int hx, ix; - ULONGLONG llx; #ifdef __i386__ unsigned int x87_cw, sse2_cw; -#endif + unsigned int hx = *(ULONGLONG*)&x >> 32; + unsigned int ix = hx & 0x7fffffff;
- hx = *(ULONGLONG*)&x >> 32; - ix = hx & 0x7fffffff; - /* |x| >= 1 or nan */ - if (ix >= 0x3ff00000) { - unsigned int lx; - lx = *(ULONGLONG*)&x; - if (((ix - 0x3ff00000) | lx) == 0) - /* asin(1) = +-pi/2 with inexact */ - return x * pio2_hi + 7.5231638452626401e-37; - if (isnan(x)) - { -#ifdef __i386__ - return math_error(_DOMAIN, "asin", x, 0, x); -#else - return x; -#endif - } - return math_error(_DOMAIN, "asin", x, 0, 0 / (x - x)); - } + if (isnan(x)) return math_error(_DOMAIN, "asin", x, 0, x);
-#ifdef __i386__ - __control87_2(0, 0, &x87_cw, &sse2_cw); - if (!sse2_enabled || (x87_cw & _MCW_EM) != _MCW_EM + /* |x| < 1 */ + if (ix < 0x3ff00000) + { + __control87_2(0, 0, &x87_cw, &sse2_cw); + if (!sse2_enabled || (x87_cw & _MCW_EM) != _MCW_EM || (sse2_cw & (_MCW_EM | _MCW_RC)) != _MCW_EM) - return x87_asin(x); + return x87_asin(x); + } +#else + if (isnan(x)) return x; #endif
- /* |x| < 0.5 */ - if (ix < 0x3fe00000) { - /* if 0x1p-1022 <= |x| < 0x1p-26, avoid raising underflow */ - if (ix < 0x3e500000 && ix >= 0x00100000) - return x; - return x + x * asin_R(x * x); - } - /* 1 > |x| >= 0.5 */ - z = (1 - fabs(x)) * 0.5; - s = sqrt(z); - r = asin_R(z); - if (ix >= 0x3fef3333) { /* if |x| > 0.975 */ - x = pio2_hi - (2 * (s + s * r) - pio2_lo); - } else { - double f, c; - /* f+c = sqrt(z) */ - f = s; - llx = (*(ULONGLONG*)&f >> 32) << 32; - f = *(double*)&llx; - c = (z - f * f) / (s + f); - x = 0.5 * pio2_hi - (2 * s * r - (pio2_lo - 2 * c) - (0.5 * pio2_hi - 2 * f)); - } - if (hx >> 31) - return -x; - return x; + return asin( x ); }
/********************************************************************* diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index aaca212c63c..2d3e27be81a 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -1253,7 +1253,7 @@ @ cdecl -arch=!i386 acosf(float) @ cdecl asctime(ptr) @ cdecl asctime_s(ptr long ptr) -@ cdecl asin(double) +@ cdecl asin(double) MSVCRT_asin @ cdecl atan(double) @ cdecl atan2(double double) @ cdecl -arch=!i386 asinf(float) diff --git a/dlls/msvcrtd/msvcrtd.spec b/dlls/msvcrtd/msvcrtd.spec index 2c3f4912a03..09c0a947683 100644 --- a/dlls/msvcrtd/msvcrtd.spec +++ b/dlls/msvcrtd/msvcrtd.spec @@ -641,7 +641,7 @@ @ cdecl abs(long) @ cdecl acos(double) @ cdecl asctime(ptr) -@ cdecl asin(double) +@ cdecl asin(double) MSVCRT_asin @ cdecl atan(double) @ cdecl atan2(double double) @ cdecl -private atexit(ptr) MSVCRT_atexit diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index a05023b9f3e..45d883d410c 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -1567,7 +1567,7 @@ @ cdecl _o_acoshl(double) acosh @ cdecl _o_asctime(ptr) asctime @ cdecl _o_asctime_s(ptr long ptr) asctime_s -@ cdecl _o_asin(double) asin +@ cdecl _o_asin(double) MSVCRT_asin @ cdecl -arch=!i386 _o_asinf(float) asinf @ cdecl _o_asinh(double) asinh @ cdecl _o_asinhf(float) asinhf @@ -2161,7 +2161,7 @@ @ cdecl acoshl(double) acosh @ cdecl asctime(ptr) @ cdecl asctime_s(ptr long ptr) -@ cdecl asin(double) +@ cdecl asin(double) MSVCRT_asin @ cdecl -arch=!i386 asinf(float) @ cdecl asinh(double) @ cdecl asinhf(float) diff --git a/libs/musl/src/math/asin.c b/libs/musl/src/math/asin.c index 0ff68c07899..0686522f0f7 100644 --- a/libs/musl/src/math/asin.c +++ b/libs/musl/src/math/asin.c @@ -78,7 +78,7 @@ double __cdecl asin(double x) if ((ix-0x3ff00000 | lx) == 0) /* asin(1) = +-pi/2 with inexact */ return x*pio2_hi + 0x1p-120f; - return 0/(x-x); + return math_error(_DOMAIN, "asin", x, 0, 0 / (x - x)); } /* |x| < 0.5 */ if (ix < 0x3fe00000) {
From: Alexandre Julliard julliard@winehq.org
--- dlls/msvcrt/math.c | 93 ++++------------------------------------- dlls/msvcrt/msvcrt.spec | 2 +- 2 files changed, 9 insertions(+), 86 deletions(-)
diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index 69dfca332af..2a523b589ae 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -78,11 +78,13 @@ void msvcrt_init_math( void *module ) }
/* Copied from musl: src/internal/libm.h */ +#if !defined(__i386__) || _MSVCR_VER>=120 static inline float fp_barrierf(float x) { volatile float y = x; return y; } +#endif
static inline double fp_barrier(double x) { @@ -489,93 +491,14 @@ double CDECL MSVCRT_asin( double x )
/********************************************************************* * atan (MSVCRT.@) - * - * Copied from musl: src/math/atan.c - */ -double CDECL atan( double x ) -{ - static const double atanhi[] = { - 4.63647609000806093515e-01, - 7.85398163397448278999e-01, - 9.82793723247329054082e-01, - 1.57079632679489655800e+00, - }; - static const double atanlo[] = { - 2.26987774529616870924e-17, - 3.06161699786838301793e-17, - 1.39033110312309984516e-17, - 6.12323399573676603587e-17, - }; - static const double aT[] = { - 3.33333333333329318027e-01, - -1.99999999998764832476e-01, - 1.42857142725034663711e-01, - -1.11111104054623557880e-01, - 9.09088713343650656196e-02, - -7.69187620504482999495e-02, - 6.66107313738753120669e-02, - -5.83357013379057348645e-02, - 4.97687799461593236017e-02, - -3.65315727442169155270e-02, - 1.62858201153657823623e-02, - }; - - double w, s1, s2, z; - unsigned int ix, sign; - int id; - -#if _MSVCR_VER == 0 + */ +#if _MSVCR_VER == 0 /* other versions call atan() directly */ +double CDECL MSVCRT_atan( double x ) +{ if (isnan(x)) return math_error(_DOMAIN, "atan", x, 0, x); -#endif - - ix = *(ULONGLONG*)&x >> 32; - sign = ix >> 31; - ix &= 0x7fffffff; - if (ix >= 0x44100000) { /* if |x| >= 2^66 */ - if (isnan(x)) - return x; - z = atanhi[3] + 7.5231638452626401e-37; - return sign ? -z : z; - } - if (ix < 0x3fdc0000) { /* |x| < 0.4375 */ - if (ix < 0x3e400000) { /* |x| < 2^-27 */ - if (ix < 0x00100000) - /* raise underflow for subnormal x */ - fp_barrierf((float)x); - return x; - } - id = -1; - } else { - x = fabs(x); - if (ix < 0x3ff30000) { /* |x| < 1.1875 */ - if (ix < 0x3fe60000) { /* 7/16 <= |x| < 11/16 */ - id = 0; - x = (2.0 * x - 1.0) / (2.0 + x); - } else { /* 11/16 <= |x| < 19/16 */ - id = 1; - x = (x - 1.0) / (x + 1.0); - } - } else { - if (ix < 0x40038000) { /* |x| < 2.4375 */ - id = 2; - x = (x - 1.5) / (1.0 + 1.5 * x); - } else { /* 2.4375 <= |x| < 2^66 */ - id = 3; - x = -1.0 / x; - } - } - } - /* end of argument reduction */ - z = x * x; - w = z * z; - /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ - s1 = z * (aT[0] + w * (aT[2] + w * (aT[4] + w * (aT[6] + w * (aT[8] + w * aT[10]))))); - s2 = w * (aT[1] + w * (aT[3] + w * (aT[5] + w * (aT[7] + w * aT[9])))); - if (id < 0) - return x - x * (s1 + s2); - z = atanhi[id] - (x * (s1 + s2) - atanlo[id] - x); - return sign ? -z : z; + return atan( x ); } +#endif
/********************************************************************* * exp (MSVCRT.@) diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 2d3e27be81a..c7facd39df1 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -1254,7 +1254,7 @@ @ cdecl asctime(ptr) @ cdecl asctime_s(ptr long ptr) @ cdecl asin(double) MSVCRT_asin -@ cdecl atan(double) +@ cdecl atan(double) MSVCRT_atan @ cdecl atan2(double double) @ cdecl -arch=!i386 asinf(float) @ cdecl -arch=!i386 atanf(float) MSVCRT_atanf
From: Alexandre Julliard julliard@winehq.org
--- dlls/msvcrt/math.c | 51 ---------------------------------------------- 1 file changed, 51 deletions(-)
diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index 2a523b589ae..ea72ca2f01c 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -3347,57 +3347,6 @@ int CDECL _fdpcomp(float x, float y) return _dpcomp(x, y); }
-/********************************************************************* - * asinh (MSVCR120.@) - * - * Copied from musl: src/math/asinh.c - */ -double CDECL asinh(double 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; -} - -/********************************************************************* - * asinhf (MSVCR120.@) - * - * Copied from musl: src/math/asinhf.c - */ -float CDECL asinhf(float x) -{ - UINT32 ux = *(UINT32*)&x; - UINT32 i = ux & 0x7fffffff; - int s = ux >> 31; - - /* |x| */ - x = *(float*)&i; - - if (i >= 0x3f800000 + (12 << 23))/* |x| >= 0x1p12 or inf or nan */ - x = logf(x) + 0.693147180559945309417232121458176568f; - else if (i >= 0x3f800000 + (1 << 23)) /* |x| >= 2 */ - x = logf(2 * x + 1 / (sqrtf(x * x + 1) + x)); - else if (i >= 0x3f800000 - (12 << 23)) /* |x| >= 0x1p-12 */ - x = log1pf(x + x * x / (sqrtf(x * x + 1) + 1)); - else /* |x| < 0x1p-12, raise inexact if x!=0 */ - fp_barrierf(x + 0x1p120f); - return s ? -x : x; -} - /********************************************************************* * acosh (MSVCR120.@) *
From: Alexandre Julliard julliard@winehq.org
--- dlls/msvcr120/msvcr120.spec | 6 +++--- dlls/msvcrt/math.c | 28 ++++------------------------ dlls/ucrtbase/ucrtbase.spec | 12 ++++++------ 3 files changed, 13 insertions(+), 33 deletions(-)
diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index 33bd6efb73e..f536aba9ba3 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -2012,9 +2012,9 @@ @ cdecl abs(long) @ cdecl acos(double) @ cdecl -arch=!i386 acosf(float) -@ cdecl acosh(double) -@ cdecl acoshf(float) -@ cdecl acoshl(double) acosh +@ cdecl acosh(double) MSVCRT_acosh +@ cdecl acoshf(float) MSVCRT_acoshf +@ cdecl acoshl(double) MSVCRT_acosh @ cdecl asctime(ptr) @ cdecl asctime_s(ptr long ptr) @ cdecl asin(double) MSVCRT_asin diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index ea72ca2f01c..4f95a4747a9 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -3349,50 +3349,30 @@ int CDECL _fdpcomp(float x, float y)
/********************************************************************* * acosh (MSVCR120.@) - * - * Copied from musl: src/math/acosh.c */ -double CDECL acosh(double x) +double CDECL MSVCRT_acosh(double x) { - int e = *(UINT64*)&x >> 52 & 0x7ff; - if (x < 1) { *_errno() = EDOM; feraiseexcept(FE_INVALID); return NAN; } - - if (e < 0x3ff + 1) /* |x| < 2, up to 2ulp error in [1,1.125] */ - return log1p(x - 1 + sqrt((x - 1) * (x - 1) + 2 * (x - 1))); - if (e < 0x3ff + 26) /* |x| < 0x1p26 */ - return log(2 * x - 1 / (x + sqrt(x * x - 1))); - /* |x| >= 0x1p26 or nan */ - return log(x) + 0.693147180559945309417232121458176568; + return acosh( x ); }
/********************************************************************* * acoshf (MSVCR120.@) - * - * Copied from musl: src/math/acoshf.c */ -float CDECL acoshf(float x) +float CDECL MSVCRT_acoshf(float x) { - UINT32 a = *(UINT32*)&x & 0x7fffffff; - if (x < 1) { *_errno() = EDOM; feraiseexcept(FE_INVALID); return NAN; } - - if (a < 0x3f800000 + (1 << 23)) /* |x| < 2, up to 2ulp error in [1,1.125] */ - return log1pf(x - 1 + sqrtf((x - 1) * (x - 1) + 2 * (x - 1))); - if (*(UINT32*)&x < 0x3f800000 + (12 << 23)) /* 2 <= x < 0x1p12 */ - return logf(2 * x - 1 / (x + sqrtf(x * x - 1))); - /* x >= 0x1p12 or x <= -2 or nan */ - return logf(x) + 0.693147180559945309417232121458176568f; + return acoshf( x ); }
/********************************************************************* diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index 45d883d410c..5bea04dad62 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -1562,9 +1562,9 @@ @ cdecl _o_abort() abort @ cdecl _o_acos(double) acos @ cdecl -arch=!i386 _o_acosf(float) acosf -@ cdecl _o_acosh(double) acosh -@ cdecl _o_acoshf(float) acoshf -@ cdecl _o_acoshl(double) acosh +@ cdecl _o_acosh(double) MSVCRT_acosh +@ cdecl _o_acoshf(float) MSVCRT_acoshf +@ cdecl _o_acoshl(double) MSVCRT_acosh @ cdecl _o_asctime(ptr) asctime @ cdecl _o_asctime_s(ptr long ptr) asctime_s @ cdecl _o_asin(double) MSVCRT_asin @@ -2156,9 +2156,9 @@ @ cdecl abs(long) @ cdecl acos(double) @ cdecl -arch=!i386 acosf(float) -@ cdecl acosh(double) -@ cdecl acoshf(float) -@ cdecl acoshl(double) acosh +@ cdecl acosh(double) MSVCRT_acosh +@ cdecl acoshf(float) MSVCRT_acoshf +@ cdecl acoshl(double) MSVCRT_acosh @ cdecl asctime(ptr) @ cdecl asctime_s(ptr long ptr) @ cdecl asin(double) MSVCRT_asin
From: Alexandre Julliard julliard@winehq.org
--- 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; }
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);
This merge request was approved by Piotr Caban.
@rbernon Do you have any comments on replacing the implementation of trigonometric functions? Would it make Wine's error profile on those functions deviate further from the one in msvcrt or ucrtbase?
On Mon Apr 10 16:32:13 2023 +0000, Jinoh Kang wrote:
@rbernon Do you have any comments on replacing the implementation of trigonometric functions? Would it make Wine's error profile on those functions deviate further from the one in msvcrt or ucrtbase?
This patch is not changing the code (it's just moving the code around). We were already using modified version of musl code to implement the functions.