// Copyright 2025 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_zfh_instructions.h"

#include <sys/types.h>

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

#include "absl/base/casts.h"
#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_csr.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 HalfFP = ::mpact::sim::generic::HalfFP;
using ::mpact::sim::generic::IsMpactFp;
using ::mpact::sim::generic::operator*;  // NOLINT: is used below (clang error).

namespace {

template <typename T>
struct DataTypeRegValue {};

template <>
struct DataTypeRegValue<float> {
  using type = RVFpRegister::ValueType;
};

template <>
struct DataTypeRegValue<double> {
  using type = RVFpRegister::ValueType;
};

template <>
struct DataTypeRegValue<HalfFP> {
  using type = RVFpRegister::ValueType;
};

template <>
struct DataTypeRegValue<int32_t> {
  using type = RV32Register::ValueType;
};

template <>
struct DataTypeRegValue<uint32_t> {
  using type = RV32Register::ValueType;
};

template <>
struct DataTypeRegValue<int64_t> {
  using type = RV64Register::ValueType;
};

template <>
struct DataTypeRegValue<uint64_t> {
  using type = RV64Register::ValueType;
};

// Convert from half precision to single or double precision.
template <typename T>
inline T ConvertFromHalfFP(HalfFP half_fp, uint32_t& fflags) {
  using UIntType = typename FPTypeInfo<T>::UIntType;
  using HalfFPUIntType = typename FPTypeInfo<HalfFP>::UIntType;
  HalfFPUIntType in_int = half_fp.value;

  if (FPTypeInfo<HalfFP>::IsNaN(half_fp)) {
    if (FPTypeInfo<HalfFP>::IsSNaN(half_fp)) {
      fflags |= static_cast<uint32_t>(FPExceptions::kInvalidOp);
    }
    UIntType uint_value = FPTypeInfo<T>::kCanonicalNaN;
    return absl::bit_cast<T>(uint_value);
  }

  if (FPTypeInfo<HalfFP>::IsInf(half_fp)) {
    UIntType uint_value = FPTypeInfo<T>::kPosInf;
    UIntType sign = in_int >> (FPTypeInfo<HalfFP>::kBitSize - 1);
    uint_value |= sign << (FPTypeInfo<T>::kBitSize - 1);
    return absl::bit_cast<T>(uint_value);
  }

  if ((in_int == 0) || (in_int == (1 << (FPTypeInfo<HalfFP>::kBitSize - 1)))) {
    UIntType uint_value =
        static_cast<UIntType>(in_int)
        << (FPTypeInfo<T>::kBitSize - FPTypeInfo<HalfFP>::kBitSize);
    return absl::bit_cast<T>(uint_value);
  }

  UIntType in_sign = FPTypeInfo<HalfFP>::SignBit(half_fp);
  UIntType in_exp =
      (in_int & FPTypeInfo<HalfFP>::kExpMask) >> FPTypeInfo<HalfFP>::kSigSize;
  UIntType in_sig = in_int & FPTypeInfo<HalfFP>::kSigMask;
  UIntType out_int = 0;
  UIntType out_sig = in_sig;
  if ((in_exp == 0) && (in_sig != 0)) {
    // Handle subnormal half precision inputs. They always result in a normal
    // float or double. Calculate how much shifting is needed move the MSB to
    // the location of the implicit bit. Then it can be handled as a normal
    // value from here on.
    int32_t shift_count =
        (1 + FPTypeInfo<HalfFP>::kSigSize) -
        (std::numeric_limits<UIntType>::digits - absl::countl_zero(out_sig));
    out_sig = (out_sig << shift_count) & FPTypeInfo<HalfFP>::kSigMask;
    in_exp = 1 - shift_count;
  }
  out_int |= in_sign << (FPTypeInfo<T>::kBitSize - 1);
  out_int |= (in_exp + FPTypeInfo<T>::kExpBias - FPTypeInfo<HalfFP>::kExpBias)
             << FPTypeInfo<T>::kSigSize;
  out_int |=
      out_sig << (FPTypeInfo<T>::kSigSize - FPTypeInfo<HalfFP>::kSigSize);
  return absl::bit_cast<T>(out_int);
}

// This is a soft conversion from a float or double to a half precision value.
// It is not a direct conversion from the floating point format to the half
// format. Instead, it uses the floating point hardware to do the conversion.
// This is done to get the correct rounding behavior for free from the FPU.
template <typename T>
inline HalfFP ConvertToHalfFP(T input_value, FPRoundingMode rm,
                              uint32_t& fflags) {
  using UIntType = typename FPTypeInfo<T>::UIntType;
  using IntType = typename FPTypeInfo<T>::IntType;
  UIntType in_int = absl::bit_cast<UIntType>(input_value);
  HalfFP half_fp = {.value = 0x0000};

  // Extract the mantissa, exponent and sign.
  UIntType mantissa = in_int & FPTypeInfo<T>::kSigMask;
  UIntType exponent =
      (in_int & FPTypeInfo<T>::kExpMask) >> FPTypeInfo<T>::kSigSize;
  UIntType sign = in_int >> (FPTypeInfo<T>::kBitSize - 1);

  if (std::isnan(input_value)) {
    half_fp.value = FPTypeInfo<HalfFP>::kCanonicalNaN;
    if (FPTypeInfo<T>::IsSNaN(input_value)) {
      fflags |= static_cast<UIntType>(FPExceptions::kInvalidOp);
    }
    return half_fp;
  }

  if (std::isinf(input_value)) {
    half_fp.value = FPTypeInfo<HalfFP>::kPosInf;
    half_fp.value |= (sign & 1) << (FPTypeInfo<HalfFP>::kBitSize - 1);
    return half_fp;
  }

  if ((in_int == 0) || (in_int == (1ULL << (FPTypeInfo<T>::kBitSize - 1)))) {
    half_fp.value =
        in_int >> (FPTypeInfo<T>::kBitSize - FPTypeInfo<HalfFP>::kBitSize);
    return half_fp;
  }

  IntType bias_diff = FPTypeInfo<T>::kExpBias - FPTypeInfo<HalfFP>::kExpBias;
  IntType unbounded_half_exponent = static_cast<IntType>(exponent) - bias_diff;
  IntType sig_size_diff =
      FPTypeInfo<T>::kSigSize - FPTypeInfo<HalfFP>::kSigSize;
  UIntType half_inf_exponent = ((1 << FPTypeInfo<HalfFP>::kExpSize) - 1);
  UIntType source_type_inf_exponent = ((1 << FPTypeInfo<T>::kExpSize) - 1);

  // Create a temp float with the smallest normal exponent and input mantissa.
  T ftmp = absl::bit_cast<T>(
      (sign << (FPTypeInfo<T>::kBitSize - 1)) |
      (static_cast<UIntType>(1ULL) << FPTypeInfo<T>::kSigSize) | mantissa);

  // Create a divisor float that will be used for shifting the mantissa in a
  // rounding aware way. The amount of shifting depends on if the result is
  // subnormal or normal.
  T fdiv = 0;
  UIntType default_fdiv_exp = FPTypeInfo<T>::kExpBias + sig_size_diff;
  UIntType fdiv_exp = default_fdiv_exp;
  if (unbounded_half_exponent > 0) {
    fdiv_exp = default_fdiv_exp;
  } else if (unbounded_half_exponent < 0) {
    // shift_count: emin - unbiased exponent
    IntType shift_count = 1 - static_cast<int>(exponent) + bias_diff;
    fdiv_exp = default_fdiv_exp + shift_count;
    fdiv_exp = std::min(fdiv_exp, source_type_inf_exponent - 1);
  } else {
    fdiv_exp = default_fdiv_exp + 1;
  }
  fdiv = absl::bit_cast<T>(fdiv_exp << FPTypeInfo<T>::kSigSize);

  // Shift right by doing division.
  T fres = ftmp / fdiv;
  UIntType res = absl::bit_cast<UIntType>(fres);

  // Shift left by doing multiplication.
  T fmultiply = absl::bit_cast<T>(default_fdiv_exp << FPTypeInfo<T>::kSigSize);
  T fres2 = fres * fmultiply;
  UIntType res2 = absl::bit_cast<UIntType>(fres2);

  // Update the exponent if rounding caused an increase.
  IntType exp_diff = static_cast<IntType>((res2 >> FPTypeInfo<T>::kSigSize) &
                                          source_type_inf_exponent) -
                     1;
  UIntType new_exponent = (exponent + exp_diff) & source_type_inf_exponent;

  UIntType half_exponent = 0;
  if (unbounded_half_exponent > 0) {
    half_exponent = new_exponent - bias_diff;
  } else if (unbounded_half_exponent < 0) {
    // Guaranteed subnormal. Nothing to do.
  } else {
    // This case could be normal or subnormal depending on the rounding result.
    half_exponent = (res2 >> FPTypeInfo<T>::kSigSize) & half_inf_exponent;
  }

  UIntType half_mantissa =
      (res2 >> sig_size_diff) & FPTypeInfo<HalfFP>::kSigMask;
  if (unbounded_half_exponent < 0) {  // Guaranteed Subnormal
    half_mantissa = (res & (1 << FPTypeInfo<HalfFP>::kSigSize))
                        ? ((res >> 1) & FPTypeInfo<HalfFP>::kSigMask)
                        : res & FPTypeInfo<HalfFP>::kSigMask;
  }

  // Handle the rules for overflowing to infinity depending on the rounding
  // mode.
  if (half_exponent >= half_inf_exponent) {
    fflags |= static_cast<uint32_t>(FPExceptions::kOverflow);
    fflags |= static_cast<uint32_t>(FPExceptions::kInexact);
    switch (rm) {
      case FPRoundingMode::kRoundToNearest:
        half_exponent = half_inf_exponent;
        half_mantissa = 0;
        break;
      case FPRoundingMode::kRoundTowardsZero:
        half_exponent = half_inf_exponent - 1;
        half_mantissa = FPTypeInfo<HalfFP>::kSigMask;
        break;
      case FPRoundingMode::kRoundDown:
        half_exponent = sign ? half_inf_exponent : half_inf_exponent - 1;
        half_mantissa = sign ? 0 : FPTypeInfo<HalfFP>::kSigMask;
        break;
      case FPRoundingMode::kRoundUp:
        half_exponent = sign ? half_inf_exponent - 1 : half_inf_exponent;
        half_mantissa = sign ? FPTypeInfo<HalfFP>::kSigMask : 0;
        break;
      default:
        half_exponent = half_inf_exponent;
        half_mantissa = 0;
        break;
    }
  }

  // Construct the half float.
  half_fp.value = half_mantissa |
                  (half_exponent << FPTypeInfo<HalfFP>::kSigSize) |
                  (sign << (FPTypeInfo<HalfFP>::kBitSize - 1));

  uint32_t temp_fflags = 0;
  T reconstructed_value = ConvertFromHalfFP<T>(half_fp, temp_fflags);
  bool exact_conversion = reconstructed_value == input_value;

  // Handle flags for the specific underflow case.
  if (!exact_conversion &&
      ((unbounded_half_exponent < 0) ||
       ((unbounded_half_exponent == 0) && (fres2 != ftmp)))) {
    fflags |= static_cast<uint32_t>(FPExceptions::kUnderflow);
  }

  // Handle flags for the specific inexact case.
  if (!exact_conversion && (fres2 != ftmp)) {
    fflags |= static_cast<uint32_t>(FPExceptions::kInexact);
  }
  return half_fp;
}

template <typename Result, typename Argument>
void RiscVZfhCvtHelper(
    const Instruction* instruction,
    std::function<Result(Argument, FPRoundingMode, uint32_t&)> operation) {
  RiscVCsrDestinationOperand* fflags_dest =
      static_cast<RiscVCsrDestinationOperand*>(instruction->Destination(1));
  using DstRegValue = typename DataTypeRegValue<Result>::type;
  uint32_t fflags = 0;

  Argument lhs;
  if constexpr (IsMpactFp<Argument>::value) {
    lhs = GetNaNBoxedSource<RVFpRegister::ValueType, Argument>(instruction, 0);
    if (FPTypeInfo<Argument>::IsSNaN(lhs)) {
      fflags |= *FPExceptions::kInvalidOp;
    }
  } else {
    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;
  {
    ScopedFPRoundingMode scoped_rm(rv_fp->host_fp_interface(), rm_value);
    dest_value = operation(lhs, static_cast<FPRoundingMode>(rm_value), fflags);
  }
  fflags_dest->GetRiscVCsr()->SetBits(fflags);
  auto* reg = static_cast<generic::RegisterDestinationOperand<DstRegValue>*>(
                  instruction->Destination(0))
                  ->GetRegister();

  if (sizeof(DstRegValue) > sizeof(Result) && IsMpactFp<Result>::value) {
    // 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(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 enabling HalfFP operations in native datatypes.
template <typename Argument, typename IntermediateType>
void RiscVZfhUnaryHelper(
    const Instruction* instruction,
    std::function<IntermediateType(IntermediateType)> operation) {
  RiscVCsrDestinationOperand* fflags_dest =
      static_cast<RiscVCsrDestinationOperand*>(instruction->Destination(1));
  uint32_t fflags = 0;
  RiscVUnaryFloatNaNBoxOp<RVFpRegister::ValueType, RVFpRegister::ValueType,
                          HalfFP, Argument>(
      instruction, [instruction, &operation, &fflags](Argument a) -> HalfFP {
        RiscVFPState* rv_fp =
            static_cast<RiscVState*>(instruction->state())->rv_fp();
        int rm_value = generic::GetInstructionSource<int>(instruction, 1);

        // 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";
          }
          rm_value = *(rv_fp->GetRoundingMode());
        }
        FPRoundingMode rm = static_cast<FPRoundingMode>(rm_value);
        IntermediateType argument1 =
            ConvertFromHalfFP<IntermediateType>(a, fflags);
        IntermediateType result;
        {
          ScopedFPStatus set_fpstatus(rv_fp->host_fp_interface(), rm);
          result = operation(argument1);
        }
        // To get the correct fflags we need a combination of host flags from
        // the operation and the conversion flags. Copy the host flags and merge
        // them with the conversion flags.
        fflags |= rv_fp->fflags()->GetUint32();
        {
          // ConvertToHalfFP pollutes the host flags so we need to create a
          // ScopedFPRoundingMode to restore the host flags.
          ScopedFPRoundingMode scoped_rm(rv_fp->host_fp_interface(), rm_value);
          return ConvertToHalfFP(result, rm, fflags);
        }
      });
  fflags_dest->GetRiscVCsr()->SetBits(fflags);
}

// Generic helper function enabling HalfFP operations in native datatypes.
template <typename Argument, typename IntermediateType>
void RiscVZfhBinaryHelper(
    const Instruction* instruction,
    std::function<IntermediateType(IntermediateType, IntermediateType)>
        operation) {
  RiscVCsrDestinationOperand* fflags_dest =
      static_cast<RiscVCsrDestinationOperand*>(instruction->Destination(1));
  uint32_t fflags = 0;
  RiscVBinaryFloatNaNBoxOp<RVFpRegister::ValueType, HalfFP, Argument>(
      instruction,
      [instruction, &operation, &fflags](Argument a, Argument b) -> HalfFP {
        RiscVFPState* rv_fp =
            static_cast<RiscVState*>(instruction->state())->rv_fp();
        int rm_value = generic::GetInstructionSource<int>(instruction, 2);
        // 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";
          }
          rm_value = *(rv_fp->GetRoundingMode());
        }
        FPRoundingMode rm = static_cast<FPRoundingMode>(rm_value);
        IntermediateType argument1 =
            ConvertFromHalfFP<IntermediateType>(a, fflags);
        IntermediateType argument2 =
            ConvertFromHalfFP<IntermediateType>(b, fflags);
        IntermediateType result;
        {
          ScopedFPStatus set_fpstatus(rv_fp->host_fp_interface(), rm);
          result = operation(argument1, argument2);
        }
        // To get the correct fflags we need a combination of host flags from
        // the operation and the conversion flags. Copy the host flags and merge
        // them with the conversion flags.
        fflags |= rv_fp->fflags()->GetUint32();
        {
          // ConvertToHalfFP pollutes the host flags so we need to create a
          // ScopedFPRoundingMode to restore the host flags.
          ScopedFPRoundingMode scoped_rm(rv_fp->host_fp_interface(), rm_value);
          return ConvertToHalfFP(result, rm, fflags);
        }
      });
  fflags_dest->GetRiscVCsr()->SetBits(fflags);
}

// Generic helper function enabling HalfFP operations in native datatypes.
template <typename Argument, typename IntermediateType>
void RiscVZfhTernaryHelper(
    const Instruction* instruction,
    std::function<IntermediateType(IntermediateType, IntermediateType,
                                   IntermediateType)>
        operation) {
  RiscVCsrDestinationOperand* fflags_dest =
      static_cast<RiscVCsrDestinationOperand*>(instruction->Destination(1));
  uint32_t fflags = 0;
  // RiscVTernaryFloatNaNBoxOp will handle the register NaN boxed reads and
  // write. The operation is in a native datatype so we will handle conversions
  // from/to half precision float values before and after the operation.
  RiscVTernaryFloatNaNBoxOp<RVFpRegister::ValueType, HalfFP, Argument>(
      instruction,
      [instruction, &operation, &fflags](Argument a, Argument b,
                                         Argument c) -> HalfFP {
        RiscVFPState* rv_fp =
            static_cast<RiscVState*>(instruction->state())->rv_fp();
        int rm_value = generic::GetInstructionSource<int>(instruction, 3);
        // 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";
          }
          rm_value = *(rv_fp->GetRoundingMode());
        }
        FPRoundingMode rm = static_cast<FPRoundingMode>(rm_value);
        IntermediateType argument1 =
            ConvertFromHalfFP<IntermediateType>(a, fflags);
        IntermediateType argument2 =
            ConvertFromHalfFP<IntermediateType>(b, fflags);
        IntermediateType argument3 =
            ConvertFromHalfFP<IntermediateType>(c, fflags);
        IntermediateType result;
        {
          ScopedFPStatus set_fpstatus(rv_fp->host_fp_interface(), rm_value);
          result = operation(argument1, argument2, argument3);
        }
        // To get the correct fflags we need a combination of host flags from
        // the operation and the conversion flags. Copy the host flags and merge
        // them with the conversion flags.
        fflags |= rv_fp->fflags()->GetUint32();
        {
          // ConvertToHalfFP pollutes the host flags so we need to create a
          // ScopedFPRoundingMode to restore the host flags.
          ScopedFPRoundingMode scoped_rm(rv_fp->host_fp_interface(), rm_value);
          return ConvertToHalfFP(result, rm, fflags);
        }
      });
  fflags_dest->GetRiscVCsr()->SetBits(fflags);
}

// Move a half precision value from a float register to an integer register.
template <typename XRegister>
void RiscVZfhFMvxhHelper(const Instruction* instruction) {
  using XRegValue = typename XRegister::ValueType;
  RiscVUnaryFloatOp<XRegValue, HalfFP>(instruction, [](HalfFP a) -> XRegValue {
    if (FPTypeInfo<HalfFP>::SignBit(a)) {
      // Repeat the sign bit for negative values.
      return (std::numeric_limits<XRegValue>::max() << 16) | a.value;
    }
    return static_cast<XRegValue>(a.value);
  });
}

// Move a half precision value from an integer register to a float register
template <typename XRegister>
inline void RiscVZfhFMvhxHelper(const Instruction* instruction) {
  using DstRegValue = typename RVFpRegister::ValueType;
  using SrcRegValue = typename XRegister::ValueType;
  SrcRegValue lhs = generic::GetInstructionSource<SrcRegValue>(instruction, 0);
  HalfFP dest_value = {.value = static_cast<uint16_t>(lhs)};

  auto* reg = static_cast<generic::RegisterDestinationOperand<DstRegValue>*>(
                  instruction->Destination(0))
                  ->GetRegister();

  // NaN box the value.
  using UReg = typename std::make_unsigned<DstRegValue>::type;
  using UInt = typename FPTypeInfo<HalfFP>::UIntType;
  auto dest_u_value = *reinterpret_cast<UInt*>(&dest_value);
  UReg reg_value = std::numeric_limits<UReg>::max();
  int shift = 8 * sizeof(HalfFP);
  reg_value = (reg_value << shift) | dest_u_value;
  reg->data_buffer()->template Set<DstRegValue>(0, reg_value);
}

// Compare two half precision values for equality.
template <typename XRegister>
inline void RiscVZfhFcmpeqHelper(const Instruction* instruction) {
  using DstRegValue = typename XRegister::ValueType;
  uint32_t fflags = 0;
  HalfFP lhs =
      GetNaNBoxedSource<RVFpRegister::ValueType, HalfFP>(instruction, 0);
  HalfFP rhs =
      GetNaNBoxedSource<RVFpRegister::ValueType, HalfFP>(instruction, 1);
  float lhs_f = ConvertFromHalfFP<float>(lhs, fflags);
  float rhs_f = ConvertFromHalfFP<float>(rhs, fflags);

  DstRegValue result = lhs_f == rhs_f ? 1 : 0;
  auto* reg = static_cast<generic::RegisterDestinationOperand<DstRegValue>*>(
                  instruction->Destination(0))
                  ->GetRegister();
  reg->data_buffer()->template Set<DstRegValue>(0, result);

  RiscVCsrDestinationOperand* fflags_dest =
      static_cast<RiscVCsrDestinationOperand*>(instruction->Destination(1));
  fflags_dest->GetRiscVCsr()->SetBits(fflags & *FPExceptions::kInvalidOp);
}

// Compare two half precision values for less than.
template <typename XRegister>
inline void RiscVZfhFcmpltHelper(const Instruction* instruction) {
  using DstRegValue = typename XRegister::ValueType;
  uint32_t unused_fflags = 0;
  HalfFP lhs =
      GetNaNBoxedSource<RVFpRegister::ValueType, HalfFP>(instruction, 0);
  HalfFP rhs =
      GetNaNBoxedSource<RVFpRegister::ValueType, HalfFP>(instruction, 1);
  float lhs_f = ConvertFromHalfFP<float>(lhs, unused_fflags);
  float rhs_f = ConvertFromHalfFP<float>(rhs, unused_fflags);

  DstRegValue result = lhs_f < rhs_f ? 1 : 0;
  auto* reg = static_cast<generic::RegisterDestinationOperand<DstRegValue>*>(
                  instruction->Destination(0))
                  ->GetRegister();
  reg->data_buffer()->template Set<DstRegValue>(0, result);

  RiscVCsrDestinationOperand* fflags_dest =
      static_cast<RiscVCsrDestinationOperand*>(instruction->Destination(1));
  if (std::isnan(lhs_f) || std::isnan(rhs_f)) {
    fflags_dest->GetRiscVCsr()->SetBits(*FPExceptions::kInvalidOp);
  }
}

// Compare two half precision values for less than or equal to.
template <typename XRegister>
void RiscVZfhFcmpleHelper(const Instruction* instruction) {
  using DstRegValue = typename XRegister::ValueType;
  uint32_t unused_fflags = 0;
  HalfFP lhs =
      GetNaNBoxedSource<RVFpRegister::ValueType, HalfFP>(instruction, 0);
  HalfFP rhs =
      GetNaNBoxedSource<RVFpRegister::ValueType, HalfFP>(instruction, 1);
  float lhs_f = ConvertFromHalfFP<float>(lhs, unused_fflags);
  float rhs_f = ConvertFromHalfFP<float>(rhs, unused_fflags);

  DstRegValue result = lhs_f <= rhs_f ? 1 : 0;
  auto* reg = static_cast<generic::RegisterDestinationOperand<DstRegValue>*>(
                  instruction->Destination(0))
                  ->GetRegister();
  reg->data_buffer()->template Set<DstRegValue>(0, result);

  RiscVCsrDestinationOperand* fflags_dest =
      static_cast<RiscVCsrDestinationOperand*>(instruction->Destination(1));
  if (std::isnan(lhs_f) || std::isnan(rhs_f)) {
    fflags_dest->GetRiscVCsr()->SetBits(*FPExceptions::kInvalidOp);
  }
}

}  // namespace

namespace RV32 {
// Move a half precision value from a float register to a 32 bit integer
// register.
void RiscVZfhFMvxh(const Instruction* instruction) {
  RiscVZfhFMvxhHelper<RV32Register>(instruction);
}

// Move a half precision value from an integer register to a float register and
// NaN box the value.
void RiscVZfhFMvhx(const Instruction* instruction) {
  RiscVZfhFMvhxHelper<RV32Register>(instruction);
}

// Convert from half precision to signed 32 bit integer.
void RiscVZfhCvtWh(const Instruction* instruction) {
  RiscVConvertFloatWithFflagsOp<typename RV32Register::ValueType, HalfFP,
                                int32_t>(instruction);
}

// Convert from half precision to unsigned 32 bit integer.
void RiscVZfhCvtWuh(const Instruction* instruction) {
  RiscVConvertFloatWithFflagsOp<typename RV32Register::ValueType, HalfFP,
                                uint32_t>(instruction);
}

// Compare two half precision values for equality.
void RiscVZfhFcmpeq(const Instruction* instruction) {
  RiscVZfhFcmpeqHelper<RV32Register>(instruction);
}

// Compare two half precision values for less than.
void RiscVZfhFcmplt(const Instruction* instruction) {
  RiscVZfhFcmpltHelper<RV32Register>(instruction);
}

// Compare two half precision values for less than or equal to.
void RiscVZfhFcmple(const Instruction* instruction) {
  RiscVZfhFcmpleHelper<RV32Register>(instruction);
}

// Classify a half precision value.
void RiscVZfhFclass(const Instruction* instruction) {
  RiscVUnaryOp<RV32Register, uint32_t, HalfFP>(
      instruction, [](HalfFP a) -> uint32_t {
        return static_cast<uint32_t>(ClassifyFP(a));
      });
}

}  // namespace RV32

namespace RV64 {
// Move a half precision value from a float register to a 32 bit integer
// register.
void RiscVZfhFMvxh(const Instruction* instruction) {
  RiscVZfhFMvxhHelper<RV64Register>(instruction);
}

// Move a half precision value from an integer register to a float register and
// NaN box the value.
void RiscVZfhFMvhx(const Instruction* instruction) {
  RiscVZfhFMvhxHelper<RV64Register>(instruction);
}

// Convert from half precision to signed 32 bit integer.
void RiscVZfhCvtWh(const Instruction* instruction) {
  RiscVConvertFloatWithFflagsOp<typename RV64Register::ValueType, HalfFP,
                                int32_t>(instruction);
}

// Convert from half precision to unsigned 32 bit integer.
void RiscVZfhCvtWuh(const Instruction* instruction) {
  RiscVConvertFloatWithFflagsOp<typename RV64Register::ValueType, HalfFP,
                                uint32_t>(instruction);
}

// Compare two half precision values for equality.
void RiscVZfhFcmpeq(const Instruction* instruction) {
  RiscVZfhFcmpeqHelper<RV64Register>(instruction);
}

// Compare two half precision values for less than.
void RiscVZfhFcmplt(const Instruction* instruction) {
  RiscVZfhFcmpltHelper<RV64Register>(instruction);
}

// Compare two half precision values for less than or equal to.
void RiscVZfhFcmple(const Instruction* instruction) {
  RiscVZfhFcmpleHelper<RV64Register>(instruction);
}

// Classify a half precision value.
void RiscVZfhFclass(const Instruction* instruction) {
  RiscVUnaryOp<RV64Register, uint64_t, HalfFP>(
      instruction, [](HalfFP a) -> uint64_t {
        return static_cast<uint64_t>(ClassifyFP(a));
      });
}

// Converts from half precision to signed 64 bit integer.
void RiscVZfhCvtLh(const Instruction* instruction) {
  RiscVConvertFloatWithFflagsOp<typename RV64Register::ValueType, HalfFP,
                                int64_t>(instruction);
}

// Converts from half precision to unsigned 64 bit integer.
void RiscVZfhCvtLuh(const Instruction* instruction) {
  RiscVConvertFloatWithFflagsOp<typename RV64Register::ValueType, HalfFP,
                                uint64_t>(instruction);
}

// Converts from signed 64 bit integer to half precision.
void RiscVZfhCvtHl(const Instruction* instruction) {
  RiscVZfhCvtHelper<HalfFP, int64_t>(
      instruction,
      [](int64_t a, FPRoundingMode rm, uint32_t& fflags) -> HalfFP {
        return ConvertToHalfFP(static_cast<float>(a), rm, fflags);
      });
}

// Convert from unsigned 64 bit integer to half precision.
void RiscVZfhCvtHlu(const Instruction* instruction) {
  RiscVZfhCvtHelper<HalfFP, uint64_t>(
      instruction,
      [](uint64_t a, FPRoundingMode rm, uint32_t& fflags) -> HalfFP {
        return ConvertToHalfFP(static_cast<float>(a), rm, fflags);
      });
}

}  // namespace RV64

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

// Convert from half precision to single precision.
void RiscVZfhCvtSh(const Instruction* instruction) {
  RiscVZfhCvtHelper<float, HalfFP>(
      instruction, [](HalfFP a, FPRoundingMode rm, uint32_t& fflags) -> float {
        return ConvertFromHalfFP<float>(a, fflags);
      });
}

// Convert from single precision to half precision.
void RiscVZfhCvtHs(const Instruction* instruction) {
  RiscVZfhCvtHelper<HalfFP, float>(
      instruction, [](float a, FPRoundingMode rm, uint32_t& fflags) -> HalfFP {
        return ConvertToHalfFP(a, rm, fflags);
      });
}

// Convert from half precision to double precision.
void RiscVZfhCvtDh(const Instruction* instruction) {
  RiscVZfhCvtHelper<double, HalfFP>(
      instruction, [](HalfFP a, FPRoundingMode rm, uint32_t& fflags) -> double {
        return ConvertFromHalfFP<double>(a, fflags);
      });
}

// Convert from double precision to half precision.
void RiscVZfhCvtHd(const Instruction* instruction) {
  RiscVZfhCvtHelper<HalfFP, double>(
      instruction, [](double a, FPRoundingMode rm, uint32_t& fflags) -> HalfFP {
        return ConvertToHalfFP(a, rm, fflags);
      });
}

// Add two half precision values. Do the calculation in single precision.
void RiscVZfhFadd(const Instruction* instruction) {
  RiscVZfhBinaryHelper<HalfFP, float>(
      instruction, [](float a, float b) -> float { return a + b; });
}

// Subtract two half precision values. Do the calculation in single precision.
void RiscVZfhFsub(const Instruction* instruction) {
  RiscVZfhBinaryHelper<HalfFP, float>(
      instruction, [](float a, float b) -> float { return a - b; });
}

// Multiply two half precision values. Do the calculation in single precision.
void RiscVZfhFmul(const Instruction* instruction) {
  RiscVZfhBinaryHelper<HalfFP, float>(
      instruction, [](float a, float b) -> float { return a * b; });
}

// Divide two half precision values. Do the calculation in single precision.
void RiscVZfhFdiv(const Instruction* instruction) {
  RiscVZfhBinaryHelper<HalfFP, float>(
      instruction, [](float a, float b) -> float { return a / b; });
}

// Take the minimum of two half precision values. Do the operation in single
// precision.
void RiscVZfhFmin(const Instruction* instruction) {
  RiscVZfhBinaryHelper<HalfFP, float>(instruction,
                                      [](float a, float b) -> float {
                                        // On ARM std::fminf returns NaN if
                                        // either input is NaN. Add extra checks
                                        // to make X86 and ARM behavior the
                                        // same.
                                        if (std::isnan(a)) {
                                          return b;
                                        } else if (std::isnan(b)) {
                                          return a;
                                        }
                                        return std::fminf(a, b);
                                      });
}

// Take the maximum of two half precision values. Do the operation in single
// precision.
void RiscVZfhFmax(const Instruction* instruction) {
  RiscVZfhBinaryHelper<HalfFP, float>(instruction,
                                      [](float a, float b) -> float {
                                        // On ARM std::fmaxf returns NaN if
                                        // either input is NaN. Add extra checks
                                        // to make X86 and ARM behavior the
                                        // same.
                                        if (std::isnan(a)) {
                                          return b;
                                        } else if (std::isnan(b)) {
                                          return a;
                                        }
                                        return std::fmaxf(a, b);
                                      });
}

// Calculate the square root of a half precision value. Do the operation in
// single precision and then convert back to half precision.
void RiscVZfhFsqrt(const Instruction* instruction) {
  RiscVZfhUnaryHelper<HalfFP, float>(
      instruction, [](float a) -> float { return std::sqrt(a); });
}

// The result is the exponent and significand of the first source with the
// sign bit of the second source.
void RiscVZfhFsgnj(const Instruction* instruction) {
  RiscVBinaryFloatNaNBoxOp<RVFpRegister::ValueType, HalfFP, HalfFP>(
      instruction, [](HalfFP a, HalfFP b) -> HalfFP {
        uint16_t mask =
            FPTypeInfo<HalfFP>::kExpMask | FPTypeInfo<HalfFP>::kSigMask;
        return HalfFP{.value = static_cast<uint16_t>((a.value & mask) |
                                                     (b.value & ~mask))};
      });
}

// The result is the exponent and significand of the first source with the
// opposite sign bit of the second source.
void RiscVZfhFsgnjn(const Instruction* instruction) {
  RiscVBinaryFloatNaNBoxOp<RVFpRegister::ValueType, HalfFP, HalfFP>(
      instruction, [](HalfFP a, HalfFP b) -> HalfFP {
        uint16_t mask =
            FPTypeInfo<HalfFP>::kExpMask | FPTypeInfo<HalfFP>::kSigMask;
        return HalfFP{.value = static_cast<uint16_t>((a.value & mask) |
                                                     (~b.value & ~mask))};
      });
}

// The result is the exponent and significand of the first source with the
// sign bit that is the exclusive or of the two source sign bits.
void RiscVZfhFsgnjx(const Instruction* instruction) {
  RiscVBinaryFloatNaNBoxOp<RVFpRegister::ValueType, HalfFP, HalfFP>(
      instruction, [](HalfFP a, HalfFP b) -> HalfFP {
        uint16_t mask =
            FPTypeInfo<HalfFP>::kExpMask | FPTypeInfo<HalfFP>::kSigMask;
        return HalfFP{.value = static_cast<uint16_t>(
                          (a.value & mask) | ((a.value ^ b.value) & ~mask))};
      });
}

// Fused multiply add in half precision. Do the operation in single precision.
// (rs1 * rs2) + rs3
void RiscVZfhFmadd(const Instruction* instruction) {
  RiscVZfhTernaryHelper<HalfFP, float>(
      instruction,
      [](float a, float b, float c) -> float { return fma(a, b, c); });
}

// Fused multiply add in half precision. Do the operation in single precision.
// (rs1 * rs2) - rs3
void RiscVZfhFmsub(const Instruction* instruction) {
  RiscVZfhTernaryHelper<HalfFP, float>(
      instruction,
      [](float a, float b, float c) -> float { return fma(a, b, -c); });
}

// Fused multiply add in half precision. Do the operation in single precision.
// -(rs1 * rs2) - rs3
void RiscVZfhFnmadd(const Instruction* instruction) {
  RiscVZfhTernaryHelper<HalfFP, float>(
      instruction,
      [](float a, float b, float c) -> float { return fma(-a, b, -c); });
}

// Fused multiply add in half precision. Do the operation in single precision.
// -(rs1 * rs2) + rs3
void RiscVZfhFnmsub(const Instruction* instruction) {
  RiscVZfhTernaryHelper<HalfFP, float>(
      instruction,
      [](float a, float b, float c) -> float { return fma(-a, b, c); });
}

// Convert from signed 32 bit integer to half precision.
void RiscVZfhCvtHw(const Instruction* instruction) {
  RiscVZfhCvtHelper<HalfFP, int32_t>(
      instruction,
      [](int32_t a, FPRoundingMode rm, uint32_t& fflags) -> HalfFP {
        float input_float = static_cast<float>(a);
        return ConvertToHalfFP(input_float, rm, fflags);
      });
}

// Convert from unsigned 32 bit integer to half precision.
void RiscVZfhCvtHwu(const Instruction* instruction) {
  RiscVZfhCvtHelper<HalfFP, uint32_t>(
      instruction,
      [](uint32_t a, FPRoundingMode rm, uint32_t& fflags) -> HalfFP {
        float input_float = static_cast<float>(a);
        return ConvertToHalfFP(input_float, rm, fflags);
      });
}

// TODO(b/409778536): Factor out generic unimplemented instruction semantic
//                    function.
void RV32VUnimplementedInstruction(const Instruction* instruction) {
  auto* state = static_cast<RiscVState*>(instruction->state());
  state->Trap(/*is_interrupt*/ false, /*trap_value*/ 0,
              *ExceptionCode::kIllegalInstruction,
              /*epc*/ instruction->address(), instruction);
}

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