131914882SAlex Richardson /*
231914882SAlex Richardson * Double-precision x^y function.
331914882SAlex Richardson *
431914882SAlex Richardson * Copyright (c) 2018-2020, Arm Limited.
5*072a4ba8SAndrew Turner * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception
631914882SAlex Richardson */
731914882SAlex Richardson
831914882SAlex Richardson #include <float.h>
931914882SAlex Richardson #include <math.h>
1031914882SAlex Richardson #include <stdint.h>
1131914882SAlex Richardson #include "math_config.h"
1231914882SAlex Richardson
1331914882SAlex Richardson /*
1431914882SAlex Richardson Worst-case error: 0.54 ULP (~= ulperr_exp + 1024*Ln2*relerr_log*2^53)
1531914882SAlex Richardson relerr_log: 1.3 * 2^-68 (Relative error of log, 1.5 * 2^-68 without fma)
1631914882SAlex Richardson ulperr_exp: 0.509 ULP (ULP error of exp, 0.511 ULP without fma)
1731914882SAlex Richardson */
1831914882SAlex Richardson
1931914882SAlex Richardson #define T __pow_log_data.tab
2031914882SAlex Richardson #define A __pow_log_data.poly
2131914882SAlex Richardson #define Ln2hi __pow_log_data.ln2hi
2231914882SAlex Richardson #define Ln2lo __pow_log_data.ln2lo
2331914882SAlex Richardson #define N (1 << POW_LOG_TABLE_BITS)
2431914882SAlex Richardson #define OFF 0x3fe6955500000000
2531914882SAlex Richardson
2631914882SAlex Richardson /* Top 12 bits of a double (sign and exponent bits). */
2731914882SAlex Richardson static inline uint32_t
top12(double x)2831914882SAlex Richardson top12 (double x)
2931914882SAlex Richardson {
3031914882SAlex Richardson return asuint64 (x) >> 52;
3131914882SAlex Richardson }
3231914882SAlex Richardson
3331914882SAlex Richardson /* Compute y+TAIL = log(x) where the rounded result is y and TAIL has about
3431914882SAlex Richardson additional 15 bits precision. IX is the bit representation of x, but
3531914882SAlex Richardson normalized in the subnormal range using the sign bit for the exponent. */
3631914882SAlex Richardson static inline double_t
log_inline(uint64_t ix,double_t * tail)3731914882SAlex Richardson log_inline (uint64_t ix, double_t *tail)
3831914882SAlex Richardson {
3931914882SAlex Richardson /* double_t for better performance on targets with FLT_EVAL_METHOD==2. */
4031914882SAlex Richardson double_t z, r, y, invc, logc, logctail, kd, hi, t1, t2, lo, lo1, lo2, p;
4131914882SAlex Richardson uint64_t iz, tmp;
4231914882SAlex Richardson int k, i;
4331914882SAlex Richardson
4431914882SAlex Richardson /* x = 2^k z; where z is in range [OFF,2*OFF) and exact.
4531914882SAlex Richardson The range is split into N subintervals.
4631914882SAlex Richardson The ith subinterval contains z and c is near its center. */
4731914882SAlex Richardson tmp = ix - OFF;
4831914882SAlex Richardson i = (tmp >> (52 - POW_LOG_TABLE_BITS)) % N;
4931914882SAlex Richardson k = (int64_t) tmp >> 52; /* arithmetic shift */
5031914882SAlex Richardson iz = ix - (tmp & 0xfffULL << 52);
5131914882SAlex Richardson z = asdouble (iz);
5231914882SAlex Richardson kd = (double_t) k;
5331914882SAlex Richardson
5431914882SAlex Richardson /* log(x) = k*Ln2 + log(c) + log1p(z/c-1). */
5531914882SAlex Richardson invc = T[i].invc;
5631914882SAlex Richardson logc = T[i].logc;
5731914882SAlex Richardson logctail = T[i].logctail;
5831914882SAlex Richardson
5931914882SAlex Richardson /* Note: 1/c is j/N or j/N/2 where j is an integer in [N,2N) and
6031914882SAlex Richardson |z/c - 1| < 1/N, so r = z/c - 1 is exactly representible. */
6131914882SAlex Richardson #if HAVE_FAST_FMA
6231914882SAlex Richardson r = fma (z, invc, -1.0);
6331914882SAlex Richardson #else
6431914882SAlex Richardson /* Split z such that rhi, rlo and rhi*rhi are exact and |rlo| <= |r|. */
6531914882SAlex Richardson double_t zhi = asdouble ((iz + (1ULL << 31)) & (-1ULL << 32));
6631914882SAlex Richardson double_t zlo = z - zhi;
6731914882SAlex Richardson double_t rhi = zhi * invc - 1.0;
6831914882SAlex Richardson double_t rlo = zlo * invc;
6931914882SAlex Richardson r = rhi + rlo;
7031914882SAlex Richardson #endif
7131914882SAlex Richardson
7231914882SAlex Richardson /* k*Ln2 + log(c) + r. */
7331914882SAlex Richardson t1 = kd * Ln2hi + logc;
7431914882SAlex Richardson t2 = t1 + r;
7531914882SAlex Richardson lo1 = kd * Ln2lo + logctail;
7631914882SAlex Richardson lo2 = t1 - t2 + r;
7731914882SAlex Richardson
7831914882SAlex Richardson /* Evaluation is optimized assuming superscalar pipelined execution. */
7931914882SAlex Richardson double_t ar, ar2, ar3, lo3, lo4;
8031914882SAlex Richardson ar = A[0] * r; /* A[0] = -0.5. */
8131914882SAlex Richardson ar2 = r * ar;
8231914882SAlex Richardson ar3 = r * ar2;
8331914882SAlex Richardson /* k*Ln2 + log(c) + r + A[0]*r*r. */
8431914882SAlex Richardson #if HAVE_FAST_FMA
8531914882SAlex Richardson hi = t2 + ar2;
8631914882SAlex Richardson lo3 = fma (ar, r, -ar2);
8731914882SAlex Richardson lo4 = t2 - hi + ar2;
8831914882SAlex Richardson #else
8931914882SAlex Richardson double_t arhi = A[0] * rhi;
9031914882SAlex Richardson double_t arhi2 = rhi * arhi;
9131914882SAlex Richardson hi = t2 + arhi2;
9231914882SAlex Richardson lo3 = rlo * (ar + arhi);
9331914882SAlex Richardson lo4 = t2 - hi + arhi2;
9431914882SAlex Richardson #endif
9531914882SAlex Richardson /* p = log1p(r) - r - A[0]*r*r. */
9631914882SAlex Richardson #if POW_LOG_POLY_ORDER == 8
9731914882SAlex Richardson p = (ar3
9831914882SAlex Richardson * (A[1] + r * A[2] + ar2 * (A[3] + r * A[4] + ar2 * (A[5] + r * A[6]))));
9931914882SAlex Richardson #endif
10031914882SAlex Richardson lo = lo1 + lo2 + lo3 + lo4 + p;
10131914882SAlex Richardson y = hi + lo;
10231914882SAlex Richardson *tail = hi - y + lo;
10331914882SAlex Richardson return y;
10431914882SAlex Richardson }
10531914882SAlex Richardson
10631914882SAlex Richardson #undef N
10731914882SAlex Richardson #undef T
10831914882SAlex Richardson #define N (1 << EXP_TABLE_BITS)
10931914882SAlex Richardson #define InvLn2N __exp_data.invln2N
11031914882SAlex Richardson #define NegLn2hiN __exp_data.negln2hiN
11131914882SAlex Richardson #define NegLn2loN __exp_data.negln2loN
11231914882SAlex Richardson #define Shift __exp_data.shift
11331914882SAlex Richardson #define T __exp_data.tab
11431914882SAlex Richardson #define C2 __exp_data.poly[5 - EXP_POLY_ORDER]
11531914882SAlex Richardson #define C3 __exp_data.poly[6 - EXP_POLY_ORDER]
11631914882SAlex Richardson #define C4 __exp_data.poly[7 - EXP_POLY_ORDER]
11731914882SAlex Richardson #define C5 __exp_data.poly[8 - EXP_POLY_ORDER]
11831914882SAlex Richardson #define C6 __exp_data.poly[9 - EXP_POLY_ORDER]
11931914882SAlex Richardson
12031914882SAlex Richardson /* Handle cases that may overflow or underflow when computing the result that
12131914882SAlex Richardson is scale*(1+TMP) without intermediate rounding. The bit representation of
12231914882SAlex Richardson scale is in SBITS, however it has a computed exponent that may have
12331914882SAlex Richardson overflown into the sign bit so that needs to be adjusted before using it as
12431914882SAlex Richardson a double. (int32_t)KI is the k used in the argument reduction and exponent
12531914882SAlex Richardson adjustment of scale, positive k here means the result may overflow and
12631914882SAlex Richardson negative k means the result may underflow. */
12731914882SAlex Richardson static inline double
specialcase(double_t tmp,uint64_t sbits,uint64_t ki)12831914882SAlex Richardson specialcase (double_t tmp, uint64_t sbits, uint64_t ki)
12931914882SAlex Richardson {
13031914882SAlex Richardson double_t scale, y;
13131914882SAlex Richardson
13231914882SAlex Richardson if ((ki & 0x80000000) == 0)
13331914882SAlex Richardson {
13431914882SAlex Richardson /* k > 0, the exponent of scale might have overflowed by <= 460. */
13531914882SAlex Richardson sbits -= 1009ull << 52;
13631914882SAlex Richardson scale = asdouble (sbits);
13731914882SAlex Richardson y = 0x1p1009 * (scale + scale * tmp);
13831914882SAlex Richardson return check_oflow (eval_as_double (y));
13931914882SAlex Richardson }
14031914882SAlex Richardson /* k < 0, need special care in the subnormal range. */
14131914882SAlex Richardson sbits += 1022ull << 52;
14231914882SAlex Richardson /* Note: sbits is signed scale. */
14331914882SAlex Richardson scale = asdouble (sbits);
14431914882SAlex Richardson y = scale + scale * tmp;
14531914882SAlex Richardson if (fabs (y) < 1.0)
14631914882SAlex Richardson {
14731914882SAlex Richardson /* Round y to the right precision before scaling it into the subnormal
14831914882SAlex Richardson range to avoid double rounding that can cause 0.5+E/2 ulp error where
14931914882SAlex Richardson E is the worst-case ulp error outside the subnormal range. So this
15031914882SAlex Richardson is only useful if the goal is better than 1 ulp worst-case error. */
15131914882SAlex Richardson double_t hi, lo, one = 1.0;
15231914882SAlex Richardson if (y < 0.0)
15331914882SAlex Richardson one = -1.0;
15431914882SAlex Richardson lo = scale - y + scale * tmp;
15531914882SAlex Richardson hi = one + y;
15631914882SAlex Richardson lo = one - hi + y + lo;
15731914882SAlex Richardson y = eval_as_double (hi + lo) - one;
15831914882SAlex Richardson /* Fix the sign of 0. */
15931914882SAlex Richardson if (y == 0.0)
16031914882SAlex Richardson y = asdouble (sbits & 0x8000000000000000);
16131914882SAlex Richardson /* The underflow exception needs to be signaled explicitly. */
16231914882SAlex Richardson force_eval_double (opt_barrier_double (0x1p-1022) * 0x1p-1022);
16331914882SAlex Richardson }
16431914882SAlex Richardson y = 0x1p-1022 * y;
16531914882SAlex Richardson return check_uflow (eval_as_double (y));
16631914882SAlex Richardson }
16731914882SAlex Richardson
16831914882SAlex Richardson #define SIGN_BIAS (0x800 << EXP_TABLE_BITS)
16931914882SAlex Richardson
17031914882SAlex Richardson /* Computes sign*exp(x+xtail) where |xtail| < 2^-8/N and |xtail| <= |x|.
17131914882SAlex Richardson The sign_bias argument is SIGN_BIAS or 0 and sets the sign to -1 or 1. */
17231914882SAlex Richardson static inline double
exp_inline(double_t x,double_t xtail,uint32_t sign_bias)17331914882SAlex Richardson exp_inline (double_t x, double_t xtail, uint32_t sign_bias)
17431914882SAlex Richardson {
17531914882SAlex Richardson uint32_t abstop;
17631914882SAlex Richardson uint64_t ki, idx, top, sbits;
17731914882SAlex Richardson /* double_t for better performance on targets with FLT_EVAL_METHOD==2. */
17831914882SAlex Richardson double_t kd, z, r, r2, scale, tail, tmp;
17931914882SAlex Richardson
18031914882SAlex Richardson abstop = top12 (x) & 0x7ff;
18131914882SAlex Richardson if (unlikely (abstop - top12 (0x1p-54) >= top12 (512.0) - top12 (0x1p-54)))
18231914882SAlex Richardson {
18331914882SAlex Richardson if (abstop - top12 (0x1p-54) >= 0x80000000)
18431914882SAlex Richardson {
18531914882SAlex Richardson /* Avoid spurious underflow for tiny x. */
18631914882SAlex Richardson /* Note: 0 is common input. */
18731914882SAlex Richardson double_t one = WANT_ROUNDING ? 1.0 + x : 1.0;
18831914882SAlex Richardson return sign_bias ? -one : one;
18931914882SAlex Richardson }
19031914882SAlex Richardson if (abstop >= top12 (1024.0))
19131914882SAlex Richardson {
19231914882SAlex Richardson /* Note: inf and nan are already handled. */
19331914882SAlex Richardson if (asuint64 (x) >> 63)
19431914882SAlex Richardson return __math_uflow (sign_bias);
19531914882SAlex Richardson else
19631914882SAlex Richardson return __math_oflow (sign_bias);
19731914882SAlex Richardson }
19831914882SAlex Richardson /* Large x is special cased below. */
19931914882SAlex Richardson abstop = 0;
20031914882SAlex Richardson }
20131914882SAlex Richardson
20231914882SAlex Richardson /* exp(x) = 2^(k/N) * exp(r), with exp(r) in [2^(-1/2N),2^(1/2N)]. */
20331914882SAlex Richardson /* x = ln2/N*k + r, with int k and r in [-ln2/2N, ln2/2N]. */
20431914882SAlex Richardson z = InvLn2N * x;
20531914882SAlex Richardson #if TOINT_INTRINSICS
20631914882SAlex Richardson kd = roundtoint (z);
20731914882SAlex Richardson ki = converttoint (z);
20831914882SAlex Richardson #elif EXP_USE_TOINT_NARROW
20931914882SAlex Richardson /* z - kd is in [-0.5-2^-16, 0.5] in all rounding modes. */
21031914882SAlex Richardson kd = eval_as_double (z + Shift);
21131914882SAlex Richardson ki = asuint64 (kd) >> 16;
21231914882SAlex Richardson kd = (double_t) (int32_t) ki;
21331914882SAlex Richardson #else
21431914882SAlex Richardson /* z - kd is in [-1, 1] in non-nearest rounding modes. */
21531914882SAlex Richardson kd = eval_as_double (z + Shift);
21631914882SAlex Richardson ki = asuint64 (kd);
21731914882SAlex Richardson kd -= Shift;
21831914882SAlex Richardson #endif
21931914882SAlex Richardson r = x + kd * NegLn2hiN + kd * NegLn2loN;
22031914882SAlex Richardson /* The code assumes 2^-200 < |xtail| < 2^-8/N. */
22131914882SAlex Richardson r += xtail;
22231914882SAlex Richardson /* 2^(k/N) ~= scale * (1 + tail). */
22331914882SAlex Richardson idx = 2 * (ki % N);
22431914882SAlex Richardson top = (ki + sign_bias) << (52 - EXP_TABLE_BITS);
22531914882SAlex Richardson tail = asdouble (T[idx]);
22631914882SAlex Richardson /* This is only a valid scale when -1023*N < k < 1024*N. */
22731914882SAlex Richardson sbits = T[idx + 1] + top;
22831914882SAlex Richardson /* exp(x) = 2^(k/N) * exp(r) ~= scale + scale * (tail + exp(r) - 1). */
22931914882SAlex Richardson /* Evaluation is optimized assuming superscalar pipelined execution. */
23031914882SAlex Richardson r2 = r * r;
23131914882SAlex Richardson /* Without fma the worst case error is 0.25/N ulp larger. */
23231914882SAlex Richardson /* Worst case error is less than 0.5+1.11/N+(abs poly error * 2^53) ulp. */
23331914882SAlex Richardson #if EXP_POLY_ORDER == 4
23431914882SAlex Richardson tmp = tail + r + r2 * C2 + r * r2 * (C3 + r * C4);
23531914882SAlex Richardson #elif EXP_POLY_ORDER == 5
23631914882SAlex Richardson tmp = tail + r + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5);
23731914882SAlex Richardson #elif EXP_POLY_ORDER == 6
23831914882SAlex Richardson tmp = tail + r + r2 * (0.5 + r * C3) + r2 * r2 * (C4 + r * C5 + r2 * C6);
23931914882SAlex Richardson #endif
24031914882SAlex Richardson if (unlikely (abstop == 0))
24131914882SAlex Richardson return specialcase (tmp, sbits, ki);
24231914882SAlex Richardson scale = asdouble (sbits);
24331914882SAlex Richardson /* Note: tmp == 0 or |tmp| > 2^-200 and scale > 2^-739, so there
24431914882SAlex Richardson is no spurious underflow here even without fma. */
24531914882SAlex Richardson return eval_as_double (scale + scale * tmp);
24631914882SAlex Richardson }
24731914882SAlex Richardson
24831914882SAlex Richardson /* Returns 0 if not int, 1 if odd int, 2 if even int. The argument is
24931914882SAlex Richardson the bit representation of a non-zero finite floating-point value. */
25031914882SAlex Richardson static inline int
checkint(uint64_t iy)25131914882SAlex Richardson checkint (uint64_t iy)
25231914882SAlex Richardson {
25331914882SAlex Richardson int e = iy >> 52 & 0x7ff;
25431914882SAlex Richardson if (e < 0x3ff)
25531914882SAlex Richardson return 0;
25631914882SAlex Richardson if (e > 0x3ff + 52)
25731914882SAlex Richardson return 2;
25831914882SAlex Richardson if (iy & ((1ULL << (0x3ff + 52 - e)) - 1))
25931914882SAlex Richardson return 0;
26031914882SAlex Richardson if (iy & (1ULL << (0x3ff + 52 - e)))
26131914882SAlex Richardson return 1;
26231914882SAlex Richardson return 2;
26331914882SAlex Richardson }
26431914882SAlex Richardson
26531914882SAlex Richardson /* Returns 1 if input is the bit representation of 0, infinity or nan. */
26631914882SAlex Richardson static inline int
zeroinfnan(uint64_t i)26731914882SAlex Richardson zeroinfnan (uint64_t i)
26831914882SAlex Richardson {
26931914882SAlex Richardson return 2 * i - 1 >= 2 * asuint64 (INFINITY) - 1;
27031914882SAlex Richardson }
27131914882SAlex Richardson
27231914882SAlex Richardson double
pow(double x,double y)27331914882SAlex Richardson pow (double x, double y)
27431914882SAlex Richardson {
27531914882SAlex Richardson uint32_t sign_bias = 0;
27631914882SAlex Richardson uint64_t ix, iy;
27731914882SAlex Richardson uint32_t topx, topy;
27831914882SAlex Richardson
27931914882SAlex Richardson ix = asuint64 (x);
28031914882SAlex Richardson iy = asuint64 (y);
28131914882SAlex Richardson topx = top12 (x);
28231914882SAlex Richardson topy = top12 (y);
28331914882SAlex Richardson if (unlikely (topx - 0x001 >= 0x7ff - 0x001
28431914882SAlex Richardson || (topy & 0x7ff) - 0x3be >= 0x43e - 0x3be))
28531914882SAlex Richardson {
28631914882SAlex Richardson /* Note: if |y| > 1075 * ln2 * 2^53 ~= 0x1.749p62 then pow(x,y) = inf/0
28731914882SAlex Richardson and if |y| < 2^-54 / 1075 ~= 0x1.e7b6p-65 then pow(x,y) = +-1. */
28831914882SAlex Richardson /* Special cases: (x < 0x1p-126 or inf or nan) or
28931914882SAlex Richardson (|y| < 0x1p-65 or |y| >= 0x1p63 or nan). */
29031914882SAlex Richardson if (unlikely (zeroinfnan (iy)))
29131914882SAlex Richardson {
29231914882SAlex Richardson if (2 * iy == 0)
29331914882SAlex Richardson return issignaling_inline (x) ? x + y : 1.0;
29431914882SAlex Richardson if (ix == asuint64 (1.0))
29531914882SAlex Richardson return issignaling_inline (y) ? x + y : 1.0;
29631914882SAlex Richardson if (2 * ix > 2 * asuint64 (INFINITY)
29731914882SAlex Richardson || 2 * iy > 2 * asuint64 (INFINITY))
29831914882SAlex Richardson return x + y;
29931914882SAlex Richardson if (2 * ix == 2 * asuint64 (1.0))
30031914882SAlex Richardson return 1.0;
30131914882SAlex Richardson if ((2 * ix < 2 * asuint64 (1.0)) == !(iy >> 63))
30231914882SAlex Richardson return 0.0; /* |x|<1 && y==inf or |x|>1 && y==-inf. */
30331914882SAlex Richardson return y * y;
30431914882SAlex Richardson }
30531914882SAlex Richardson if (unlikely (zeroinfnan (ix)))
30631914882SAlex Richardson {
30731914882SAlex Richardson double_t x2 = x * x;
30831914882SAlex Richardson if (ix >> 63 && checkint (iy) == 1)
30931914882SAlex Richardson {
31031914882SAlex Richardson x2 = -x2;
31131914882SAlex Richardson sign_bias = 1;
31231914882SAlex Richardson }
31331914882SAlex Richardson if (WANT_ERRNO && 2 * ix == 0 && iy >> 63)
31431914882SAlex Richardson return __math_divzero (sign_bias);
31531914882SAlex Richardson /* Without the barrier some versions of clang hoist the 1/x2 and
31631914882SAlex Richardson thus division by zero exception can be signaled spuriously. */
31731914882SAlex Richardson return iy >> 63 ? opt_barrier_double (1 / x2) : x2;
31831914882SAlex Richardson }
31931914882SAlex Richardson /* Here x and y are non-zero finite. */
32031914882SAlex Richardson if (ix >> 63)
32131914882SAlex Richardson {
32231914882SAlex Richardson /* Finite x < 0. */
32331914882SAlex Richardson int yint = checkint (iy);
32431914882SAlex Richardson if (yint == 0)
32531914882SAlex Richardson return __math_invalid (x);
32631914882SAlex Richardson if (yint == 1)
32731914882SAlex Richardson sign_bias = SIGN_BIAS;
32831914882SAlex Richardson ix &= 0x7fffffffffffffff;
32931914882SAlex Richardson topx &= 0x7ff;
33031914882SAlex Richardson }
33131914882SAlex Richardson if ((topy & 0x7ff) - 0x3be >= 0x43e - 0x3be)
33231914882SAlex Richardson {
33331914882SAlex Richardson /* Note: sign_bias == 0 here because y is not odd. */
33431914882SAlex Richardson if (ix == asuint64 (1.0))
33531914882SAlex Richardson return 1.0;
33631914882SAlex Richardson if ((topy & 0x7ff) < 0x3be)
33731914882SAlex Richardson {
33831914882SAlex Richardson /* |y| < 2^-65, x^y ~= 1 + y*log(x). */
33931914882SAlex Richardson if (WANT_ROUNDING)
34031914882SAlex Richardson return ix > asuint64 (1.0) ? 1.0 + y : 1.0 - y;
34131914882SAlex Richardson else
34231914882SAlex Richardson return 1.0;
34331914882SAlex Richardson }
34431914882SAlex Richardson return (ix > asuint64 (1.0)) == (topy < 0x800) ? __math_oflow (0)
34531914882SAlex Richardson : __math_uflow (0);
34631914882SAlex Richardson }
34731914882SAlex Richardson if (topx == 0)
34831914882SAlex Richardson {
34931914882SAlex Richardson /* Normalize subnormal x so exponent becomes negative. */
35031914882SAlex Richardson /* Without the barrier some versions of clang evalutate the mul
35131914882SAlex Richardson unconditionally causing spurious overflow exceptions. */
35231914882SAlex Richardson ix = asuint64 (opt_barrier_double (x) * 0x1p52);
35331914882SAlex Richardson ix &= 0x7fffffffffffffff;
35431914882SAlex Richardson ix -= 52ULL << 52;
35531914882SAlex Richardson }
35631914882SAlex Richardson }
35731914882SAlex Richardson
35831914882SAlex Richardson double_t lo;
35931914882SAlex Richardson double_t hi = log_inline (ix, &lo);
36031914882SAlex Richardson double_t ehi, elo;
36131914882SAlex Richardson #if HAVE_FAST_FMA
36231914882SAlex Richardson ehi = y * hi;
36331914882SAlex Richardson elo = y * lo + fma (y, hi, -ehi);
36431914882SAlex Richardson #else
36531914882SAlex Richardson double_t yhi = asdouble (iy & -1ULL << 27);
36631914882SAlex Richardson double_t ylo = y - yhi;
36731914882SAlex Richardson double_t lhi = asdouble (asuint64 (hi) & -1ULL << 27);
36831914882SAlex Richardson double_t llo = hi - lhi + lo;
36931914882SAlex Richardson ehi = yhi * lhi;
37031914882SAlex Richardson elo = ylo * lhi + y * llo; /* |elo| < |ehi| * 2^-25. */
37131914882SAlex Richardson #endif
37231914882SAlex Richardson return exp_inline (ehi, elo, sign_bias);
37331914882SAlex Richardson }
37431914882SAlex Richardson #if USE_GLIBC_ABI
strong_alias(pow,__pow_finite)37531914882SAlex Richardson strong_alias (pow, __pow_finite)
37631914882SAlex Richardson hidden_alias (pow, __ieee754_pow)
37731914882SAlex Richardson # if LDBL_MANT_DIG == 53
37831914882SAlex Richardson long double powl (long double x, long double y) { return pow (x, y); }
37931914882SAlex Richardson # endif
38031914882SAlex Richardson #endif
381