// 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.

#ifndef MPACT_RISCV_RISCV_RISCV_INSTRUCTION_HELPERS_H_
#define MPACT_RISCV_RISCV_RISCV_INSTRUCTION_HELPERS_H_

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

#include "absl/log/log.h"
#include "mpact/sim/generic/arch_state.h"
#include "mpact/sim/generic/data_buffer.h"
#include "mpact/sim/generic/instruction.h"
#include "mpact/sim/generic/operand_interface.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_fp_state.h"
#include "riscv/riscv_state.h"

namespace mpact {
namespace sim {
namespace riscv {

using ::mpact::sim::generic::operator*;
using ::mpact::sim::generic::FPTypeInfo;

// Templated helper function for convert instruction semantic functions.
template <typename From, typename To>
inline std::tuple<To, uint32_t> CvtHelper(From value) {
  constexpr From kMax = static_cast<From>(std::numeric_limits<To>::max());
  constexpr From kMin = static_cast<From>(std::numeric_limits<To>::min());

  if (FPTypeInfo<From>::IsNaN(value)) {
    return std::make_tuple(std::numeric_limits<To>::max(),
                           *FPExceptions::kInvalidOp);
  }
  if (value > kMax) {
    return std::make_tuple(std::numeric_limits<To>::max(),
                           *FPExceptions::kInvalidOp);
  }
  if (value < kMin) {
    if (std::is_unsigned<To>::value && (value > -1.0)) {
      using SignedTo = typename std::make_signed<To>::type;
      SignedTo signed_val = static_cast<SignedTo>(value);
      if (signed_val == 0) {
        return std::make_tuple(0, *FPExceptions::kInexact);
      }
    }
    return std::make_tuple(std::numeric_limits<To>::min(),
                           *FPExceptions::kInvalidOp);
  }

  auto output_value = static_cast<To>(value);
  return std::make_tuple(output_value, 0);
}

// Generic helper function for floating op instructions that do not require
// NaN boxing since they produce non fp-values, but set fflags.
template <typename Result, typename From, typename To>
inline void RiscVConvertFloatWithFflagsOp(const Instruction* instruction) {
  constexpr To kMax = std::numeric_limits<To>::max();
  constexpr To kMin = std::numeric_limits<To>::min();

  From lhs = generic::GetInstructionSource<From>(instruction, 0);
  using FromUint = typename FPTypeInfo<From>::UIntType;
  FromUint lhs_u = *reinterpret_cast<FromUint*>(&lhs);
  auto constexpr kExpMask = FPTypeInfo<From>::kExpMask;
  auto constexpr kSigMask = FPTypeInfo<From>::kSigMask;
  uint32_t flags = 0;
  uint32_t rm = generic::GetInstructionSource<uint32_t>(instruction, 1);
  // Dynamic rounding mode will get rounding mode from the global state.
  if (rm == *FPRoundingMode::kDynamic) {
    auto* rv_fp = static_cast<RiscVState*>(instruction->state())->rv_fp();
    if (!rv_fp->rounding_mode_valid()) {
      LOG(ERROR) << "Invalid rounding mode";
      return;
    }
    rm = *rv_fp->GetRoundingMode();
  }
  To value = 0;
  if (FPTypeInfo<From>::IsNaN(lhs) || lhs_u == FPTypeInfo<From>::kPosInf) {
    value = std::numeric_limits<To>::max();
    flags = *FPExceptions::kInvalidOp;
  } else if (lhs_u == FPTypeInfo<From>::kNegInf) {
    value = std::numeric_limits<To>::min();
    flags = *FPExceptions::kInvalidOp;
  } else if ((lhs_u & (kExpMask | kSigMask)) == 0) {  // lhs == 0.0
    value = 0;
  } else {
    // static_cast<>() doesn't necessarily round, so will have to force
    // rounding before converting to the integer type if necessary.
    using FromUint = typename FPTypeInfo<From>::UIntType;
    auto constexpr kBias = FPTypeInfo<From>::kExpBias;
    auto constexpr kExpMask = FPTypeInfo<From>::kExpMask;
    auto constexpr kSigSize = FPTypeInfo<From>::kSigSize;
    auto constexpr kSigMask = FPTypeInfo<From>::kSigMask;
    auto constexpr kBitSize = FPTypeInfo<From>::kBitSize;
    FromUint lhs_u = *reinterpret_cast<FromUint*>(&lhs);
    const bool sign = (lhs_u & (1ULL << (kBitSize - 1))) != 0;
    FromUint exp = kExpMask & lhs_u;
    int exp_value = exp >> kSigSize;
    int unbiased_exp = exp_value - kBias;
    FromUint sig = kSigMask & lhs_u;

    // Get fraction part of the number, and right shift it to leave 1 bits
    // length of fraction part.
    // In forms of "<integer_value>.<fraction>"", where fraction is 2 bits.
    // e.g., 1.75 -> 0b1.11
    //  (float32) -> base = 0b110'0000'0000'0000'0000'0000'(23bits)
    //               exp = 127 (unbiased exp = 0)
    // After right shift to leave 1 bit in fraction part.
    // base = 0b1
    // rightshift_compressed = 1 (compress the right-shift eliminated number)
    int right_shift = exp ? kSigSize - 1 - unbiased_exp : 1;
    uint64_t base = sig;
    bool rightshift_compressed = 0;
    if (exp == 0) {
      // Denormalized value.
      // Format: (-1)^sign * 2 ^(exp - bias + 1) * 0.{sig}
      // fraction part is too small keep it as 1 bits if not zero.
      rightshift_compressed = base != 0;
      base = 0;
      flags = *FPExceptions::kInexact;
    } else {
      // Normalized value.
      // Format: (-1)^sign * 2 ^(exp - bias) * 1.{sig
      // base = 1.{sig} (total (1 + `kSigSize`) bits)
      base |= 1ULL << kSigSize;

      // Right shift all base part out.
      if (right_shift > (kBitSize - 1)) {
        rightshift_compressed = base != 0;
        flags = *FPExceptions::kInexact;
        base = 0;
      } else if (right_shift > 0) {
        // Right shift to leave only 1 bit in the fraction part, compressed the
        // right-shift eliminated number.
        right_shift = std::min(right_shift, kBitSize);
        uint64_t right_shifted_sig_mask = (1ULL << right_shift) - 1;
        rightshift_compressed = (base & right_shifted_sig_mask) != 0;
        base >>= right_shift;
      }
    }

    // Handle fraction part rounding.
    if (right_shift >= 0) {
      switch (rm) {
        case *FPRoundingMode::kRoundToNearest:
          // 0.5, tie condition
          if (rightshift_compressed == 0 && base & 0b1) {
            // <odd>.5 -> <odd>.5 + 0.5 = even
            if ((base & 0b11) == 0b11) {
              flags = *FPExceptions::kInexact;
              base += 0b01;
            }
          } else if (base & 0b1 || rightshift_compressed) {
            // not tie condition, round to nearest integer, it equals to add
            // 0.5(=base + 0b01) and eliminate the fraction part.
            base += 0b01;
          }
          break;
        case *FPRoundingMode::kRoundTowardsZero:
          // Round towards zero will eliminate the fraction part.
          // Do nothing on fraction part.
          // 1.2 -> 1.0, -1.5 -> -1.0, -0.7 -> 0.0
          break;
        case *FPRoundingMode::kRoundDown:
          // Positive float will eliminate the fraction part.
          // Negative float with fraction part will subtract 1(= base + 0b10),
          // and eliminate the fraction part.
          // e.g., 1.2 -> 1.0, -1.5 -> -2.0, -0.7 -> -1.0
          if (sign && (base & 0b1 || rightshift_compressed)) {
            base += 0b10;
          }
          break;
        case *FPRoundingMode::kRoundUp:
          // Positive float will add 1(= base + 0b10), and eliminate the
          // fraction part.
          // Negative float will eliminate the fraction part.
          // e.g., 1.2 -> 2.0, -1.5 -> -1.0, -0.7 -> 0.0
          if (!sign && (base & 0b1 || rightshift_compressed)) {
            base += 0b10;
          }
          break;
        case *FPRoundingMode::kRoundToNearestTiesToMax:
          // Round to nearest integer that is far from zero.
          // e.g., 1.2 -> 2.0, -1.5 -> -2.0, -0.7 -> -1.0
          if (base & 0b1 || rightshift_compressed) {
            base += 0b1;
          }
          break;
        default:
          LOG(ERROR) << "Invalid rounding mode";
          return;
      }
    }
    uint64_t unsigned_value;
    // Handle base with fraction part and store it to `unsigned_value`.
    if (right_shift >= 0) {
      // Set inexact flag if floating value has fraction part.
      if (base & 0b1 || rightshift_compressed) {
        flags = *FPExceptions::kInexact;
      }
      unsigned_value = base >> 1;
    } else {
      // Handle base without fraction part but need to left shift.
      int left_shift = -right_shift - 1;
      auto prev = unsigned_value = base;
      while (left_shift) {
        unsigned_value <<= 1;
        // Check if overflow happened and set the flag.
        if (prev > unsigned_value) {
          flags = *FPExceptions::kInvalidOp;
          unsigned_value = sign ? kMin : kMax;
          break;
        }
        prev = unsigned_value;
        --left_shift;
      }
    }

    // Handle the case that value is out of range, and final convert to value
    // with sign.
    if (std::is_signed<To>::value) {
      // Positive value but exceeds the max value.
      if (!sign && unsigned_value > kMax) {
        flags = *FPExceptions::kInvalidOp;
        value = kMax;
      } else if (sign && (unsigned_value > 0 && -unsigned_value < kMin)) {
        // Negative value but exceeds the min value.
        flags = *FPExceptions::kInvalidOp;
        value = kMin;
      } else {
        value = sign ? -((To)unsigned_value) : unsigned_value;
      }
    } else {
      // Positive value but exceeds the max value.
      if (unsigned_value > kMax) {
        flags = *FPExceptions::kInvalidOp;
        value = sign ? kMin : kMax;
      } else if (sign && unsigned_value != 0) {
        // float is negative value this is out of range of valid unsigned value.
        flags = *FPExceptions::kInvalidOp;
        value = kMin;
      } else {
        value = sign ? -((To)unsigned_value) : unsigned_value;
      }
    }
  }
  using SignedTo = typename std::make_signed<To>::type;
  auto* dest = instruction->Destination(0);
  auto* reg_dest =
      static_cast<generic::RegisterDestinationOperand<Result>*>(dest);
  auto* reg = reg_dest->GetRegister();
  // The final value is sign-extended to the register width, even if it's
  // conversion to an unsigned value.
  SignedTo signed_value = static_cast<SignedTo>(value);
  Result dest_value = static_cast<Result>(signed_value);
  reg->data_buffer()->template Set<Result>(0, dest_value);
  if (flags) {
    auto* flag_db = instruction->Destination(1)->AllocateDataBuffer();
    flag_db->Set<uint32_t>(0, flags);
    flag_db->Submit();
  }
}

// Helper function to read a NaN boxed source value, converting it to NaN if
// it isn't formatted properly.
template <typename RegValue, typename Argument>
inline Argument GetNaNBoxedSource(const Instruction* instruction, int arg) {
  if (sizeof(RegValue) <= sizeof(Argument)) {
    return generic::GetInstructionSource<Argument>(instruction, arg);
  } else {
    using UInt = typename std::make_unsigned<RegValue>::type;
    UInt uval = generic::GetInstructionSource<UInt>(instruction, arg);
    UInt mask = std::numeric_limits<UInt>::max() << (sizeof(Argument) * 8);
    if (((mask & uval) != mask)) {
      return *reinterpret_cast<const Argument*>(
          &FPTypeInfo<Argument>::kCanonicalNaN);
    }
    return generic::GetInstructionSource<Argument>(instruction, arg);
  }
}

// Generic helper function for binary instructions.
template <typename Register, typename Result, typename Argument>
inline void RiscVBinaryOp(const Instruction* instruction,
                          std::function<Result(Argument, Argument)> operation) {
  using RegValue = typename Register::ValueType;
  Argument lhs = generic::GetInstructionSource<Argument>(instruction, 0);
  Argument rhs = generic::GetInstructionSource<Argument>(instruction, 1);
  Result dest_value = operation(lhs, rhs);
  auto* reg = static_cast<generic::RegisterDestinationOperand<RegValue>*>(
                  instruction->Destination(0))
                  ->GetRegister();
  reg->data_buffer()->template Set<Result>(0, dest_value);
}

// Generic helper function for writing a value to a register by destination
// operand index.
template <typename Register, typename Value>
inline void RiscVWriteReg(const Instruction* instruction, int index,
                          Value value) {
  auto* reg = static_cast<generic::RegisterDestinationOperand<Value>*>(
                  instruction->Destination(index))
                  ->GetRegister();
  reg->data_buffer()->template Set<Value>(0, value);
}

// Generic helper function for unary instructions.
template <typename Register, typename Result, typename Argument>
inline void RiscVUnaryOp(const Instruction* instruction,
                         std::function<Result(Argument)> operation) {
  using RegValue = typename Register::ValueType;
  auto lhs = generic::GetInstructionSource<Argument>(instruction, 0);
  Result dest_value = operation(lhs);
  auto* reg = static_cast<generic::RegisterDestinationOperand<RegValue>*>(
                  instruction->Destination(0))
                  ->GetRegister();
  reg->data_buffer()->template Set<Result>(0, dest_value);
}

// Helper function for conditional branches.
template <typename RegisterType, typename ValueType>
static inline void BranchConditional(
    const Instruction* instruction,
    std::function<bool(ValueType, ValueType)> cond) {
  using UIntType =
      typename std::make_unsigned<typename RegisterType::ValueType>::type;
  ValueType a = generic::GetInstructionSource<ValueType>(instruction, 0);
  ValueType b = generic::GetInstructionSource<ValueType>(instruction, 1);
  if (cond(a, b)) {
    UIntType offset = generic::GetInstructionSource<UIntType>(instruction, 2);
    UIntType target = offset + instruction->address();
    auto* db = instruction->Destination(0)->AllocateDataBuffer();
    db->SetSubmit<UIntType>(0, target);
    auto state = static_cast<RiscVState*>(instruction->state());
    state->set_branch(true);
  }
}

// Generic helper function for load instructions.
template <typename Register, typename ValueType>
inline void RVLoad(const Instruction* instruction) {
  using RegVal = typename Register::ValueType;
  using URegVal = typename std::make_unsigned<RegVal>::type;
  URegVal base = generic::GetInstructionSource<URegVal>(instruction, 0);
  RegVal offset = generic::GetInstructionSource<RegVal>(instruction, 1);
  URegVal address = base + offset;
  auto* value_db =
      instruction->state()->db_factory()->Allocate(sizeof(ValueType));
  value_db->set_latency(0);
  auto* context = new LoadContext(value_db);
  auto* state = static_cast<RiscVState*>(instruction->state());
  state->LoadMemory(instruction, address, value_db, instruction->child(),
                    context);
  context->DecRef();
}

// Generic helper function for load instructions' "child instruction".
template <typename Register, typename ValueType>
inline void RVLoadChild(const Instruction* instruction) {
  using RegVal = typename Register::ValueType;
  using URegVal = typename std::make_unsigned<RegVal>::type;
  using SRegVal = typename std::make_signed<URegVal>::type;
  LoadContext* context = static_cast<LoadContext*>(instruction->context());
  auto* reg = static_cast<generic::RegisterDestinationOperand<RegVal>*>(
                  instruction->Destination(0))
                  ->GetRegister();
  if (std::is_signed<ValueType>::value) {
    SRegVal value = static_cast<SRegVal>(context->value_db->Get<ValueType>(0));
    reg->data_buffer()->template Set<SRegVal>(0, value);
  } else {
    URegVal value = static_cast<URegVal>(context->value_db->Get<ValueType>(0));
    reg->data_buffer()->template Set<URegVal>(0, value);
  }
}

// Generic helper function for store instructions.
template <typename RegisterType, typename ValueType>
inline void RVStore(const Instruction* instruction) {
  using URegVal =
      typename std::make_unsigned<typename RegisterType::ValueType>::type;
  using SRegVal = typename std::make_signed<URegVal>::type;
  URegVal base = generic::GetInstructionSource<URegVal>(instruction, 0);
  SRegVal offset = generic::GetInstructionSource<SRegVal>(instruction, 1);
  URegVal address = base + offset;
  ValueType value = generic::GetInstructionSource<ValueType>(instruction, 2);
  auto* state = static_cast<RiscVState*>(instruction->state());
  auto* db = state->db_factory()->Allocate(sizeof(ValueType));
  db->Set<ValueType>(0, value);
  state->StoreMemory(instruction, address, db);
  db->DecRef();
}

// Generic helper function for binary instructions with NaN boxing. This is
// used for those instructions that produce results in fp registers, but are
// not really executing an fp operation that requires rounding.
template <typename RegValue, typename Result, typename Argument>
inline void RiscVBinaryNaNBoxOp(
    const Instruction* instruction,
    std::function<Result(Argument, Argument)> operation) {
  Argument lhs = GetNaNBoxedSource<RegValue, Argument>(instruction, 0);
  Argument rhs = GetNaNBoxedSource<RegValue, Argument>(instruction, 1);
  Result dest_value = operation(lhs, rhs);
  auto* reg = static_cast<generic::RegisterDestinationOperand<RegValue>*>(
                  instruction->Destination(0))
                  ->GetRegister();
  // Check to see if we need to NaN box the result.
  if (sizeof(RegValue) > sizeof(Result)) {
    // If the floating point value is narrower than the register, the upper
    // bits have to be set to all ones.
    using UReg = typename std::make_unsigned<RegValue>::type;
    using UInt = typename FPTypeInfo<Result>::UIntType;
    auto dest_u_value = *reinterpret_cast<UInt*>(&dest_value);
    UReg reg_value = std::numeric_limits<UReg>::max();
    int shift = 8 * (sizeof(RegValue) - sizeof(Result));
    reg_value = (reg_value << shift) | dest_u_value;
    reg->data_buffer()->template Set<RegValue>(0, reg_value);
    return;
  }
  reg->data_buffer()->template Set<Result>(0, dest_value);
}

// Generic helper function for unary instructions with NaN boxing.
template <typename DstRegValue, typename SrcRegValue, typename Result,
          typename Argument>
inline void RiscVUnaryNaNBoxOp(const Instruction* instruction,
                               std::function<Result(Argument)> operation) {
  Argument lhs = GetNaNBoxedSource<SrcRegValue, Argument>(instruction, 0);
  Result dest_value = operation(lhs);
  auto* reg = static_cast<generic::RegisterDestinationOperand<DstRegValue>*>(
                  instruction->Destination(0))
                  ->GetRegister();
  // Check to see if we need to NaN box the result.
  if (sizeof(DstRegValue) > sizeof(Result)) {
    // If the floating point value is narrower than the register, the upper
    // bits have to be set to all ones.
    using UReg = typename std::make_unsigned<DstRegValue>::type;
    using UInt = typename FPTypeInfo<Result>::UIntType;
    auto dest_u_value = *reinterpret_cast<UInt*>(&dest_value);
    UReg reg_value = std::numeric_limits<UReg>::max();
    int shift = 8 * (sizeof(DstRegValue) - sizeof(Result));
    reg_value = (reg_value << shift) | dest_u_value;
    reg->data_buffer()->template Set<DstRegValue>(0, reg_value);
    return;
  }
  reg->data_buffer()->template Set<Result>(0, dest_value);
}

// Generic helper function for unary floating point instructions. The main
// difference is that it handles rounding mode and performs NaN boxing.
template <typename DstRegValue, typename SrcRegValue, typename Result,
          typename Argument>
inline void RiscVUnaryFloatNaNBoxOp(const Instruction* instruction,
                                    std::function<Result(Argument)> operation) {
  using ResUint = typename FPTypeInfo<Result>::UIntType;
  Argument lhs = GetNaNBoxedSource<SrcRegValue, Argument>(instruction, 0);
  // Get the rounding mode.
  int rm_value = generic::GetInstructionSource<int>(instruction, 1);

  // If the rounding mode is dynamic, read it from the current state.
  auto* rv_fp = static_cast<RiscVState*>(instruction->state())->rv_fp();
  if (rm_value == *FPRoundingMode::kDynamic) {
    if (!rv_fp->rounding_mode_valid()) {
      LOG(ERROR) << "Invalid rounding mode";
      return;
    }
    rm_value = *(rv_fp->GetRoundingMode());
  }
  Result dest_value;
  {
    ScopedFPStatus set_fp_status(rv_fp->host_fp_interface(), rm_value);
    dest_value = operation(lhs);
  }
  if (FPTypeInfo<Result>::IsNaN(dest_value) &&
      FPTypeInfo<Result>::SignBit(dest_value)) {
    ResUint res_value = *reinterpret_cast<ResUint*>(&dest_value);
    res_value &= FPTypeInfo<Result>::kInfMask;
    dest_value = *reinterpret_cast<Result*>(&res_value);
  }
  auto* dest = instruction->Destination(0);
  auto* reg_dest =
      static_cast<generic::RegisterDestinationOperand<DstRegValue>*>(dest);
  auto* reg = reg_dest->GetRegister();
  // Check to see if we need to NaN box the result.
  if (sizeof(DstRegValue) > sizeof(Result)) {
    // If the floating point Value is narrower than the register, the upper
    // bits have to be set to all ones.
    using UReg = typename std::make_unsigned<DstRegValue>::type;
    using UInt = typename FPTypeInfo<Result>::UIntType;
    auto dest_u_value = *reinterpret_cast<UInt*>(&dest_value);
    UReg reg_value = std::numeric_limits<UReg>::max();
    int shift = 8 * (sizeof(DstRegValue) - sizeof(Result));
    reg_value = (reg_value << shift) | dest_u_value;
    reg->data_buffer()->template Set<DstRegValue>(0, reg_value);
    return;
  }
  reg->data_buffer()->template Set<Result>(0, dest_value);
}

// Generic helper function for floating op instructions that do not require
// NaN boxing since they produce non fp-values.
template <typename Result, typename Argument>
inline void RiscVUnaryFloatOp(const Instruction* instruction,
                              std::function<Result(Argument)> operation) {
  Argument lhs = generic::GetInstructionSource<Argument>(instruction, 0);
  // 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;
    }
    rm_value = *rv_fp->GetRoundingMode();
  }
  Result dest_value;
  {
    ScopedFPStatus set_fp_status(rv_fp->host_fp_interface(), rm_value);
    dest_value = operation(lhs);
  }
  auto* dest = instruction->Destination(0);
  using UInt = typename FPTypeInfo<Result>::UIntType;
  auto* reg_dest =
      static_cast<generic::RegisterDestinationOperand<UInt>*>(dest);
  auto* reg = reg_dest->GetRegister();
  reg->data_buffer()->template Set<Result>(0, dest_value);
}

// Generic helper function for floating op instructions that do not require
// NaN boxing since they produce non fp-values, but set fflags.
template <typename Result, typename Argument>
inline void RiscVUnaryFloatWithFflagsOp(
    const Instruction* instruction,
    std::function<Result(Argument, uint32_t&)> operation) {
  Argument lhs = generic::GetInstructionSource<Argument>(instruction, 0);
  // 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;
    }
    rm_value = *rv_fp->GetRoundingMode();
  }
  uint32_t flag = 0;
  Result dest_value;
  {
    ScopedFPStatus set_fp_status(rv_fp->host_fp_interface(), rm_value);
    dest_value = operation(lhs, flag);
  }
  auto* dest = instruction->Destination(0);
  using UInt = typename FPTypeInfo<Result>::UIntType;
  auto* reg_dest =
      static_cast<generic::RegisterDestinationOperand<UInt>*>(dest);
  auto* reg = reg_dest->GetRegister();
  reg->data_buffer()->template Set<Result>(0, dest_value);
  auto* flag_db = instruction->Destination(1)->AllocateDataBuffer();
  flag_db->Set<uint32_t>(0, flag);
  flag_db->Submit();
}

// Generic helper function for binary floating point instructions. The main
// difference is that it handles rounding mode.
template <typename Register, typename Result, typename Argument>
inline void RiscVBinaryFloatNaNBoxOp(
    const Instruction* instruction,
    std::function<Result(Argument, Argument)> operation) {
  Argument lhs = GetNaNBoxedSource<Register, Argument>(instruction, 0);
  Argument rhs = GetNaNBoxedSource<Register, Argument>(instruction, 1);

  // Get the rounding mode.
  int rm_value = generic::GetInstructionSource<int>(instruction, 2);

  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;
    }
    rm_value = *rv_fp->GetRoundingMode();
  }
  Result dest_value;
  {
    ScopedFPStatus fp_status(rv_fp->host_fp_interface(), rm_value);
    dest_value = operation(lhs, rhs);
  }
  if (FPTypeInfo<Result>::IsNaN(dest_value)) {
    *reinterpret_cast<typename FPTypeInfo<Result>::UIntType*>(&dest_value) =
        FPTypeInfo<Result>::kCanonicalNaN;
  }
  auto* reg = static_cast<generic::RegisterDestinationOperand<Register>*>(
                  instruction->Destination(0))
                  ->GetRegister();
  // Check to see if we need to NaN box the result.
  if (sizeof(Register) > sizeof(Result)) {
    // If the floating point value is narrower than the register, the upper
    // bits have to be set to all ones.
    using UReg = typename std::make_unsigned<Register>::type;
    using UInt = typename FPTypeInfo<Result>::UIntType;
    auto dest_u_value = *reinterpret_cast<UInt*>(&dest_value);
    UReg reg_value = std::numeric_limits<UReg>::max();
    int shift = 8 * (sizeof(Register) - sizeof(Result));
    reg_value = (reg_value << shift) | dest_u_value;
    reg->data_buffer()->template Set<Register>(0, reg_value);
    return;
  }
  reg->data_buffer()->template Set<Result>(0, dest_value);
}

// Generic helper function for ternary floating point instructions.
template <typename Register, typename Result, typename Argument>
inline void RiscVTernaryFloatNaNBoxOp(
    const Instruction* instruction,
    std::function<Result(Argument, Argument, Argument)> operation) {
  Argument rs1 = generic::GetInstructionSource<Argument>(instruction, 0);
  Argument rs2 = generic::GetInstructionSource<Argument>(instruction, 1);
  Argument rs3 = generic::GetInstructionSource<Argument>(instruction, 2);
  // Get the rounding mode.
  int rm_value = generic::GetInstructionSource<int>(instruction, 3);

  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;
    }
    rm_value = *rv_fp->GetRoundingMode();
  }
  Result dest_value;
  {
    ScopedFPStatus fp_status(rv_fp->host_fp_interface(), rm_value);
    dest_value = operation(rs1, rs2, rs3);
  }
  auto* reg = static_cast<generic::RegisterDestinationOperand<Register>*>(
                  instruction->Destination(0))
                  ->GetRegister();
  // Check to see if we need to NaN box the result.
  if (sizeof(Register) > sizeof(Result)) {
    // If the floating point value is narrower than the register, the upper
    // bits have to be set to all ones.
    using UReg = typename std::make_unsigned<Register>::type;
    using UInt = typename FPTypeInfo<Result>::UIntType;
    auto dest_u_value = *reinterpret_cast<UInt*>(&dest_value);
    UReg reg_value = std::numeric_limits<UReg>::max();
    int shift = 8 * (sizeof(Register) - sizeof(Result));
    reg_value = (reg_value << shift) | dest_u_value;
    reg->data_buffer()->template Set<Register>(0, reg_value);
    return;
  }
  reg->data_buffer()->template Set<Result>(0, dest_value);
}

// Helper function to classify floating point values.
template <typename T>
typename FPTypeInfo<T>::UIntType ClassifyFP(T val) {
  using UIntType = typename FPTypeInfo<T>::UIntType;
  auto int_value = *reinterpret_cast<UIntType*>(&val);
  UIntType sign = int_value >> (FPTypeInfo<T>::kBitSize - 1);
  UIntType exp_mask = (1 << FPTypeInfo<T>::kExpSize) - 1;
  UIntType exp = (int_value >> FPTypeInfo<T>::kSigSize) & exp_mask;
  UIntType sig =
      int_value & ((static_cast<UIntType>(1) << FPTypeInfo<T>::kSigSize) - 1);
  if (exp == 0) {    // The number is denormal or zero.
    if (sig == 0) {  // The number is zero.
      return sign ? 1 << 3 : 1 << 4;
    } else {  // subnormal.
      return sign ? 1 << 2 : 1 << 5;
    }
  } else if (exp == exp_mask) {  //  The number is infinity or NaN.
    if (sig == 0) {              // infinity
      return sign ? 1 : 1 << 7;
    } else {
      if ((sig >> (FPTypeInfo<T>::kSigSize - 1)) != 0) {  // Quiet NaN.
        return 1 << 9;
      } else {  // signaling NaN.
        return 1 << 8;
      }
    }
  }
  return sign ? 1 << 1 : 1 << 6;
}

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

#endif  // MPACT_RISCV_RISCV_RISCV_INSTRUCTION_HELPERS_H_
