// 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_d_instructions.h"

#include <cmath>
#include <cstdint>
#include <type_traits>

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

namespace mpact {
namespace sim {
namespace riscv {

using ::mpact::sim::generic::Instruction;
using ::mpact::sim::generic::operator*;  // NOLINT: is used below.

// The following instruction semantic functions implement the double 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.

// These types are used instead of uint64_t and int64_t to represent the
// integer type of equal width to double when values of these types are
// really reinterpreted double values.
using UInt = FPTypeInfo<double>::UIntType;
using SInt = FPTypeInfo<double>::IntType;

using FPRegister = RVFpRegister;

namespace internal {

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

// Basic arithmetic operations.
void RiscVDAdd(const Instruction *instruction) {
  RiscVBinaryFloatNaNBoxOp<RVFpRegister::ValueType, double, double>(
      instruction, [](double a, double b) { return a + b; });
}

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

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

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

// Square root uses the library square root.
void RiscVDSqrt(const Instruction *instruction) {
  RiscVUnaryNaNBoxOp<FPRegister::ValueType, FPRegister::ValueType, double,
                     double>(instruction, [instruction](double a) -> double {
    // If the input value is NaN or less than zero, set the invalid op flag.
    if (FPTypeInfo<double>::IsNaN(a) || (a < 0.0)) {
      if (!FPTypeInfo<double>::IsQNaN(a)) {
        auto *flag_db = instruction->Destination(1)->AllocateDataBuffer();
        flag_db->Set<uint32_t>(0, *FPExceptions::kInvalidOp);
        flag_db->Submit();
      }
      return *reinterpret_cast<const double *>(
          &FPTypeInfo<double>::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 double *>(
            &FPTypeInfo<double>::kCanonicalNaN);
      }
      rm_value = *rv_fp->GetRoundingMode();
    }
    double 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 RiscVDMin(const Instruction *instruction) {
  RiscVBinaryOp<FPRegister, double, double>(
      instruction, [instruction](double a, double b) -> double {
        if (FPTypeInfo<double>::IsSNaN(a) || FPTypeInfo<double>::IsSNaN(b)) {
          auto *db = instruction->Destination(1)->AllocateDataBuffer();
          db->Set<uint32_t>(0, *FPExceptions::kInvalidOp);
          db->Submit();
        }
        if (FPTypeInfo<double>::IsNaN(a)) {
          if (FPTypeInfo<double>::IsNaN(b)) {
            UInt not_a_number = FPTypeInfo<double>::kCanonicalNaN;
            return *reinterpret_cast<double *>(&not_a_number);
          }
          return b;
        }
        if (FPTypeInfo<double>::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 RiscVDMax(const Instruction *instruction) {
  RiscVBinaryOp<FPRegister, double, double>(
      instruction, [instruction](double a, double b) {
        if (FPTypeInfo<double>::IsSNaN(a) || FPTypeInfo<double>::IsSNaN(b)) {
          auto *db = instruction->Destination(1)->AllocateDataBuffer();
          db->Set<uint32_t>(0, *FPExceptions::kInvalidOp);
          db->Submit();
        }
        if (FPTypeInfo<double>::IsNaN(a)) {
          if (FPTypeInfo<double>::IsNaN(b)) {
            UInt not_a_number = FPTypeInfo<double>::kCanonicalNaN;
            return *reinterpret_cast<double *>(&not_a_number);
          }
          return b;
        }
        if (FPTypeInfo<double>::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)) ? b : a;
        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 RiscVDMadd(const Instruction *instruction) {
  using T = double;
  RiscVTernaryFloatNaNBoxOp<FPRegister::ValueType, T, T>(
      instruction, [instruction](T a, T b, T c) -> T {
        if (FPTypeInfo<T>::IsNaN(a)) return internal::CanonicalizeNaN(a);
        if (FPTypeInfo<T>::IsNaN(b)) return internal::CanonicalizeNaN(b);
        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();
        }
        if (FPTypeInfo<T>::IsNaN(c)) return internal::CanonicalizeNaN(c);
        if (std::isinf(c) && !std::isinf(a) && !std::isinf(b)) return c;
        if (c == 0.0) {
          if ((a == 0.0 && !std::isinf(b)) || (b == 0.0 && !std::isinf(a))) {
            UInt c_sign =
                *reinterpret_cast<UInt *>(&c) >> (FPTypeInfo<T>::kBitSize - 1);
            UInt ua = *reinterpret_cast<UInt *>(&a);
            UInt ub = *reinterpret_cast<UInt *>(&b);
            UInt prod_sign = (ua ^ ub) >> (FPTypeInfo<T>::kBitSize - 1);
            if (prod_sign != c_sign) return 0.0;
            return c;
          }
          return internal::CanonicalizeNaN(a * b);
        }
        return internal::CanonicalizeNaN(fma(a, b, c));
      });
}

void RiscVDMsub(const Instruction *instruction) {
  using T = double;
  RiscVTernaryFloatNaNBoxOp<FPRegister::ValueType, T, T>(
      instruction, [instruction](T a, T b, T c) -> T {
        if (FPTypeInfo<T>::IsNaN(a)) return internal::CanonicalizeNaN(a);
        if (FPTypeInfo<T>::IsNaN(b)) return internal::CanonicalizeNaN(b);
        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();
        }
        if (FPTypeInfo<T>::IsNaN(c)) return internal::CanonicalizeNaN(c);
        if (std::isinf(c) && !std::isinf(a) && !std::isinf(b)) return -c;
        if (c == 0.0) {
          if ((a == 0.0 && !std::isinf(b)) || (b == 0.0 && !std::isinf(a))) {
            UInt c_sign =
                -*reinterpret_cast<UInt *>(&c) >> (FPTypeInfo<T>::kBitSize - 1);
            UInt ua = *reinterpret_cast<UInt *>(&a);
            UInt ub = *reinterpret_cast<UInt *>(&b);
            UInt prod_sign = (ua ^ ub) >> (FPTypeInfo<T>::kBitSize - 1);
            if (prod_sign == c_sign) return 0.0;
            return -c;
          }
          return internal::CanonicalizeNaN(a * b);
        }
        return internal::CanonicalizeNaN(fma(a, b, -c));
      });
}

void RiscVDNmadd(const Instruction *instruction) {
  using T = double;
  RiscVTernaryFloatNaNBoxOp<FPRegister::ValueType, T, T>(
      instruction, [instruction](T a, T b, T c) -> T {
        if (FPTypeInfo<T>::IsNaN(a)) return internal::CanonicalizeNaN(a);
        if (FPTypeInfo<T>::IsNaN(b)) return internal::CanonicalizeNaN(b);
        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();
        }
        if (FPTypeInfo<T>::IsNaN(c)) return internal::CanonicalizeNaN(c);
        if (std::isinf(c) && !std::isinf(a) && !std::isinf(b)) return -c;
        if (c == 0.0) {
          if ((a == 0.0 && !std::isinf(b)) || (b == 0.0 && !std::isinf(a))) {
            UInt c_sign =
                *reinterpret_cast<UInt *>(&c) >> (FPTypeInfo<T>::kBitSize - 1);
            UInt ua = *reinterpret_cast<UInt *>(&a);
            UInt ub = *reinterpret_cast<UInt *>(&b);
            UInt prod_sign = (ua ^ ub) >> (FPTypeInfo<T>::kBitSize - 1);
            if (prod_sign != c_sign) return 0.0;
            return -c;
          }
          return internal::CanonicalizeNaN(-a * b);
        }
        return internal::CanonicalizeNaN(-fma(a, b, c));
      });
}

void RiscVDNmsub(const Instruction *instruction) {
  using T = double;
  RiscVTernaryFloatNaNBoxOp<FPRegister::ValueType, T, T>(
      instruction, [instruction](T a, T b, T c) -> T {
        if (FPTypeInfo<T>::IsNaN(a)) return internal::CanonicalizeNaN(a);
        if (FPTypeInfo<T>::IsNaN(b)) return internal::CanonicalizeNaN(b);
        // Illegal operation flag set if either a or b are infinite, and
        // the other is zero.
        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();
        }
        if (FPTypeInfo<T>::IsNaN(c)) return internal::CanonicalizeNaN(c);
        if (std::isinf(c) && !std::isinf(a) && !std::isinf(b)) return c;
        if (c == 0.0) {
          if ((a == 0.0 && !std::isinf(b)) || (b == 0.0 && !std::isinf(a))) {
            UInt c_sign =
                -*reinterpret_cast<UInt *>(&c) >> (FPTypeInfo<T>::kBitSize - 1);
            UInt ua = *reinterpret_cast<UInt *>(&a);
            UInt ub = *reinterpret_cast<UInt *>(&b);
            UInt prod_sign = (ua ^ ub) >> (FPTypeInfo<T>::kBitSize - 1);
            if (prod_sign != c_sign) return 0.0;
            return c;
          }
          return internal::CanonicalizeNaN(-a * b);
        }
        return internal::CanonicalizeNaN(-fma(a, b, -c));
      });
}

// Conversion instructions.

// Convert int to double.
void RiscVDCvtDw(const Instruction *instruction) {
  RiscVUnaryFloatOp<double, int32_t>(
      instruction, [](int32_t a) -> double { return static_cast<double>(a); });
}

// Convert unsigned word to double.
void RiscVDCvtDwu(const Instruction *instruction) {
  RiscVUnaryFloatOp<double, uint32_t>(
      instruction, [](uint32_t a) -> double { return static_cast<double>(a); });
}

// Convert double to float.
void RiscVDCvtSd(const Instruction *instruction) {
  RiscVUnaryFloatNaNBoxOp<RVFpRegister::ValueType, RVFpRegister::ValueType,
                          float, double>(instruction, [](double a) -> float {
    if (FPTypeInfo<double>::IsNaN(a)) {
      typename FPTypeInfo<float>::UIntType uint_value;
      uint_value = FPTypeInfo<float>::kCanonicalNaN;
      return *reinterpret_cast<float *>(&uint_value);
    }
    return static_cast<float>(a);
  });
}

// Convert float to double.
void RiscVDCvtDs(const Instruction *instruction) {
  RiscVUnaryFloatOp<double, float>(instruction, [](float a) -> double {
    if (FPTypeInfo<float>::IsNaN(a)) {
      typename FPTypeInfo<double>::UIntType uint_value;
      uint_value = FPTypeInfo<double>::kCanonicalNaN;
      return *reinterpret_cast<double *>(&uint_value);
    }
    return static_cast<double>(a);
  });
}

// Use sign of the second operand as the sign in the first.
void RiscVDSgnj(const Instruction *instruction) {
  RiscVBinaryOp<FPRegister, UInt, UInt>(
      instruction, [](UInt a, UInt b) -> UInt {
        return (a & 0x7fff'ffff'ffff'ffff) | (b & 0x8000'0000'0000'0000);
      });
}

// Use negation of the sign of the second operand as the sign in the first.
void RiscVDSgnjn(const Instruction *instruction) {
  RiscVBinaryOp<FPRegister, UInt, UInt>(
      instruction, [](UInt a, UInt b) -> UInt {
        return (a & 0x7fff'ffff'ffff'ffff) | (~b & 0x8000'0000'0000'0000);
      });
}

// Use the xor of the signs of the two operands as the sign in the first.
void RiscVDSgnjx(const Instruction *instruction) {
  RiscVBinaryOp<FPRegister, UInt, UInt>(
      instruction, [](UInt a, UInt b) -> UInt {
        return (a & 0x7fff'ffff'ffff'ffff) | ((a ^ b) & 0x8000'0000'0000'0000);
      });
}

namespace RV32 {

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

void RiscVDSd(const Instruction *instruction) {
  using T = uint64_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 double to int.
void RiscVDCvtWd(const Instruction *instruction) {
  RiscVConvertFloatWithFflagsOp<XInt, double, int32_t>(instruction);
}
// Convert double to unsigned word.
void RiscVDCvtWud(const Instruction *instruction) {
  RiscVConvertFloatWithFflagsOp<XUInt, double, uint32_t>(instruction);
}

// Double precision floating point compare equal.
void RiscVDCmpeq(const Instruction *instruction) {
  RiscVBinaryOp<XRegister, uint32_t, double>(
      instruction, [instruction](double a, double b) -> uint32_t {
        if (FPTypeInfo<double>::IsSNaN(a) || FPTypeInfo<double>::IsSNaN(b)) {
          auto *db = instruction->Destination(1)->AllocateDataBuffer();
          db->Set<uint32_t>(0, *FPExceptions::kInvalidOp);
          db->Submit();
        }
        return a == b;
      });
}

// Double precision floating point compare less.
void RiscVDCmplt(const Instruction *instruction) {
  RiscVBinaryOp<XRegister, uint32_t, double>(
      instruction, [instruction](double a, double b) -> uint32_t {
        if (FPTypeInfo<double>::IsNaN(a) || FPTypeInfo<double>::IsNaN(b)) {
          auto *db = instruction->Destination(1)->AllocateDataBuffer();
          db->Set<uint32_t>(0, *FPExceptions::kInvalidOp);
          db->Submit();
        }
        return a < b;
      });
}

// Double precision floating point compare less than or equal.
void RiscVDCmple(const Instruction *instruction) {
  RiscVBinaryOp<XRegister, uint32_t, double>(
      instruction, [instruction](double a, double b) -> uint32_t {
        if (FPTypeInfo<double>::IsNaN(a) || FPTypeInfo<double>::IsNaN(b)) {
          auto *db = instruction->Destination(1)->AllocateDataBuffer();
          db->Set<uint32_t>(0, *FPExceptions::kInvalidOp);
          db->Submit();
        }
        return a <= b;
      });
}

// Return the class attribute of the source operand.
void RiscVDClass(const Instruction *instruction) {
  RiscVUnaryOp<XRegister, XUInt, double>(instruction, [](double a) -> XUInt {
    auto res = static_cast<XUInt>(ClassifyFP(a));
    return res;
  });
}

}  // namespace RV32

namespace RV64 {

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

void RiscVDSd(const Instruction *instruction) {
  using T = uint64_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 double to int.
void RiscVDCvtWd(const Instruction *instruction) {
  RiscVConvertFloatWithFflagsOp<XInt, double, int32_t>(instruction);
}
// Convert double to unsigned word.
void RiscVDCvtWud(const Instruction *instruction) {
  RiscVConvertFloatWithFflagsOp<XUInt, double, uint32_t>(instruction);
}

// Double precision floating point compare equal.
void RiscVDCmpeq(const Instruction *instruction) {
  RiscVBinaryOp<XRegister, XUInt, double>(
      instruction, [instruction](double a, double b) -> XUInt {
        if (FPTypeInfo<double>::IsSNaN(a) || FPTypeInfo<double>::IsSNaN(b)) {
          auto *db = instruction->Destination(1)->AllocateDataBuffer();
          db->Set<uint32_t>(0, *FPExceptions::kInvalidOp);
          db->Submit();
        }
        return a == b;
      });
}

// Double precision floating point compare less.
void RiscVDCmplt(const Instruction *instruction) {
  RiscVBinaryOp<XRegister, XUInt, double>(
      instruction, [instruction](double a, double b) -> XUInt {
        if (FPTypeInfo<double>::IsNaN(a) || FPTypeInfo<double>::IsNaN(b)) {
          auto *db = instruction->Destination(1)->AllocateDataBuffer();
          db->Set<uint32_t>(0, *FPExceptions::kInvalidOp);
          db->Submit();
        }
        return a < b;
      });
}

// Double precision floating point compare less than or equal.
void RiscVDCmple(const Instruction *instruction) {
  RiscVBinaryOp<XRegister, XUInt, double>(
      instruction, [instruction](double a, double b) -> XUInt {
        if (FPTypeInfo<double>::IsNaN(a) || FPTypeInfo<double>::IsNaN(b)) {
          auto *db = instruction->Destination(1)->AllocateDataBuffer();
          db->Set<uint32_t>(0, *FPExceptions::kInvalidOp);
          db->Submit();
        }
        return a <= b;
      });
}

// Return the class attribute of the source operand.
void RiscVDClass(const Instruction *instruction) {
  RiscVUnaryOp<XRegister, UInt, double>(instruction, [](double a) -> UInt {
    auto res = static_cast<UInt>(ClassifyFP(a));
    return res;
  });
}

// Convert double to 64 bit signed integer.
void RiscVDCvtLd(const Instruction *instruction) {
  RiscVConvertFloatWithFflagsOp<XInt, double, int64_t>(instruction);
}

// Convert double to 64 bit unsigned integer.
void RiscVDCvtLud(const Instruction *instruction) {
  RiscVConvertFloatWithFflagsOp<XInt, double, uint64_t>(instruction);
}

// Convert signed 64 bit integer to double.
void RiscVDCvtDl(const Instruction *instruction) {
  RiscVUnaryFloatOp<double, int64_t>(
      instruction, [](int64_t a) -> double { return static_cast<double>(a); });
}

// Convert unsigned 64 bit integer to double.
void RiscVDCvtDlu(const Instruction *instruction) {
  RiscVUnaryFloatOp<double, uint64_t>(
      instruction, [](uint64_t a) -> double { return static_cast<double>(a); });
}

void RiscVDMvxd(const Instruction *instruction) {
  RiscVUnaryOp<XRegister, uint64_t, uint64_t>(
      instruction, [](uint64_t a) -> uint64_t { return a; });
}

void RiscVDMvdx(const Instruction *instruction) {
  RiscVUnaryOp<FPRegister, uint64_t, uint64_t>(
      instruction, [](uint64_t a) -> uint64_t { return a; });
}

}  // namespace RV64

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