/*
 * Copyright 2024 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
 *
 *     http://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_CHERIOT__RISCV_CHERIOT_INSTRUCTION_HELPERS_H_
#define MPACT_CHERIOT__RISCV_CHERIOT_INSTRUCTION_HELPERS_H_

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

#include "absl/log/log.h"
#include "cheriot/cheriot_register.h"
#include "cheriot/cheriot_state.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 cheriot {

using ::mpact::sim::generic::Instruction;
using ::mpact::sim::generic::operator*;
using ::mpact::sim::generic::FPTypeInfo;
using ::mpact::sim::generic::RegisterBase;
using ::mpact::sim::riscv::FPExceptions;
using ::mpact::sim::riscv::FPRoundingMode;
using ::mpact::sim::riscv::ScopedFPStatus;

using CapReg = CheriotRegister;
using PB = ::mpact::sim::cheriot::CheriotRegister::PermissionBits;

// Get the destination capability register.
static inline CapReg *GetCapDest(const Instruction *instruction, int i) {
  return static_cast<CapReg *>(
      std::any_cast<RegisterBase *>(instruction->Destination(i)->GetObject()));
}

// Writing an integer result requires invalidating the capability and setting
// it to null.
template <typename Result>
static inline void WriteCapIntResult(const Instruction *instruction, int i,
                                     Result value) {
  auto *cap_reg = GetCapDest(instruction, i);
  cap_reg->data_buffer()->Set<Result>(0, value);
  cap_reg->Invalidate();
  cap_reg->set_is_null();
}

// 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 RVCheriotConvertFloatWithFflagsOp(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);

  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<CheriotState *>(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)) {
    value = std::numeric_limits<To>::max();
    flags = *FPExceptions::kInvalidOp;
  } else if (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;
  // 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);
  WriteCapIntResult(instruction, 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 SInt = typename std::make_signed<RegValue>::type;
    using UInt = typename std::make_unsigned<RegValue>::type;
    SInt val = generic::GetInstructionSource<SInt>(instruction, arg);
    UInt uval = static_cast<UInt>(val);
    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);
  }
}

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 functions for binary instructions. Clears the tag bit for
// the capability register and sets it to null.
template <typename Register, typename Result, typename Argument1,
          typename Argument2>
inline void RVCheriotBinaryOp(
    const Instruction *instruction,
    std::function<Result(Argument1, Argument2)> operation) {
  Argument1 lhs = generic::GetInstructionSource<Argument1>(instruction, 0);
  Argument2 rhs = generic::GetInstructionSource<Argument2>(instruction, 1);
  Result dest_value = operation(lhs, rhs);
  WriteCapIntResult(instruction, 0, dest_value);
}

template <typename Register, typename Result, typename Argument>
inline void RVCheriotBinaryOp(
    const Instruction *instruction,
    std::function<Result(Argument, Argument)> operation) {
  Argument lhs = generic::GetInstructionSource<Argument>(instruction, 0);
  Argument rhs = generic::GetInstructionSource<Argument>(instruction, 1);
  Result dest_value = operation(lhs, rhs);
  WriteCapIntResult(instruction, 0, dest_value);
}

template <typename Register, typename Result>
inline void RVCheriotBinaryOp(const Instruction *instruction,
                              std::function<Result(Result, Result)> operation) {
  Result lhs = generic::GetInstructionSource<Result>(instruction, 0);
  Result rhs = generic::GetInstructionSource<Result>(instruction, 1);
  Result dest_value = operation(lhs, rhs);
  WriteCapIntResult(instruction, 0, dest_value);
}

// Generic helper function for unary instructions.
template <typename Register, typename Result, typename Argument>
inline void RVCheriotUnaryOp(const Instruction *instruction,
                             std::function<Result(Argument)> operation) {
  auto lhs = generic::GetInstructionSource<Argument>(instruction, 0);
  Result dest_value = operation(lhs);
  WriteCapIntResult(instruction, 0, dest_value);
}

// Helper function for conditional branches.
template <typename RegisterType, typename ValueType>
static inline void RVCheriotBranchConditional(
    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 *state = static_cast<CheriotState *>(instruction->state());
    auto *pcc = state->pcc();
    if (!pcc->HasPermission(PB::kPermitExecute)) {
      state->HandleCheriRegException(
          instruction, pcc->address(),
          ExceptionCode::kCapExPermitExecuteViolation, pcc);
      return;
    }
    pcc->set_address(target);
    state->set_branch(true);
  }
}

// Generic helper function for load instructions.
template <typename Register, typename ValueType>
inline void RVCheriotLoad(const Instruction *instruction) {
  using RegVal = typename Register::ValueType;
  using URegVal = typename std::make_unsigned<RegVal>::type;
  // Bet the capability.
  auto *cap_reg = static_cast<CheriotRegister *>(
      static_cast<generic::RegisterSourceOperand<RegVal> *>(
          instruction->Source(0))
          ->GetRegister());
  URegVal base = cap_reg->address();
  RegVal offset = generic::GetInstructionSource<RegVal>(instruction, 1);
  URegVal address = base + offset;
  auto *state = static_cast<CheriotState *>(instruction->state());
  // Check for tag unset.
  if (!cap_reg->tag()) {
    state->HandleCheriRegException(instruction, instruction->address(),
                                   ExceptionCode::kCapExTagViolation, cap_reg);
    return;
  }
  // Check for sealed.
  if (cap_reg->IsSealed()) {
    state->HandleCheriRegException(instruction, instruction->address(),
                                   ExceptionCode::kCapExSealViolation, cap_reg);
    return;
  }
  // Check for permissions.
  if (!cap_reg->HasPermission(CheriotRegister::kPermitLoad)) {
    state->HandleCheriRegException(instruction, instruction->address(),
                                   ExceptionCode::kCapExPermitLoadViolation,
                                   cap_reg);
    return;
  }
  // Check for bounds.
  if (!cap_reg->IsInBounds(address, sizeof(ValueType))) {
    state->HandleCheriRegException(instruction, instruction->address(),
                                   ExceptionCode::kCapExBoundsViolation,
                                   cap_reg);
    return;
  }
  auto *value_db =
      instruction->state()->db_factory()->Allocate(sizeof(ValueType));
  value_db->set_latency(0);
  auto *context = new riscv::LoadContext(value_db);
  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 RVCheriotLoadChild(const Instruction *instruction) {
  using RegVal = typename Register::ValueType;
  using URegVal = typename std::make_unsigned<RegVal>::type;
  using SRegVal = typename std::make_signed<URegVal>::type;
  riscv::LoadContext *context =
      static_cast<riscv::LoadContext *>(instruction->context());
  if (std::is_signed<ValueType>::value) {
    SRegVal value = static_cast<SRegVal>(context->value_db->Get<ValueType>(0));
    WriteCapIntResult(instruction, 0, value);
  } else {
    URegVal value = static_cast<URegVal>(context->value_db->Get<ValueType>(0));
    WriteCapIntResult(instruction, 0, value);
  }
}

// Generic helper function for store instructions.
template <typename RegisterType, typename ValueType>
inline void RVCheriotStore(const Instruction *instruction) {
  using URegVal =
      typename std::make_unsigned<typename RegisterType::ValueType>::type;
  using SRegVal = typename std::make_signed<URegVal>::type;
  ValueType value = generic::GetInstructionSource<ValueType>(instruction, 2);
  auto *cap_reg = static_cast<CheriotRegister *>(
      static_cast<
          generic::RegisterSourceOperand<typename RegisterType::ValueType> *>(
          instruction->Source(0))
          ->GetRegister());
  URegVal base = cap_reg->address();
  SRegVal offset = generic::GetInstructionSource<SRegVal>(instruction, 1);
  URegVal address = base + offset;
  auto *state = static_cast<CheriotState *>(instruction->state());
  // Check for tag unset.
  if (!cap_reg->tag()) {
    state->HandleCheriRegException(instruction, instruction->address(),
                                   ExceptionCode::kCapExTagViolation, cap_reg);
    return;
  }
  // Check for sealed.
  if (cap_reg->IsSealed()) {
    state->HandleCheriRegException(instruction, instruction->address(),
                                   ExceptionCode::kCapExSealViolation, cap_reg);
    return;
  }
  // Check for permissions.
  if (!cap_reg->HasPermission(CheriotRegister::kPermitStore)) {
    state->HandleCheriRegException(instruction, instruction->address(),
                                   ExceptionCode::kCapExPermitStoreViolation,
                                   cap_reg);
    return;
  }
  // Check for bounds.
  if (!cap_reg->IsInBounds(address, sizeof(ValueType))) {
    state->HandleCheriRegException(instruction, instruction->address(),
                                   ExceptionCode::kCapExBoundsViolation,
                                   cap_reg);
    return;
  }
  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 RVCheriotBinaryNaNBoxOp(
    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 RVCheriotUnaryNaNBoxOp(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;
    WriteCapIntResult(instruction, 0, reg_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 RVCheriotUnaryFloatNaNBoxOp(
    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<CheriotState *>(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 (std::isnan(dest_value) && std::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 RVCheriotUnaryFloatOp(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<CheriotState *>(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 RVCheriotUnaryFloatWithFflagsOp(
    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<CheriotState *>(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 RVCheriotBinaryFloatNaNBoxOp(
    const Instruction *instruction,
    std::function<Result(Argument, Argument)> operation) {
  Argument lhs = GetNaNBoxedSource<Register, Argument>(instruction, 0);
  Argument rhs = GetNaNBoxedSource<Register, Argument>(instruction, 1);
  // Argument lhs = generic::GetInstructionSource<Argument>(instruction, 0);
  // Argument rhs = generic::GetInstructionSource<Argument>(instruction, 1);

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

  auto *rv_fp = static_cast<CheriotState *>(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 (std::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 RVCheriotTernaryFloatNaNBoxOp(
    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<CheriotState *>(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 cheriot
}  // namespace sim
}  // namespace mpact

#endif  // MPACT_CHERIOT__RISCV_CHERIOT_INSTRUCTION_HELPERS_H_
