//===-- Single-precision asinh 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/asinhf.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, asinhf, (float x)) {
  using FPBits_t = typename fputil::FPBits<float>;
  FPBits_t xbits(x);
  uint32_t x_u = xbits.uintval();
  uint32_t x_abs = xbits.abs().uintval();

  // |x| <= 2^-3
  if (LIBC_UNLIKELY(x_abs <= 0x3e80'0000U)) {
    // |x| <= 2^-26
    if (LIBC_UNLIKELY(x_abs <= 0x3280'0000U)) {
      return static_cast<float>(LIBC_UNLIKELY(x_abs == 0)
                                    ? x
                                    : (x - 0x1.5555555555555p-3 * x * x * x));
    }

    double x_d = x;
    double x_sq = x_d * x_d;
    // Generated by Sollya with:
    // > P = fpminimax(asinh(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14, 16], [|D...|],
    //                 [0, 2^-2]);
    double p = fputil::polyeval(
        x_sq, 0.0, -0x1.555555555551ep-3, 0x1.3333333325495p-4,
        -0x1.6db6db5a7622bp-5, 0x1.f1c70f82928c6p-6, -0x1.6e893934266b7p-6,
        0x1.1c0b41d3fbe78p-6, -0x1.c0f47810b3c4fp-7, 0x1.2c8602690143dp-7);
    return static_cast<float>(fputil::multiply_add(x_d, p, x_d));
  }

  const double SIGN[2] = {1.0, -1.0};
  double x_sign = SIGN[x_u >> 31];
  double x_d = x;

  // Helper functions to set results for exceptional cases.
  auto round_result_slightly_down = [x_sign](float r) -> float {
    return fputil::multiply_add(static_cast<float>(x_sign), r,
                                static_cast<float>(x_sign) * (-0x1.0p-24f));
  };
  auto round_result_slightly_up = [x_sign](float r) -> float {
    return fputil::multiply_add(static_cast<float>(x_sign), r,
                                static_cast<float>(x_sign) * 0x1.0p-24f);
  };

  if (LIBC_UNLIKELY(x_abs >= 0x4bdd'65a5U)) {
    if (LIBC_UNLIKELY(xbits.is_inf_or_nan()))
      return x;

    // Exceptional cases when x > 2^24.
    switch (x_abs) {
    case 0x4bdd65a5: // |x| = 0x1.bacb4ap24f
      return round_result_slightly_down(0x1.1e0696p4f);
    case 0x4c803f2c: // |x| = 0x1.007e58p26f
      return round_result_slightly_down(0x1.2b786cp4f);
    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 0x65de7ca6: // |x| = 0x1.bcf94cp76f
      return round_result_slightly_up(0x1.af66cp5f);
    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 {
    // Exceptional cases when x < 2^24.
    if (LIBC_UNLIKELY(x_abs == 0x45abaf26)) {
      // |x| = 0x1.575e4cp12f
      return round_result_slightly_down(0x1.29becap3f);
    }
    if (LIBC_UNLIKELY(x_abs == 0x49d29048)) {
      // |x| = 0x1.a5209p20f
      return round_result_slightly_down(0x1.e1b92p3f);
    }
  }

  // asinh(x) = log(x + sqrt(x^2 + 1))
  return static_cast<float>(
      x_sign * log_eval(fputil::multiply_add(
                   x_d, x_sign,
                   fputil::sqrt<double>(fputil::multiply_add(x_d, x_d, 1.0)))));
}

} // namespace LIBC_NAMESPACE_DECL
