//===-- Double-precision 2^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/exp2.h"
#include "common_constants.h" // Lookup tables EXP2_MID1 and EXP_M2.
#include "explogxf.h"         // ziv_test_denorm.
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/optional.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/nearest_integer.h"
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/FPUtil/triple_double.h"
#include "src/__support/common.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY

#include <errno.h>

namespace LIBC_NAMESPACE {

using fputil::DoubleDouble;
using fputil::TripleDouble;
using Float128 = typename fputil::DyadicFloat<128>;
using Sign = fputil::Sign;

// Error bounds:
// Errors when using double precision.
#ifdef LIBC_TARGET_CPU_HAS_FMA
constexpr double ERR_D = 0x1.0p-63;
#else
constexpr double ERR_D = 0x1.8p-63;
#endif // LIBC_TARGET_CPU_HAS_FMA

// Errors when using double-double precision.
constexpr double ERR_DD = 0x1.0p-100;

namespace {

// Polynomial approximations with double precision.  Generated by Sollya with:
// > P = fpminimax((2^x - 1)/x, 3, [|D...|], [-2^-13 - 2^-30, 2^-13 + 2^-30]);
// > P;
// Error bounds:
//   | output - (2^dx - 1) / dx | < 1.5 * 2^-52.
LIBC_INLINE double poly_approx_d(double dx) {
  // dx^2
  double dx2 = dx * dx;
  double c0 =
      fputil::multiply_add(dx, 0x1.ebfbdff82c58ep-3, 0x1.62e42fefa39efp-1);
  double c1 =
      fputil::multiply_add(dx, 0x1.3b2aba7a95a89p-7, 0x1.c6b08e8fc0c0ep-5);
  double p = fputil::multiply_add(dx2, c1, c0);
  return p;
}

// Polynomial approximation with double-double precision.  Generated by Solya
// with:
// > P = fpminimax((2^x - 1)/x, 5, [|DD...|], [-2^-13 - 2^-30, 2^-13 + 2^-30]);
// Error bounds:
//   | output - 2^(dx) | < 2^-101
DoubleDouble poly_approx_dd(const DoubleDouble &dx) {
  // Taylor polynomial.
  constexpr DoubleDouble COEFFS[] = {
      {0, 0x1p0},
      {0x1.abc9e3b39824p-56, 0x1.62e42fefa39efp-1},
      {-0x1.5e43a53e4527bp-57, 0x1.ebfbdff82c58fp-3},
      {-0x1.d37963a9444eep-59, 0x1.c6b08d704a0cp-5},
      {0x1.4eda1a81133dap-62, 0x1.3b2ab6fba4e77p-7},
      {-0x1.c53fd1ba85d14p-64, 0x1.5d87fe7a265a5p-10},
      {0x1.d89250b013eb8p-70, 0x1.430912f86cb8ep-13},
  };

  DoubleDouble p = fputil::polyeval(dx, COEFFS[0], COEFFS[1], COEFFS[2],
                                    COEFFS[3], COEFFS[4], COEFFS[5], COEFFS[6]);
  return p;
}

// Polynomial approximation with 128-bit precision:
// Return exp(dx) ~ 1 + a0 * dx + a1 * dx^2 + ... + a6 * dx^7
// For |dx| < 2^-13 + 2^-30:
//   | output - exp(dx) | < 2^-126.
Float128 poly_approx_f128(const Float128 &dx) {
  using MType = typename Float128::MantissaType;

  constexpr Float128 COEFFS_128[]{
      {Sign::POS, -127, MType({0, 0x8000000000000000})}, // 1.0
      {Sign::POS, -128, MType({0xc9e3b39803f2f6af, 0xb17217f7d1cf79ab})},
      {Sign::POS, -128, MType({0xde2d60dd9c9a1d9f, 0x3d7f7bff058b1d50})},
      {Sign::POS, -132, MType({0x9d3b15d9e7fb6897, 0xe35846b82505fc59})},
      {Sign::POS, -134, MType({0x184462f6bcd2b9e7, 0x9d955b7dd273b94e})},
      {Sign::POS, -137, MType({0x39ea1bb964c51a89, 0xaec3ff3c53398883})},
      {Sign::POS, -138, MType({0x842c53418fa8ae61, 0x2861225f345c396a})},
      {Sign::POS, -144, MType({0x7abeb5abd5ad2079, 0xffe5fe2d109a319d})},
  };

  Float128 p = fputil::polyeval(dx, COEFFS_128[0], COEFFS_128[1], COEFFS_128[2],
                                COEFFS_128[3], COEFFS_128[4], COEFFS_128[5],
                                COEFFS_128[6], COEFFS_128[7]);
  return p;
}

// Compute 2^(x) using 128-bit precision.
// TODO(lntue): investigate triple-double precision implementation for this
// step.
Float128 exp2_f128(double x, int hi, int idx1, int idx2) {
  Float128 dx = Float128(x);

  // TODO: Skip recalculating exp_mid1 and exp_mid2.
  Float128 exp_mid1 =
      fputil::quick_add(Float128(EXP2_MID1[idx1].hi),
                        fputil::quick_add(Float128(EXP2_MID1[idx1].mid),
                                          Float128(EXP2_MID1[idx1].lo)));

  Float128 exp_mid2 =
      fputil::quick_add(Float128(EXP2_MID2[idx2].hi),
                        fputil::quick_add(Float128(EXP2_MID2[idx2].mid),
                                          Float128(EXP2_MID2[idx2].lo)));

  Float128 exp_mid = fputil::quick_mul(exp_mid1, exp_mid2);

  Float128 p = poly_approx_f128(dx);

  Float128 r = fputil::quick_mul(exp_mid, p);

  r.exponent += hi;

  return r;
}

// Compute 2^x with double-double precision.
DoubleDouble exp2_double_double(double x, const DoubleDouble &exp_mid) {
  DoubleDouble dx({0, x});

  // Degree-6 polynomial approximation in double-double precision.
  // | p - 2^x | < 2^-103.
  DoubleDouble p = poly_approx_dd(dx);

  // Error bounds: 2^-102.
  DoubleDouble r = fputil::quick_mult(exp_mid, p);

  return r;
}

// When output is denormal.
double exp2_denorm(double x) {
  // Range reduction.
  int k =
      static_cast<int>(cpp::bit_cast<uint64_t>(x + 0x1.8000'0000'4p21) >> 19);
  double kd = static_cast<double>(k);

  uint32_t idx1 = (k >> 6) & 0x3f;
  uint32_t idx2 = k & 0x3f;

  int hi = k >> 12;

  DoubleDouble exp_mid1{EXP2_MID1[idx1].mid, EXP2_MID1[idx1].hi};
  DoubleDouble exp_mid2{EXP2_MID2[idx2].mid, EXP2_MID2[idx2].hi};
  DoubleDouble exp_mid = fputil::quick_mult(exp_mid1, exp_mid2);

  // |dx| < 2^-13 + 2^-30.
  double dx = fputil::multiply_add(kd, -0x1.0p-12, x); // exact

  double mid_lo = dx * exp_mid.hi;

  // Approximate (2^dx - 1)/dx ~ 1 + a0*dx + a1*dx^2 + a2*dx^3 + a3*dx^4.
  double p = poly_approx_d(dx);

  double lo = fputil::multiply_add(p, mid_lo, exp_mid.lo);

  if (auto r = ziv_test_denorm(hi, exp_mid.hi, lo, ERR_D);
      LIBC_LIKELY(r.has_value()))
    return r.value();

  // Use double-double
  DoubleDouble r_dd = exp2_double_double(dx, exp_mid);

  if (auto r = ziv_test_denorm(hi, r_dd.hi, r_dd.lo, ERR_DD);
      LIBC_LIKELY(r.has_value()))
    return r.value();

  // Use 128-bit precision
  Float128 r_f128 = exp2_f128(dx, hi, idx1, idx2);

  return static_cast<double>(r_f128);
}

// Check for exceptional cases when:
//  * log2(1 - 2^-54) < x < log2(1 + 2^-53)
//  * x >= 1024
//  * x <= -1022
//  * x is inf or nan
double set_exceptional(double x) {
  using FPBits = typename fputil::FPBits<double>;
  FPBits xbits(x);

  uint64_t x_u = xbits.uintval();
  uint64_t x_abs = xbits.abs().uintval();

  // |x| < log2(1 + 2^-53)
  if (x_abs <= 0x3ca71547652b82fd) {
    // 2^(x) ~ 1 + x/2
    return fputil::multiply_add(x, 0.5, 1.0);
  }

  // x <= -1022 || x >= 1024 or inf/nan.
  if (x_u > 0xc08ff00000000000) {
    // x <= -1075 or -inf/nan
    if (x_u >= 0xc090cc0000000000) {
      // exp(-Inf) = 0
      if (xbits.is_inf())
        return 0.0;

      // exp(nan) = nan
      if (xbits.is_nan())
        return x;

      if (fputil::quick_get_round() == FE_UPWARD)
        return FPBits::min_subnormal().get_val();
      fputil::set_errno_if_required(ERANGE);
      fputil::raise_except_if_required(FE_UNDERFLOW);
      return 0.0;
    }

    return exp2_denorm(x);
  }

  // x >= 1024 or +inf/nan
  // x is finite
  if (x_u < 0x7ff0'0000'0000'0000ULL) {
    int rounding = fputil::quick_get_round();
    if (rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO)
      return FPBits::max_normal().get_val();

    fputil::set_errno_if_required(ERANGE);
    fputil::raise_except_if_required(FE_OVERFLOW);
  }
  // x is +inf or nan
  return x + FPBits::inf().get_val();
}

} // namespace

LLVM_LIBC_FUNCTION(double, exp2, (double x)) {
  using FPBits = typename fputil::FPBits<double>;
  FPBits xbits(x);

  uint64_t x_u = xbits.uintval();

  // x < -1022 or x >= 1024 or log2(1 - 2^-54) < x < log2(1 + 2^-53).
  if (LIBC_UNLIKELY(x_u > 0xc08ff00000000000 ||
                    (x_u <= 0xbc971547652b82fe && x_u >= 0x4090000000000000) ||
                    x_u <= 0x3ca71547652b82fd)) {
    return set_exceptional(x);
  }

  // Now -1075 < x <= log2(1 - 2^-54) or log2(1 + 2^-53) < x < 1024

  // Range reduction:
  // Let x = (hi + mid1 + mid2) + lo
  // in which:
  //   hi is an integer
  //   mid1 * 2^6 is an integer
  //   mid2 * 2^12 is an integer
  // then:
  //   2^(x) = 2^hi * 2^(mid1) * 2^(mid2) * 2^(lo).
  // With this formula:
  //   - multiplying by 2^hi is exact and cheap, simply by adding the exponent
  //     field.
  //   - 2^(mid1) and 2^(mid2) are stored in 2 x 64-element tables.
  //   - 2^(lo) ~ 1 + a0*lo + a1 * lo^2 + ...
  //
  // We compute (hi + mid1 + mid2) together by perform the rounding on x * 2^12.
  // Since |x| < |-1075)| < 2^11,
  //   |x * 2^12| < 2^11 * 2^12 < 2^23,
  // So we can fit the rounded result round(x * 2^12) in int32_t.
  // Thus, the goal is to be able to use an additional addition and fixed width
  // shift to get an int32_t representing round(x * 2^12).
  //
  // Assuming int32_t using 2-complement representation, since the mantissa part
  // of a double precision is unsigned with the leading bit hidden, if we add an
  // extra constant C = 2^e1 + 2^e2 with e1 > e2 >= 2^25 to the product, the
  // part that are < 2^e2 in resulted mantissa of (x*2^12*L2E + C) can be
  // considered as a proper 2-complement representations of x*2^12.
  //
  // One small problem with this approach is that the sum (x*2^12 + C) in
  // double precision is rounded to the least significant bit of the dorminant
  // factor C.  In order to minimize the rounding errors from this addition, we
  // want to minimize e1.  Another constraint that we want is that after
  // shifting the mantissa so that the least significant bit of int32_t
  // corresponds to the unit bit of (x*2^12*L2E), the sign is correct without
  // any adjustment.  So combining these 2 requirements, we can choose
  //   C = 2^33 + 2^32, so that the sign bit corresponds to 2^31 bit, and hence
  // after right shifting the mantissa, the resulting int32_t has correct sign.
  // With this choice of C, the number of mantissa bits we need to shift to the
  // right is: 52 - 33 = 19.
  //
  // Moreover, since the integer right shifts are equivalent to rounding down,
  // we can add an extra 0.5 so that it will become round-to-nearest, tie-to-
  // +infinity.  So in particular, we can compute:
  //   hmm = x * 2^12 + C,
  // where C = 2^33 + 2^32 + 2^-1, then if
  //   k = int32_t(lower 51 bits of double(x * 2^12 + C) >> 19),
  // the reduced argument:
  //   lo = x - 2^-12 * k is bounded by:
  //   |lo| <= 2^-13 + 2^-12*2^-19
  //         = 2^-13 + 2^-31.
  //
  // Finally, notice that k only uses the mantissa of x * 2^12, so the
  // exponent 2^12 is not needed.  So we can simply define
  //   C = 2^(33 - 12) + 2^(32 - 12) + 2^(-13 - 12), and
  //   k = int32_t(lower 51 bits of double(x + C) >> 19).

  // Rounding errors <= 2^-31.
  int k =
      static_cast<int>(cpp::bit_cast<uint64_t>(x + 0x1.8000'0000'4p21) >> 19);
  double kd = static_cast<double>(k);

  uint32_t idx1 = (k >> 6) & 0x3f;
  uint32_t idx2 = k & 0x3f;

  int hi = k >> 12;

  DoubleDouble exp_mid1{EXP2_MID1[idx1].mid, EXP2_MID1[idx1].hi};
  DoubleDouble exp_mid2{EXP2_MID2[idx2].mid, EXP2_MID2[idx2].hi};
  DoubleDouble exp_mid = fputil::quick_mult(exp_mid1, exp_mid2);

  // |dx| < 2^-13 + 2^-30.
  double dx = fputil::multiply_add(kd, -0x1.0p-12, x); // exact

  // We use the degree-4 polynomial to approximate 2^(lo):
  //   2^(lo) ~ 1 + a0 * lo + a1 * lo^2 + a2 * lo^3 + a3 * lo^4 = 1 + lo * P(lo)
  // So that the errors are bounded by:
  //   |P(lo) - (2^lo - 1)/lo| < |lo|^4 / 64 < 2^(-13 * 4) / 64 = 2^-58
  // Let P_ be an evaluation of P where all intermediate computations are in
  // double precision.  Using either Horner's or Estrin's schemes, the evaluated
  // errors can be bounded by:
  //      |P_(lo) - P(lo)| < 2^-51
  //   => |lo * P_(lo) - (2^lo - 1) | < 2^-64
  //   => 2^(mid1 + mid2) * |lo * P_(lo) - expm1(lo)| < 2^-63.
  // Since we approximate
  //   2^(mid1 + mid2) ~ exp_mid.hi + exp_mid.lo,
  // We use the expression:
  //    (exp_mid.hi + exp_mid.lo) * (1 + dx * P_(dx)) ~
  //  ~ exp_mid.hi + (exp_mid.hi * dx * P_(dx) + exp_mid.lo)
  // with errors bounded by 2^-63.

  double mid_lo = dx * exp_mid.hi;

  // Approximate (2^dx - 1)/dx ~ 1 + a0*dx + a1*dx^2 + a2*dx^3 + a3*dx^4.
  double p = poly_approx_d(dx);

  double lo = fputil::multiply_add(p, mid_lo, exp_mid.lo);

  double upper = exp_mid.hi + (lo + ERR_D);
  double lower = exp_mid.hi + (lo - ERR_D);

  if (LIBC_LIKELY(upper == lower)) {
    // To multiply by 2^hi, a fast way is to simply add hi to the exponent
    // field.
    int64_t exp_hi = static_cast<int64_t>(hi) << FPBits::FRACTION_LEN;
    double r = cpp::bit_cast<double>(exp_hi + cpp::bit_cast<int64_t>(upper));
    return r;
  }

  // Use double-double
  DoubleDouble r_dd = exp2_double_double(dx, exp_mid);

  double upper_dd = r_dd.hi + (r_dd.lo + ERR_DD);
  double lower_dd = r_dd.hi + (r_dd.lo - ERR_DD);

  if (LIBC_LIKELY(upper_dd == lower_dd)) {
    // To multiply by 2^hi, a fast way is to simply add hi to the exponent
    // field.
    int64_t exp_hi = static_cast<int64_t>(hi) << FPBits::FRACTION_LEN;
    double r = cpp::bit_cast<double>(exp_hi + cpp::bit_cast<int64_t>(upper_dd));
    return r;
  }

  // Use 128-bit precision
  Float128 r_f128 = exp2_f128(dx, hi, idx1, idx2);

  return static_cast<double>(r_f128);
}

} // namespace LIBC_NAMESPACE
