// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "riscv/riscv_f_instructions.h"

#include <cmath>
#include <cstdint>
#include <functional>
#include <limits>
#include <type_traits>

#include "absl/log/log.h"
#include "mpact/sim/generic/instruction.h"
#include "mpact/sim/generic/register.h"
#include "mpact/sim/generic/type_helpers.h"
#include "riscv/riscv_fp_host.h"
#include "riscv/riscv_fp_info.h"
#include "riscv/riscv_instruction_helpers.h"
#include "riscv/riscv_register.h"
#include "riscv/riscv_state.h"

namespace mpact {
namespace sim {
namespace riscv {

// The following instruction semantic functions implement the single precision
// floating point instructions in the RiscV architecture. They all utilize the
// templated helper functions in riscv_instruction_helpers.h to implement
// the boiler plate code.

using FPRegister = RVFpRegister;
using RegUInt = typename std::make_unsigned<RVFpRegister::ValueType>::type;

// These types are used instead of uint32_t and int32_t to represent the
// integer type of equal value to float when values of these types are
// really reinterpreted float values.
using FPUInt = FPTypeInfo<float>::UIntType;
using FPSInt = FPTypeInfo<float>::IntType;

// Note, for any SP operation on values in 64-bit DP registers, the input
// values have to be properly NaN-boxed. If not, the value is treated as
// a canonical NaN.

// Templated helper functions.

namespace internal {

// Convert float to signed 32 bit integer.
template <typename XInt>
static inline void RVFCvtWs(const Instruction* instruction) {
  RiscVConvertFloatWithFflagsOp<XInt, float, int32_t>(instruction);
}

// Convert float to unsigned 32 bit integer.
template <typename XUint>
static inline void RVFCvtWus(const Instruction* instruction) {
  RiscVConvertFloatWithFflagsOp<XUint, float, uint32_t>(instruction);
}

// Convert float to signed 64 bit integer.
template <typename XInt>
static inline void RVFCvtLs(const Instruction* instruction) {
  RiscVConvertFloatWithFflagsOp<XInt, float, int64_t>(instruction);
}

// Convert float to unsigned 64 bit integer.
template <typename XUint>
static inline void RVFCvtLus(const Instruction* instruction) {
  RiscVConvertFloatWithFflagsOp<XUint, float, uint64_t>(instruction);
}

// Single precision compare equal.
template <typename XRegister>
static inline void RVFCmpeq(const Instruction* instruction) {
  RiscVBinaryNaNBoxOp<typename XRegister::ValueType,
                      typename XRegister::ValueType, float>(
      instruction,
      [instruction](float a, float b) -> typename XRegister::ValueType {
        if (FPTypeInfo<float>::IsSNaN(a) || FPTypeInfo<float>::IsSNaN(b)) {
          auto* db = instruction->Destination(1)->AllocateDataBuffer();
          db->Set<uint32_t>(0, *FPExceptions::kInvalidOp);
          db->Submit();
        }
        return a == b;
      });
}

// Single precicion compare less than.
template <typename XRegister>
static inline void RVFCmplt(const Instruction* instruction) {
  RiscVBinaryNaNBoxOp<typename XRegister::ValueType,
                      typename XRegister::ValueType, float>(
      instruction,
      [instruction](float a, float b) -> typename XRegister::ValueType {
        if (FPTypeInfo<float>::IsNaN(a) || FPTypeInfo<float>::IsNaN(b)) {
          auto* db = instruction->Destination(1)->AllocateDataBuffer();
          db->Set<uint32_t>(0, *FPExceptions::kInvalidOp);
          db->Submit();
        }
        return a < b;
      });
}

// Single precision compare less than or equal.
template <typename XRegister>
static inline void RVFCmple(const Instruction* instruction) {
  RiscVBinaryNaNBoxOp<typename XRegister::ValueType,
                      typename XRegister::ValueType, float>(
      instruction,
      [instruction](float a, float b) -> typename XRegister::ValueType {
        if (FPTypeInfo<float>::IsNaN(a) || FPTypeInfo<float>::IsNaN(b)) {
          auto* db = instruction->Destination(1)->AllocateDataBuffer();
          db->Set<uint32_t>(0, *FPExceptions::kInvalidOp);
          db->Submit();
        }
        return a <= b;
      });
}

template <typename T>
static inline T CanonicalizeNaN(T value) {
  if (!std::isnan(value)) return value;
  auto nan_value = FPTypeInfo<T>::kCanonicalNaN;
  return *reinterpret_cast<T*>(&nan_value);
}

}  // namespace internal

// Load child instruction.
void RiscVIFlwChild(const Instruction* instruction) {
  LoadContext* context = static_cast<LoadContext*>(instruction->context());
  auto value = context->value_db->Get<FPUInt>(0);
  auto* reg =
      static_cast<generic::RegisterDestinationOperand<FPRegister::ValueType>*>(
          instruction->Destination(0))
          ->GetRegister();
  if (sizeof(FPRegister::ValueType) > sizeof(FPUInt)) {
    // NaN box the loaded value.
    auto reg_value = std::numeric_limits<FPRegister::ValueType>::max();
    reg_value <<= sizeof(FPUInt) * 8;
    reg_value |= value;
    reg->data_buffer()->Set<FPRegister::ValueType>(0, reg_value);
    return;
  }
  reg->data_buffer()->Set<FPRegister::ValueType>(0, value);
}

// Basic arithmetic instructions.
void RiscVFAdd(const Instruction* instruction) {
  RiscVBinaryFloatNaNBoxOp<FPRegister::ValueType, float, float>(
      instruction, [](float a, float b) { return a + b; },
      [](double a, double b) { return a + b; });
}

void RiscVFSub(const Instruction* instruction) {
  RiscVBinaryFloatNaNBoxOp<FPRegister::ValueType, float, float>(
      instruction, [](float a, float b) { return a - b; },
      [](double a, double b) { return a - b; });
}

void RiscVFMul(const Instruction* instruction) {
  RiscVBinaryFloatNaNBoxOp<FPRegister::ValueType, float, float>(
      instruction, [](float a, float b) { return a * b; },
      [](double a, double b) { return a * b; });
}

void RiscVFDiv(const Instruction* instruction) {
  RiscVBinaryFloatNaNBoxOp<FPRegister::ValueType, float, float>(
      instruction, [](float a, float b) { return a / b; },
      [](double a, double b) { return a / b; });
}

// Square root uses the library square root, but check for special conditions
// to set flags that may not be set correctly with the library version.
void RiscVFSqrt(const Instruction* instruction) {
  RiscVUnaryNaNBoxOp<FPRegister::ValueType, FPRegister::ValueType, float,
                     float>(instruction, [instruction](float a) -> float {
    // If the input value is NaN or less than zero, set the invalid op flag.
    if (FPTypeInfo<float>::IsNaN(a) || (a < 0.0)) {
      if (!FPTypeInfo<float>::IsQNaN(a)) {
        auto* flag_db = instruction->Destination(1)->AllocateDataBuffer();
        flag_db->Set<uint32_t>(0, *FPExceptions::kInvalidOp);
        flag_db->Submit();
      }
      return *reinterpret_cast<const float*>(&FPTypeInfo<float>::kCanonicalNaN);
    }

    // Square root of 0 returns 0, and of -0.0 returns -0.0.
    if (a == 0.0) return a;

    // For all other cases use the library sqrt.
    // Get the rounding mode.
    int rm_value = generic::GetInstructionSource<int>(instruction, 1);

    auto* rv_fp = static_cast<RiscVState*>(instruction->state())->rv_fp();
    // If the rounding mode is dynamic, read it from the current state.
    if (rm_value == *FPRoundingMode::kDynamic) {
      if (!rv_fp->rounding_mode_valid()) {
        LOG(ERROR) << "Invalid rounding mode";
        return *reinterpret_cast<const float*>(
            &FPTypeInfo<float>::kCanonicalNaN);
      }
      rm_value = *rv_fp->GetRoundingMode();
    }
    float res;
    {
      ScopedFPStatus set_fp_status(rv_fp->host_fp_interface(), rm_value);
      res = sqrt(a);
    }
    if (rm_value == *FPRoundingMode::kRoundToNearestTiesToMax) {
      res = CorrectRMMTie(res, std::sqrt(static_cast<double>(a)));
    }
    return res;
  });
}

// If either operand is NaN return the other.
void RiscVFMin(const Instruction* instruction) {
  RiscVBinaryNaNBoxOp<FPRegister::ValueType, float, float>(
      instruction, [instruction](float a, float b) -> float {
        if (FPTypeInfo<float>::IsSNaN(a) || FPTypeInfo<float>::IsSNaN(b)) {
          auto* db = instruction->Destination(1)->AllocateDataBuffer();
          db->Set<uint32_t>(0, *FPExceptions::kInvalidOp);
          db->Submit();
        }
        if (FPTypeInfo<float>::IsNaN(a)) {
          if (FPTypeInfo<float>::IsNaN(b)) {
            FPTypeInfo<float>::UIntType not_a_number =
                FPTypeInfo<float>::kCanonicalNaN;
            return *reinterpret_cast<float*>(&not_a_number);
          }
          return b;
        }
        if (FPTypeInfo<float>::IsNaN(b)) {
          return a;
        }
        // If both are zero, return the negative zero if there is one.
        if ((a == 0.0) && (b == 0.0)) return (std::signbit(a)) ? a : b;
        return (a > b) ? b : a;
      });
}

// If either operand is NaN return the other.
void RiscVFMax(const Instruction* instruction) {
  RiscVBinaryNaNBoxOp<FPRegister::ValueType, float, float>(
      instruction, [instruction](float a, float b) -> float {
        if (FPTypeInfo<float>::IsSNaN(a) || FPTypeInfo<float>::IsSNaN(b)) {
          auto* db = instruction->Destination(1)->AllocateDataBuffer();
          db->Set<uint32_t>(0, *FPExceptions::kInvalidOp);
          db->Submit();
        }
        if (FPTypeInfo<float>::IsNaN(a)) {
          if (FPTypeInfo<float>::IsNaN(b)) {
            FPTypeInfo<float>::UIntType not_a_number =
                FPTypeInfo<float>::kCanonicalNaN;
            return *reinterpret_cast<float*>(&not_a_number);
          }
          return b;
        }
        if (FPTypeInfo<float>::IsNaN(b)) return a;
        // If both are zero, return the positive zero if there is one.
        if ((a == 0.0) && (b == 0.0)) return (std::signbit(b)) ? a : b;
        return (a < b) ? b : a;
      });
}

// Four flavors of multiply-accumulate.
// Multiply-add (a * b) + c
// Multiply-subtract (a * b) - c
// Negated multiply-add -((a * b) + c)
// Negated multiply-subtract -((a * b) - c)

void RiscVFMadd(const Instruction* instruction) {
  using T = float;
  RiscVTernaryFloatNaNBoxOp<FPRegister::ValueType, T, T>(
      instruction,
      [instruction](T a, T b, T c) -> T {
        // Propagate any NaNs.
        if ((std::isinf(a) && (b == 0.0)) || ((std::isinf(b) && (a == 0.0)))) {
          auto* flag_db = instruction->Destination(1)->AllocateDataBuffer();
          flag_db->Set<uint32_t>(0, *FPExceptions::kInvalidOp);
          flag_db->Submit();
        }
        return internal::CanonicalizeNaN(std::fma(a, b, c));
      },
      [](double a, double b, double c) -> double { return std::fma(a, b, c); });
}

void RiscVFMsub(const Instruction* instruction) {
  using T = float;
  RiscVTernaryFloatNaNBoxOp<FPRegister::ValueType, T, T>(
      instruction,
      [instruction](T a, T b, T c) -> T {
        if ((std::isinf(a) && (b == 0.0)) || ((std::isinf(b) && (a == 0.0)))) {
          auto* flag_db = instruction->Destination(1)->AllocateDataBuffer();
          flag_db->Set<uint32_t>(0, *FPExceptions::kInvalidOp);
          flag_db->Submit();
        }
        return internal::CanonicalizeNaN(std::fma(a, b, -c));
      },
      [](double a, double b, double c) -> double {
        return std::fma(a, b, -c);
      });
}

void RiscVFNmadd(const Instruction* instruction) {
  using T = float;
  RiscVTernaryFloatNaNBoxOp<FPRegister::ValueType, T, T>(
      instruction,
      [instruction](T a, T b, T c) -> T {
        if ((std::isinf(a) && (b == 0.0)) || ((std::isinf(b) && (a == 0.0)))) {
          auto* flag_db = instruction->Destination(1)->AllocateDataBuffer();
          flag_db->Set<uint32_t>(0, *FPExceptions::kInvalidOp);
          flag_db->Submit();
        }
        return internal::CanonicalizeNaN(std::fma(-a, b, -c));
      },
      [](double a, double b, double c) -> double {
        return std::fma(-a, b, -c);
      });
}

void RiscVFNmsub(const Instruction* instruction) {
  using T = float;
  RiscVTernaryFloatNaNBoxOp<FPRegister::ValueType, T, T>(
      instruction,
      [instruction](T a, T b, T c) -> T {
        if ((std::isinf(a) && (b == 0.0)) || ((std::isinf(b) && (a == 0.0)))) {
          auto* flag_db = instruction->Destination(1)->AllocateDataBuffer();
          flag_db->Set<uint32_t>(0, *FPExceptions::kInvalidOp);
          flag_db->Submit();
        }
        return internal::CanonicalizeNaN(std::fma(-a, b, c));
      },
      [](double a, double b, double c) -> double {
        return std::fma(-a, b, c);
      });
}

// Set sign of the first operand to that of the second.
void RiscVFSgnj(const Instruction* instruction) {
  RiscVBinaryNaNBoxOp<FPRegister::ValueType, FPUInt, FPUInt>(
      instruction,
      [](FPUInt a, FPUInt b) { return (a & 0x7fff'ffff) | (b & 0x8000'0000); });
}

// Set the sign of the first operand to the opposite of the second.
void RiscVFSgnjn(const Instruction* instruction) {
  RiscVBinaryNaNBoxOp<FPRegister::ValueType, FPUInt, FPUInt>(
      instruction, [](FPUInt a, FPUInt b) {
        return (a & 0x7fff'ffff) | (~b & 0x8000'0000);
      });
}

// Set the sign of the first operand to the xor of the signs of the two
// operands.
void RiscVFSgnjx(const Instruction* instruction) {
  RiscVBinaryNaNBoxOp<FPRegister::ValueType, FPUInt, FPUInt>(
      instruction, [](FPUInt a, FPUInt b) {
        return (a & 0x7fff'ffff) | ((a ^ b) & 0x8000'0000);
      });
}

// Convert signed 32 bit integer to float.
void RiscVFCvtSw(const Instruction* instruction) {
  RiscVUnaryFloatNaNBoxOp<FPRegister::ValueType, uint32_t, float, int32_t>(
      instruction, [](int32_t a) -> float { return static_cast<float>(a); });
}

// Convert unsigned 32 bit integer to float.
void RiscVFCvtSwu(const Instruction* instruction) {
  RiscVUnaryFloatNaNBoxOp<FPRegister::ValueType, uint32_t, float, uint32_t>(
      instruction, [](uint32_t a) -> float { return static_cast<float>(a); });
}

// Convert signed 64 bit integer to float.
void RiscVFCvtSl(const Instruction* instruction) {
  RiscVUnaryFloatNaNBoxOp<FPRegister::ValueType, uint64_t, float, int64_t>(
      instruction, [](int64_t a) -> float { return static_cast<float>(a); });
}

// Convert unsigned 64 bit integer to float.
void RiscVFCvtSlu(const Instruction* instruction) {
  RiscVUnaryFloatNaNBoxOp<FPRegister::ValueType, uint64_t, float, uint64_t>(
      instruction, [](uint64_t a) -> float { return static_cast<float>(a); });
}

// Single precision move instruction from integer to fp register file.
void RiscVFMvwx(const Instruction* instruction) {
  RiscVUnaryNaNBoxOp<FPRegister::ValueType, uint32_t, uint32_t, uint32_t>(
      instruction, [](uint32_t a) -> uint32_t { return a; });
}

namespace RV32 {

using XRegister = RV32Register;
using XUint = typename std::make_unsigned<XRegister::ValueType>::type;
using XInt = typename std::make_signed<XRegister::ValueType>::type;

void RiscVFSw(const Instruction* instruction) {
  using T = uint32_t;
  auto* state = static_cast<RiscVState*>(instruction->state());
  if (state->mstatus()->fs() == 0) return;
  XUint base = generic::GetInstructionSource<XUint>(instruction, 0);
  XInt offset = generic::GetInstructionSource<XInt>(instruction, 1);
  XUint address = base + offset;
  T value = generic::GetInstructionSource<T>(instruction, 2);
  auto* db = state->db_factory()->Allocate(sizeof(T));
  db->Set<T>(0, value);
  state->StoreMemory(instruction, address, db);
  db->DecRef();
}

// Single precision conversion instructions.

// Convert float to signed 32 bit integer.
void RiscVFCvtWs(const Instruction* instruction) {
  internal::RVFCvtWs<XInt>(instruction);
}

// Convert float to unsigned 32 bit integer.
void RiscVFCvtWus(const Instruction* instruction) {
  internal::RVFCvtWus<XUint>(instruction);
}

// Single precision move instruction to integer register file, with
// sign-extension.
void RiscVFMvxw(const Instruction* instruction) {
  RiscVUnaryOp<XRegister, int32_t, int32_t>(instruction,
                                            [](int32_t a) { return a; });
}

// Single precision compare equal.
void RiscVFCmpeq(const Instruction* instruction) {
  internal::RVFCmpeq<XRegister>(instruction);
}

// Single precicion compare less than.
void RiscVFCmplt(const Instruction* instruction) {
  internal::RVFCmplt<XRegister>(instruction);
}

// Single precision compare less than or equal.
void RiscVFCmple(const Instruction* instruction) {
  internal::RVFCmple<XRegister>(instruction);
}

// Single precision fp class instruction.
void RiscVFClass(const Instruction* instruction) {
  RiscVUnaryOp<XRegister, uint32_t, float>(
      instruction,
      [](float a) -> uint32_t { return static_cast<uint32_t>(ClassifyFP(a)); });
}

}  // namespace RV32

namespace RV64 {

using XRegister = RV64Register;
using XUint = typename std::make_unsigned<XRegister::ValueType>::type;
using XInt = typename std::make_signed<XRegister::ValueType>::type;

void RiscVFSw(const Instruction* instruction) {
  using T = uint32_t;
  auto* state = static_cast<RiscVState*>(instruction->state());
  if (state->mstatus()->fs() == 0) return;
  XUint base = generic::GetInstructionSource<XUint>(instruction, 0);
  XInt offset = generic::GetInstructionSource<XInt>(instruction, 1);
  XUint address = base + offset;
  T value = generic::GetInstructionSource<T>(instruction, 2);
  auto* db = state->db_factory()->Allocate(sizeof(T));
  db->Set<T>(0, value);
  state->StoreMemory(instruction, address, db);
  db->DecRef();
}

// Convert float to signed 32 bit integer in a 64 bit register.
void RiscVFCvtWs(const Instruction* instruction) {
  internal::RVFCvtWs<XInt>(instruction);
}

// Convert float to unsigned 32 bit integer in a 64 bit register.
void RiscVFCvtWus(const Instruction* instruction) {
  internal::RVFCvtWus<XUint>(instruction);
}

// Convert float to signed 64 bit integer.
void RiscVFCvtLs(const Instruction* instruction) {
  internal::RVFCvtLs<XInt>(instruction);
}

// Convert float to unsigned 64 bit integer.
void RiscVFCvtLus(const Instruction* instruction) {
  internal::RVFCvtLus<XUint>(instruction);
}

// Single precision move instruction to integer register file, with
// sign-extension.
void RiscVFMvxw(const Instruction* instruction) {
  RiscVUnaryOp<XRegister, XInt, int32_t>(
      instruction, [](int32_t a) { return static_cast<XInt>(a); });
}

// Single precision move instruction from integer to fp register file.
void RiscVFMvwx(const Instruction* instruction) {
  RiscVUnaryNaNBoxOp<FPRegister::ValueType, uint32_t, uint32_t, uint32_t>(
      instruction, [](uint32_t a) -> uint32_t { return a; });
}

// Single precision compare equal.
void RiscVFCmpeq(const Instruction* instruction) {
  internal::RVFCmpeq<XRegister>(instruction);
}

// Single precicion compare less than.
void RiscVFCmplt(const Instruction* instruction) {
  internal::RVFCmplt<XRegister>(instruction);
}

// Single precision compare less than or equal.
void RiscVFCmple(const Instruction* instruction) {
  internal::RVFCmple<XRegister>(instruction);
}

// Single precision fp class instruction.
void RiscVFClass(const Instruction* instruction) {
  RiscVUnaryOp<XRegister, uint32_t, float>(
      instruction,
      [](float a) -> uint32_t { return static_cast<uint32_t>(ClassifyFP(a)); });
}

}  // namespace RV64

}  // namespace riscv
}  // namespace sim
}  // namespace mpact
