Module: wine Branch: master Commit: 18fa9cf624467c4a3549c1fd9868104e6a49fde3 URL: https://source.winehq.org/git/wine.git/?a=commit;h=18fa9cf624467c4a3549c1fd9...
Author: Piotr Caban piotr@codeweavers.com Date: Thu Aug 6 16:59:29 2020 +0200
msvcrt: Import atanf from musl.
Signed-off-by: Piotr Caban piotr@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/msvcrt/math.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 3 deletions(-)
diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index 85565d2bf3..5fbb93ea16 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -330,12 +330,91 @@ float CDECL MSVCRT_asinf( float x )
/********************************************************************* * MSVCRT_atanf (MSVCRT.@) + * + * Copied from musl: src/math/atanf.c */ +static inline float fp_barrierf(float x) +{ + volatile float y = x; + return y; +} float CDECL MSVCRT_atanf( float x ) { - float ret = atanf(x); - if (!finitef(x)) return math_error(_DOMAIN, "atanf", x, 0, ret); - return ret; + 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 (MSVCRT__isnanf(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 (MSVCRT__isnanf(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; }
/*********************************************************************