//===-- Single-precision cospi 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/cospif.h"
#include "sincosf_utils.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.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" // LIBC_TARGET_CPU_HAS_FMA

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(float, cospif, (float x)) {
  using FPBits = typename fputil::FPBits<float>;

  FPBits xbits(x);
  xbits.set_sign(Sign::POS);

  uint32_t x_abs = xbits.uintval();
  double xd = static_cast<double>(xbits.get_val());

  // Range reduction:
  // For |x| > 1/32, we perform range reduction as follows:
  // Find k and y such that:
  //   x = (k + y) * 1/32
  //   k is an integer
  //   |y| < 0.5
  //
  // This is done by performing:
  //   k = round(x * 32)
  //   y = x * 32 - k
  //
  // Once k and y are computed, we then deduce the answer by the cosine of sum
  // formula:
  //   cospi(x) = cos((k + y)*pi/32)
  //          = cos(y*pi/32) * cos(k*pi/32) - sin(y*pi/32) * sin(k*pi/32)
  // The values of sin(k*pi/32) and cos(k*pi/32) for k = 0..63 are precomputed
  // and stored using a vector of 32 doubles. Sin(y*pi/32) and cos(y*pi/32) are
  // computed using degree-7 and degree-6 minimax polynomials generated by
  // Sollya respectively.

  // The exhautive test passes for smaller values
  if (LIBC_UNLIKELY(x_abs < 0x38A2'F984U)) {

#if defined(LIBC_TARGET_CPU_HAS_FMA)
    return fputil::multiply_add(xbits.get_val(), -0x1.0p-25f, 1.0f);
#else
    return static_cast<float>(fputil::multiply_add(xd, -0x1.0p-25, 1.0));
#endif // LIBC_TARGET_CPU_HAS_FMA
  }

  // Numbers greater or equal to 2^23 are always integers or NaN
  if (LIBC_UNLIKELY(x_abs >= 0x4B00'0000)) {

    if (LIBC_UNLIKELY(x_abs < 0x4B80'0000)) {
      return (x_abs & 0x1) ? -1.0f : 1.0f;
    }

    // x is inf or nan.
    if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) {
      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();
    }

    return 1.0f;
  }

  // Combine the results with the sine of sum formula:
  //   cos(pi * x) = cos((k + y)*pi/32)
  //          = cos(y*pi/32) * cos(k*pi/32) - sin(y*pi/32) * sin(k*pi/32)
  //          = (cosm1_y + 1) * cos_k - sin_y * sin_k
  //          = (cosm1_y * cos_k + cos_k) - sin_y * sin_k
  double sin_k, cos_k, sin_y, cosm1_y;

  sincospif_eval(xd, sin_k, cos_k, sin_y, cosm1_y);

  if (LIBC_UNLIKELY(sin_y == 0 && cos_k == 0)) {
    return 0.0f;
  }

  return static_cast<float>(fputil::multiply_add(
      sin_y, -sin_k, fputil::multiply_add(cosm1_y, cos_k, cos_k)));
}

} // namespace LIBC_NAMESPACE_DECL
