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