//===-- Single-precision log1p(x) function --------------------------------===//
//
// 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 "src/math/log1pf.h"
#include "common_constants.h" // Lookup table for (1/f) and log(f)
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FMA.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/macros/properties/cpu_features.h"

// This is an algorithm for log10(x) in single precision which is
// correctly rounded for all rounding modes.
// - An exhaustive test show that when x >= 2^45, log1pf(x) == logf(x)
// for all rounding modes.
// - When 2^(-6) <= |x| < 2^45, the sum (double(x) + 1.0) is exact,
// so we can adapt the correctly rounded algorithm of logf to compute
// log(double(x) + 1.0) correctly.  For more information about the logf
// algorithm, see `libc/src/math/generic/logf.cpp`.
// - When |x| < 2^(-6), we use a degree-8 polynomial in double precision
// generated with Sollya using the following command:
//   fpminimax(log(1 + x)/x, 7, [|D...|], [-2^-6; 2^-6]);

namespace LIBC_NAMESPACE_DECL {

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>;
  FPBits xbits(x);

  uint64_t x_u = xbits.uintval();

  if (LIBC_UNLIKELY(x_u > FPBits::max_normal().uintval())) {
    if (xbits.is_neg() && !xbits.is_nan()) {
      fputil::set_errno_if_required(EDOM);
      fputil::raise_except_if_required(FE_INVALID);
      return fputil::FPBits<float>::quiet_nan().get_val();
    }
    return static_cast<float>(x);
  }

  double m = static_cast<double>(xbits.get_exponent());

  // Get the 8 highest bits, use 7 bits (excluding the implicit hidden bit) for
  // lookup tables.
  int f_index = static_cast<int>(xbits.get_mantissa() >>
                                 (fputil::FPBits<double>::FRACTION_LEN - 7));

  // Set bits to 1.m
  xbits.set_biased_exponent(0x3FF);
  FPBits f = xbits;

  // Clear the lowest 45 bits.
  f.set_uintval(f.uintval() & ~0x0000'1FFF'FFFF'FFFFULL);

  double d = xbits.get_val() - f.get_val();
  d *= ONE_OVER_F[f_index];

  double extra_factor = fputil::multiply_add(m, LOG_2, LOG_F[f_index]);

  double r = fputil::polyeval(d, extra_factor, 0x1.fffffffffffacp-1,
                              -0x1.fffffffef9cb2p-2, 0x1.5555513bc679ap-2,
                              -0x1.fff4805ea441p-3, 0x1.930180dbde91ap-3);

  return static_cast<float>(r);
}

} // namespace internal

LLVM_LIBC_FUNCTION(float, log1pf, (float x)) {
  using FPBits = typename fputil::FPBits<float>;
  FPBits xbits(x);
  uint32_t x_u = xbits.uintval();
  uint32_t x_a = x_u & 0x7fff'ffffU;
  double xd = static_cast<double>(x);

  // Use log1p(x) = log(1 + x) for |x| > 2^-6;
  if (x_a > 0x3c80'0000U) {
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
    // Hard-to-round cases.
    switch (x_u) {
    case 0x41078febU: // x = 0x1.0f1fd6p3
      return fputil::round_result_slightly_up(0x1.1fcbcep1f);
    case 0x5cd69e88U: // x = 0x1.ad3d1p+58f
      return fputil::round_result_slightly_up(0x1.45c146p+5f);
    case 0x65d890d3U: // x = 0x1.b121a6p+76f
      return fputil::round_result_slightly_down(0x1.a9a3f2p+5f);
    case 0x6f31a8ecU: // x = 0x1.6351d8p+95f
      return fputil::round_result_slightly_down(0x1.08b512p+6f);
    case 0x7a17f30aU: // x = 0x1.2fe614p+117f
      return fputil::round_result_slightly_up(0x1.451436p+6f);
    case 0xbd1d20afU: // x = -0x1.3a415ep-5f
      return fputil::round_result_slightly_up(-0x1.407112p-5f);
    case 0xbf800000U: // x = -1.0
      fputil::set_errno_if_required(ERANGE);
      fputil::raise_except_if_required(FE_DIVBYZERO);
      return FPBits::inf(Sign::NEG).get_val();
#ifndef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
    case 0x4cc1c80bU: // x = 0x1.839016p+26f
      return fputil::round_result_slightly_down(0x1.26fc04p+4f);
    case 0x5ee8984eU: // x = 0x1.d1309cp+62f
      return fputil::round_result_slightly_up(0x1.5c9442p+5f);
    case 0x665e7ca6U: // x = 0x1.bcf94cp+77f
      return fputil::round_result_slightly_up(0x1.af66cp+5f);
    case 0x79e7ec37U: // x = 0x1.cfd86ep+116f
      return fputil::round_result_slightly_up(0x1.43ff6ep+6f);
#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
    }
#else
    if (x == -1.0f) {
      fputil::set_errno_if_required(ERANGE);
      fputil::raise_except_if_required(FE_DIVBYZERO);
      return FPBits::inf(Sign::NEG).get_val();
    }
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS

    return internal::log(xd + 1.0);
  }

  // |x| <= 2^-6.
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
  // Hard-to round cases.
  switch (x_u) {
  case 0x35400003U: // x = 0x1.800006p-21f
    return fputil::round_result_slightly_down(0x1.7ffffep-21f);
  case 0x3710001bU: // x = 0x1.200036p-17f
    return fputil::round_result_slightly_down(0x1.1fffe6p-17f);
  case 0xb53ffffdU: // x = -0x1.7ffffap-21
    return fputil::round_result_slightly_down(-0x1.800002p-21f);
  case 0xb70fffe5U: // x = -0x1.1fffcap-17
    return fputil::round_result_slightly_down(-0x1.20001ap-17f);
  case 0xbb0ec8c4U: // x = -0x1.1d9188p-9
    return fputil::round_result_slightly_up(-0x1.1de14ap-9f);
  }
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS

  // Polymial generated by Sollya with:
  // > fpminimax(log(1 + x)/x, 7, [|D...|], [-2^-6; 2^-6]);
  const double COEFFS[7] = {-0x1.0000000000000p-1, 0x1.5555555556aadp-2,
                            -0x1.000000000181ap-2, 0x1.999998998124ep-3,
                            -0x1.55555452e2a2bp-3, 0x1.24adb8cde4aa7p-3,
                            -0x1.0019db915ef6fp-3};

  double xsq = xd * xd;
  double c0 = fputil::multiply_add(xd, COEFFS[1], COEFFS[0]);
  double c1 = fputil::multiply_add(xd, COEFFS[3], COEFFS[2]);
  double c2 = fputil::multiply_add(xd, COEFFS[5], COEFFS[4]);
  double r = fputil::polyeval(xsq, xd, c0, c1, c2, COEFFS[6]);

  return static_cast<float>(r);
}

} // namespace LIBC_NAMESPACE_DECL
