//===-- Implementation of fmul 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/fmul.h"
#include "hdr/errno_macros.h"
#include "hdr/fenv_macros.h"
#include "src/__support/FPUtil/double_double.h"
#include "src/__support/FPUtil/generic/mul.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(float, fmul, (double x, double y)) {

  // Without FMA instructions, fputil::exact_mult is not
  // correctly rounded for all rounding modes, so we fall
  // back to the generic `fmul` implementation

#ifndef LIBC_TARGET_CPU_HAS_FMA
  return fputil::generic::mul<float>(x, y);
#else
  fputil::DoubleDouble prod = fputil::exact_mult(x, y);
  using DoubleBits = fputil::FPBits<double>;
  using DoubleStorageType = typename DoubleBits::StorageType;
  using FloatBits = fputil::FPBits<float>;
  using FloatStorageType = typename FloatBits::StorageType;
  DoubleBits x_bits(x);
  DoubleBits y_bits(y);

  Sign result_sign = x_bits.sign() == y_bits.sign() ? Sign::POS : Sign::NEG;
  double result = prod.hi;
  DoubleBits hi_bits(prod.hi), lo_bits(prod.lo);
  // Check for cases where we need to propagate the sticky bits:
  constexpr uint64_t STICKY_MASK = 0xFFF'FFF; // Lower (52 - 23 - 1 = 28 bits)
  uint64_t sticky_bits = (hi_bits.uintval() & STICKY_MASK);
  if (LIBC_UNLIKELY(sticky_bits == 0)) {
    // Might need to propagate sticky bits:
    if (!(lo_bits.is_inf_or_nan() || lo_bits.is_zero())) {
      // Now prod.lo is nonzero and finite, we need to propagate sticky bits.
      if (lo_bits.sign() != hi_bits.sign())
        result = DoubleBits(hi_bits.uintval() - 1).get_val();
      else
        result = DoubleBits(hi_bits.uintval() | 1).get_val();
    }
  }

  float result_f = static_cast<float>(result);
  FloatBits rf_bits(result_f);
  uint32_t rf_exp = rf_bits.get_biased_exponent();
  if (LIBC_LIKELY(rf_exp > 0 && rf_exp < 2 * FloatBits::EXP_BIAS + 1)) {
    return result_f;
  }

  // Now result_f is either inf/nan/zero/denormal.
  if (x_bits.is_nan() || y_bits.is_nan()) {
    if (x_bits.is_signaling_nan() || y_bits.is_signaling_nan())
      fputil::raise_except_if_required(FE_INVALID);

    if (x_bits.is_quiet_nan()) {
      DoubleStorageType x_payload = x_bits.get_mantissa();
      x_payload >>= DoubleBits::FRACTION_LEN - FloatBits::FRACTION_LEN;
      return FloatBits::quiet_nan(x_bits.sign(),
                                  static_cast<FloatStorageType>(x_payload))
          .get_val();
    }

    if (y_bits.is_quiet_nan()) {
      DoubleStorageType y_payload = y_bits.get_mantissa();
      y_payload >>= DoubleBits::FRACTION_LEN - FloatBits::FRACTION_LEN;
      return FloatBits::quiet_nan(y_bits.sign(),
                                  static_cast<FloatStorageType>(y_payload))
          .get_val();
    }

    return FloatBits::quiet_nan().get_val();
  }

  if (x_bits.is_inf()) {
    if (y_bits.is_zero()) {
      fputil::set_errno_if_required(EDOM);
      fputil::raise_except_if_required(FE_INVALID);

      return FloatBits::quiet_nan().get_val();
    }

    return FloatBits::inf(result_sign).get_val();
  }

  if (y_bits.is_inf()) {
    if (x_bits.is_zero()) {
      fputil::set_errno_if_required(EDOM);
      fputil::raise_except_if_required(FE_INVALID);
      return FloatBits::quiet_nan().get_val();
    }

    return FloatBits::inf(result_sign).get_val();
  }

  // Now either x or y is zero, and the other one is finite.
  if (rf_bits.is_inf()) {
    fputil::set_errno_if_required(ERANGE);
    return FloatBits::inf(result_sign).get_val();
  }

  if (x_bits.is_zero() || y_bits.is_zero())
    return FloatBits::zero(result_sign).get_val();

  fputil::set_errno_if_required(ERANGE);
  fputil::raise_except_if_required(FE_UNDERFLOW);
  return result_f;

#endif
}
} // namespace LIBC_NAMESPACE_DECL
