//===-- lib/Evaluate/real.cpp ---------------------------------------------===//
//
// 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 "flang/Evaluate/real.h"
#include "int-power.h"
#include "flang/Common/idioms.h"
#include "flang/Decimal/decimal.h"
#include "flang/Parser/characters.h"
#include "llvm/Support/raw_ostream.h"
#include <limits>

namespace Fortran::evaluate::value {

template <typename W, int P> Relation Real<W, P>::Compare(const Real &y) const {
  if (IsNotANumber() || y.IsNotANumber()) { // NaN vs x, x vs NaN
    return Relation::Unordered;
  } else if (IsInfinite()) {
    if (y.IsInfinite()) {
      if (IsNegative()) { // -Inf vs +/-Inf
        return y.IsNegative() ? Relation::Equal : Relation::Less;
      } else { // +Inf vs +/-Inf
        return y.IsNegative() ? Relation::Greater : Relation::Equal;
      }
    } else { // +/-Inf vs finite
      return IsNegative() ? Relation::Less : Relation::Greater;
    }
  } else if (y.IsInfinite()) { // finite vs +/-Inf
    return y.IsNegative() ? Relation::Greater : Relation::Less;
  } else { // two finite numbers
    bool isNegative{IsNegative()};
    if (isNegative != y.IsNegative()) {
      if (word_.IOR(y.word_).IBCLR(bits - 1).IsZero()) {
        return Relation::Equal; // +/-0.0 == -/+0.0
      } else {
        return isNegative ? Relation::Less : Relation::Greater;
      }
    } else {
      // same sign
      Ordering order{evaluate::Compare(Exponent(), y.Exponent())};
      if (order == Ordering::Equal) {
        order = GetSignificand().CompareUnsigned(y.GetSignificand());
      }
      if (isNegative) {
        order = Reverse(order);
      }
      return RelationFromOrdering(order);
    }
  }
}

template <typename W, int P>
ValueWithRealFlags<Real<W, P>> Real<W, P>::Add(
    const Real &y, Rounding rounding) const {
  ValueWithRealFlags<Real> result;
  if (IsNotANumber() || y.IsNotANumber()) {
    result.value = NotANumber(); // NaN + x -> NaN
    if (IsSignalingNaN() || y.IsSignalingNaN()) {
      result.flags.set(RealFlag::InvalidArgument);
    }
    return result;
  }
  bool isNegative{IsNegative()};
  bool yIsNegative{y.IsNegative()};
  if (IsInfinite()) {
    if (y.IsInfinite()) {
      if (isNegative == yIsNegative) {
        result.value = *this; // +/-Inf + +/-Inf -> +/-Inf
      } else {
        result.value = NotANumber(); // +/-Inf + -/+Inf -> NaN
        result.flags.set(RealFlag::InvalidArgument);
      }
    } else {
      result.value = *this; // +/-Inf + x -> +/-Inf
    }
    return result;
  }
  if (y.IsInfinite()) {
    result.value = y; // x + +/-Inf -> +/-Inf
    return result;
  }
  int exponent{Exponent()};
  int yExponent{y.Exponent()};
  if (exponent < yExponent) {
    // y is larger in magnitude; simplify by reversing operands
    return y.Add(*this, rounding);
  }
  if (exponent == yExponent && isNegative != yIsNegative) {
    Ordering order{GetSignificand().CompareUnsigned(y.GetSignificand())};
    if (order == Ordering::Less) {
      // Same exponent, opposite signs, and y is larger in magnitude
      return y.Add(*this, rounding);
    }
    if (order == Ordering::Equal) {
      // x + (-x) -> +0.0 unless rounding is directed downwards
      if (rounding.mode == common::RoundingMode::Down) {
        result.value.word_ = result.value.word_.IBSET(bits - 1); // -0.0
      }
      return result;
    }
  }
  // Our exponent is greater than y's, or the exponents match and y is not
  // of the opposite sign and greater magnitude.  So (x+y) will have the
  // same sign as x.
  Fraction fraction{GetFraction()};
  Fraction yFraction{y.GetFraction()};
  int rshift = exponent - yExponent;
  if (exponent > 0 && yExponent == 0) {
    --rshift; // correct overshift when only y is subnormal
  }
  RoundingBits roundingBits{yFraction, rshift};
  yFraction = yFraction.SHIFTR(rshift);
  bool carry{false};
  if (isNegative != yIsNegative) {
    // Opposite signs: subtract via addition of two's complement of y and
    // the rounding bits.
    yFraction = yFraction.NOT();
    carry = roundingBits.Negate();
  }
  auto sum{fraction.AddUnsigned(yFraction, carry)};
  fraction = sum.value;
  if (isNegative == yIsNegative && sum.carry) {
    roundingBits.ShiftRight(sum.value.BTEST(0));
    fraction = fraction.SHIFTR(1).IBSET(fraction.bits - 1);
    ++exponent;
  }
  NormalizeAndRound(
      result, isNegative, exponent, fraction, rounding, roundingBits);
  return result;
}

template <typename W, int P>
ValueWithRealFlags<Real<W, P>> Real<W, P>::Multiply(
    const Real &y, Rounding rounding) const {
  ValueWithRealFlags<Real> result;
  if (IsNotANumber() || y.IsNotANumber()) {
    result.value = NotANumber(); // NaN * x -> NaN
    if (IsSignalingNaN() || y.IsSignalingNaN()) {
      result.flags.set(RealFlag::InvalidArgument);
    }
  } else {
    bool isNegative{IsNegative() != y.IsNegative()};
    if (IsInfinite() || y.IsInfinite()) {
      if (IsZero() || y.IsZero()) {
        result.value = NotANumber(); // 0 * Inf -> NaN
        result.flags.set(RealFlag::InvalidArgument);
      } else {
        result.value = Infinity(isNegative);
      }
    } else {
      auto product{GetFraction().MultiplyUnsigned(y.GetFraction())};
      std::int64_t exponent{CombineExponents(y, false)};
      if (exponent < 1) {
        int rshift = 1 - exponent;
        exponent = 1;
        bool sticky{false};
        if (rshift >= product.upper.bits + product.lower.bits) {
          sticky = !product.lower.IsZero() || !product.upper.IsZero();
        } else if (rshift >= product.lower.bits) {
          sticky = !product.lower.IsZero() ||
              !product.upper
                   .IAND(product.upper.MASKR(rshift - product.lower.bits))
                   .IsZero();
        } else {
          sticky = !product.lower.IAND(product.lower.MASKR(rshift)).IsZero();
        }
        product.lower = product.lower.SHIFTRWithFill(product.upper, rshift);
        product.upper = product.upper.SHIFTR(rshift);
        if (sticky) {
          product.lower = product.lower.IBSET(0);
        }
      }
      int leadz{product.upper.LEADZ()};
      if (leadz >= product.upper.bits) {
        leadz += product.lower.LEADZ();
      }
      int lshift{leadz};
      if (lshift > exponent - 1) {
        lshift = exponent - 1;
      }
      exponent -= lshift;
      product.upper = product.upper.SHIFTLWithFill(product.lower, lshift);
      product.lower = product.lower.SHIFTL(lshift);
      RoundingBits roundingBits{product.lower, product.lower.bits};
      NormalizeAndRound(result, isNegative, exponent, product.upper, rounding,
          roundingBits, true /*multiply*/);
    }
  }
  return result;
}

template <typename W, int P>
ValueWithRealFlags<Real<W, P>> Real<W, P>::Divide(
    const Real &y, Rounding rounding) const {
  ValueWithRealFlags<Real> result;
  if (IsNotANumber() || y.IsNotANumber()) {
    result.value = NotANumber(); // NaN / x -> NaN, x / NaN -> NaN
    if (IsSignalingNaN() || y.IsSignalingNaN()) {
      result.flags.set(RealFlag::InvalidArgument);
    }
  } else {
    bool isNegative{IsNegative() != y.IsNegative()};
    if (IsInfinite()) {
      if (y.IsInfinite()) {
        result.value = NotANumber(); // Inf/Inf -> NaN
        result.flags.set(RealFlag::InvalidArgument);
      } else { // Inf/x -> Inf,  Inf/0 -> Inf
        result.value = Infinity(isNegative);
      }
    } else if (y.IsZero()) {
      if (IsZero()) { // 0/0 -> NaN
        result.value = NotANumber();
        result.flags.set(RealFlag::InvalidArgument);
      } else { // x/0 -> Inf, Inf/0 -> Inf
        result.value = Infinity(isNegative);
        result.flags.set(RealFlag::DivideByZero);
      }
    } else if (IsZero() || y.IsInfinite()) { // 0/x, x/Inf -> 0
      if (isNegative) {
        result.value.word_ = result.value.word_.IBSET(bits - 1);
      }
    } else {
      // dividend and divisor are both finite and nonzero numbers
      Fraction top{GetFraction()}, divisor{y.GetFraction()};
      std::int64_t exponent{CombineExponents(y, true)};
      Fraction quotient;
      bool msb{false};
      if (!top.BTEST(top.bits - 1) || !divisor.BTEST(divisor.bits - 1)) {
        // One or two subnormals
        int topLshift{top.LEADZ()};
        top = top.SHIFTL(topLshift);
        int divisorLshift{divisor.LEADZ()};
        divisor = divisor.SHIFTL(divisorLshift);
        exponent += divisorLshift - topLshift;
      }
      for (int j{1}; j <= quotient.bits; ++j) {
        if (NextQuotientBit(top, msb, divisor)) {
          quotient = quotient.IBSET(quotient.bits - j);
        }
      }
      bool guard{NextQuotientBit(top, msb, divisor)};
      bool round{NextQuotientBit(top, msb, divisor)};
      bool sticky{msb || !top.IsZero()};
      RoundingBits roundingBits{guard, round, sticky};
      if (exponent < 1) {
        std::int64_t rshift{1 - exponent};
        for (; rshift > 0; --rshift) {
          roundingBits.ShiftRight(quotient.BTEST(0));
          quotient = quotient.SHIFTR(1);
        }
        exponent = 1;
      }
      NormalizeAndRound(
          result, isNegative, exponent, quotient, rounding, roundingBits);
    }
  }
  return result;
}

template <typename W, int P>
ValueWithRealFlags<Real<W, P>> Real<W, P>::SQRT(Rounding rounding) const {
  ValueWithRealFlags<Real> result;
  if (IsNotANumber()) {
    result.value = NotANumber();
    if (IsSignalingNaN()) {
      result.flags.set(RealFlag::InvalidArgument);
    }
  } else if (IsNegative()) {
    if (IsZero()) {
      // SQRT(-0) == -0 in IEEE-754.
      result.value.word_ = result.value.word_.IBSET(bits - 1);
    } else {
      result.value = NotANumber();
    }
  } else if (IsInfinite()) {
    // SQRT(+Inf) == +Inf
    result.value = Infinity(false);
  } else {
    // Slow but reliable bit-at-a-time method.  Start with a clear significand
    // and half the unbiased exponent, and then try to set significand bits
    // in descending order of magnitude without exceeding the exact result.
    int expo{UnbiasedExponent()};
    if (IsSubnormal()) {
      expo -= GetFraction().LEADZ();
    }
    expo = expo / 2 + exponentBias;
    result.value.Normalize(false, expo, Fraction::MASKL(1));
    for (int bit{significandBits - 1}; bit >= 0; --bit) {
      Word word{result.value.word_};
      result.value.word_ = word.IBSET(bit);
      auto squared{result.value.Multiply(result.value, rounding)};
      if (squared.flags.test(RealFlag::Overflow) ||
          squared.flags.test(RealFlag::Underflow) ||
          Compare(squared.value) == Relation::Less) {
        result.value.word_ = word;
      }
    }
    // The computed square root, when squared, has a square that's not greater
    // than the original argument.  Check this square against the square of the
    // next Real value, and return that one if its square is closer in magnitude
    // to the original argument.
    Real resultSq{result.value.Multiply(result.value).value};
    Real diff{Subtract(resultSq).value.ABS()};
    if (diff.IsZero()) {
      return result; // exact
    }
    Real ulp;
    ulp.Normalize(false, expo, Fraction::MASKR(1));
    Real nextAfter{result.value.Add(ulp).value};
    auto nextAfterSq{nextAfter.Multiply(nextAfter)};
    if (!nextAfterSq.flags.test(RealFlag::Overflow) &&
        !nextAfterSq.flags.test(RealFlag::Underflow)) {
      Real nextAfterDiff{Subtract(nextAfterSq.value).value.ABS()};
      if (nextAfterDiff.Compare(diff) == Relation::Less) {
        result.value = nextAfter;
        if (nextAfterDiff.IsZero()) {
          return result; // exact
        }
      }
    }
    result.flags.set(RealFlag::Inexact);
  }
  return result;
}

// HYPOT(x,y) = SQRT(x**2 + y**2) by definition, but those squared intermediate
// values are susceptible to over/underflow when computed naively.
// Assuming that x>=y, calculate instead:
//   HYPOT(x,y) = SQRT(x**2 * (1+(y/x)**2))
//              = ABS(x) * SQRT(1+(y/x)**2)
template <typename W, int P>
ValueWithRealFlags<Real<W, P>> Real<W, P>::HYPOT(
    const Real &y, Rounding rounding) const {
  ValueWithRealFlags<Real> result;
  if (IsNotANumber() || y.IsNotANumber()) {
    result.flags.set(RealFlag::InvalidArgument);
    result.value = NotANumber();
  } else if (ABS().Compare(y.ABS()) == Relation::Less) {
    return y.HYPOT(*this);
  } else if (IsZero()) {
    return result; // x==y==0
  } else {
    auto yOverX{y.Divide(*this, rounding)}; // y/x
    bool inexact{yOverX.flags.test(RealFlag::Inexact)};
    auto squared{yOverX.value.Multiply(yOverX.value, rounding)}; // (y/x)**2
    inexact |= squared.flags.test(RealFlag::Inexact);
    Real one;
    one.Normalize(false, exponentBias, Fraction::MASKL(1)); // 1.0
    auto sum{squared.value.Add(one, rounding)}; // 1.0 + (y/x)**2
    inexact |= sum.flags.test(RealFlag::Inexact);
    auto sqrt{sum.value.SQRT()};
    inexact |= sqrt.flags.test(RealFlag::Inexact);
    result = sqrt.value.Multiply(ABS(), rounding);
    if (inexact) {
      result.flags.set(RealFlag::Inexact);
    }
  }
  return result;
}

template <typename W, int P>
ValueWithRealFlags<Real<W, P>> Real<W, P>::ToWholeNumber(
    common::RoundingMode mode) const {
  ValueWithRealFlags<Real> result{*this};
  if (IsNotANumber()) {
    result.flags.set(RealFlag::InvalidArgument);
    result.value = NotANumber();
  } else if (IsInfinite()) {
    result.flags.set(RealFlag::Overflow);
  } else {
    constexpr int noClipExponent{exponentBias + binaryPrecision - 1};
    if (Exponent() < noClipExponent) {
      Real adjust; // ABS(EPSILON(adjust)) == 0.5
      adjust.Normalize(IsSignBitSet(), noClipExponent, Fraction::MASKL(1));
      // Compute ival=(*this + adjust), losing any fractional bits; keep flags
      result = Add(adjust, Rounding{mode});
      result.flags.reset(RealFlag::Inexact); // result *is* exact
      // Return (ival-adjust) with original sign in case we've generated a zero.
      result.value =
          result.value.Subtract(adjust, Rounding{common::RoundingMode::ToZero})
              .value.SIGN(*this);
    }
  }
  return result;
}

template <typename W, int P>
RealFlags Real<W, P>::Normalize(bool negative, int exponent,
    const Fraction &fraction, Rounding rounding, RoundingBits *roundingBits) {
  int lshift{fraction.LEADZ()};
  if (lshift == fraction.bits /* fraction is zero */ &&
      (!roundingBits || roundingBits->empty())) {
    // No fraction, no rounding bits -> +/-0.0
    exponent = lshift = 0;
  } else if (lshift < exponent) {
    exponent -= lshift;
  } else if (exponent > 0) {
    lshift = exponent - 1;
    exponent = 0;
  } else if (lshift == 0) {
    exponent = 1;
  } else {
    lshift = 0;
  }
  if (exponent >= maxExponent) {
    // Infinity or overflow
    if (rounding.mode == common::RoundingMode::TiesToEven ||
        rounding.mode == common::RoundingMode::TiesAwayFromZero ||
        (rounding.mode == common::RoundingMode::Up && !negative) ||
        (rounding.mode == common::RoundingMode::Down && negative)) {
      word_ = Word{maxExponent}.SHIFTL(significandBits); // Inf
    } else {
      // directed rounding: round to largest finite value rather than infinity
      // (x86 does this, not sure whether it's standard behavior)
      word_ = Word{word_.MASKR(word_.bits - 1)}.IBCLR(significandBits);
    }
    if (negative) {
      word_ = word_.IBSET(bits - 1);
    }
    RealFlags flags{RealFlag::Overflow};
    if (!fraction.IsZero()) {
      flags.set(RealFlag::Inexact);
    }
    return flags;
  }
  word_ = Word::ConvertUnsigned(fraction).value;
  if (lshift > 0) {
    word_ = word_.SHIFTL(lshift);
    if (roundingBits) {
      for (; lshift > 0; --lshift) {
        if (roundingBits->ShiftLeft()) {
          word_ = word_.IBSET(lshift - 1);
        }
      }
    }
  }
  if constexpr (isImplicitMSB) {
    word_ = word_.IBCLR(significandBits);
  }
  word_ = word_.IOR(Word{exponent}.SHIFTL(significandBits));
  if (negative) {
    word_ = word_.IBSET(bits - 1);
  }
  return {};
}

template <typename W, int P>
RealFlags Real<W, P>::Round(
    Rounding rounding, const RoundingBits &bits, bool multiply) {
  int origExponent{Exponent()};
  RealFlags flags;
  bool inexact{!bits.empty()};
  if (inexact) {
    flags.set(RealFlag::Inexact);
  }
  if (origExponent < maxExponent &&
      bits.MustRound(rounding, IsNegative(), word_.BTEST(0) /* is odd */)) {
    typename Fraction::ValueWithCarry sum{
        GetFraction().AddUnsigned(Fraction{}, true)};
    int newExponent{origExponent};
    if (sum.carry) {
      // The fraction was all ones before rounding; sum.value is now zero
      sum.value = sum.value.IBSET(binaryPrecision - 1);
      if (++newExponent >= maxExponent) {
        flags.set(RealFlag::Overflow); // rounded away to an infinity
      }
    }
    flags |= Normalize(IsNegative(), newExponent, sum.value);
  }
  if (inexact && origExponent == 0) {
    // inexact subnormal input: signal Underflow unless in an x86-specific
    // edge case
    if (rounding.x86CompatibleBehavior && Exponent() != 0 && multiply &&
        bits.sticky() &&
        (bits.guard() ||
            (rounding.mode != common::RoundingMode::Up &&
                rounding.mode != common::RoundingMode::Down))) {
      // x86 edge case in which Underflow fails to signal when a subnormal
      // inexact multiplication product rounds to a normal result when
      // the guard bit is set or we're not using directed rounding
    } else {
      flags.set(RealFlag::Underflow);
    }
  }
  return flags;
}

template <typename W, int P>
void Real<W, P>::NormalizeAndRound(ValueWithRealFlags<Real> &result,
    bool isNegative, int exponent, const Fraction &fraction, Rounding rounding,
    RoundingBits roundingBits, bool multiply) {
  result.flags |= result.value.Normalize(
      isNegative, exponent, fraction, rounding, &roundingBits);
  result.flags |= result.value.Round(rounding, roundingBits, multiply);
}

inline enum decimal::FortranRounding MapRoundingMode(
    common::RoundingMode rounding) {
  switch (rounding) {
  case common::RoundingMode::TiesToEven:
    break;
  case common::RoundingMode::ToZero:
    return decimal::RoundToZero;
  case common::RoundingMode::Down:
    return decimal::RoundDown;
  case common::RoundingMode::Up:
    return decimal::RoundUp;
  case common::RoundingMode::TiesAwayFromZero:
    return decimal::RoundCompatible;
  }
  return decimal::RoundNearest; // dodge gcc warning about lack of result
}

inline RealFlags MapFlags(decimal::ConversionResultFlags flags) {
  RealFlags result;
  if (flags & decimal::Overflow) {
    result.set(RealFlag::Overflow);
  }
  if (flags & decimal::Inexact) {
    result.set(RealFlag::Inexact);
  }
  if (flags & decimal::Invalid) {
    result.set(RealFlag::InvalidArgument);
  }
  return result;
}

template <typename W, int P>
ValueWithRealFlags<Real<W, P>> Real<W, P>::Read(
    const char *&p, Rounding rounding) {
  auto converted{
      decimal::ConvertToBinary<P>(p, MapRoundingMode(rounding.mode))};
  const auto *value{reinterpret_cast<Real<W, P> *>(&converted.binary)};
  return {*value, MapFlags(converted.flags)};
}

template <typename W, int P> std::string Real<W, P>::DumpHexadecimal() const {
  if (IsNotANumber()) {
    return "NaN0x"s + word_.Hexadecimal();
  } else if (IsNegative()) {
    return "-"s + Negate().DumpHexadecimal();
  } else if (IsInfinite()) {
    return "Inf"s;
  } else if (IsZero()) {
    return "0.0"s;
  } else {
    Fraction frac{GetFraction()};
    std::string result{"0x"};
    char intPart = '0' + frac.BTEST(frac.bits - 1);
    result += intPart;
    result += '.';
    int trailz{frac.TRAILZ()};
    if (trailz >= frac.bits - 1) {
      result += '0';
    } else {
      int remainingBits{frac.bits - 1 - trailz};
      int wholeNybbles{remainingBits / 4};
      int lostBits{remainingBits - 4 * wholeNybbles};
      if (wholeNybbles > 0) {
        std::string fracHex{frac.SHIFTR(trailz + lostBits)
                                .IAND(frac.MASKR(4 * wholeNybbles))
                                .Hexadecimal()};
        std::size_t field = wholeNybbles;
        if (fracHex.size() < field) {
          result += std::string(field - fracHex.size(), '0');
        }
        result += fracHex;
      }
      if (lostBits > 0) {
        result += frac.SHIFTR(trailz)
                      .IAND(frac.MASKR(lostBits))
                      .SHIFTL(4 - lostBits)
                      .Hexadecimal();
      }
    }
    result += 'p';
    int exponent = Exponent() - exponentBias;
    result += Integer<32>{exponent}.SignedDecimal();
    return result;
  }
}

template <typename W, int P>
llvm::raw_ostream &Real<W, P>::AsFortran(
    llvm::raw_ostream &o, int kind, bool minimal) const {
  if (IsNotANumber()) {
    o << "(0._" << kind << "/0.)";
  } else if (IsInfinite()) {
    if (IsNegative()) {
      o << "(-1._" << kind << "/0.)";
    } else {
      o << "(1._" << kind << "/0.)";
    }
  } else {
    using B = decimal::BinaryFloatingPointNumber<P>;
    B value{word_.template ToUInt<typename B::RawType>()};
    char buffer[common::MaxDecimalConversionDigits(P) +
        EXTRA_DECIMAL_CONVERSION_SPACE];
    decimal::DecimalConversionFlags flags{}; // default: exact representation
    if (minimal) {
      flags = decimal::Minimize;
    }
    auto result{decimal::ConvertToDecimal<P>(buffer, sizeof buffer, flags,
        static_cast<int>(sizeof buffer), decimal::RoundNearest, value)};
    const char *p{result.str};
    if (DEREF(p) == '-' || *p == '+') {
      o << *p++;
    }
    int expo{result.decimalExponent};
    if (*p != '0') {
      --expo;
    }
    o << *p << '.' << (p + 1);
    if (expo != 0) {
      o << 'e' << expo;
    }
    o << '_' << kind;
  }
  return o;
}

template class Real<Integer<16>, 11>;
template class Real<Integer<16>, 8>;
template class Real<Integer<32>, 24>;
template class Real<Integer<64>, 53>;
template class Real<Integer<80>, 64>;
template class Real<Integer<128>, 113>;
} // namespace Fortran::evaluate::value
