aboutsummaryrefslogtreecommitdiff
path: root/libc/src/math/generic
diff options
context:
space:
mode:
Diffstat (limited to 'libc/src/math/generic')
-rw-r--r--libc/src/math/generic/CMakeLists.txt120
-rw-r--r--libc/src/math/generic/acos.cpp266
-rw-r--r--libc/src/math/generic/acosf.cpp121
-rw-r--r--libc/src/math/generic/acosf16.cpp138
-rw-r--r--libc/src/math/generic/acoshf.cpp68
-rw-r--r--libc/src/math/generic/acoshf16.cpp98
-rw-r--r--libc/src/math/generic/asin.cpp3
-rw-r--r--libc/src/math/generic/asin_utils.h574
-rw-r--r--libc/src/math/generic/asinf.cpp3
-rw-r--r--libc/src/math/generic/asinhf.cpp1
-rw-r--r--libc/src/math/generic/asinhf16.cpp1
-rw-r--r--libc/src/math/generic/atan2f.cpp3
-rw-r--r--libc/src/math/generic/atanf.cpp3
-rw-r--r--libc/src/math/generic/atanhf.cpp1
-rw-r--r--libc/src/math/generic/common_constants.cpp92
-rw-r--r--libc/src/math/generic/common_constants.h7
-rw-r--r--libc/src/math/generic/erff.cpp174
-rw-r--r--libc/src/math/generic/exp10f16.cpp122
-rw-r--r--libc/src/math/generic/exp10m1f16.cpp2
-rw-r--r--libc/src/math/generic/explogxf.h36
-rw-r--r--libc/src/math/generic/expxf16.h56
-rw-r--r--libc/src/math/generic/inv_trigf_utils.cpp86
-rw-r--r--libc/src/math/generic/inv_trigf_utils.h110
-rw-r--r--libc/src/math/generic/log1pf.cpp1
24 files changed, 51 insertions, 2035 deletions
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 99db743..408f99e 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -1295,12 +1295,8 @@ add_entrypoint_object(
HDRS
../erff.h
DEPENDS
- .common_constants
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.except_value_utils
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.FPUtil.polyeval
- libc.src.__support.macros.optimization
+ libc.src.__support.math.erff
+ libc.src.errno.errno
)
add_entrypoint_object(
@@ -1477,20 +1473,8 @@ add_entrypoint_object(
HDRS
../exp10f16.h
DEPENDS
- .expxf16
- libc.hdr.errno_macros
- libc.hdr.fenv_macros
- libc.src.__support.CPP.array
- libc.src.__support.FPUtil.cast
- libc.src.__support.FPUtil.except_value_utils
- libc.src.__support.FPUtil.fenv_impl
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.FPUtil.nearest_integer
- libc.src.__support.FPUtil.polyeval
- libc.src.__support.FPUtil.rounding_mode
- libc.src.__support.macros.optimization
- libc.src.__support.macros.properties.cpu_features
+ libc.src.__support.math.exp10f16
+ libc.src.errno.errno
)
add_entrypoint_object(
@@ -1519,7 +1503,6 @@ add_entrypoint_object(
HDRS
../exp10m1f16.h
DEPENDS
- .expxf16
libc.hdr.errno_macros
libc.hdr.fenv_macros
libc.src.__support.FPUtil.cast
@@ -1531,6 +1514,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.macros.optimization
libc.src.__support.macros.properties.cpu_features
+ libc.src.__support.math.exp10f16_utils
)
add_entrypoint_object(
@@ -1910,6 +1894,7 @@ add_object_library(
common_constants.cpp
DEPENDS
libc.src.__support.math.exp_constants
+ libc.src.__support.math.acosh_float_constants
libc.src.__support.number_pair
)
@@ -3773,7 +3758,7 @@ add_header_library(
DEPENDS
.common_constants
libc.src.__support.math.exp_utils
- libc.src.__support.math.exp10f_utils
+ libc.src.__support.math.acoshf_utils
libc.src.__support.macros.properties.cpu_features
libc.src.errno.errno
)
@@ -3883,12 +3868,7 @@ add_entrypoint_object(
../acoshf.h
DEPENDS
.explogxf
- libc.src.__support.FPUtil.fenv_impl
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.FPUtil.polyeval
- libc.src.__support.FPUtil.sqrt
- libc.src.__support.macros.optimization
+ libc.src.__support.math.acoshf
)
add_entrypoint_object(
@@ -3898,18 +3878,8 @@ add_entrypoint_object(
HDRS
../acoshf16.h
DEPENDS
- .explogxf
- libc.hdr.errno_macros
- libc.hdr.fenv_macros
- libc.src.__support.FPUtil.cast
- libc.src.__support.FPUtil.except_value_utils
- libc.src.__support.FPUtil.fenv_impl
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.FPUtil.polyeval
- libc.src.__support.FPUtil.sqrt
- libc.src.__support.macros.optimization
- libc.src.__support.macros.properties.types
+ libc.src.__support.math.acoshf16
+ libc.src.errno.errno
)
add_entrypoint_object(
@@ -3981,18 +3951,6 @@ add_entrypoint_object(
libc.src.__support.macros.properties.types
)
-add_object_library(
- inv_trigf_utils
- HDRS
- inv_trigf_utils.h
- SRCS
- inv_trigf_utils.cpp
- DEPENDS
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.FPUtil.polyeval
- libc.src.__support.common
-)
-
add_entrypoint_object(
asinf
SRCS
@@ -4006,7 +3964,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.polyeval
libc.src.__support.FPUtil.sqrt
libc.src.__support.macros.optimization
- .inv_trigf_utils
+ libc.src.__support.math.inv_trigf_utils
)
add_entrypoint_object(
@@ -4028,20 +3986,6 @@ add_entrypoint_object(
libc.src.__support.macros.properties.types
)
-add_header_library(
- asin_utils
- HDRS
- atan_utils.h
- DEPENDS
- libc.src.__support.integer_literals
- libc.src.__support.FPUtil.double_double
- libc.src.__support.FPUtil.dyadic_float
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.FPUtil.nearest_integer
- libc.src.__support.FPUtil.polyeval
- libc.src.__support.macros.optimization
-)
-
add_entrypoint_object(
asin
SRCS
@@ -4049,7 +3993,7 @@ add_entrypoint_object(
HDRS
../asin.h
DEPENDS
- .asin_utils
+ libc.src.__support.math.asin_utils
libc.src.__support.FPUtil.double_double
libc.src.__support.FPUtil.dyadic_float
libc.src.__support.FPUtil.fenv_impl
@@ -4068,13 +4012,7 @@ add_entrypoint_object(
HDRS
../acosf.h
DEPENDS
- libc.src.__support.FPUtil.except_value_utils
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.FPUtil.polyeval
- libc.src.__support.FPUtil.sqrt
- libc.src.__support.macros.optimization
- .inv_trigf_utils
+ libc.src.__support.math.acosf
)
add_entrypoint_object(
@@ -4084,17 +4022,8 @@ add_entrypoint_object(
HDRS
../acosf16.h
DEPENDS
- libc.hdr.errno_macros
- libc.hdr.fenv_macros
- libc.src.__support.FPUtil.cast
- libc.src.__support.FPUtil.except_value_utils
- libc.src.__support.FPUtil.fenv_impl
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.FPUtil.polyeval
- libc.src.__support.FPUtil.sqrt
- libc.src.__support.macros.optimization
- libc.src.__support.macros.properties.types
+ libc.src.__support.math.acosf16
+ libc.src.errno.errno
)
add_entrypoint_object(
@@ -4104,17 +4033,7 @@ add_entrypoint_object(
HDRS
../acos.h
DEPENDS
- .asin_utils
- libc.src.__support.FPUtil.double_double
- libc.src.__support.FPUtil.dyadic_float
- libc.src.__support.FPUtil.fenv_impl
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.FPUtil.polyeval
- libc.src.__support.FPUtil.sqrt
- libc.src.__support.macros.optimization
- libc.src.__support.macros.properties.types
- libc.src.__support.macros.properties.cpu_features
+ libc.src.__support.math.acos
)
add_entrypoint_object(
@@ -4156,7 +4075,6 @@ add_entrypoint_object(
HDRS
../atanf.h
DEPENDS
- .inv_trigf_utils
libc.src.__support.FPUtil.except_value_utils
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.multiply_add
@@ -4164,6 +4082,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.polyeval
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.macros.optimization
+ libc.src.__support.math.inv_trigf_utils
)
add_entrypoint_object(
@@ -4212,7 +4131,6 @@ add_entrypoint_object(
../atan2f.h
atan2f_float.h
DEPENDS
- .inv_trigf_utils
libc.hdr.fenv_macros
libc.src.__support.FPUtil.double_double
libc.src.__support.FPUtil.fenv_impl
@@ -4222,6 +4140,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.polyeval
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.macros.optimization
+ libc.src.__support.math.inv_trigf_utils
)
add_entrypoint_object(
@@ -5023,10 +4942,11 @@ add_header_library(
HDRS
expxf16.h
DEPENDS
- libc.src.__support.FPUtil.cast
libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.cast
libc.src.__support.FPUtil.multiply_add
libc.src.__support.FPUtil.nearest_integer
libc.src.__support.macros.attributes
libc.src.__support.math.expf16_utils
+ libc.src.__support.math.exp10_float16_constants
)
diff --git a/libc/src/math/generic/acos.cpp b/libc/src/math/generic/acos.cpp
index c14721f..3a59642 100644
--- a/libc/src/math/generic/acos.cpp
+++ b/libc/src/math/generic/acos.cpp
@@ -7,272 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/acos.h"
-#include "asin_utils.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/PolyEval.h"
-#include "src/__support/FPUtil/double_double.h"
-#include "src/__support/FPUtil/dyadic_float.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/FPUtil/sqrt.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
-#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA
+#include "src/__support/math/acos.h"
namespace LIBC_NAMESPACE_DECL {
-using DoubleDouble = fputil::DoubleDouble;
-using Float128 = fputil::DyadicFloat<128>;
-
-LLVM_LIBC_FUNCTION(double, acos, (double x)) {
- using FPBits = fputil::FPBits<double>;
-
- FPBits xbits(x);
- int x_exp = xbits.get_biased_exponent();
-
- // |x| < 0.5.
- if (x_exp < FPBits::EXP_BIAS - 1) {
- // |x| < 2^-55.
- if (LIBC_UNLIKELY(x_exp < FPBits::EXP_BIAS - 55)) {
- // When |x| < 2^-55, acos(x) = pi/2
-#if defined(LIBC_MATH_HAS_SKIP_ACCURATE_PASS)
- return PI_OVER_TWO.hi;
-#else
- // Force the evaluation and prevent constant propagation so that it
- // is rounded correctly for FE_UPWARD rounding mode.
- return (xbits.abs().get_val() + 0x1.0p-160) + PI_OVER_TWO.hi;
-#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- }
-
-#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- // acos(x) = pi/2 - asin(x)
- // = pi/2 - x * P(x^2)
- double p = asin_eval(x * x);
- return PI_OVER_TWO.hi + fputil::multiply_add(-x, p, PI_OVER_TWO.lo);
-#else
- unsigned idx;
- DoubleDouble x_sq = fputil::exact_mult(x, x);
- double err = xbits.abs().get_val() * 0x1.0p-51;
- // Polynomial approximation:
- // p ~ asin(x)/x
- DoubleDouble p = asin_eval(x_sq, idx, err);
- // asin(x) ~ x * p
- DoubleDouble r0 = fputil::exact_mult(x, p.hi);
- // acos(x) = pi/2 - asin(x)
- // ~ pi/2 - x * p
- // = pi/2 - x * (p.hi + p.lo)
- double r_hi = fputil::multiply_add(-x, p.hi, PI_OVER_TWO.hi);
- // Use Dekker's 2SUM algorithm to compute the lower part.
- double r_lo = ((PI_OVER_TWO.hi - r_hi) - r0.hi) - r0.lo;
- r_lo = fputil::multiply_add(-x, p.lo, r_lo + PI_OVER_TWO.lo);
-
- // Ziv's accuracy test.
-
- double r_upper = r_hi + (r_lo + err);
- double r_lower = r_hi + (r_lo - err);
-
- if (LIBC_LIKELY(r_upper == r_lower))
- return r_upper;
-
- // Ziv's accuracy test failed, perform 128-bit calculation.
-
- // Recalculate mod 1/64.
- idx = static_cast<unsigned>(fputil::nearest_integer(x_sq.hi * 0x1.0p6));
-
- // Get x^2 - idx/64 exactly. When FMA is available, double-double
- // multiplication will be correct for all rounding modes. Otherwise we use
- // Float128 directly.
- Float128 x_f128(x);
-
-#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
- // u = x^2 - idx/64
- Float128 u_hi(
- fputil::multiply_add(static_cast<double>(idx), -0x1.0p-6, x_sq.hi));
- Float128 u = fputil::quick_add(u_hi, Float128(x_sq.lo));
-#else
- Float128 x_sq_f128 = fputil::quick_mul(x_f128, x_f128);
- Float128 u = fputil::quick_add(
- x_sq_f128, Float128(static_cast<double>(idx) * (-0x1.0p-6)));
-#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
-
- Float128 p_f128 = asin_eval(u, idx);
- // Flip the sign of x_f128 to perform subtraction.
- x_f128.sign = x_f128.sign.negate();
- Float128 r =
- fputil::quick_add(PI_OVER_TWO_F128, fputil::quick_mul(x_f128, p_f128));
-
- return static_cast<double>(r);
-#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- }
- // |x| >= 0.5
-
- double x_abs = xbits.abs().get_val();
-
- // Maintaining the sign:
- constexpr double SIGN[2] = {1.0, -1.0};
- double x_sign = SIGN[xbits.is_neg()];
- // |x| >= 1
- if (LIBC_UNLIKELY(x_exp >= FPBits::EXP_BIAS)) {
- // x = +-1, asin(x) = +- pi/2
- if (x_abs == 1.0) {
- // x = 1, acos(x) = 0,
- // x = -1, acos(x) = pi
- return x == 1.0 ? 0.0 : fputil::multiply_add(-x_sign, PI.hi, PI.lo);
- }
- // |x| > 1, return NaN.
- if (xbits.is_quiet_nan())
- return x;
-
- // Set domain error for non-NaN input.
- if (!xbits.is_nan())
- fputil::set_errno_if_required(EDOM);
-
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
- }
-
- // When |x| >= 0.5, we perform range reduction as follow:
- //
- // When 0.5 <= x < 1, let:
- // y = acos(x)
- // We will use the double angle formula:
- // cos(2y) = 1 - 2 sin^2(y)
- // and the complement angle identity:
- // x = cos(y) = 1 - 2 sin^2 (y/2)
- // So:
- // sin(y/2) = sqrt( (1 - x)/2 )
- // And hence:
- // y/2 = asin( sqrt( (1 - x)/2 ) )
- // Equivalently:
- // acos(x) = y = 2 * asin( sqrt( (1 - x)/2 ) )
- // Let u = (1 - x)/2, then:
- // acos(x) = 2 * asin( sqrt(u) )
- // Moreover, since 0.5 <= x < 1:
- // 0 < u <= 1/4, and 0 < sqrt(u) <= 0.5,
- // And hence we can reuse the same polynomial approximation of asin(x) when
- // |x| <= 0.5:
- // acos(x) ~ 2 * sqrt(u) * P(u).
- //
- // When -1 < x <= -0.5, we reduce to the previous case using the formula:
- // acos(x) = pi - acos(-x)
- // = pi - 2 * asin ( sqrt( (1 + x)/2 ) )
- // ~ pi - 2 * sqrt(u) * P(u),
- // where u = (1 - |x|)/2.
-
- // u = (1 - |x|)/2
- double u = fputil::multiply_add(x_abs, -0.5, 0.5);
- // v_hi + v_lo ~ sqrt(u).
- // Let:
- // h = u - v_hi^2 = (sqrt(u) - v_hi) * (sqrt(u) + v_hi)
- // Then:
- // sqrt(u) = v_hi + h / (sqrt(u) + v_hi)
- // ~ v_hi + h / (2 * v_hi)
- // So we can use:
- // v_lo = h / (2 * v_hi).
- double v_hi = fputil::sqrt<double>(u);
-
-#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- constexpr DoubleDouble CONST_TERM[2] = {{0.0, 0.0}, PI};
- DoubleDouble const_term = CONST_TERM[xbits.is_neg()];
-
- double p = asin_eval(u);
- double scale = x_sign * 2.0 * v_hi;
- double r = const_term.hi + fputil::multiply_add(scale, p, const_term.lo);
- return r;
-#else
-
-#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
- double h = fputil::multiply_add(v_hi, -v_hi, u);
-#else
- DoubleDouble v_hi_sq = fputil::exact_mult(v_hi, v_hi);
- double h = (u - v_hi_sq.hi) - v_hi_sq.lo;
-#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
-
- // Scale v_lo and v_hi by 2 from the formula:
- // vh = v_hi * 2
- // vl = 2*v_lo = h / v_hi.
- double vh = v_hi * 2.0;
- double vl = h / v_hi;
-
- // Polynomial approximation:
- // p ~ asin(sqrt(u))/sqrt(u)
- unsigned idx;
- double err = vh * 0x1.0p-51;
-
- DoubleDouble p = asin_eval(DoubleDouble{0.0, u}, idx, err);
-
- // Perform computations in double-double arithmetic:
- // asin(x) = pi/2 - (v_hi + v_lo) * (ASIN_COEFFS[idx][0] + p)
- DoubleDouble r0 = fputil::quick_mult(DoubleDouble{vl, vh}, p);
-
- double r_hi, r_lo;
- if (xbits.is_pos()) {
- r_hi = r0.hi;
- r_lo = r0.lo;
- } else {
- DoubleDouble r = fputil::exact_add(PI.hi, -r0.hi);
- r_hi = r.hi;
- r_lo = (PI.lo - r0.lo) + r.lo;
- }
-
- // Ziv's accuracy test.
-
- double r_upper = r_hi + (r_lo + err);
- double r_lower = r_hi + (r_lo - err);
-
- if (LIBC_LIKELY(r_upper == r_lower))
- return r_upper;
-
- // Ziv's accuracy test failed, we redo the computations in Float128.
- // Recalculate mod 1/64.
- idx = static_cast<unsigned>(fputil::nearest_integer(u * 0x1.0p6));
-
- // After the first step of Newton-Raphson approximating v = sqrt(u), we have
- // that:
- // sqrt(u) = v_hi + h / (sqrt(u) + v_hi)
- // v_lo = h / (2 * v_hi)
- // With error:
- // sqrt(u) - (v_hi + v_lo) = h * ( 1/(sqrt(u) + v_hi) - 1/(2*v_hi) )
- // = -h^2 / (2*v * (sqrt(u) + v)^2).
- // Since:
- // (sqrt(u) + v_hi)^2 ~ (2sqrt(u))^2 = 4u,
- // we can add another correction term to (v_hi + v_lo) that is:
- // v_ll = -h^2 / (2*v_hi * 4u)
- // = -v_lo * (h / 4u)
- // = -vl * (h / 8u),
- // making the errors:
- // sqrt(u) - (v_hi + v_lo + v_ll) = O(h^3)
- // well beyond 128-bit precision needed.
-
- // Get the rounding error of vl = 2 * v_lo ~ h / vh
- // Get full product of vh * vl
-#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
- double vl_lo = fputil::multiply_add(-v_hi, vl, h) / v_hi;
-#else
- DoubleDouble vh_vl = fputil::exact_mult(v_hi, vl);
- double vl_lo = ((h - vh_vl.hi) - vh_vl.lo) / v_hi;
-#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
- // vll = 2*v_ll = -vl * (h / (4u)).
- double t = h * (-0.25) / u;
- double vll = fputil::multiply_add(vl, t, vl_lo);
- // m_v = -(v_hi + v_lo + v_ll).
- Float128 m_v = fputil::quick_add(
- Float128(vh), fputil::quick_add(Float128(vl), Float128(vll)));
- m_v.sign = xbits.sign();
-
- // Perform computations in Float128:
- // acos(x) = (v_hi + v_lo + vll) * P(u) , when 0.5 <= x < 1,
- // = pi - (v_hi + v_lo + vll) * P(u) , when -1 < x <= -0.5.
- Float128 y_f128(fputil::multiply_add(static_cast<double>(idx), -0x1.0p-6, u));
-
- Float128 p_f128 = asin_eval(y_f128, idx);
- Float128 r_f128 = fputil::quick_mul(m_v, p_f128);
-
- if (xbits.is_neg())
- r_f128 = fputil::quick_add(PI_F128, r_f128);
-
- return static_cast<double>(r_f128);
-#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-}
+LLVM_LIBC_FUNCTION(double, acos, (double x)) { return math::acos(x); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/acosf.cpp b/libc/src/math/generic/acosf.cpp
index 8dd6de2..7afc7d6 100644
--- a/libc/src/math/generic/acosf.cpp
+++ b/libc/src/math/generic/acosf.cpp
@@ -7,127 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/acosf.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/PolyEval.h"
-#include "src/__support/FPUtil/except_value_utils.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/FPUtil/sqrt.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
-
-#include "inv_trigf_utils.h"
+#include "src/__support/math/acosf.h"
namespace LIBC_NAMESPACE_DECL {
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-static constexpr size_t N_EXCEPTS = 4;
-
-// Exceptional values when |x| <= 0.5
-static constexpr fputil::ExceptValues<float, N_EXCEPTS> ACOSF_EXCEPTS = {{
- // (inputs, RZ output, RU offset, RD offset, RN offset)
- // x = 0x1.110b46p-26, acosf(x) = 0x1.921fb4p0 (RZ)
- {0x328885a3, 0x3fc90fda, 1, 0, 1},
- // x = -0x1.110b46p-26, acosf(x) = 0x1.921fb4p0 (RZ)
- {0xb28885a3, 0x3fc90fda, 1, 0, 1},
- // x = 0x1.04c444p-12, acosf(x) = 0x1.920f68p0 (RZ)
- {0x39826222, 0x3fc907b4, 1, 0, 1},
- // x = -0x1.04c444p-12, acosf(x) = 0x1.923p0 (RZ)
- {0xb9826222, 0x3fc91800, 1, 0, 1},
-}};
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
-LLVM_LIBC_FUNCTION(float, acosf, (float x)) {
- using FPBits = typename fputil::FPBits<float>;
-
- FPBits xbits(x);
- uint32_t x_uint = xbits.uintval();
- uint32_t x_abs = xbits.uintval() & 0x7fff'ffffU;
- uint32_t x_sign = x_uint >> 31;
-
- // |x| <= 0.5
- if (LIBC_UNLIKELY(x_abs <= 0x3f00'0000U)) {
- // |x| < 0x1p-10
- if (LIBC_UNLIKELY(x_abs < 0x3a80'0000U)) {
- // When |x| < 2^-10, we use the following approximation:
- // acos(x) = pi/2 - asin(x)
- // ~ pi/2 - x - x^3 / 6
-
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- // Check for exceptional values
- if (auto r = ACOSF_EXCEPTS.lookup(x_uint); LIBC_UNLIKELY(r.has_value()))
- return r.value();
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
- double xd = static_cast<double>(x);
- return static_cast<float>(fputil::multiply_add(
- -0x1.5555555555555p-3 * xd, xd * xd, M_MATH_PI_2 - xd));
- }
-
- // For |x| <= 0.5, we approximate acosf(x) by:
- // acos(x) = pi/2 - asin(x) = pi/2 - x * P(x^2)
- // Where P(X^2) = Q(X) is a degree-20 minimax even polynomial approximating
- // asin(x)/x on [0, 0.5] generated by Sollya with:
- // > Q = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20|],
- // [|1, D...|], [0, 0.5]);
- double xd = static_cast<double>(x);
- double xsq = xd * xd;
- double x3 = xd * xsq;
- double r = asin_eval(xsq);
- return static_cast<float>(fputil::multiply_add(-x3, r, M_MATH_PI_2 - xd));
- }
-
- // |x| >= 1, return 0, 2pi, or NaNs.
- if (LIBC_UNLIKELY(x_abs >= 0x3f80'0000U)) {
- if (x_abs == 0x3f80'0000U)
- return x_sign ? /* x == -1.0f */ fputil::round_result_slightly_down(
- 0x1.921fb6p+1f)
- : /* x == 1.0f */ 0.0f;
-
- if (xbits.is_signaling_nan()) {
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
- }
-
- // |x| <= +/-inf
- if (x_abs <= 0x7f80'0000U) {
- fputil::set_errno_if_required(EDOM);
- fputil::raise_except_if_required(FE_INVALID);
- }
-
- return x + FPBits::quiet_nan().get_val();
- }
-
- // When 0.5 < |x| < 1, we perform range reduction as follow:
- //
- // Assume further that 0.5 < x <= 1, and let:
- // y = acos(x)
- // We use the double angle formula:
- // x = cos(y) = 1 - 2 sin^2(y/2)
- // So:
- // sin(y/2) = sqrt( (1 - x)/2 )
- // And hence:
- // y = 2 * asin( sqrt( (1 - x)/2 ) )
- // Let u = (1 - x)/2, then
- // acos(x) = 2 * asin( sqrt(u) )
- // Moreover, since 0.5 < x <= 1,
- // 0 <= u < 1/4, and 0 <= sqrt(u) < 0.5,
- // And hence we can reuse the same polynomial approximation of asin(x) when
- // |x| <= 0.5:
- // acos(x) ~ 2 * sqrt(u) * P(u).
- //
- // When -1 < x <= -0.5, we use the identity:
- // acos(x) = pi - acos(-x)
- // which is reduced to the postive case.
-
- xbits.set_sign(Sign::POS);
- double xd = static_cast<double>(xbits.get_val());
- double u = fputil::multiply_add(-0.5, xd, 0.5);
- double cv = 2 * fputil::sqrt<double>(u);
-
- double r3 = asin_eval(u);
- double r = fputil::multiply_add(cv * u, r3, cv);
- return static_cast<float>(x_sign ? M_MATH_PI - r : r);
-}
+LLVM_LIBC_FUNCTION(float, acosf, (float x)) { return math::acosf(x); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/acosf16.cpp b/libc/src/math/generic/acosf16.cpp
index 202a950..0bf85f8 100644
--- a/libc/src/math/generic/acosf16.cpp
+++ b/libc/src/math/generic/acosf16.cpp
@@ -8,144 +8,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/acosf16.h"
-#include "hdr/errno_macros.h"
-#include "hdr/fenv_macros.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/PolyEval.h"
-#include "src/__support/FPUtil/cast.h"
-#include "src/__support/FPUtil/except_value_utils.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/FPUtil/sqrt.h"
-#include "src/__support/macros/optimization.h"
+#include "src/__support/math/acosf16.h"
namespace LIBC_NAMESPACE_DECL {
-// Generated by Sollya using the following command:
-// > round(pi/2, SG, RN);
-// > round(pi, SG, RN);
-static constexpr float PI_OVER_2 = 0x1.921fb6p0f;
-static constexpr float PI = 0x1.921fb6p1f;
+LLVM_LIBC_FUNCTION(float16, acosf16, (float16 x)) { return math::acosf16(x); }
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-static constexpr size_t N_EXCEPTS = 2;
-
-static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSF16_EXCEPTS{{
- // (input, RZ output, RU offset, RD offset, RN offset)
- {0xacaf, 0x3e93, 1, 0, 0},
- {0xb874, 0x4052, 1, 0, 1},
-}};
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
-LLVM_LIBC_FUNCTION(float16, acosf16, (float16 x)) {
- using FPBits = fputil::FPBits<float16>;
- FPBits xbits(x);
-
- uint16_t x_u = xbits.uintval();
- uint16_t x_abs = x_u & 0x7fff;
- uint16_t x_sign = x_u >> 15;
-
- // |x| > 0x1p0, |x| > 1, or x is NaN.
- if (LIBC_UNLIKELY(x_abs > 0x3c00)) {
- // acosf16(NaN) = NaN
- if (xbits.is_nan()) {
- if (xbits.is_signaling_nan()) {
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
- }
-
- return x;
- }
-
- // 1 < |x| <= +/-inf
- fputil::raise_except_if_required(FE_INVALID);
- fputil::set_errno_if_required(EDOM);
-
- return FPBits::quiet_nan().get_val();
- }
-
- float xf = x;
-
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- // Handle exceptional values
- if (auto r = ACOSF16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
- return r.value();
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
- // |x| == 0x1p0, x is 1 or -1
- // if x is (-)1, return pi, else
- // if x is (+)1, return 0
- if (LIBC_UNLIKELY(x_abs == 0x3c00))
- return fputil::cast<float16>(x_sign ? PI : 0.0f);
-
- float xsq = xf * xf;
-
- // |x| <= 0x1p-1, |x| <= 0.5
- if (x_abs <= 0x3800) {
- // if x is 0, return pi/2
- if (LIBC_UNLIKELY(x_abs == 0))
- return fputil::cast<float16>(PI_OVER_2);
-
- // Note that: acos(x) = pi/2 + asin(-x) = pi/2 - asin(x)
- // Degree-6 minimax polynomial of asin(x) generated by Sollya with:
- // > P = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8|], [|SG...|], [0, 0.5]);
- float interm =
- fputil::polyeval(xsq, 0x1.000002p0f, 0x1.554c2ap-3f, 0x1.3541ccp-4f,
- 0x1.43b2d6p-5f, 0x1.a0d73ep-5f);
- return fputil::cast<float16>(fputil::multiply_add(-xf, interm, PI_OVER_2));
- }
-
- // When |x| > 0.5, assume that 0.5 < |x| <= 1
- //
- // Step-by-step range-reduction proof:
- // 1: Let y = asin(x), such that, x = sin(y)
- // 2: From complimentary angle identity:
- // x = sin(y) = cos(pi/2 - y)
- // 3: Let z = pi/2 - y, such that x = cos(z)
- // 4: From double angle formula; cos(2A) = 1 - 2 * sin^2(A):
- // z = 2A, z/2 = A
- // cos(z) = 1 - 2 * sin^2(z/2)
- // 5: Make sin(z/2) subject of the formula:
- // sin(z/2) = sqrt((1 - cos(z))/2)
- // 6: Recall [3]; x = cos(z). Therefore:
- // sin(z/2) = sqrt((1 - x)/2)
- // 7: Let u = (1 - x)/2
- // 8: Therefore:
- // asin(sqrt(u)) = z/2
- // 2 * asin(sqrt(u)) = z
- // 9: Recall [3]; z = pi/2 - y. Therefore:
- // y = pi/2 - z
- // y = pi/2 - 2 * asin(sqrt(u))
- // 10: Recall [1], y = asin(x). Therefore:
- // asin(x) = pi/2 - 2 * asin(sqrt(u))
- // 11: Recall that: acos(x) = pi/2 + asin(-x) = pi/2 - asin(x)
- // Therefore:
- // acos(x) = pi/2 - (pi/2 - 2 * asin(sqrt(u)))
- // acos(x) = 2 * asin(sqrt(u))
- //
- // THE RANGE REDUCTION, HOW?
- // 12: Recall [7], u = (1 - x)/2
- // 13: Since 0.5 < x <= 1, therefore:
- // 0 <= u <= 0.25 and 0 <= sqrt(u) <= 0.5
- //
- // Hence, we can reuse the same [0, 0.5] domain polynomial approximation for
- // Step [11] as `sqrt(u)` is in range.
- // When -1 < x <= -0.5, the identity:
- // acos(x) = pi - acos(-x)
- // allows us to compute for the negative x value (lhs)
- // with a positive x value instead (rhs).
-
- float xf_abs = (xf < 0 ? -xf : xf);
- float u = fputil::multiply_add(-0.5f, xf_abs, 0.5f);
- float sqrt_u = fputil::sqrt<float>(u);
-
- // Degree-6 minimax polynomial of asin(x) generated by Sollya with:
- // > P = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8|], [|SG...|], [0, 0.5]);
- float asin_sqrt_u =
- sqrt_u * fputil::polyeval(u, 0x1.000002p0f, 0x1.554c2ap-3f,
- 0x1.3541ccp-4f, 0x1.43b2d6p-5f, 0x1.a0d73ep-5f);
-
- return fputil::cast<float16>(
- x_sign ? fputil::multiply_add(-2.0f, asin_sqrt_u, PI) : 2 * asin_sqrt_u);
-}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/acoshf.cpp b/libc/src/math/generic/acoshf.cpp
index c4927fa..5c04583 100644
--- a/libc/src/math/generic/acoshf.cpp
+++ b/libc/src/math/generic/acoshf.cpp
@@ -7,73 +7,11 @@
//===----------------------------------------------------------------------===//
#include "src/math/acoshf.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/PolyEval.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/FPUtil/sqrt.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
-#include "src/math/generic/common_constants.h"
-#include "src/math/generic/explogxf.h"
-namespace LIBC_NAMESPACE_DECL {
-
-LLVM_LIBC_FUNCTION(float, acoshf, (float x)) {
- using FPBits_t = typename fputil::FPBits<float>;
- FPBits_t xbits(x);
-
- if (LIBC_UNLIKELY(x <= 1.0f)) {
- if (x == 1.0f)
- return 0.0f;
- // x < 1.
- fputil::set_errno_if_required(EDOM);
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits_t::quiet_nan().get_val();
- }
+#include "src/__support/math/acoshf.h"
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- uint32_t x_u = xbits.uintval();
- if (LIBC_UNLIKELY(x_u >= 0x4f8ffb03)) {
- if (LIBC_UNLIKELY(xbits.is_inf_or_nan()))
- return x;
-
- // Helper functions to set results for exceptional cases.
- auto round_result_slightly_down = [](float r) -> float {
- volatile float tmp = r;
- tmp = tmp - 0x1.0p-25f;
- return tmp;
- };
- auto round_result_slightly_up = [](float r) -> float {
- volatile float tmp = r;
- tmp = tmp + 0x1.0p-25f;
- return tmp;
- };
-
- switch (x_u) {
- case 0x4f8ffb03: // x = 0x1.1ff606p32f
- return round_result_slightly_up(0x1.6fdd34p4f);
- case 0x5c569e88: // x = 0x1.ad3d1p57f
- return round_result_slightly_up(0x1.45c146p5f);
- case 0x5e68984e: // x = 0x1.d1309cp61f
- return round_result_slightly_up(0x1.5c9442p5f);
- case 0x655890d3: // x = 0x1.b121a6p75f
- return round_result_slightly_down(0x1.a9a3f2p5f);
- case 0x6eb1a8ec: // x = 0x1.6351d8p94f
- return round_result_slightly_down(0x1.08b512p6f);
- case 0x7997f30a: // x = 0x1.2fe614p116f
- return round_result_slightly_up(0x1.451436p6f);
- }
- }
-#else
- if (LIBC_UNLIKELY(xbits.is_inf_or_nan()))
- return x;
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+namespace LIBC_NAMESPACE_DECL {
- double x_d = static_cast<double>(x);
- // acosh(x) = log(x + sqrt(x^2 - 1))
- return static_cast<float>(log_eval(
- x_d + fputil::sqrt<double>(fputil::multiply_add(x_d, x_d, -1.0))));
-}
+LLVM_LIBC_FUNCTION(float, acoshf, (float x)) { return math::acoshf(x); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/acoshf16.cpp b/libc/src/math/generic/acoshf16.cpp
index 44783a8..bb3a91f 100644
--- a/libc/src/math/generic/acoshf16.cpp
+++ b/libc/src/math/generic/acoshf16.cpp
@@ -7,104 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/acoshf16.h"
-#include "explogxf.h"
-#include "hdr/errno_macros.h"
-#include "hdr/fenv_macros.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/PolyEval.h"
-#include "src/__support/FPUtil/cast.h"
-#include "src/__support/FPUtil/except_value_utils.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/FPUtil/sqrt.h"
-#include "src/__support/common.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h"
+#include "src/__support/math/acoshf16.h"
namespace LIBC_NAMESPACE_DECL {
-static constexpr size_t N_EXCEPTS = 2;
-static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
- // (input, RZ output, RU offset, RD offset, RN offset)
- // x = 0x1.6dcp+1, acoshf16(x) = 0x1.b6p+0 (RZ)
- {0x41B7, 0x3ED8, 1, 0, 0},
- // x = 0x1.39p+0, acoshf16(x) = 0x1.4f8p-1 (RZ)
- {0x3CE4, 0x393E, 1, 0, 1},
-}};
-
-LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
- using FPBits = fputil::FPBits<float16>;
- FPBits xbits(x);
- uint16_t x_u = xbits.uintval();
-
- // Check for NaN input first.
- if (LIBC_UNLIKELY(xbits.is_inf_or_nan())) {
- if (xbits.is_signaling_nan()) {
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
- }
- if (xbits.is_neg()) {
- fputil::set_errno_if_required(EDOM);
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
- }
- return x;
- }
-
- // Domain error for inputs less than 1.0.
- if (LIBC_UNLIKELY(x <= 1.0f)) {
- if (x == 1.0f)
- return FPBits::zero().get_val();
- fputil::set_errno_if_required(EDOM);
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
- }
-
- if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
- LIBC_UNLIKELY(r.has_value()))
- return r.value();
-
- float xf = x;
- // High-precision polynomial approximation for inputs close to 1.0
- // ([1, 1.25)).
- //
- // Brief derivation:
- // 1. Expand acosh(1 + delta) using Taylor series around delta=0:
- // acosh(1 + delta) ≈ sqrt(2 * delta) * [1 - delta/12 + 3*delta^2/160
- // - 5*delta^3/896 + 35*delta^4/18432 + ...]
- // 2. Truncate the series to fit accurately for delta in [0, 0.25].
- // 3. Polynomial coefficients (from sollya) used here are:
- // P(delta) ≈ 1 - 0x1.555556p-4 * delta + 0x1.333334p-6 * delta^2
- // - 0x1.6db6dcp-8 * delta^3 + 0x1.f1c71cp-10 * delta^4
- // 4. The Sollya commands used to generate these coefficients were:
- // > display = hexadecimal;
- // > round(1/12, SG, RN);
- // > round(3/160, SG, RN);
- // > round(5/896, SG, RN);
- // > round(35/18432, SG, RN);
- // With hexadecimal display mode enabled, the outputs were:
- // 0x1.555556p-4
- // 0x1.333334p-6
- // 0x1.6db6dcp-8
- // 0x1.f1c71cp-10
- // 5. The maximum absolute error, estimated using:
- // dirtyinfnorm(acosh(1 + x) - sqrt(2*x) * P(x), [0, 0.25])
- // is:
- // 0x1.d84281p-22
- if (LIBC_UNLIKELY(x_u < 0x3D00U)) {
- float delta = xf - 1.0f;
- float sqrt_2_delta = fputil::sqrt<float>(2.0 * delta);
- float pe = fputil::polyeval(delta, 0x1p+0f, -0x1.555556p-4f, 0x1.333334p-6f,
- -0x1.6db6dcp-8f, 0x1.f1c71cp-10f);
- float approx = sqrt_2_delta * pe;
- return fputil::cast<float16>(approx);
- }
-
- // acosh(x) = log(x + sqrt(x^2 - 1))
- float sqrt_term = fputil::sqrt<float>(fputil::multiply_add(xf, xf, -1.0f));
- float result = static_cast<float>(log_eval(xf + sqrt_term));
-
- return fputil::cast<float16>(result);
-}
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) { return math::acoshf16(x); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/asin.cpp b/libc/src/math/generic/asin.cpp
index ad77683..d286fce 100644
--- a/libc/src/math/generic/asin.cpp
+++ b/libc/src/math/generic/asin.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "src/math/asin.h"
-#include "asin_utils.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
@@ -18,6 +17,7 @@
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA
+#include "src/__support/math/asin_utils.h"
namespace LIBC_NAMESPACE_DECL {
@@ -25,6 +25,7 @@ using DoubleDouble = fputil::DoubleDouble;
using Float128 = fputil::DyadicFloat<128>;
LLVM_LIBC_FUNCTION(double, asin, (double x)) {
+ using namespace asin_internal;
using FPBits = fputil::FPBits<double>;
FPBits xbits(x);
diff --git a/libc/src/math/generic/asin_utils.h b/libc/src/math/generic/asin_utils.h
deleted file mode 100644
index 44913d5..0000000
--- a/libc/src/math/generic/asin_utils.h
+++ /dev/null
@@ -1,574 +0,0 @@
-//===-- Collection of utils for asin/acos -----------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIBC_SRC_MATH_GENERIC_ASIN_UTILS_H
-#define LLVM_LIBC_SRC_MATH_GENERIC_ASIN_UTILS_H
-
-#include "src/__support/FPUtil/PolyEval.h"
-#include "src/__support/FPUtil/double_double.h"
-#include "src/__support/FPUtil/dyadic_float.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/FPUtil/nearest_integer.h"
-#include "src/__support/integer_literals.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h"
-
-namespace LIBC_NAMESPACE_DECL {
-
-namespace {
-
-using DoubleDouble = fputil::DoubleDouble;
-using Float128 = fputil::DyadicFloat<128>;
-
-constexpr DoubleDouble PI = {0x1.1a62633145c07p-53, 0x1.921fb54442d18p1};
-
-constexpr DoubleDouble PI_OVER_TWO = {0x1.1a62633145c07p-54,
- 0x1.921fb54442d18p0};
-
-#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
-// When correct rounding is not needed, we use a degree-22 minimax polynomial to
-// approximate asin(x)/x on [0, 0.5] using Sollya with:
-// > P = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22|],
-// [|1, D...|], [0, 0.5]);
-// > dirtyinfnorm(asin(x)/x - P, [0, 0.5]);
-// 0x1.1a71ef0a0f26a9fb7ed7e41dee788b13d1770db3dp-52
-
-constexpr double ASIN_COEFFS[12] = {
- 0x1.0000000000000p0, 0x1.5555555556dcfp-3, 0x1.3333333082e11p-4,
- 0x1.6db6dd14099edp-5, 0x1.f1c69b35bf81fp-6, 0x1.6e97194225a67p-6,
- 0x1.1babddb82ce12p-6, 0x1.d55bd078600d6p-7, 0x1.33328959e63d6p-7,
- 0x1.2b5993bda1d9bp-6, -0x1.806aff270bf25p-7, 0x1.02614e5ed3936p-5,
-};
-
-LIBC_INLINE double asin_eval(double u) {
- double u2 = u * u;
- double c0 = fputil::multiply_add(u, ASIN_COEFFS[1], ASIN_COEFFS[0]);
- double c1 = fputil::multiply_add(u, ASIN_COEFFS[3], ASIN_COEFFS[2]);
- double c2 = fputil::multiply_add(u, ASIN_COEFFS[5], ASIN_COEFFS[4]);
- double c3 = fputil::multiply_add(u, ASIN_COEFFS[7], ASIN_COEFFS[6]);
- double c4 = fputil::multiply_add(u, ASIN_COEFFS[9], ASIN_COEFFS[8]);
- double c5 = fputil::multiply_add(u, ASIN_COEFFS[11], ASIN_COEFFS[10]);
-
- double u4 = u2 * u2;
- double d0 = fputil::multiply_add(u2, c1, c0);
- double d1 = fputil::multiply_add(u2, c3, c2);
- double d2 = fputil::multiply_add(u2, c5, c4);
-
- return fputil::polyeval(u4, d0, d1, d2);
-}
-
-#else
-
-// The Taylor expansion of asin(x) around 0 is:
-// asin(x) = x + x^3/6 + 3x^5/40 + ...
-// ~ x * P(x^2).
-// Let u = x^2, then P(x^2) = P(u), and |x| = sqrt(u). Note that when
-// |x| <= 0.5, we have |u| <= 0.25.
-// We approximate P(u) by breaking it down by performing range reduction mod
-// 2^-5 = 1/32.
-// So for:
-// k = round(u * 32),
-// y = u - k/32,
-// we have that:
-// x = sqrt(u) = sqrt(k/32 + y),
-// |y| <= 2^-5 = 1/32,
-// and:
-// P(u) = P(k/32 + y) = Q_k(y).
-// Hence :
-// asin(x) = sqrt(k/32 + y) * Q_k(y),
-// Or equivalently:
-// Q_k(y) = asin(sqrt(k/32 + y)) / sqrt(k/32 + y).
-// We generate the coefficients of Q_k by Sollya as following:
-// > procedure ASIN_APPROX(N, Deg) {
-// abs_error = 0;
-// rel_error = 0;
-// deg = [||];
-// for i from 2 to Deg do deg = deg :. i;
-// for i from 1 to N/4 do {
-// F = asin(sqrt(i/N + x))/sqrt(i/N + x);
-// T = taylor(F, 1, 0);
-// T_DD = roundcoefficients(T, [|DD...|]);
-// I = [-1/(2*N), 1/(2*N)];
-// Q = fpminimax(F, deg, [|D...|], I, T_DD);
-// abs_err = dirtyinfnorm(F - Q, I);
-// rel_err = dirtyinfnorm((F - Q)/x^2, I);
-// if (abs_err > abs_error) then abs_error = abs_err;
-// if (rel_err > rel_error) then rel_error = rel_err;
-// d0 = D(coeff(Q, 0));
-// d1 = coeff(Q, 0) - d0;
-// write("{", d0, ", ", d1);
-// d0 = D(coeff(Q, 1)); d1 = coeff(Q, 1) - d0; write(", ", d0, ", ", d1);
-// for j from 2 to Deg do {
-// write(", ", coeff(Q, j));
-// };
-// print("},");
-// };
-// print("Absolute Errors:", D(abs_error));
-// print("Relative Errors:", D(rel_error));
-// };
-// > ASIN_APPROX(32, 9);
-// Absolute Errors: 0x1.69837b5183654p-72
-// Relative Errors: 0x1.4d7f82835bf64p-55
-
-// For k = 0, we use the degree-18 Taylor polynomial of asin(x)/x:
-//
-// > P = 1 + x^2 * DD(1/6) + x^4 * D(3/40) + x^6 * D(5/112) + x^8 * D(35/1152) +
-// x^10 * D(63/2816) + x^12 * D(231/13312) + x^14 * D(143/10240) +
-// x^16 * D(6435/557056) + x^18 * D(12155/1245184);
-// > dirtyinfnorm(asin(x)/x - P, [-1/64, 1/64]);
-// 0x1.999075402cafp-83
-
-constexpr double ASIN_COEFFS[9][12] = {
- {1.0, 0.0, 0x1.5555555555555p-3, 0x1.5555555555555p-57,
- 0x1.3333333333333p-4, 0x1.6db6db6db6db7p-5, 0x1.f1c71c71c71c7p-6,
- 0x1.6e8ba2e8ba2e9p-6, 0x1.1c4ec4ec4ec4fp-6, 0x1.c99999999999ap-7,
- 0x1.7a87878787878p-7, 0x1.3fde50d79435ep-7},
- {0x1.015a397cf0f1cp0, -0x1.eebd6ccfe3ee3p-55, 0x1.5f3581be7b08bp-3,
- -0x1.5df80d0e7237dp-57, 0x1.4519ddf1ae53p-4, 0x1.8eb4b6eeb1696p-5,
- 0x1.17bc85420fec8p-5, 0x1.a8e39b5dcad81p-6, 0x1.53f8df127539bp-6,
- 0x1.1a485a0b0130ap-6, 0x1.e20e6e493002p-7, 0x1.a466a7030f4c9p-7},
- {0x1.02be9ce0b87cdp0, 0x1.e5d09da2e0f04p-56, 0x1.69ab5325bc359p-3,
- -0x1.92f480cfede2dp-57, 0x1.58a4c3097aab1p-4, 0x1.b3db36068dd8p-5,
- 0x1.3b9482184625p-5, 0x1.eedc823765d21p-6, 0x1.98e35d756be6bp-6,
- 0x1.5ea4f1b32731ap-6, 0x1.355115764148ep-6, 0x1.16a5853847c91p-6},
- {0x1.042dc6a65ffbfp0, -0x1.c7ea28dce95d1p-55, 0x1.74c4bd7412f9dp-3,
- 0x1.447024c0a3c87p-58, 0x1.6e09c6d2b72b9p-4, 0x1.ddd9dcdae5315p-5,
- 0x1.656f1f64058b8p-5, 0x1.21a42e4437101p-5, 0x1.eed0350b7edb2p-6,
- 0x1.b6bc877e58c52p-6, 0x1.903a0872eb2a4p-6, 0x1.74da839ddd6d8p-6},
- {0x1.05a8621feb16bp0, -0x1.e5b33b1407c5fp-56, 0x1.809186c2e57ddp-3,
- -0x1.3dcb4d6069407p-60, 0x1.8587d99442dc5p-4, 0x1.06c23d1e75be3p-4,
- 0x1.969024051c67dp-5, 0x1.54e4f934aacfdp-5, 0x1.2d60a732dbc9cp-5,
- 0x1.149f0c046eac7p-5, 0x1.053a56dba1fbap-5, 0x1.f7face3343992p-6},
- {0x1.072f2b6f1e601p0, -0x1.2dcbb0541997p-54, 0x1.8d2397127aebap-3,
- 0x1.ead0c497955fbp-57, 0x1.9f68df88da518p-4, 0x1.21ee26a5900d7p-4,
- 0x1.d08e7081b53a9p-5, 0x1.938dd661713f7p-5, 0x1.71b9f299b72e6p-5,
- 0x1.5fbc7d2450527p-5, 0x1.58573247ec325p-5, 0x1.585a174a6a4cep-5},
- {0x1.08c2f1d638e4cp0, 0x1.b47c159534a3dp-56, 0x1.9a8f592078624p-3,
- -0x1.ea339145b65cdp-57, 0x1.bc04165b57aabp-4, 0x1.410df5f58441dp-4,
- 0x1.0ab6bdf5f8f7p-4, 0x1.e0b92eea1fce1p-5, 0x1.c9094e443a971p-5,
- 0x1.c34651d64bc74p-5, 0x1.caa008d1af08p-5, 0x1.dc165bc0c4fc5p-5},
- {0x1.0a649a73e61f2p0, 0x1.74ac0d817e9c7p-55, 0x1.a8ec30dc9389p-3,
- -0x1.8ab1c0eef300cp-59, 0x1.dbc11ea95061bp-4, 0x1.64e371d661328p-4,
- 0x1.33e0023b3d895p-4, 0x1.2042269c243cep-4, 0x1.1cce74bda223p-4,
- 0x1.244d425572ce9p-4, 0x1.34d475c7f1e3ep-4, 0x1.4d4e653082ad3p-4},
- {0x1.0c152382d7366p0, -0x1.ee6913347c2a6p-54, 0x1.b8550d62bfb6dp-3,
- -0x1.d10aec3f116d5p-57, 0x1.ff1bde0fa3cap-4, 0x1.8e5f3ab69f6a4p-4,
- 0x1.656be8b6527cep-4, 0x1.5c39755dc041ap-4, 0x1.661e6ebd40599p-4,
- 0x1.7ea3dddee2a4fp-4, 0x1.a4f439abb4869p-4, 0x1.d9181c0fda658p-4},
-};
-
-// We calculate the lower part of the approximation P(u).
-LIBC_INLINE DoubleDouble asin_eval(const DoubleDouble &u, unsigned &idx,
- double &err) {
- using fputil::multiply_add;
- // k = round(u * 32).
- double k = fputil::nearest_integer(u.hi * 0x1.0p5);
- idx = static_cast<unsigned>(k);
- // y = u - k/32.
- double y_hi = multiply_add(k, -0x1.0p-5, u.hi); // Exact
- DoubleDouble y = fputil::exact_add(y_hi, u.lo);
- double y2 = y.hi * y.hi;
- // Add double-double errors in addition to the relative errors from y2.
- err = fputil::multiply_add(err, y2, 0x1.0p-102);
- DoubleDouble c0 = fputil::quick_mult(
- y, DoubleDouble{ASIN_COEFFS[idx][3], ASIN_COEFFS[idx][2]});
- double c1 = multiply_add(y.hi, ASIN_COEFFS[idx][5], ASIN_COEFFS[idx][4]);
- double c2 = multiply_add(y.hi, ASIN_COEFFS[idx][7], ASIN_COEFFS[idx][6]);
- double c3 = multiply_add(y.hi, ASIN_COEFFS[idx][9], ASIN_COEFFS[idx][8]);
- double c4 = multiply_add(y.hi, ASIN_COEFFS[idx][11], ASIN_COEFFS[idx][10]);
-
- double y4 = y2 * y2;
- double d0 = multiply_add(y2, c2, c1);
- double d1 = multiply_add(y2, c4, c3);
-
- DoubleDouble r = fputil::exact_add(ASIN_COEFFS[idx][0], c0.hi);
-
- double e1 = multiply_add(y4, d1, d0);
-
- r.lo = multiply_add(y2, e1, ASIN_COEFFS[idx][1] + c0.lo + r.lo);
-
- return r;
-}
-
-// Follow the discussion above, we generate the coefficients of Q_k by Sollya as
-// following:
-// > procedure PRINTF128(a) {
-// write("{");
-// if (a < 0)
-// then write("Sign::NEG, ") else write("Sign::POS, ");
-// a_exp = floor(log2(a)) + 1;
-// write((a + 2 ^ a_exp) * 2 ^ -128);
-// print("},");
-// };
-// > verbosity = 0;
-// > procedure ASIN_APPROX(N, Deg) {
-// abs_error = 0;
-// rel_error = 0;
-// for i from 1 to N / 4 do {
-// Q = fpminimax(asin(sqrt(i / N + x)) / sqrt(i / N + x), Deg,
-// [| 128... | ], [ -1 / (2 * N), 1 / (2 * N) ]);
-// abs_err = dirtyinfnorm(asin(sqrt(i / N + x)) - sqrt(i / N + x) * Q,
-// [ -1 / (2 * N), 1 / (2 * N) ]);
-// rel_err = dirtyinfnorm(asin(sqrt(i / N + x)) / sqrt(i / N + x) - Q,
-// [ -1 / (2 * N), 1 / (2 * N) ]);
-// if (abs_err > abs_error) then abs_error = abs_err;
-// if (rel_err > rel_error) then rel_error = rel_err;
-// write("{");
-// for j from 0 to Deg do PRINTF128(coeff(Q, j));
-// print("},");
-// };
-// print("Absolute Errors:", abs_error);
-// print("Relative Errors:", rel_error);
-// };
-// > ASIN_APPROX(64, 15);
-// ...
-// Absolute Errors: 0x1.0b3...p-129
-// Relative Errors: 0x1.1db...p-128
-//
-// For k = 0, we use Taylor polynomial of asin(x)/x around x = 0.
-// asin(x)/x ~ 1 + x^2/6 + (3 x^4)/40 + (5 x^6)/112 + (35 x^8)/1152 +
-// + (63 x^10)/2816 + (231 x^12)/13312 + (143 x^14)/10240 +
-// + (6435 x^16)/557056 + (12155 x^18)/1245184 +
-// + (46189 x^20)/5505024 + (88179 x^22)/12058624 +
-// + (676039 x^24)/104857600 + (1300075 x^26)/226492416 +
-// + (5014575 x^28)/973078528 + (9694845 x^30)/2080374784.
-
-constexpr Float128 ASIN_COEFFS_F128[17][16] = {
- {
- {Sign::POS, -127, 0x80000000'00000000'00000000'00000000_u128},
- {Sign::POS, -130, 0xaaaaaaaa'aaaaaaaa'aaaaaaaa'aaaaaaab_u128},
- {Sign::POS, -131, 0x99999999'99999999'99999999'9999999a_u128},
- {Sign::POS, -132, 0xb6db6db6'db6db6db'6db6db6d'b6db6db7_u128},
- {Sign::POS, -133, 0xf8e38e38'e38e38e3'8e38e38e'38e38e39_u128},
- {Sign::POS, -133, 0xb745d174'5d1745d1'745d1745'd1745d17_u128},
- {Sign::POS, -133, 0x8e276276'27627627'62762762'76276276_u128},
- {Sign::POS, -134, 0xe4cccccc'cccccccc'cccccccc'cccccccd_u128},
- {Sign::POS, -134, 0xbd43c3c3'c3c3c3c3'c3c3c3c3'c3c3c3c4_u128},
- {Sign::POS, -134, 0x9fef286b'ca1af286'bca1af28'6bca1af3_u128},
- {Sign::POS, -134, 0x89779e79'e79e79e7'9e79e79e'79e79e7a_u128},
- {Sign::POS, -135, 0xef9de9bd'37a6f4de'9bd37a6f'4de9bd38_u128},
- {Sign::POS, -135, 0xd3431eb8'51eb851e'b851eb85'1eb851ec_u128},
- {Sign::POS, -135, 0xbc16ed09'7b425ed0'97b425ed'097b425f_u128},
- {Sign::POS, -135, 0xa8dd1846'9ee58469'ee58469e'e58469ee_u128},
- {Sign::POS, -135, 0x98b41def'7bdef7bd'ef7bdef7'bdef7bdf_u128},
- },
- {
- {Sign::POS, -127, 0x8055f060'94f0f05f'3ac3b927'50a701d9_u128},
- {Sign::POS, -130, 0xad19c2ea'e3dd2429'8d04f71d'b965ee1b_u128},
- {Sign::POS, -131, 0x9dfa882b'7b31af17'f9f19d33'0c45d24b_u128},
- {Sign::POS, -132, 0xbedd3b58'c9e605ef'1404e1f0'4ba57940_u128},
- {Sign::POS, -132, 0x83df2581'cb4fea82'b406f201'2fde6d5c_u128},
- {Sign::POS, -133, 0xc534fe61'9b82dd16'ed5d8a43'f7710526_u128},
- {Sign::POS, -133, 0x9b56fa62'88295ddf'ce8425fe'a04d733e_u128},
- {Sign::POS, -134, 0xfdeddb19'4a030da7'27158080'd24caf46_u128},
- {Sign::POS, -134, 0xd55827db'ff416ea8'042c4d8c'07cddeeb_u128},
- {Sign::POS, -134, 0xb71d73a9'f2ba0688'5eaeeae9'413a0f5f_u128},
- {Sign::POS, -134, 0x9fde87e2'ace91274'38f82666'd619c1ba_u128},
- {Sign::POS, -134, 0x8d876557'5e4626a1'1b621336'93587847_u128},
- {Sign::POS, -135, 0xfd801840'c8710595'6880fe13'a9657f8f_u128},
- {Sign::POS, -135, 0xe54245a9'4c8c2ebb'30488494'64b0e34d_u128},
- {Sign::POS, -135, 0xd11eb46f'4095a661'8890d123'15c96482_u128},
- {Sign::POS, -135, 0xc01a4201'467fbc0b'960618d5'ec2adaa8_u128},
- },
- {
- {Sign::POS, -127, 0x80ad1cbe'7878de11'4293301c'11ce9d49_u128},
- {Sign::POS, -130, 0xaf9ac0df'3d845544'0fe5e31b'9051d03e_u128},
- {Sign::POS, -131, 0xa28ceef8'd7297e05'f94773ad'f4a695c6_u128},
- {Sign::POS, -132, 0xc75a5b77'58b4b11d'396c68ad'6733022b_u128},
- {Sign::POS, -132, 0x8bde42a1'084a6674'50c5bceb'005d4b62_u128},
- {Sign::POS, -133, 0xd471cdae'e2f35a96'bd4bc513'e0ccdf2c_u128},
- {Sign::POS, -133, 0xa9fc6fd5'd204a4e3'e609940c'6b991b67_u128},
- {Sign::POS, -133, 0x8d242d97'ba12b492'e25c7e7c'0c3fcf60_u128},
- {Sign::POS, -134, 0xf0f1ba74'b149afc3'2f0bbab5'a20c6199_u128},
- {Sign::POS, -134, 0xd21b42fb'd8e9098d'19612692'9a043332_u128},
- {Sign::POS, -134, 0xba5e5492'7896a3e7'193a74d5'78631587_u128},
- {Sign::POS, -134, 0xa7a17ae7'fc707f45'910e7a5d'c95251f4_u128},
- {Sign::POS, -134, 0x98889a6a'b0370464'50c950d3'61d79ed7_u128},
- {Sign::POS, -134, 0x8c29330e'4318fd29'25c5b528'84e39e7c_u128},
- {Sign::POS, -134, 0x81e7bf48'b25bc7c0'b9204a4f'd4f5fa8b_u128},
- {Sign::POS, -135, 0xf2801b09'11bf0768'773996dd'5224d852_u128},
- },
- {
- {Sign::POS, -127, 0x81058e3e'f82ba622'ab81cd63'e1a91d57_u128},
- {Sign::POS, -130, 0xb22e7055'c80dd354'8a2f2e8e'860d3f33_u128},
- {Sign::POS, -131, 0xa753ce1a'7e3d1f57'247b37e6'03f93624_u128},
- {Sign::POS, -132, 0xd05c5604'8eca8d18'dcdd76b7'f4b1f185_u128},
- {Sign::POS, -132, 0x947cdd5e'f1d64df0'84f78df1'e2ecb854_u128},
- {Sign::POS, -133, 0xe5218370'2ebbf6e8'3727a755'57843b93_u128},
- {Sign::POS, -133, 0xba482553'383b92eb'186f78f1'8c35d6af_u128},
- {Sign::POS, -133, 0x9d2b034a'7266c6a1'54b78a98'1a547429_u128},
- {Sign::POS, -133, 0x8852f723'feea6046'e125f5a9'64e168e6_u128},
- {Sign::POS, -134, 0xf19c9891'6c896c99'732052fe'5c54e992_u128},
- {Sign::POS, -134, 0xd9cc81a5'c5ddf0f0'd651011e'a8ecd936_u128},
- {Sign::POS, -134, 0xc7173169'dcb6095f'a6160847'b595aaff_u128},
- {Sign::POS, -134, 0xb81cd3f6'4a422ebe'07aeb734'e4dcf3a1_u128},
- {Sign::POS, -134, 0xabf01b1c'd15932aa'698d4382'512318a9_u128},
- {Sign::POS, -134, 0xa1f1cf1b'd889a1ac'7120ca2f'bbbc1745_u128},
- {Sign::POS, -134, 0x99a1b838'e38fbf11'429a4350'76b7d191_u128},
- },
- {
- {Sign::POS, -127, 0x815f4e70'5c3e68f2'e84ed170'78211dfd_u128},
- {Sign::POS, -130, 0xb4d5a992'de1ac4da'16fe6024'3a6cc371_u128},
- {Sign::POS, -131, 0xac526184'bd558c65'66642dce'edc4b04a_u128},
- {Sign::POS, -132, 0xd9ed9b03'46ec0bab'429ea221'4774bbc1_u128},
- {Sign::POS, -132, 0x9dca410c'1efaeb74'87956685'dd5fe848_u128},
- {Sign::POS, -133, 0xf76e411b'a926fc02'7f942265'9c39a882_u128},
- {Sign::POS, -133, 0xcc71b004'eeb60c0f'1d387f76'44b46bf8_u128},
- {Sign::POS, -133, 0xaf527a40'6f1084fb'5019904e'd12d384d_u128},
- {Sign::POS, -133, 0x9a9304b0'd8a9de19'e1803691'269be22c_u128},
- {Sign::POS, -133, 0x8b3d37c0'dbde09ef'342ddf4f'e80dd3fb_u128},
- {Sign::POS, -134, 0xff2e9111'3a961c78'92297bab'cc257804_u128},
- {Sign::POS, -134, 0xed1fb643'f2ca31c1'b0a1553a'e077285a_u128},
- {Sign::POS, -134, 0xdeeb0f5e'81ad5e30'78d79ae3'83be1c18_u128},
- {Sign::POS, -134, 0xd3a13ba6'8ce9abfc'a66eb1fd'c0c760fd_u128},
- {Sign::POS, -134, 0xcaa8c381'd44bb44f'0ab25126'9a5fae10_u128},
- {Sign::POS, -134, 0xc36fb2c4'244401cf'10dd8a39'78ccbf7f_u128},
- },
- {
- {Sign::POS, -127, 0x81ba6750'6064f4dd'08015b7c'713688f0_u128},
- {Sign::POS, -130, 0xb791524b'd975fdd1'584037b7'103b42ca_u128},
- {Sign::POS, -131, 0xb18c26c5'3ced9856'db5bc672'cc95a64f_u128},
- {Sign::POS, -132, 0xe4199ce5'd25be89b'4a0ad208'da77022d_u128},
- {Sign::POS, -132, 0xa7d77999'0f80e3e9'7e97e9d1'0e337550_u128},
- {Sign::POS, -132, 0x85c3e039'8959c95b'e6e1e87f'7e6636b1_u128},
- {Sign::POS, -133, 0xe0b90ecd'95f7e6eb'a675bae0'628bd214_u128},
- {Sign::POS, -133, 0xc3edb6b4'ed0a684c'c7a3ee4d'f1dcd3f9_u128},
- {Sign::POS, -133, 0xafa274d2'e66e1f61'9e8ab3c7'7221214e_u128},
- {Sign::POS, -133, 0xa0dd903d'e110b71a'8a1fc9df'cc080308_u128},
- {Sign::POS, -133, 0x95e2f38c'60441961'72b90625'e3a37573_u128},
- {Sign::POS, -133, 0x8d9fe38f'2c705139'029f857c'9f628b2b_u128},
- {Sign::POS, -133, 0x8762410a'4967a974'6b609e83'7c025a39_u128},
- {Sign::POS, -133, 0x82b220be'd9ec0e5a'9ce9af7c'c65c94b9_u128},
- {Sign::POS, -134, 0xfe866073'2312c056'4265d82a'3afea10c_u128},
- {Sign::POS, -134, 0xf99b667c'5f8ef6a6'11fafa4d'5c76ebb3_u128},
- },
- {
- {Sign::POS, -127, 0x8216e353'2ffdf638'15d72316'a2f327f2_u128},
- {Sign::POS, -130, 0xba625eba'097ce944'7024c0a3'c873729b_u128},
- {Sign::POS, -131, 0xb704e369'5b95ce44'cde30106'90e92cc3_u128},
- {Sign::POS, -132, 0xeeecee6d'7298b8a3'075da5d7'456bdcde_u128},
- {Sign::POS, -132, 0xb2b78fb1'fcfdc273'1d1ac11c'e29c16f1_u128},
- {Sign::POS, -132, 0x90d21722'148fdaf5'0d566a01'0bb8784b_u128},
- {Sign::POS, -133, 0xf7681c54'9771ebb6'17686858'eb5e1caf_u128},
- {Sign::POS, -133, 0xdb5e45c0'52ec0c1c'ff28765e'd4c44bfb_u128},
- {Sign::POS, -133, 0xc7ff0dd7'a34ee29b'7cb689af'fe887bf5_u128},
- {Sign::POS, -133, 0xba4e6f37'a98a3e3f'f1175427'20f45c82_u128},
- {Sign::POS, -133, 0xb08f6e11'688e4174'b3d48abe'c0a6d5cd_u128},
- {Sign::POS, -133, 0xa9af6a33'14aabe45'26da1218'05bbb52e_u128},
- {Sign::POS, -133, 0xa4fd22fa'1b4f0d7f'1456af96'cbd0cde6_u128},
- {Sign::POS, -133, 0xa20229b4'7e9c2e39'22c49987'66a05c5a_u128},
- {Sign::POS, -133, 0xa0775ca8'4409c735'351d01f1'34467927_u128},
- {Sign::POS, -133, 0xa010d2d9'08428a53'53603f20'66c8b8ba_u128},
- },
- {
- {Sign::POS, -127, 0x8274cd6a'f25e642d'0b1a02fb'03f53f3e_u128},
- {Sign::POS, -130, 0xbd49d2c8'b9005b2a'ee795b17'92181a48_u128},
- {Sign::POS, -131, 0xbcc0ac23'98e00fd7'c40811f5'486aca6a_u128},
- {Sign::POS, -132, 0xfa756493'b381b917'6cdea268'e44dd2fd_u128},
- {Sign::POS, -132, 0xbe7fce1e'462b43c6'0537d6f7'138c87ac_u128},
- {Sign::POS, -132, 0x9d00958b'edc83095'b4cc907c'a92c30f1_u128},
- {Sign::POS, -132, 0x886a2440'ed93d825'333c19c2'6de36d73_u128},
- {Sign::POS, -133, 0xf616ebc0'4f576462'd9312544'e8fbe0fd_u128},
- {Sign::POS, -133, 0xe43f4c9d'ebb5d685'00903a00'7bd6ad39_u128},
- {Sign::POS, -133, 0xd8516eab'32337672'569b4e19'a44e795c_u128},
- {Sign::POS, -133, 0xd091fa04'954666ee'cc4da283'82e977c0_u128},
- {Sign::POS, -133, 0xcbf13442'c4c0f859'0449c2c4'2fc046fe_u128},
- {Sign::POS, -133, 0xc9c1d1b4'dea4c76c'd101e562'dc3af77f_u128},
- {Sign::POS, -133, 0xc9924d2a'b8ec37d9'80af1780'0fb63e4e_u128},
- {Sign::POS, -133, 0xcb24b252'1ff37e4a'41f35260'2b9ace95_u128},
- {Sign::POS, -133, 0xce2d87ac'194a6304'1658ed0e'4cdb8161_u128},
- },
- {
- {Sign::POS, -127, 0x82d4310f'f58b570d'266275fc'1d085c87_u128},
- {Sign::POS, -130, 0xc048c361'72bee7b0'8d2ca7e5'afe4f335_u128},
- {Sign::POS, -131, 0xc2c3ecca'216e290e'b99c5c53'5d48595a_u128},
- {Sign::POS, -131, 0x83611e8f'3adf2217'be3c342a'dfb1c562_u128},
- {Sign::POS, -132, 0xcb481202'8b0ba9aa'e586f73d'faea68e4_u128},
- {Sign::POS, -132, 0xaa727c9a'4caba65d'c8dc13ef'8bed52e4_u128},
- {Sign::POS, -132, 0x96b05462'efac126e'db6871d0'0be1eff9_u128},
- {Sign::POS, -132, 0x8a4f8752'9b3c9232'63eb1596'a2c83eb4_u128},
- {Sign::POS, -132, 0x828be6f4'1b14e6e6'8efc1012'2afe425a_u128},
- {Sign::POS, -133, 0xfbd2f055'9d699ea9'b572008e'1fb08088_u128},
- {Sign::POS, -133, 0xf71b3c70'dc4610e6'bc1e581c'817b88bd_u128},
- {Sign::POS, -133, 0xf5e8ebf6'3b0aef3f'97ba4c8f'e49b6f0a_u128},
- {Sign::POS, -133, 0xf7986238'1eb8bd7a'73577ed0'c05e4abf_u128},
- {Sign::POS, -133, 0xfbc3832a'a903cd65'a46ee523'f342c621_u128},
- {Sign::POS, -132, 0x811ea5f3'7409245e'1777fdd1'59b29f80_u128},
- {Sign::POS, -132, 0x85619588'b83c90ef'67740d6a'd2f372a8_u128},
- },
- {
- {Sign::POS, -127, 0x83351a49'8764656f'e1774024'a5e751a6_u128},
- {Sign::POS, -130, 0xc36057da'23d39c2b'336474e0'3a893914_u128},
- {Sign::POS, -131, 0xc913714c'a46cc0bf'3bdd68ba'53a309d4_u128},
- {Sign::POS, -131, 0x89f2254d'f1469d60'e1324bac'95db6742_u128},
- {Sign::POS, -132, 0xd92b27f6'38df6911'5842365c'c120cc63_u128},
- {Sign::POS, -132, 0xb94ff079'7848d391'486efffa'a6fbc37f_u128},
- {Sign::POS, -132, 0xa6c03919'862e8437'70f86a73'43da3a6e_u128},
- {Sign::POS, -132, 0x9bcb70c9'a378e97f'a59f25f3'ba202e33_u128},
- {Sign::POS, -132, 0x95b103b0'62aa9f64'ee2d6146'76020bc5_u128},
- {Sign::POS, -132, 0x92fa4a1c'7d7fd161'8f25aa4e'f65ca52f_u128},
- {Sign::POS, -132, 0x92d387a2'c5dd771d'4015ca29'e3eda1d9_u128},
- {Sign::POS, -132, 0x94c13c5c'997615c3'8a2f63c8'c314226f_u128},
- {Sign::POS, -132, 0x987b8c8f'5e9e7a5f'e8497909'd60d1194_u128},
- {Sign::POS, -132, 0x9ddb0978'da99e6ad'83d5eca2'9d079ef7_u128},
- {Sign::POS, -132, 0xa4d9aeee'4b512ed4'5ec95cd1'37ce3f22_u128},
- {Sign::POS, -132, 0xad602af3'1e14d681'8a267da2'57c030de_u128},
- },
- {
- {Sign::POS, -127, 0x839795b7'8f3005a4'689f57cc'd201f7dc_u128},
- {Sign::POS, -130, 0xc691cb89'3d75d3d5'a1892f2a'bf54ec45_u128},
- {Sign::POS, -131, 0xcfb46fc4'6d28c32c'9ae5ad3d'a7749dc8_u128},
- {Sign::POS, -131, 0x90f71352'c806c830'20edb8b2'7594386b_u128},
- {Sign::POS, -132, 0xe8473840'd511dc77'd63def5d'7f4de9c0_u128},
- {Sign::POS, -132, 0xc9c6eb30'aaf2b63d'ec20f671'8689534a_u128},
- {Sign::POS, -132, 0xb8dcfa84'eb6cab93'3023ddcc'b8f68a2f_u128},
- {Sign::POS, -132, 0xafde4094'c1a14390'9609a3ea'847225a9_u128},
- {Sign::POS, -132, 0xac1254e7'5852a836'b2aca5e5'0cfc484f_u128},
- {Sign::POS, -132, 0xac0d3ffa'd6171016'b1a12557'858663c1_u128},
- {Sign::POS, -132, 0xaf0877f9'0ca5c52f'fc54b5af'b5cbc350_u128},
- {Sign::POS, -132, 0xb498574f'af349a2b'f391ff83'b3570919_u128},
- {Sign::POS, -132, 0xbc87c7bb'34182440'280647cd'976affb0_u128},
- {Sign::POS, -132, 0xc6c5688f'58a42593'4569de36'0855c393_u128},
- {Sign::POS, -132, 0xd368b088'5bb9496a'dd7c92df'8798aaf7_u128},
- {Sign::POS, -132, 0xe272168a'c8dbe668'381542bf'fc24c266_u128},
- },
- {
- {Sign::POS, -127, 0x83fbb09c'fbb0ebf4'208c9037'70373f79_u128},
- {Sign::POS, -130, 0xc9de6f84'8e652b0b'3b2a2bb9'f7ce3de8_u128},
- {Sign::POS, -131, 0xd6ac93c7'6e215233'f184fdcc'e5872970_u128},
- {Sign::POS, -131, 0x987a35b9'87c02522'1927dee9'70fc6b18_u128},
- {Sign::POS, -132, 0xf8be450d'266409a9'2e534ffd'905f4424_u128},
- {Sign::POS, -132, 0xdc0c36d7'34415e3b'c5121c4d'4e28c17d_u128},
- {Sign::POS, -132, 0xcd551b98'81d982a8'1399d9ba'ddf55821_u128},
- {Sign::POS, -132, 0xc6f91e3f'428d6be3'646f3147'20445145_u128},
- {Sign::POS, -132, 0xc64f100c'85e1e8f1'6f501d1e'2155f872_u128},
- {Sign::POS, -132, 0xc9fe25ae'295f1f24'5924cf9a'036a31f2_u128},
- {Sign::POS, -132, 0xd157410e'fcc10fbb'fceb318a'b4990bd7_u128},
- {Sign::POS, -132, 0xdc0aeb56'ca679f92'3b3c44d8'99b1add7_u128},
- {Sign::POS, -132, 0xea05b383'bc339550'e5c5c34b'bfa416a1_u128},
- {Sign::POS, -132, 0xfb5e3897'5a5c8f62'280a90dc'9ebe9107_u128},
- {Sign::POS, -131, 0x88301d81'b38f225d'2226ab7e'df342d90_u128},
- {Sign::POS, -131, 0x949e3465'e4a8aef7'46311182'5fc3fde8_u128},
- },
- {
- {Sign::POS, -127, 0x846178eb'1c7260da'3e0aca9a'51e68d84_u128},
- {Sign::POS, -130, 0xcd47ac90'3c311c2b'98dd7493'4656d210_u128},
- {Sign::POS, -131, 0xde020b2d'abd5628c'b88634e5'73f312fc_u128},
- {Sign::POS, -131, 0xa086fafa'c220fb73'9939cae3'2d69683f_u128},
- {Sign::POS, -131, 0x855b5efa'f6963d73'e4664cb1'd43f03a9_u128},
- {Sign::POS, -132, 0xf05c9774'fe0de25c'ccf1c1df'd2ed9941_u128},
- {Sign::POS, -132, 0xe484a941'19639229'f06ae955'f8edc7d1_u128},
- {Sign::POS, -132, 0xe1a32bb2'52ca122c'bf2f0904'cfc476cb_u128},
- {Sign::POS, -132, 0xe528e091'7bb8a01a'9218ce3e'1e85af60_u128},
- {Sign::POS, -132, 0xeddd556a'faa2d46f'e91c61fa'adf12aec_u128},
- {Sign::POS, -132, 0xfb390fa3'15e9d55f'5683c0c4'c7719f81_u128},
- {Sign::POS, -131, 0x868e5fa4'15597c8f'7c42a262'8f2d6332_u128},
- {Sign::POS, -131, 0x91d79767'a3d037f9'cd84ead5'c0714310_u128},
- {Sign::POS, -131, 0x9fa6a035'915bc052'377a8abb'faf4e3c6_u128},
- {Sign::POS, -131, 0xb04edefd'6ac2a93e'ec33e6f6'3d53e7c2_u128},
- {Sign::POS, -131, 0xc416980d'dc5c186b'7bdcded6'97ea5844_u128},
- },
- {
- {Sign::POS, -127, 0x84c8fd4d'ffdf9fc6'bdd7ebca'88183d7b_u128},
- {Sign::POS, -130, 0xd0cf0544'11dbf845'cb6eeae5'bc980e2f_u128},
- {Sign::POS, -131, 0xe5bb9480'7ce0eaca'74300a46'8398e944_u128},
- {Sign::POS, -131, 0xa92a18f8'd611860b'5f2ef8c6'8e8ca002_u128},
- {Sign::POS, -131, 0x8f2e1684'17eb4e6c'1ec44b9b'e4b1c3e5_u128},
- {Sign::POS, -131, 0x837f1764'0ee8f416'8694b4a1'c647af0c_u128},
- {Sign::POS, -132, 0xfed7e2a9'05a5190e'b7d70a61'a24ad801_u128},
- {Sign::POS, -131, 0x803f29ff'dc6fd2bc'3c3c4b50'a9dc860c_u128},
- {Sign::POS, -131, 0x84c61e09'b8aa35e4'96239f9c'b1d00b3c_u128},
- {Sign::POS, -131, 0x8c7ed311'f77980d6'842ddf90'6a68a0bc_u128},
- {Sign::POS, -131, 0x9746077b'd397c2d1'038a4744'a76f5fb5_u128},
- {Sign::POS, -131, 0xa5341277'c4185ace'54f26328'322158e8_u128},
- {Sign::POS, -131, 0xb68d78f5'0972f6de'9189aa23'd3ecefc2_u128},
- {Sign::POS, -131, 0xcbbcefc2'15bade4e'f1d36947'c8b6e460_u128},
- {Sign::POS, -131, 0xe564a459'c851390d'd45a4748'f29f182b_u128},
- {Sign::POS, -130, 0x820ea28b'c89662c3'2a64ccdc'efb2b259_u128},
- },
- {
- {Sign::POS, -127, 0x85324d39'f30f9174'ac0d817e'9c744b0b_u128},
- {Sign::POS, -130, 0xd476186e'49c47f3a'a71f8886'7f9f21c4_u128},
- {Sign::POS, -131, 0xede08f54'a830e87b'07881700'65e57b6c_u128},
- {Sign::POS, -131, 0xb271b8eb'309963ee'89187c73'0b92f7d5_u128},
- {Sign::POS, -131, 0x99f0011d'95d3a6dd'282bd00a'db808151_u128},
- {Sign::POS, -131, 0x9021134e'02b479e7'3aabf9bb'b7ab6cf3_u128},
- {Sign::POS, -131, 0x8e673bf2'f11db54a'909c4c72'6389499f_u128},
- {Sign::POS, -131, 0x9226a371'88dd55f7'bfe21777'4a42a7ae_u128},
- {Sign::POS, -131, 0x9a4d78fc'9df79d9a'44609c02'a625808a_u128},
- {Sign::POS, -131, 0xa68335fb'41d2d91c'e7bbd2a3'31a1d17b_u128},
- {Sign::POS, -131, 0xb6d89c39'28d0cb26'809d4df6'e55cba1a_u128},
- {Sign::POS, -131, 0xcba71468'9177fc2d'7f23df2f'37226488_u128},
- {Sign::POS, -131, 0xe5846de8'44833ae9'34416c87'0315eb9e_u128},
- {Sign::POS, -130, 0x82a07032'64e6226b'200d94a1'66fc7951_u128},
- {Sign::POS, -130, 0x9602695c'b6fa8886'68ca0cba'b59ea683_u128},
- {Sign::POS, -130, 0xad7d185a'ab3d14dd'd908a7b1'c57352bb_u128},
- },
- {
- {Sign::POS, -127, 0x859d78fa'4405d8fa'287dbc69'95d0975e_u128},
- {Sign::POS, -130, 0xd83ea3bc'131d6baa'67c51d88'4c4dae01_u128},
- {Sign::POS, -131, 0xf6790edb'df07342b'aad85870'167af128_u128},
- {Sign::POS, -131, 0xbc6daa33'12be0f85'bc7fa753'52b10a83_u128},
- {Sign::POS, -131, 0xa5bd41bc'9c986b13'1af2542e'92aacb59_u128},
- {Sign::POS, -131, 0x9e4358bc'24e04364'b4539b76'e444b790_u128},
- {Sign::POS, -131, 0x9f7fc21b'dca1f2b5'f3f6d44b'c5a37626_u128},
- {Sign::POS, -131, 0xa6fd793c'0b9c44c1'30a518cc'66b5e511_u128},
- {Sign::POS, -131, 0xb3dccfac'cd1592b3'bcd6b7c0'9749993d_u128},
- {Sign::POS, -131, 0xc6056c3a'4a5f329a'48f1429d'27f930fc_u128},
- {Sign::POS, -131, 0xddd9e529'858a4502'6e7f3d1c'1e7dcb89_u128},
- {Sign::POS, -131, 0xfc1bccee'dc8d2567'1721c468'6f7f53ec_u128},
- {Sign::POS, -130, 0x90f2bb21'5cdbe7e2'f9ef8e12'059cc66a_u128},
- {Sign::POS, -130, 0xa857d5df'5b4da940'15ce4e95'7201fc79_u128},
- {Sign::POS, -130, 0xc54119c0'10c02bf4'd87ece17'1ef85c5f_u128},
- {Sign::POS, -130, 0xe8c50ebc'880356de'2c1f4c42'9ee9748f_u128},
- },
- {
- {Sign::POS, -127, 0x860a91c1'6b9b2c23'2dd99707'ab3d688b_u128},
- {Sign::POS, -130, 0xdc2a86b1'5fdb645d'ea2781dd'25555f49_u128},
- {Sign::POS, -131, 0xff8def07'd1e514d7'b2e8ebb6'5c3afe5e_u128},
- {Sign::POS, -131, 0xc72f9d5b'4fb559e3'20db92e3'a5ae3f73_u128},
- {Sign::POS, -131, 0xb2b5f45b'1d26f4dd'0b210309'fb68914f_u128},
- {Sign::POS, -131, 0xae1cbaae'c7b55465'4da858f5'47e62a37_u128},
- {Sign::POS, -131, 0xb30f3998'10202a0d'a52ec085'a7d63289_u128},
- {Sign::POS, -131, 0xbf51f27f'b7aff89d'dc24e2aa'208d2054_u128},
- {Sign::POS, -131, 0xd250735e'87d0b527'6f99bcc9'bd6fc717_u128},
- {Sign::POS, -131, 0xec543ec2'bddb2efb'36d9ce81'a7c84336_u128},
- {Sign::POS, -130, 0x871f73e3'298ef45c'eed83998'2bc731b9_u128},
- {Sign::POS, -130, 0x9cbb5447'af8574f1'21fa4cda'93d82b7e_u128},
- {Sign::POS, -130, 0xb7f5a6c0'430a347f'11b22cde'91de0885_u128},
- {Sign::POS, -130, 0xda153cc4'14abdb96'840df7c2'3299fec0_u128},
- {Sign::POS, -129, 0x826c129b'3e4a2612'b2cd11f1'4d2ba60c_u128},
- {Sign::POS, -129, 0x9d19c289'fc0e8aa4'f351418b'b760ce90_u128},
- },
-};
-
-constexpr Float128 PI_OVER_TWO_F128 = {
- Sign::POS, -127, 0xc90fdaa2'2168c234'c4c6628b'80dc1cd1_u128};
-
-constexpr Float128 PI_F128 = {Sign::POS, -126,
- 0xc90fdaa2'2168c234'c4c6628b'80dc1cd1_u128};
-
-LIBC_INLINE Float128 asin_eval(const Float128 &u, unsigned idx) {
- return fputil::polyeval(u, ASIN_COEFFS_F128[idx][0], ASIN_COEFFS_F128[idx][1],
- ASIN_COEFFS_F128[idx][2], ASIN_COEFFS_F128[idx][3],
- ASIN_COEFFS_F128[idx][4], ASIN_COEFFS_F128[idx][5],
- ASIN_COEFFS_F128[idx][6], ASIN_COEFFS_F128[idx][7],
- ASIN_COEFFS_F128[idx][8], ASIN_COEFFS_F128[idx][9],
- ASIN_COEFFS_F128[idx][10], ASIN_COEFFS_F128[idx][11],
- ASIN_COEFFS_F128[idx][12], ASIN_COEFFS_F128[idx][13],
- ASIN_COEFFS_F128[idx][14], ASIN_COEFFS_F128[idx][15]);
-}
-
-#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
-} // anonymous namespace
-
-} // namespace LIBC_NAMESPACE_DECL
-
-#endif // LLVM_LIBC_SRC_MATH_GENERIC_ASIN_UTILS_H
diff --git a/libc/src/math/generic/asinf.cpp b/libc/src/math/generic/asinf.cpp
index 12383bf..77d6de9 100644
--- a/libc/src/math/generic/asinf.cpp
+++ b/libc/src/math/generic/asinf.cpp
@@ -17,7 +17,7 @@
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA
-#include "inv_trigf_utils.h"
+#include "src/__support/math/inv_trigf_utils.h"
namespace LIBC_NAMESPACE_DECL {
@@ -44,6 +44,7 @@ static constexpr fputil::ExceptValues<float, N_EXCEPTS> ASINF_EXCEPTS_HI = {{
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
LLVM_LIBC_FUNCTION(float, asinf, (float x)) {
+ using namespace inv_trigf_utils_internal;
using FPBits = typename fputil::FPBits<float>;
FPBits xbits(x);
diff --git a/libc/src/math/generic/asinhf.cpp b/libc/src/math/generic/asinhf.cpp
index 0bb7065..3aed3bc 100644
--- a/libc/src/math/generic/asinhf.cpp
+++ b/libc/src/math/generic/asinhf.cpp
@@ -19,6 +19,7 @@
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(float, asinhf, (float x)) {
+ using namespace acoshf_internal;
using FPBits_t = typename fputil::FPBits<float>;
FPBits_t xbits(x);
uint32_t x_u = xbits.uintval();
diff --git a/libc/src/math/generic/asinhf16.cpp b/libc/src/math/generic/asinhf16.cpp
index 7878632..0a0b471 100644
--- a/libc/src/math/generic/asinhf16.cpp
+++ b/libc/src/math/generic/asinhf16.cpp
@@ -49,6 +49,7 @@ static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ASINHF16_EXCEPTS{{
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
LLVM_LIBC_FUNCTION(float16, asinhf16, (float16 x)) {
+ using namespace acoshf_internal;
using FPBits = fputil::FPBits<float16>;
FPBits xbits(x);
diff --git a/libc/src/math/generic/atan2f.cpp b/libc/src/math/generic/atan2f.cpp
index c04b0eb..32b977f 100644
--- a/libc/src/math/generic/atan2f.cpp
+++ b/libc/src/math/generic/atan2f.cpp
@@ -8,7 +8,6 @@
#include "src/math/atan2f.h"
#include "hdr/fenv_macros.h"
-#include "inv_trigf_utils.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
@@ -18,6 +17,7 @@
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/math/inv_trigf_utils.h"
#if defined(LIBC_MATH_HAS_SKIP_ACCURATE_PASS) && \
defined(LIBC_MATH_HAS_INTERMEDIATE_COMP_IN_FLOAT)
@@ -236,6 +236,7 @@ float atan2f_double_double(double num_d, double den_d, double q_d, int idx,
// which is about rounding errors of double-double (2^-104).
LLVM_LIBC_FUNCTION(float, atan2f, (float y, float x)) {
+ using namespace inv_trigf_utils_internal;
using FPBits = typename fputil::FPBits<float>;
constexpr double IS_NEG[2] = {1.0, -1.0};
constexpr double PI = 0x1.921fb54442d18p1;
diff --git a/libc/src/math/generic/atanf.cpp b/libc/src/math/generic/atanf.cpp
index 46196dbe..22f962e 100644
--- a/libc/src/math/generic/atanf.cpp
+++ b/libc/src/math/generic/atanf.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "src/math/atanf.h"
-#include "inv_trigf_utils.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
#include "src/__support/FPUtil/except_value_utils.h"
@@ -16,10 +15,12 @@
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/math/inv_trigf_utils.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(float, atanf, (float x)) {
+ using namespace inv_trigf_utils_internal;
using FPBits = typename fputil::FPBits<float>;
constexpr double FINAL_SIGN[2] = {1.0, -1.0};
diff --git a/libc/src/math/generic/atanhf.cpp b/libc/src/math/generic/atanhf.cpp
index f6fde76..602a8f0 100644
--- a/libc/src/math/generic/atanhf.cpp
+++ b/libc/src/math/generic/atanhf.cpp
@@ -16,6 +16,7 @@
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(float, atanhf, (float x)) {
+ using namespace acoshf_internal;
using FPBits = typename fputil::FPBits<float>;
FPBits xbits(x);
diff --git a/libc/src/math/generic/common_constants.cpp b/libc/src/math/generic/common_constants.cpp
index 4dcf84d..42e3ff0 100644
--- a/libc/src/math/generic/common_constants.cpp
+++ b/libc/src/math/generic/common_constants.cpp
@@ -51,52 +51,6 @@ const float ONE_OVER_F_FLOAT[128] = {
0x1.08421p-1f, 0x1.07326p-1f, 0x1.0624dep-1f, 0x1.05198p-1f,
0x1.041042p-1f, 0x1.03091cp-1f, 0x1.020408p-1f, 0x1.010102p-1f};
-// Lookup table for (1/f) where f = 1 + n*2^(-7), n = 0..127.
-const double ONE_OVER_F[128] = {
- 0x1.0000000000000p+0, 0x1.fc07f01fc07f0p-1, 0x1.f81f81f81f820p-1,
- 0x1.f44659e4a4271p-1, 0x1.f07c1f07c1f08p-1, 0x1.ecc07b301ecc0p-1,
- 0x1.e9131abf0b767p-1, 0x1.e573ac901e574p-1, 0x1.e1e1e1e1e1e1ep-1,
- 0x1.de5d6e3f8868ap-1, 0x1.dae6076b981dbp-1, 0x1.d77b654b82c34p-1,
- 0x1.d41d41d41d41dp-1, 0x1.d0cb58f6ec074p-1, 0x1.cd85689039b0bp-1,
- 0x1.ca4b3055ee191p-1, 0x1.c71c71c71c71cp-1, 0x1.c3f8f01c3f8f0p-1,
- 0x1.c0e070381c0e0p-1, 0x1.bdd2b899406f7p-1, 0x1.bacf914c1bad0p-1,
- 0x1.b7d6c3dda338bp-1, 0x1.b4e81b4e81b4fp-1, 0x1.b2036406c80d9p-1,
- 0x1.af286bca1af28p-1, 0x1.ac5701ac5701bp-1, 0x1.a98ef606a63bep-1,
- 0x1.a6d01a6d01a6dp-1, 0x1.a41a41a41a41ap-1, 0x1.a16d3f97a4b02p-1,
- 0x1.9ec8e951033d9p-1, 0x1.9c2d14ee4a102p-1, 0x1.999999999999ap-1,
- 0x1.970e4f80cb872p-1, 0x1.948b0fcd6e9e0p-1, 0x1.920fb49d0e229p-1,
- 0x1.8f9c18f9c18fap-1, 0x1.8d3018d3018d3p-1, 0x1.8acb90f6bf3aap-1,
- 0x1.886e5f0abb04ap-1, 0x1.8618618618618p-1, 0x1.83c977ab2beddp-1,
- 0x1.8181818181818p-1, 0x1.7f405fd017f40p-1, 0x1.7d05f417d05f4p-1,
- 0x1.7ad2208e0ecc3p-1, 0x1.78a4c8178a4c8p-1, 0x1.767dce434a9b1p-1,
- 0x1.745d1745d1746p-1, 0x1.724287f46debcp-1, 0x1.702e05c0b8170p-1,
- 0x1.6e1f76b4337c7p-1, 0x1.6c16c16c16c17p-1, 0x1.6a13cd1537290p-1,
- 0x1.6816816816817p-1, 0x1.661ec6a5122f9p-1, 0x1.642c8590b2164p-1,
- 0x1.623fa77016240p-1, 0x1.6058160581606p-1, 0x1.5e75bb8d015e7p-1,
- 0x1.5c9882b931057p-1, 0x1.5ac056b015ac0p-1, 0x1.58ed2308158edp-1,
- 0x1.571ed3c506b3ap-1, 0x1.5555555555555p-1, 0x1.5390948f40febp-1,
- 0x1.51d07eae2f815p-1, 0x1.5015015015015p-1, 0x1.4e5e0a72f0539p-1,
- 0x1.4cab88725af6ep-1, 0x1.4afd6a052bf5bp-1, 0x1.49539e3b2d067p-1,
- 0x1.47ae147ae147bp-1, 0x1.460cbc7f5cf9ap-1, 0x1.446f86562d9fbp-1,
- 0x1.42d6625d51f87p-1, 0x1.4141414141414p-1, 0x1.3fb013fb013fbp-1,
- 0x1.3e22cbce4a902p-1, 0x1.3c995a47babe7p-1, 0x1.3b13b13b13b14p-1,
- 0x1.3991c2c187f63p-1, 0x1.3813813813814p-1, 0x1.3698df3de0748p-1,
- 0x1.3521cfb2b78c1p-1, 0x1.33ae45b57bcb2p-1, 0x1.323e34a2b10bfp-1,
- 0x1.30d190130d190p-1, 0x1.2f684bda12f68p-1, 0x1.2e025c04b8097p-1,
- 0x1.2c9fb4d812ca0p-1, 0x1.2b404ad012b40p-1, 0x1.29e4129e4129ep-1,
- 0x1.288b01288b013p-1, 0x1.27350b8812735p-1, 0x1.25e22708092f1p-1,
- 0x1.2492492492492p-1, 0x1.23456789abcdfp-1, 0x1.21fb78121fb78p-1,
- 0x1.20b470c67c0d9p-1, 0x1.1f7047dc11f70p-1, 0x1.1e2ef3b3fb874p-1,
- 0x1.1cf06ada2811dp-1, 0x1.1bb4a4046ed29p-1, 0x1.1a7b9611a7b96p-1,
- 0x1.19453808ca29cp-1, 0x1.1811811811812p-1, 0x1.16e0689427379p-1,
- 0x1.15b1e5f75270dp-1, 0x1.1485f0e0acd3bp-1, 0x1.135c81135c811p-1,
- 0x1.12358e75d3033p-1, 0x1.1111111111111p-1, 0x1.0fef010fef011p-1,
- 0x1.0ecf56be69c90p-1, 0x1.0db20a88f4696p-1, 0x1.0c9714fbcda3bp-1,
- 0x1.0b7e6ec259dc8p-1, 0x1.0a6810a6810a7p-1, 0x1.0953f39010954p-1,
- 0x1.0842108421084p-1, 0x1.073260a47f7c6p-1, 0x1.0624dd2f1a9fcp-1,
- 0x1.05197f7d73404p-1, 0x1.0410410410410p-1, 0x1.03091b51f5e1ap-1,
- 0x1.0204081020408p-1, 0x1.0101010101010p-1};
-
// Lookup table for log(f) = log(1 + n*2^(-7)) where n = 0..127,
// computed and stored as float precision constants.
// Generated by Sollya with the following commands:
@@ -136,52 +90,6 @@ const float LOG_F_FLOAT[128] = {
0x1.52a2d2p-1f, 0x1.54b246p-1f, 0x1.56bf9ep-1f, 0x1.58cadcp-1f,
0x1.5ad404p-1f, 0x1.5cdb1ep-1f, 0x1.5ee02ap-1f, 0x1.60e33p-1f};
-// Lookup table for log(f) = log(1 + n*2^(-7)) where n = 0..127.
-const double LOG_F[128] = {
- 0x0.0000000000000p+0, 0x1.fe02a6b106788p-8, 0x1.fc0a8b0fc03e3p-7,
- 0x1.7b91b07d5b11ap-6, 0x1.f829b0e783300p-6, 0x1.39e87b9febd5fp-5,
- 0x1.77458f632dcfcp-5, 0x1.b42dd711971bep-5, 0x1.f0a30c01162a6p-5,
- 0x1.16536eea37ae0p-4, 0x1.341d7961bd1d0p-4, 0x1.51b073f06183fp-4,
- 0x1.6f0d28ae56b4bp-4, 0x1.8c345d6319b20p-4, 0x1.a926d3a4ad563p-4,
- 0x1.c5e548f5bc743p-4, 0x1.e27076e2af2e5p-4, 0x1.fec9131dbeabap-4,
- 0x1.0d77e7cd08e59p-3, 0x1.1b72ad52f67a0p-3, 0x1.29552f81ff523p-3,
- 0x1.371fc201e8f74p-3, 0x1.44d2b6ccb7d1ep-3, 0x1.526e5e3a1b437p-3,
- 0x1.5ff3070a793d3p-3, 0x1.6d60fe719d21cp-3, 0x1.7ab890210d909p-3,
- 0x1.87fa06520c910p-3, 0x1.9525a9cf456b4p-3, 0x1.a23bc1fe2b563p-3,
- 0x1.af3c94e80bff2p-3, 0x1.bc286742d8cd6p-3, 0x1.c8ff7c79a9a21p-3,
- 0x1.d5c216b4fbb91p-3, 0x1.e27076e2af2e5p-3, 0x1.ef0adcbdc5936p-3,
- 0x1.fb9186d5e3e2ap-3, 0x1.0402594b4d040p-2, 0x1.0a324e27390e3p-2,
- 0x1.1058bf9ae4ad5p-2, 0x1.1675cababa60ep-2, 0x1.1c898c16999fap-2,
- 0x1.22941fbcf7965p-2, 0x1.2895a13de86a3p-2, 0x1.2e8e2bae11d30p-2,
- 0x1.347dd9a987d54p-2, 0x1.3a64c556945e9p-2, 0x1.404308686a7e3p-2,
- 0x1.4618bc21c5ec2p-2, 0x1.4be5f957778a0p-2, 0x1.51aad872df82dp-2,
- 0x1.5767717455a6cp-2, 0x1.5d1bdbf5809cap-2, 0x1.62c82f2b9c795p-2,
- 0x1.686c81e9b14aep-2, 0x1.6e08eaa2ba1e3p-2, 0x1.739d7f6bbd006p-2,
- 0x1.792a55fdd47a2p-2, 0x1.7eaf83b82afc3p-2, 0x1.842d1da1e8b17p-2,
- 0x1.89a3386c1425ap-2, 0x1.8f11e873662c7p-2, 0x1.947941c2116fap-2,
- 0x1.99d958117e08ap-2, 0x1.9f323ecbf984bp-2, 0x1.a484090e5bb0ap-2,
- 0x1.a9cec9a9a0849p-2, 0x1.af1293247786bp-2, 0x1.b44f77bcc8f62p-2,
- 0x1.b9858969310fbp-2, 0x1.beb4d9da71b7bp-2, 0x1.c3dd7a7cdad4dp-2,
- 0x1.c8ff7c79a9a21p-2, 0x1.ce1af0b85f3ebp-2, 0x1.d32fe7e00ebd5p-2,
- 0x1.d83e7258a2f3ep-2, 0x1.dd46a04c1c4a0p-2, 0x1.e24881a7c6c26p-2,
- 0x1.e744261d68787p-2, 0x1.ec399d2468cc0p-2, 0x1.f128f5faf06ecp-2,
- 0x1.f6123fa7028acp-2, 0x1.faf588f78f31ep-2, 0x1.ffd2e0857f498p-2,
- 0x1.02552a5a5d0fep-1, 0x1.04bdf9da926d2p-1, 0x1.0723e5c1cdf40p-1,
- 0x1.0986f4f573520p-1, 0x1.0be72e4252a82p-1, 0x1.0e44985d1cc8bp-1,
- 0x1.109f39e2d4c96p-1, 0x1.12f719593efbcp-1, 0x1.154c3d2f4d5e9p-1,
- 0x1.179eabbd899a0p-1, 0x1.19ee6b467c96ep-1, 0x1.1c3b81f713c24p-1,
- 0x1.1e85f5e7040d0p-1, 0x1.20cdcd192ab6dp-1, 0x1.23130d7bebf42p-1,
- 0x1.2555bce98f7cbp-1, 0x1.2795e1289b11ap-1, 0x1.29d37fec2b08ap-1,
- 0x1.2c0e9ed448e8bp-1, 0x1.2e47436e40268p-1, 0x1.307d7334f10bep-1,
- 0x1.32b1339121d71p-1, 0x1.34e289d9ce1d3p-1, 0x1.37117b54747b5p-1,
- 0x1.393e0d3562a19p-1, 0x1.3b68449fffc22p-1, 0x1.3d9026a7156fap-1,
- 0x1.3fb5b84d16f42p-1, 0x1.41d8fe84672aep-1, 0x1.43f9fe2f9ce67p-1,
- 0x1.4618bc21c5ec2p-1, 0x1.48353d1ea88dfp-1, 0x1.4a4f85db03ebbp-1,
- 0x1.4c679afccee39p-1, 0x1.4e7d811b75bb0p-1, 0x1.50913cc01686bp-1,
- 0x1.52a2d265bc5aap-1, 0x1.54b2467999497p-1, 0x1.56bf9d5b3f399p-1,
- 0x1.58cadb5cd7989p-1, 0x1.5ad404c359f2cp-1, 0x1.5cdb1dc6c1764p-1,
- 0x1.5ee02a9241675p-1, 0x1.60e32f44788d8p-1};
-
// Range reduction constants for logarithms.
// r(0) = 1, r(127) = 0.5
// r(k) = 2^-8 * ceil(2^8 * (1 - 2^-8) / (1 + k*2^-7))
diff --git a/libc/src/math/generic/common_constants.h b/libc/src/math/generic/common_constants.h
index 291816a..72b1d564 100644
--- a/libc/src/math/generic/common_constants.h
+++ b/libc/src/math/generic/common_constants.h
@@ -11,6 +11,7 @@
#include "src/__support/FPUtil/triple_double.h"
#include "src/__support/macros/config.h"
+#include "src/__support/math/acosh_float_constants.h"
#include "src/__support/math/exp_constants.h"
#include "src/__support/number_pair.h"
@@ -20,16 +21,10 @@ namespace LIBC_NAMESPACE_DECL {
// computed and stored as float precision constants.
extern const float ONE_OVER_F_FLOAT[128];
-// Lookup table for (1/f) where f = 1 + n*2^(-7), n = 0..127.
-extern const double ONE_OVER_F[128];
-
// Lookup table for log(f) = log(1 + n*2^(-7)) where n = 0..127,
// computed and stored as float precision constants.
extern const float LOG_F_FLOAT[128];
-// Lookup table for log(f) = log(1 + n*2^(-7)) where n = 0..127.
-extern const double LOG_F[128];
-
// Lookup table for range reduction constants r for logarithms.
extern const float R[128];
diff --git a/libc/src/math/generic/erff.cpp b/libc/src/math/generic/erff.cpp
index 44607a5..003b346 100644
--- a/libc/src/math/generic/erff.cpp
+++ b/libc/src/math/generic/erff.cpp
@@ -7,180 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/erff.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/PolyEval.h"
-#include "src/__support/FPUtil/except_value_utils.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/common.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/math/erff.h"
namespace LIBC_NAMESPACE_DECL {
-// Polynomials approximating erf(x)/x on ( k/8, (k + 1)/8 ) generated by Sollya
-// with:
-// > P = fpminimax(erf(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14|], [|D...|],
-// [k/8, (k + 1)/8]);
-// for k = 0..31.
-constexpr double COEFFS[32][8] = {
- {0x1.20dd750429b6dp0, -0x1.812746b037753p-2, 0x1.ce2f219e8596ap-4,
- -0x1.b82cdacb78fdap-6, 0x1.56479297dfda5p-8, -0x1.8b3ac5455ef02p-11,
- -0x1.126fcac367e3bp-8, 0x1.2d0bdb3ba4984p-4},
- {0x1.20dd750429b6dp0, -0x1.812746b0379a8p-2, 0x1.ce2f21a03cf2ap-4,
- -0x1.b82ce30de083ep-6, 0x1.565bcad3eb60fp-8, -0x1.c02c66f659256p-11,
- 0x1.f92f673385229p-14, -0x1.def402648ae9p-17},
- {0x1.20dd750429b34p0, -0x1.812746b032dcep-2, 0x1.ce2f219d84aaep-4,
- -0x1.b82ce22dcf139p-6, 0x1.565b9efcd4af1p-8, -0x1.c021f1af414bcp-11,
- 0x1.f7c6d177eff82p-14, -0x1.c9e4410dcf865p-17},
- {0x1.20dd750426eabp0, -0x1.812746ae592c7p-2, 0x1.ce2f211525f14p-4,
- -0x1.b82ccc125e63fp-6, 0x1.56596f261cfd3p-8, -0x1.bfde1ff8eeecfp-11,
- 0x1.f31a9d15dc5d8p-14, -0x1.a5a4362844b3cp-17},
- {0x1.20dd75039c705p0, -0x1.812746777e74dp-2, 0x1.ce2f17af98a1bp-4,
- -0x1.b82be4b817cbep-6, 0x1.564bec2e2962ep-8, -0x1.bee86f9da3558p-11,
- 0x1.e9443689dc0ccp-14, -0x1.79c0f230805d8p-17},
- {0x1.20dd74f811211p0, -0x1.81274371a3e8fp-2, 0x1.ce2ec038262e5p-4,
- -0x1.b8265b82c5e1fp-6, 0x1.5615a2e239267p-8, -0x1.bc63ae023dcebp-11,
- 0x1.d87c2102f7e06p-14, -0x1.49584bea41d62p-17},
- {0x1.20dd746d063e3p0, -0x1.812729a8a950fp-2, 0x1.ce2cb0a2df232p-4,
- -0x1.b80eca1f51278p-6, 0x1.5572e26c46815p-8, -0x1.b715e5638b65ep-11,
- 0x1.bfbb195484968p-14, -0x1.177a565c15c52p-17},
- {0x1.20dd701b44486p0, -0x1.812691145f237p-2, 0x1.ce23a06b8cfd9p-4,
- -0x1.b7c1dc7245288p-6, 0x1.53e92f7f397ddp-8, -0x1.ad97cc4acf0b2p-11,
- 0x1.9f028b2b09b71p-14, -0x1.cdc4da08da8c1p-18},
- {0x1.20dd5715ac332p0, -0x1.8123e680bd0ebp-2, 0x1.ce0457aded691p-4,
- -0x1.b6f52d52bed4p-6, 0x1.50c291b84414cp-8, -0x1.9ea246b1ad4a9p-11,
- 0x1.77654674e0cap-14, -0x1.737c11a1bcebbp-18},
- {0x1.20dce6593e114p0, -0x1.811a59c02eadcp-2, 0x1.cdab53c7cd7d5p-4,
- -0x1.b526d2e321eedp-6, 0x1.4b1d32cd8b994p-8, -0x1.8963143ec0a1ep-11,
- 0x1.4ad5700e4db91p-14, -0x1.231e100e43ef2p-18},
- {0x1.20db48bfd5a62p0, -0x1.80fdd84f9e308p-2, 0x1.ccd340d462983p-4,
- -0x1.b196a2928768p-6, 0x1.4210c2c13a0f7p-8, -0x1.6dbdfb4ff71aep-11,
- 0x1.1bca2d17fbd71p-14, -0x1.bca36f90c7cf5p-19},
- {0x1.20d64b2f8f508p0, -0x1.80b4d4f19fa8bp-2, 0x1.cb088197262e3p-4,
- -0x1.ab51fd02e5b99p-6, 0x1.34e1e5e81a632p-8, -0x1.4c66377b502cep-11,
- 0x1.d9ad25066213cp-15, -0x1.4b0df7dd0cfa1p-19},
- {0x1.20c8fc1243576p0, -0x1.8010cb2009e27p-2, 0x1.c7a47e9299315p-4,
- -0x1.a155be5683654p-6, 0x1.233502694997bp-8, -0x1.26c94b7d813p-11,
- 0x1.8094f1de25fb9p-15, -0x1.e0e3d776c6eefp-20},
- {0x1.20a9bd1611bc1p0, -0x1.7ec7fbce83f9p-2, 0x1.c1d757d7317b7p-4,
- -0x1.92c160cd589fp-6, 0x1.0d307269cc5c2p-8, -0x1.fda5b0d2d1879p-12,
- 0x1.2fdd7b3b14a7fp-15, -0x1.54eed4a26af5ap-20},
- {0x1.20682834f943dp0, -0x1.7c73f747bf5a9p-2, 0x1.b8c2db4a9ffd1p-4,
- -0x1.7f0e4ffe989ecp-6, 0x1.e7061eae4166ep-9, -0x1.ad36e873fff2dp-12,
- 0x1.d39222396128ep-16, -0x1.d83dacec5ea6bp-21},
- {0x1.1feb8d12676d7p0, -0x1.7898347284afep-2, 0x1.aba3466b34451p-4,
- -0x1.663adc573e2f9p-6, 0x1.ae99fb17c3e08p-9, -0x1.602f950ad5535p-12,
- 0x1.5e9717490609dp-16, -0x1.3fca107bbc8d5p-21},
- {0x1.1f12fe3c536fap0, -0x1.72b1d1f22e6d3p-2, 0x1.99fc0eed4a896p-4,
- -0x1.48db0a87bd8c6p-6, 0x1.73e368895aa61p-9, -0x1.19b35d5301fc8p-12,
- 0x1.007987e4bb033p-16, -0x1.a7edcd4c2dc7p-22},
- {0x1.1db7b0df84d5dp0, -0x1.6a4e4a41cde02p-2, 0x1.83bbded16455dp-4,
- -0x1.2809b3b36977ep-6, 0x1.39c08bab44679p-9, -0x1.b7b45a70ed119p-13,
- 0x1.6e99b36410e7bp-17, -0x1.13619bb7ebc0cp-22},
- {0x1.1bb1c85c4a527p0, -0x1.5f23b99a249a3p-2, 0x1.694c91fa0d12cp-4,
- -0x1.053e1ce11c72dp-6, 0x1.02bf72c50ea78p-9, -0x1.4f478fb56cb02p-13,
- 0x1.005f80ecbe213p-17, -0x1.5f2446bde7f5bp-23},
- {0x1.18dec3bd51f9dp0, -0x1.5123f58346186p-2, 0x1.4b8a1ca536ab4p-4,
- -0x1.c4243015cc723p-7, 0x1.a1a8a01d351efp-10, -0x1.f466b34f1d86bp-14,
- 0x1.5f835eea0bf6ap-18, -0x1.b83165b939234p-24},
- {0x1.152804c3369f4p0, -0x1.4084cd4afd4bcp-2, 0x1.2ba2e836e47aap-4,
- -0x1.800f2dfc6904bp-7, 0x1.4a6daf0669c59p-10, -0x1.6e326ab872317p-14,
- 0x1.d9761a6a755a5p-19, -0x1.0fca33f9dd4b5p-24},
- {0x1.1087ad68356aap0, -0x1.2dbb044707459p-2, 0x1.0aea8ceaa0384p-4,
- -0x1.40b516d52b3d2p-7, 0x1.00c9e05f01d22p-10, -0x1.076afb0dc0ff7p-14,
- 0x1.39fadec400657p-19, -0x1.4b5761352e7e3p-25},
- {0x1.0b0a7a8ba4a22p0, -0x1.196990d22d4a1p-2, 0x1.d5551e6ac0c4dp-5,
- -0x1.07cce1770bd1ap-7, 0x1.890347b8848bfp-11, -0x1.757ec96750b6ap-15,
- 0x1.9b258a1e06bcep-20, -0x1.8fc6d22da7572p-26},
- {0x1.04ce2be70fb47p0, -0x1.0449e4b0b9cacp-2, 0x1.97f7424f4b0e7p-5,
- -0x1.ac825439c42f4p-8, 0x1.28f5f65426dfbp-11, -0x1.05b699a90f90fp-15,
- 0x1.0a888eecf4593p-20, -0x1.deace2b32bb31p-27},
- {0x1.fbf9fb0e11cc8p-1, -0x1.de2640856545ap-3, 0x1.5f5b1f47f851p-5,
- -0x1.588bc71eb41b9p-8, 0x1.bc6a0a772f56dp-12, -0x1.6b9fad1f1657ap-16,
- 0x1.573204ba66504p-21, -0x1.1d38065c94e44p-27},
- {0x1.ed8f18c99e031p-1, -0x1.b4cb6acd903b4p-3, 0x1.2c7f3dddd6fc1p-5,
- -0x1.13052067df4ep-8, 0x1.4a5027444082fp-12, -0x1.f672bab0e2554p-17,
- 0x1.b83c756348cc9p-22, -0x1.534f1a1079499p-28},
- {0x1.debd33044166dp-1, -0x1.8d7cd9053f7d8p-3, 0x1.ff9957fb3d6e7p-6,
- -0x1.b50be55de0f36p-9, 0x1.e92c8ec53a628p-13, -0x1.5a4b88d508007p-17,
- 0x1.1a27737559e26p-22, -0x1.942ae62cb2c14p-29},
- {0x1.cfdbf0386f3bdp-1, -0x1.68e33d93b0dc4p-3, 0x1.b2683d58f53dep-6,
- -0x1.5a9174e70d26fp-9, 0x1.69ddd326d49cdp-13, -0x1.dd8f397a8219cp-18,
- 0x1.6a755016ad4ddp-23, -0x1.e366e0139187dp-30},
- {0x1.c132adb8d7464p-1, -0x1.475a899f61b46p-3, 0x1.70a431397a77cp-6,
- -0x1.12e3d35beeee2p-9, 0x1.0c16b05738333p-13, -0x1.4a47f873e144ep-18,
- 0x1.d3d494c698c02p-24, -0x1.2302c59547fe5p-30},
- {0x1.b2f5fd05555e7p-1, -0x1.28feefbe03ec7p-3, 0x1.3923acbb3a676p-6,
- -0x1.b4ff793cd6358p-10, 0x1.8ea0eb8c913bcp-14, -0x1.cb31ec2baceb1p-19,
- 0x1.30011e7e80c04p-24, -0x1.617710635cb1dp-31},
- {0x1.a54853cd9593ep-1, -0x1.0dbdbaea4dc8ep-3, 0x1.0a93e2c20a0fdp-6,
- -0x1.5c969ff401ea8p-10, 0x1.29e0cc64fe627p-14, -0x1.4160d8e9d3c2ap-19,
- 0x1.8e7b67594624ap-25, -0x1.b1cf2c975b09bp-32},
- {0x1.983ceece09ff8p-1, -0x1.eacc78f7a2dp-4, 0x1.c74418410655fp-7,
- -0x1.1756a050e441ep-10, 0x1.bff3650f7f548p-15, -0x1.c56c0217d3adap-20,
- 0x1.07b4918d0b489p-25, -0x1.0d4be8c1c50f8p-32},
-};
-
-LLVM_LIBC_FUNCTION(float, erff, (float x)) {
- using FPBits = typename fputil::FPBits<float>;
- FPBits xbits(x);
-
- uint32_t x_u = xbits.uintval();
- uint32_t x_abs = x_u & 0x7fff'ffffU;
-
- if (LIBC_UNLIKELY(x_abs >= 0x4080'0000U)) {
- const float ONE[2] = {1.0f, -1.0f};
- const float SMALL[2] = {-0x1.0p-25f, 0x1.0p-25f};
-
- int sign = xbits.is_neg() ? 1 : 0;
-
- if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) {
- if (xbits.is_signaling_nan()) {
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
- }
- return (x_abs > 0x7f80'0000) ? x : ONE[sign];
- }
-
- return ONE[sign] + SMALL[sign];
- }
-
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- // Exceptional mask = common 0 bits of 2 exceptional values.
- constexpr uint32_t EXCEPT_MASK = 0x809a'6184U;
-
- if (LIBC_UNLIKELY((x_abs & EXCEPT_MASK) == 0)) {
- // Exceptional values
- if (LIBC_UNLIKELY(x_abs == 0x3f65'9229U)) // |x| = 0x1.cb2452p-1f
- return x < 0.0f ? fputil::round_result_slightly_down(-0x1.972ea8p-1f)
- : fputil::round_result_slightly_up(0x1.972ea8p-1f);
- if (LIBC_UNLIKELY(x_abs == 0x4004'1e6aU)) // |x| = 0x1.083cd4p+1f
- return x < 0.0f ? fputil::round_result_slightly_down(-0x1.fe3462p-1f)
- : fputil::round_result_slightly_up(0x1.fe3462p-1f);
- if (x_abs == 0U)
- return x;
- }
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
- // Polynomial approximation:
- // erf(x) ~ x * (c0 + c1 * x^2 + c2 * x^4 + ... + c7 * x^14)
- double xd = static_cast<double>(x);
- double xsq = xd * xd;
-
- const uint32_t EIGHT = 3 << FPBits::FRACTION_LEN;
- int idx = static_cast<int>(FPBits(x_abs + EIGHT).get_val());
-
- double x4 = xsq * xsq;
- double c0 = fputil::multiply_add(xsq, COEFFS[idx][1], COEFFS[idx][0]);
- double c1 = fputil::multiply_add(xsq, COEFFS[idx][3], COEFFS[idx][2]);
- double c2 = fputil::multiply_add(xsq, COEFFS[idx][5], COEFFS[idx][4]);
- double c3 = fputil::multiply_add(xsq, COEFFS[idx][7], COEFFS[idx][6]);
-
- double x8 = x4 * x4;
- double p0 = fputil::multiply_add(x4, c1, c0);
- double p1 = fputil::multiply_add(x4, c3, c2);
-
- return static_cast<float>(xd * fputil::multiply_add(x8, p1, p0));
-}
+LLVM_LIBC_FUNCTION(float, erff, (float x)) { return math::erff(x); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/exp10f16.cpp b/libc/src/math/generic/exp10f16.cpp
index 31abf3b..cb3c859 100644
--- a/libc/src/math/generic/exp10f16.cpp
+++ b/libc/src/math/generic/exp10f16.cpp
@@ -7,128 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/exp10f16.h"
-#include "expxf16.h"
-#include "hdr/errno_macros.h"
-#include "hdr/fenv_macros.h"
-#include "src/__support/CPP/array.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/PolyEval.h"
-#include "src/__support/FPUtil/cast.h"
-#include "src/__support/FPUtil/except_value_utils.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/FPUtil/nearest_integer.h"
-#include "src/__support/FPUtil/rounding_mode.h"
-#include "src/__support/common.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h"
-#include "src/__support/macros/properties/cpu_features.h"
+#include "src/__support/math/exp10f16.h"
namespace LIBC_NAMESPACE_DECL {
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-#ifdef LIBC_TARGET_CPU_HAS_FMA_FLOAT
-static constexpr size_t N_EXP10F16_EXCEPTS = 5;
-#else
-static constexpr size_t N_EXP10F16_EXCEPTS = 8;
-#endif
-
-static constexpr fputil::ExceptValues<float16, N_EXP10F16_EXCEPTS>
- EXP10F16_EXCEPTS = {{
- // x = 0x1.8f4p-2, exp10f16(x) = 0x1.3ap+1 (RZ)
- {0x363dU, 0x40e8U, 1U, 0U, 1U},
- // x = 0x1.95cp-2, exp10f16(x) = 0x1.3ecp+1 (RZ)
- {0x3657U, 0x40fbU, 1U, 0U, 0U},
- // x = -0x1.018p-4, exp10f16(x) = 0x1.bbp-1 (RZ)
- {0xac06U, 0x3aecU, 1U, 0U, 0U},
- // x = -0x1.c28p+0, exp10f16(x) = 0x1.1ccp-6 (RZ)
- {0xbf0aU, 0x2473U, 1U, 0U, 0U},
- // x = -0x1.e1cp+1, exp10f16(x) = 0x1.694p-13 (RZ)
- {0xc387U, 0x09a5U, 1U, 0U, 0U},
-#ifndef LIBC_TARGET_CPU_HAS_FMA_FLOAT
- // x = 0x1.0cp+1, exp10f16(x) = 0x1.f04p+6 (RZ)
- {0x4030U, 0x57c1U, 1U, 0U, 1U},
- // x = 0x1.1b8p+1, exp10f16(x) = 0x1.47cp+7 (RZ)
- {0x406eU, 0x591fU, 1U, 0U, 1U},
- // x = 0x1.1b8p+2, exp10f16(x) = 0x1.a4p+14 (RZ)
- {0x446eU, 0x7690U, 1U, 0U, 1U},
-#endif
- }};
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
-LLVM_LIBC_FUNCTION(float16, exp10f16, (float16 x)) {
- using FPBits = fputil::FPBits<float16>;
- FPBits x_bits(x);
-
- uint16_t x_u = x_bits.uintval();
- uint16_t x_abs = x_u & 0x7fffU;
-
- // When |x| >= 5, or x is NaN.
- if (LIBC_UNLIKELY(x_abs >= 0x4500U)) {
- // exp10(NaN) = NaN
- if (x_bits.is_nan()) {
- if (x_bits.is_signaling_nan()) {
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
- }
-
- return x;
- }
-
- // When x >= 5.
- if (x_bits.is_pos()) {
- // exp10(+inf) = +inf
- if (x_bits.is_inf())
- return FPBits::inf().get_val();
-
- switch (fputil::quick_get_round()) {
- case FE_TONEAREST:
- case FE_UPWARD:
- fputil::set_errno_if_required(ERANGE);
- fputil::raise_except_if_required(FE_OVERFLOW);
- return FPBits::inf().get_val();
- default:
- return FPBits::max_normal().get_val();
- }
- }
-
- // When x <= -8.
- if (x_u >= 0xc800U) {
- // exp10(-inf) = +0
- if (x_bits.is_inf())
- return FPBits::zero().get_val();
-
- fputil::set_errno_if_required(ERANGE);
- fputil::raise_except_if_required(FE_UNDERFLOW | FE_INEXACT);
-
- if (fputil::fenv_is_round_up())
- return FPBits::min_subnormal().get_val();
- return FPBits::zero().get_val();
- }
- }
-
- // When x is 1, 2, 3, or 4. These are hard-to-round cases with exact results.
- if (LIBC_UNLIKELY((x_u & ~(0x3c00U | 0x4000U | 0x4200U | 0x4400U)) == 0)) {
- switch (x_u) {
- case 0x3c00U: // x = 1.0f16
- return fputil::cast<float16>(10.0);
- case 0x4000U: // x = 2.0f16
- return fputil::cast<float16>(100.0);
- case 0x4200U: // x = 3.0f16
- return fputil::cast<float16>(1'000.0);
- case 0x4400U: // x = 4.0f16
- return fputil::cast<float16>(10'000.0);
- }
- }
-
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- if (auto r = EXP10F16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
- return r.value();
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
- // 10^x = 2^((hi + mid) * log2(10)) * 10^lo
- auto [exp2_hi_mid, exp10_lo] = exp10_range_reduction(x);
- return fputil::cast<float16>(exp2_hi_mid * exp10_lo);
-}
+LLVM_LIBC_FUNCTION(float16, exp10f16, (float16 x)) { return math::exp10f16(x); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/exp10m1f16.cpp b/libc/src/math/generic/exp10m1f16.cpp
index 545c479..6c2fdbe 100644
--- a/libc/src/math/generic/exp10m1f16.cpp
+++ b/libc/src/math/generic/exp10m1f16.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "src/math/exp10m1f16.h"
-#include "expxf16.h"
#include "hdr/errno_macros.h"
#include "hdr/fenv_macros.h"
#include "src/__support/FPUtil/FEnvImpl.h"
@@ -21,6 +20,7 @@
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h"
#include "src/__support/macros/properties/cpu_features.h"
+#include "src/__support/math/exp10f16_utils.h"
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/math/generic/explogxf.h b/libc/src/math/generic/explogxf.h
index be4328a..a2a6d60 100644
--- a/libc/src/math/generic/explogxf.h
+++ b/libc/src/math/generic/explogxf.h
@@ -13,6 +13,7 @@
#include "src/__support/common.h"
#include "src/__support/macros/properties/cpu_features.h"
+#include "src/__support/math/acoshf_utils.h"
#include "src/__support/math/exp10f_utils.h"
#include "src/__support/math/exp_utils.h"
@@ -163,41 +164,6 @@ LIBC_INLINE static float log_eval_f(float x) {
return result;
}
-// x should be positive, normal finite value
-LIBC_INLINE static double log_eval(double x) {
- // For x = 2^ex * (1 + mx)
- // log(x) = ex * log(2) + log(1 + mx)
- using FPB = fputil::FPBits<double>;
- FPB bs(x);
-
- double ex = static_cast<double>(bs.get_exponent());
-
- // p1 is the leading 7 bits of mx, i.e.
- // p1 * 2^(-7) <= m_x < (p1 + 1) * 2^(-7).
- int p1 = static_cast<int>(bs.get_mantissa() >> (FPB::FRACTION_LEN - 7));
-
- // Set bs to (1 + (mx - p1*2^(-7))
- bs.set_uintval(bs.uintval() & (FPB::FRACTION_MASK >> 7));
- bs.set_biased_exponent(FPB::EXP_BIAS);
- // dx = (mx - p1*2^(-7)) / (1 + p1*2^(-7)).
- double dx = (bs.get_val() - 1.0) * ONE_OVER_F[p1];
-
- // Minimax polynomial of log(1 + dx) generated by Sollya with:
- // > P = fpminimax(log(1 + x)/x, 6, [|D...|], [0, 2^-7]);
- const double COEFFS[6] = {-0x1.ffffffffffffcp-2, 0x1.5555555552ddep-2,
- -0x1.ffffffefe562dp-3, 0x1.9999817d3a50fp-3,
- -0x1.554317b3f67a5p-3, 0x1.1dc5c45e09c18p-3};
- double dx2 = dx * dx;
- double c1 = fputil::multiply_add(dx, COEFFS[1], COEFFS[0]);
- double c2 = fputil::multiply_add(dx, COEFFS[3], COEFFS[2]);
- double c3 = fputil::multiply_add(dx, COEFFS[5], COEFFS[4]);
-
- double p = fputil::polyeval(dx2, dx, c1, c2, c3);
- double result =
- fputil::multiply_add(ex, /*log(2)*/ 0x1.62e42fefa39efp-1, LOG_F[p1] + p);
- return result;
-}
-
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC_MATH_GENERIC_EXPLOGXF_H
diff --git a/libc/src/math/generic/expxf16.h b/libc/src/math/generic/expxf16.h
index 05ac95d..b17b14f 100644
--- a/libc/src/math/generic/expxf16.h
+++ b/libc/src/math/generic/expxf16.h
@@ -17,18 +17,11 @@
#include "src/__support/macros/config.h"
#include <stdint.h>
+#include "src/__support/math/exp10_float16_constants.h"
#include "src/__support/math/expf16_utils.h"
namespace LIBC_NAMESPACE_DECL {
-// Generated by Sollya with the following commands:
-// > display = hexadecimal;
-// > for i from 0 to 7 do printsingle(round(2^(i * 2^-3), SG, RN));
-constexpr cpp::array<uint32_t, 8> EXP2_MID_BITS = {
- 0x3f80'0000U, 0x3f8b'95c2U, 0x3f98'37f0U, 0x3fa5'fed7U,
- 0x3fb5'04f3U, 0x3fc5'672aU, 0x3fd7'44fdU, 0x3fea'c0c7U,
-};
-
LIBC_INLINE ExpRangeReduction exp2_range_reduction(float16 x) {
// For -25 < x < 16, to compute 2^x, we perform the following range reduction:
// find hi, mid, lo, such that:
@@ -68,53 +61,6 @@ LIBC_INLINE ExpRangeReduction exp2_range_reduction(float16 x) {
// Generated by Sollya with the following commands:
// > display = hexadecimal;
-// > round(log2(10), SG, RN);
-static constexpr float LOG2F_10 = 0x1.a934fp+1f;
-
-// Generated by Sollya with the following commands:
-// > display = hexadecimal;
-// > round(log10(2), SG, RN);
-static constexpr float LOG10F_2 = 0x1.344136p-2f;
-
-LIBC_INLINE ExpRangeReduction exp10_range_reduction(float16 x) {
- // For -8 < x < 5, to compute 10^x, we perform the following range reduction:
- // find hi, mid, lo, such that:
- // x = (hi + mid) * log2(10) + lo, in which
- // hi is an integer,
- // mid * 2^3 is an integer,
- // -2^(-4) <= lo < 2^(-4).
- // In particular,
- // hi + mid = round(x * 2^3) * 2^(-3).
- // Then,
- // 10^x = 10^(hi + mid + lo) = 2^((hi + mid) * log2(10)) + 10^lo
- // We store 2^mid in the lookup table EXP2_MID_BITS, and compute 2^hi * 2^mid
- // by adding hi to the exponent field of 2^mid. 10^lo is computed using a
- // degree-4 minimax polynomial generated by Sollya.
-
- float xf = x;
- float kf = fputil::nearest_integer(xf * (LOG2F_10 * 0x1.0p+3f));
- int x_hi_mid = static_cast<int>(kf);
- unsigned x_hi = static_cast<unsigned>(x_hi_mid) >> 3;
- unsigned x_mid = static_cast<unsigned>(x_hi_mid) & 0x7;
- // lo = x - (hi + mid) = round(x * 2^3 * log2(10)) * log10(2) * (-2^(-3)) + x
- float lo = fputil::multiply_add(kf, LOG10F_2 * -0x1.0p-3f, xf);
-
- uint32_t exp2_hi_mid_bits =
- EXP2_MID_BITS[x_mid] +
- static_cast<uint32_t>(x_hi << fputil::FPBits<float>::FRACTION_LEN);
- float exp2_hi_mid = fputil::FPBits<float>(exp2_hi_mid_bits).get_val();
- // Degree-4 minimax polynomial generated by Sollya with the following
- // commands:
- // > display = hexadecimal;
- // > P = fpminimax((10^x - 1)/x, 3, [|SG...|], [-2^-4, 2^-4]);
- // > 1 + x * P;
- float exp10_lo = fputil::polyeval(lo, 0x1p+0f, 0x1.26bb14p+1f, 0x1.53526p+1f,
- 0x1.04b434p+1f, 0x1.2bcf9ep+0f);
- return {exp2_hi_mid, exp10_lo};
-}
-
-// Generated by Sollya with the following commands:
-// > display = hexadecimal;
// > round(log2(exp(1)), SG, RN);
static constexpr float LOG2F_E = 0x1.715476p+0f;
diff --git a/libc/src/math/generic/inv_trigf_utils.cpp b/libc/src/math/generic/inv_trigf_utils.cpp
deleted file mode 100644
index f23028b..0000000
--- a/libc/src/math/generic/inv_trigf_utils.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-//===-- Single-precision general exp/log functions ------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "inv_trigf_utils.h"
-#include "src/__support/macros/config.h"
-
-namespace LIBC_NAMESPACE_DECL {
-
-// Polynomial approximation for 0 <= x <= 1:
-// atan(x) ~ atan((i/16) + (x - (i/16)) * Q(x - i/16)
-// = P(x - i/16)
-// Generated by Sollya with:
-// > for i from 1 to 16 do {
-// mid_point = i/16;
-// P = fpminimax(atan(mid_point + x), 8, [|D...|], [-1/32, 1/32]);
-// print("{", coeff(P, 0), ",", coeff(P, 1), ",", coeff(P, 2), ",",
-// coeff(P, 3), ",", coeff(P, 4), ",", coeff(P, 5), ",", coeff(P, 6),
-// ",", coeff(P, 7), ",", coeff(P, 8), "},");
-// };
-// For i = 0, the polynomial is generated by:
-// > P = fpminimax(atan(x)/x, 7, [|1, D...|], [0, 1/32]);
-// > dirtyinfnorm((atan(x) - x*P)/x, [0, 1/32]);
-// 0x1.feb2fcdba66447ccbe28a1a0f935b51678a718fb1p-59
-// Notice that degree-7 is good enough for atanf, but degree-8 helps reduce the
-// error bounds for atan2f's fast pass 16 times, and it does not affect the
-// performance of atanf much.
-double ATAN_COEFFS[17][9] = {
- {0.0, 1.0, 0x1.3f8d76d26d61bp-47, -0x1.5555555574cd8p-2,
- 0x1.0dde5d06878eap-29, 0x1.99997738acc77p-3, 0x1.2c43eac9797cap-16,
- -0x1.25fb020007dbdp-3, 0x1.c1b6c31d7b0aep-7},
- {0x1.ff55bb72cfde9p-5, 0x1.fe01fe01fe007p-1, -0x1.fc05f809ed8dap-5,
- -0x1.4d69303afe04ep-2, 0x1.f61bc3e8349cp-5, 0x1.820839278756bp-3,
- -0x1.eda4de1c6bf3fp-5, -0x1.0514d42d64a63p-3, 0x1.db3746a442dcbp-5},
- {0x1.fd5ba9aac2f6ep-4, 0x1.f81f81f81f813p-1, -0x1.f05e09d0dc378p-4,
- -0x1.368c3aa719215p-2, 0x1.d9b16b33ff9c9p-4, 0x1.40488f9c6262ap-3,
- -0x1.ba55933e62ea5p-4, -0x1.64c6a15cd9116p-4, 0x1.9273d5939a75ap-4},
- {0x1.7b97b4bce5b02p-3, 0x1.ee9c7f8458e05p-1, -0x1.665c226d6961p-3,
- -0x1.1344bb7391703p-2, 0x1.42aca8b0081b9p-3, 0x1.c32d9381d7c03p-4,
- -0x1.13e970672e246p-3, -0x1.181ed934dd733p-5, 0x1.bad81ea190c08p-4},
- {0x1.f5b75f92c80ddp-3, 0x1.e1e1e1e1e1e2cp-1, -0x1.c5894d10d363dp-3,
- -0x1.ce6de025f9f5ep-3, 0x1.78a3a07c8dd7fp-3, 0x1.dd5f5180f386ep-5,
- -0x1.1b1f513c4536bp-3, 0x1.0df852e58c43cp-6, 0x1.722e7a7e42505p-4},
- {0x1.362773707ebccp-2, 0x1.d272ca3fc5b2ep-1, -0x1.0997e8aeca8fbp-2,
- -0x1.6cf6666e5e693p-3, 0x1.8dd1e907e88adp-3, 0x1.24849ac0caa5dp-7,
- -0x1.f496be486229dp-4, 0x1.b7d54b8e759ecp-5, 0x1.d39c0d39c3922p-5},
- {0x1.6f61941e4def1p-2, 0x1.c0e070381c0f2p-1, -0x1.2726dd135d9eep-2,
- -0x1.09f37b39b70e4p-3, 0x1.85eacdaadd712p-3, -0x1.04d66340d5b9p-5,
- -0x1.8056b15a22b98p-4, 0x1.29baf494ad3ddp-4, 0x1.52d5881322a7ap-6},
- {0x1.a64eec3cc23fdp-2, 0x1.adbe87f94906ap-1, -0x1.3b9d8eab55addp-2,
- -0x1.57c09646eb7p-4, 0x1.6795319e3b8dfp-3, -0x1.f2d89b5ef31bep-5,
- -0x1.f38aac26203cap-5, 0x1.3262802235e3fp-4, -0x1.2afd6b9a57d66p-7},
- {0x1.dac670561bb4fp-2, 0x1.99999999999ap-1, -0x1.47ae147adff11p-2,
- -0x1.5d867c40188b7p-5, 0x1.3a92a2df85e7ap-3, -0x1.3ec457c46e851p-4,
- -0x1.ec1b9777e2e5bp-6, 0x1.0a542992a821ep-4, -0x1.ccffbe2f0d945p-6},
- {0x1.0657e94db30dp-1, 0x1.84f00c2780615p-1, -0x1.4c62cb562defap-2,
- -0x1.e6495b3c14e03p-8, 0x1.063c2fa617bfcp-3, -0x1.58b782d9907aap-4,
- -0x1.41e6ff524b7fp-8, 0x1.937dfff3205a7p-5, -0x1.0fb1fd1c729dp-5},
- {0x1.1e00babdefeb4p-1, 0x1.702e05c0b816ep-1, -0x1.4af2b78215fbep-2,
- 0x1.5d0b7e9f36997p-6, 0x1.a1247cb978debp-4, -0x1.519e1457734cap-4,
- 0x1.a755cf86b5bfbp-7, 0x1.096d174284564p-5, -0x1.081adf539ad58p-5},
- {0x1.345f01cce37bbp-1, 0x1.5babcc647fa8ep-1, -0x1.449db09426a6dp-2,
- 0x1.655caac5896dap-5, 0x1.3bbbd22d05a61p-4, -0x1.34a2febee042fp-4,
- 0x1.84df9c8269e34p-6, 0x1.200e8176c899ap-6, -0x1.c00b23c3ce222p-6},
- {0x1.4978fa3269ee1p-1, 0x1.47ae147ae1477p-1, -0x1.3a92a3055231ap-2,
- 0x1.ec21b515a4a2p-5, 0x1.c2f8b81f9a0d2p-5, -0x1.0ba9964125453p-4,
- 0x1.d7b5614777a05p-6, 0x1.971e91ed73595p-8, -0x1.3fc375a78dc74p-6},
- {0x1.5d58987169b18p-1, 0x1.34679ace01343p-1, -0x1.2ddfb039136e5p-2,
- 0x1.2491307b9fb73p-4, 0x1.29c7e4886dc22p-5, -0x1.bca78bcca83ap-5,
- 0x1.e63efd7cbe1ddp-6, -0x1.8ea6c4f03b42dp-10, -0x1.9385b5c3a6997p-7},
- {0x1.700a7c5784634p-1, 0x1.21fb78121fb76p-1, -0x1.1f6a8499e5d1ap-2,
- 0x1.41b15e5e29423p-4, 0x1.59bc953163345p-6, -0x1.63b54b13184ddp-5,
- 0x1.c9086666d213p-6, -0x1.90c3b4ad8d4bcp-8, -0x1.80f08ed9f6f57p-8},
- {0x1.819d0b7158a4dp-1, 0x1.107fbbe01107ep-1, -0x1.0feeb4089670ep-2,
- 0x1.50e5afb93f5cbp-4, 0x1.2a7c2adffeffbp-7, -0x1.12bd29b4f1b43p-5,
- 0x1.93f71f0eb00eap-6, -0x1.10ece5ad30e28p-7, -0x1.db1a76bcd2b9cp-10},
- {0x1.921fb54442d18p-1, 0x1.ffffffffffffep-2, -0x1.fffffffffc51cp-3,
- 0x1.555555557002ep-4, -0x1.a88260c338e75p-30, -0x1.99999f9a7614fp-6,
- 0x1.555e31a1e15e9p-6, -0x1.245240d65e629p-7, -0x1.fa9ba66478903p-11},
-};
-
-} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/inv_trigf_utils.h b/libc/src/math/generic/inv_trigf_utils.h
deleted file mode 100644
index 8b47aba..0000000
--- a/libc/src/math/generic/inv_trigf_utils.h
+++ /dev/null
@@ -1,110 +0,0 @@
-//===-- Single-precision general inverse trigonometric functions ----------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIBC_SRC_MATH_GENERIC_INV_TRIGF_UTILS_H
-#define LLVM_LIBC_SRC_MATH_GENERIC_INV_TRIGF_UTILS_H
-
-#include "src/__support/FPUtil/PolyEval.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/common.h"
-#include "src/__support/macros/config.h"
-
-namespace LIBC_NAMESPACE_DECL {
-
-// PI and PI / 2
-static constexpr double M_MATH_PI = 0x1.921fb54442d18p+1;
-static constexpr double M_MATH_PI_2 = 0x1.921fb54442d18p+0;
-
-extern double ATAN_COEFFS[17][9];
-
-// Look-up table for atan(k/16) with k = 0..16.
-static constexpr double ATAN_K_OVER_16[17] = {
- 0.0,
- 0x1.ff55bb72cfdeap-5,
- 0x1.fd5ba9aac2f6ep-4,
- 0x1.7b97b4bce5b02p-3,
- 0x1.f5b75f92c80ddp-3,
- 0x1.362773707ebccp-2,
- 0x1.6f61941e4def1p-2,
- 0x1.a64eec3cc23fdp-2,
- 0x1.dac670561bb4fp-2,
- 0x1.0657e94db30dp-1,
- 0x1.1e00babdefeb4p-1,
- 0x1.345f01cce37bbp-1,
- 0x1.4978fa3269ee1p-1,
- 0x1.5d58987169b18p-1,
- 0x1.700a7c5784634p-1,
- 0x1.819d0b7158a4dp-1,
- 0x1.921fb54442d18p-1,
-};
-
-// For |x| <= 1/32 and 0 <= i <= 16, return Q(x) such that:
-// Q(x) ~ (atan(x + i/16) - atan(i/16)) / x.
-LIBC_INLINE static double atan_eval(double x, unsigned i) {
- double x2 = x * x;
-
- double c0 = fputil::multiply_add(x, ATAN_COEFFS[i][2], ATAN_COEFFS[i][1]);
- double c1 = fputil::multiply_add(x, ATAN_COEFFS[i][4], ATAN_COEFFS[i][3]);
- double c2 = fputil::multiply_add(x, ATAN_COEFFS[i][6], ATAN_COEFFS[i][5]);
- double c3 = fputil::multiply_add(x, ATAN_COEFFS[i][8], ATAN_COEFFS[i][7]);
-
- double x4 = x2 * x2;
- double d1 = fputil::multiply_add(x2, c1, c0);
- double d2 = fputil::multiply_add(x2, c3, c2);
- double p = fputil::multiply_add(x4, d2, d1);
- return p;
-}
-
-// Evaluate atan without big lookup table.
-// atan(n/d) - atan(k/16) = atan((n/d - k/16) / (1 + (n/d) * (k/16)))
-// = atan((n - d * k/16)) / (d + n * k/16))
-// So we let q = (n - d * k/16) / (d + n * k/16),
-// and approximate with Taylor polynomial:
-// atan(q) ~ q - q^3/3 + q^5/5 - q^7/7 + q^9/9
-LIBC_INLINE static double atan_eval_no_table(double num, double den,
- double k_over_16) {
- double num_r = fputil::multiply_add(den, -k_over_16, num);
- double den_r = fputil::multiply_add(num, k_over_16, den);
- double q = num_r / den_r;
-
- constexpr double ATAN_TAYLOR[] = {
- -0x1.5555555555555p-2,
- 0x1.999999999999ap-3,
- -0x1.2492492492492p-3,
- 0x1.c71c71c71c71cp-4,
- };
- double q2 = q * q;
- double q3 = q2 * q;
- double q4 = q2 * q2;
- double c0 = fputil::multiply_add(q2, ATAN_TAYLOR[1], ATAN_TAYLOR[0]);
- double c1 = fputil::multiply_add(q2, ATAN_TAYLOR[3], ATAN_TAYLOR[2]);
- double d = fputil::multiply_add(q4, c1, c0);
- return fputil::multiply_add(q3, d, q);
-}
-
-// > Q = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20|],
-// [|1, D...|], [0, 0.5]);
-static constexpr double ASIN_COEFFS[10] = {
- 0x1.5555555540fa1p-3, 0x1.333333512edc2p-4, 0x1.6db6cc1541b31p-5,
- 0x1.f1caff324770ep-6, 0x1.6e43899f5f4f4p-6, 0x1.1f847cf652577p-6,
- 0x1.9b60f47f87146p-7, 0x1.259e2634c494fp-6, -0x1.df946fa875ddp-8,
- 0x1.02311ecf99c28p-5};
-
-// Evaluate P(x^2) - 1, where P(x^2) ~ asin(x)/x
-LIBC_INLINE static double asin_eval(double xsq) {
- double x4 = xsq * xsq;
- double r1 = fputil::polyeval(x4, ASIN_COEFFS[0], ASIN_COEFFS[2],
- ASIN_COEFFS[4], ASIN_COEFFS[6], ASIN_COEFFS[8]);
- double r2 = fputil::polyeval(x4, ASIN_COEFFS[1], ASIN_COEFFS[3],
- ASIN_COEFFS[5], ASIN_COEFFS[7], ASIN_COEFFS[9]);
- return fputil::multiply_add(xsq, r2, r1);
-}
-
-} // namespace LIBC_NAMESPACE_DECL
-
-#endif // LLVM_LIBC_SRC_MATH_GENERIC_INV_TRIGF_UTILS_H
diff --git a/libc/src/math/generic/log1pf.cpp b/libc/src/math/generic/log1pf.cpp
index 7f61429..16b1b34 100644
--- a/libc/src/math/generic/log1pf.cpp
+++ b/libc/src/math/generic/log1pf.cpp
@@ -37,6 +37,7 @@ namespace internal {
// We don't need to treat denormal and 0
LIBC_INLINE float log(double x) {
+ using namespace acoshf_internal;
constexpr double LOG_2 = 0x1.62e42fefa39efp-1;
using FPBits = typename fputil::FPBits<double>;