| |
| |
| |
| |
| |
| |
| |
|
|
| #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" |
|
|
| #include "inv_trigf_utils.h" |
|
|
| namespace LIBC_NAMESPACE_DECL { |
|
|
| #ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS |
| static constexpr size_t N_EXCEPTS = 4; |
|
|
| |
| static constexpr fputil::ExceptValues<float, N_EXCEPTS> ACOSF_EXCEPTS = {{ |
| |
| |
| {0x328885a3, 0x3fc90fda, 1, 0, 1}, |
| |
| {0xb28885a3, 0x3fc90fda, 1, 0, 1}, |
| |
| {0x39826222, 0x3fc907b4, 1, 0, 1}, |
| |
| {0xb9826222, 0x3fc91800, 1, 0, 1}, |
| }}; |
| #endif |
|
|
| 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; |
|
|
| |
| if (LIBC_UNLIKELY(x_abs <= 0x3f00'0000U)) { |
| |
| if (LIBC_UNLIKELY(x_abs < 0x3a80'0000U)) { |
| |
| |
| |
|
|
| #ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS |
| |
| if (auto r = ACOSF_EXCEPTS.lookup(x_uint); LIBC_UNLIKELY(r.has_value())) |
| return r.value(); |
| #endif |
|
|
| double xd = static_cast<double>(x); |
| return static_cast<float>(fputil::multiply_add( |
| -0x1.5555555555555p-3 * xd, xd * xd, M_MATH_PI_2 - xd)); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| 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)); |
| } |
|
|
| |
| if (LIBC_UNLIKELY(x_abs >= 0x3f80'0000U)) { |
| if (x_abs == 0x3f80'0000U) |
| return x_sign ? fputil::round_result_slightly_down( |
| 0x1.921fb6p+1f) |
| : 0.0f; |
|
|
| if (xbits.is_signaling_nan()) { |
| fputil::raise_except_if_required(FE_INVALID); |
| return FPBits::quiet_nan().get_val(); |
| } |
|
|
| |
| 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(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| 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); |
| } |
|
|
| } |
|
|