#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_ACOSHF_UTILS_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_ACOSHF_UTILS_H
#include "acosh_float_constants.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
#include "src/__support/FPUtil/multiply_add.h"
namespace LIBC_NAMESPACE_DECL {
namespace acoshf_internal {
LIBC_INLINE static double log_eval(double x) {
using FPB = fputil::FPBits<double>;
FPB bs(x);
double ex = static_cast<double>(bs.get_exponent());
int p1 = static_cast<int>(bs.get_mantissa() >> (FPB::FRACTION_LEN - 7));
bs.set_uintval(bs.uintval() & (FPB::FRACTION_MASK >> 7));
bs.set_biased_exponent(FPB::EXP_BIAS);
double dx = (bs.get_val() - 1.0) * ONE_OVER_F[p1];
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, 0x1.62e42fefa39efp-1, LOG_F[p1] + p);
return result;
}
}
}
#endif