// 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; });
}

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

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

void RiscVFDiv(const Instruction *instruction) {
  RiscVBinaryFloatNaNBoxOp<FPRegister::ValueType, float, float>(
      instruction, [](float a, float 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);
    }
    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(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(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(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(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
