// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "riscv/riscv64g_vec_encoding.h"

#include <cstdint>
#include <string>
#include <utility>
#include <vector>

#include "absl/base/casts.h"
#include "absl/log/log.h"
#include "absl/strings/str_cat.h"
#include "absl/types/span.h"
#include "mpact/sim/generic/immediate_operand.h"
#include "mpact/sim/generic/literal_operand.h"
#include "mpact/sim/generic/register.h"
#include "mpact/sim/generic/simple_resource.h"
#include "mpact/sim/generic/simple_resource_operand.h"
#include "mpact/sim/generic/type_helpers.h"
#include "riscv/riscv64gv_bin_decoder.h"
#include "riscv/riscv64gv_decoder.h"
#include "riscv/riscv64gv_enums.h"
#include "riscv/riscv_register.h"
#include "riscv/riscv_state.h"

namespace mpact {
namespace sim {
namespace riscv {
namespace isa64v {
namespace {

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

constexpr int kNumRegTable[8] = {8, 1, 2, 1, 4, 1, 2, 1};

template <typename M, typename E, typename G>
inline void Insert(M& map, E entry, G getter) {
  map.insert(std::make_pair(static_cast<int>(entry), getter));
}

template <typename RegType>
inline void GetVRegGroup(RiscVState* state, int reg_num, int num_fields,
                         std::vector<generic::RegisterBase*>* vreg_group) {
  // The number of registers in a vector register group depends on the register
  // index: 0, 8, 16, 24 each have 8 registers, 4, 12, 20, 28 each have 4,
  // 2, 6, 10, 14, 18, 22, 26, 30 each have two, and all odd numbered register
  // groups have only 1.
  // For segmented load and store instructions there is a register group per
  // field. Each register group size is limited by the NumRegTable limit, but
  // the total number of registers can still be up to 8.
  int num_regs = kNumRegTable[reg_num % 8];
  for (int i = 0; i < num_regs * num_fields; i++) {
    auto vreg_name = absl::StrCat(RiscVState::kVregPrefix, reg_num + i);
    vreg_group->push_back(state->GetRegister<RegType>(vreg_name).first);
  }
}

template <typename RegType>
inline SourceOperandInterface* GetVectorRegisterSourceOp(RiscVState* state,
                                                         int reg_num) {
  std::vector<generic::RegisterBase*> vreg_group;
  GetVRegGroup<RegType>(state, reg_num, /*num_fields=*/1, &vreg_group);
  auto* v_src_op = new RV32VectorSourceOperand(
      absl::Span<generic::RegisterBase*>(vreg_group),
      absl::StrCat(RiscVState::kVregPrefix, reg_num));
  return v_src_op;
}

template <typename RegType>
inline SourceOperandInterface* GetVectorRegisterSourceOpNf(RiscVState* state,
                                                           int reg_num,
                                                           int nf) {
  std::vector<generic::RegisterBase*> vreg_group;
  GetVRegGroup<RegType>(state, reg_num, nf, &vreg_group);
  auto* v_src_op = new RV32VectorSourceOperand(
      absl::Span<generic::RegisterBase*>(vreg_group),
      absl::StrCat(RiscVState::kVregPrefix, reg_num));
  return v_src_op;
}

template <typename RegType>
inline DestinationOperandInterface* GetVectorRegisterDestinationOp(
    RiscVState* state, int latency, int reg_num) {
  std::vector<generic::RegisterBase*> vreg_group;
  GetVRegGroup<RegType>(state, reg_num, /*num_fields=*/1, &vreg_group);
  auto* v_dst_op = new RV32VectorDestinationOperand(
      absl::Span<generic::RegisterBase*>(vreg_group), latency,
      absl::StrCat(RiscVState::kVregPrefix, reg_num));
  return v_dst_op;
}

template <typename RegType>
inline DestinationOperandInterface* GetVectorRegisterDestinationOpNf(
    RiscVState* state, int latency, int reg_num, int nf) {
  std::vector<generic::RegisterBase*> vreg_group;
  GetVRegGroup<RegType>(state, reg_num, nf, &vreg_group);
  auto* v_dst_op = new RV32VectorDestinationOperand(
      absl::Span<generic::RegisterBase*>(vreg_group), latency,
      absl::StrCat(RiscVState::kVregPrefix, reg_num));
  return v_dst_op;
}

template <typename RegType>
inline SourceOperandInterface* GetVectorMaskRegisterSourceOp(RiscVState* state,
                                                             int reg_num) {
  // Mask register groups only have a single register.
  std::vector<generic::RegisterBase*> vreg_group;
  vreg_group.push_back(
      state
          ->GetRegister<RegType>(absl::StrCat(RiscVState::kVregPrefix, reg_num))
          .first);
  auto* v_src_op = new RV32VectorSourceOperand(
      absl::Span<generic::RegisterBase*>(vreg_group),
      absl::StrCat(RiscVState::kVregPrefix, reg_num));
  return v_src_op;
}

template <typename RegType>
inline DestinationOperandInterface* GetVectorMaskRegisterDestinationOp(
    RiscVState* state, int latency, int reg_num) {
  // Mask register groups only have a single register.
  std::vector<generic::RegisterBase*> vreg_group;
  vreg_group.push_back(
      state
          ->GetRegister<RegType>(absl::StrCat(RiscVState::kVregPrefix, reg_num))
          .first);
  auto* v_dst_op = new RV32VectorDestinationOperand(
      absl::Span<generic::RegisterBase*>(vreg_group), latency,
      absl::StrCat(RiscVState::kVregPrefix, reg_num));
  return v_dst_op;
}

// Generic helper functions to create register operands.
template <typename RegType>
inline DestinationOperandInterface* GetRegisterDestinationOp(RiscVState* state,
                                                             std::string name,
                                                             int latency) {
  auto* reg = state->GetRegister<RegType>(name).first;
  return reg->CreateDestinationOperand(latency);
}

template <typename RegType>
inline DestinationOperandInterface* GetRegisterDestinationOp(
    RiscVState* state, std::string name, int latency, std::string op_name) {
  auto* reg = state->GetRegister<RegType>(name).first;
  return reg->CreateDestinationOperand(latency, op_name);
}

template <typename T>
inline DestinationOperandInterface* GetCSRSetBitsDestinationOp(
    RiscVState* state, std::string name, int latency, std::string op_name) {
  auto result = state->csr_set()->GetCsr(name);
  if (!result.ok()) {
    LOG(ERROR) << "No such CSR '" << name << "'";
    return nullptr;
  }
  auto* csr = result.value();
  auto* op = csr->CreateSetDestinationOperand(latency, op_name);
  return op;
}

template <typename RegType>
inline SourceOperandInterface* GetRegisterSourceOp(RiscVState* state,
                                                   std::string name) {
  auto* reg = state->GetRegister<RegType>(name).first;
  auto* op = reg->CreateSourceOperand();
  return op;
}

template <typename RegType>
inline SourceOperandInterface* GetRegisterSourceOp(RiscVState* state,
                                                   std::string name,
                                                   std::string op_name) {
  auto* reg = state->GetRegister<RegType>(name).first;
  auto* op = reg->CreateSourceOperand(op_name);
  return op;
}

}  // namespace

RiscV64GVecEncoding::RiscV64GVecEncoding(RiscVState* state)
    : RiscV64GVecEncoding(state, true) {}

RiscV64GVecEncoding::RiscV64GVecEncoding(RiscVState* state, bool use_abi_names)
    : state_(state) {
  if (use_abi_names) {
    xreg_alias_ = xreg_abi_names_;
  } else {
    xreg_alias_ = xreg_names_;
  }
  InitializeSourceOperandGetters();
  InitializeDestinationOperandGetters();
  InitializeVectorSourceOperandGetters();
  InitializeVectorDestinationOperandGetters();
  InitializeSimpleResourceGetters();
  resource_pool_ = new generic::SimpleResourcePool("RiscV64GV", 128);
  resource_delay_line_ =
      state_->CreateAndAddDelayLine<generic::SimpleResourceDelayLine>(8);
  for (int i = *SourceOpEnum::kNone; i < *SourceOpEnum::kPastMaxValue; ++i) {
    if (source_op_getters_.find(i) == source_op_getters_.end()) {
      LOG(ERROR) << "No getter for source op enum value " << i;
    }
  }
  for (int i = *DestOpEnum::kNone; i < *DestOpEnum::kPastMaxValue; ++i) {
    if (dest_op_getters_.find(i) == dest_op_getters_.end()) {
      LOG(ERROR) << "No getter for destination op enum value " << i;
    }
  }
}

RiscV64GVecEncoding::~RiscV64GVecEncoding() { delete resource_pool_; }

void RiscV64GVecEncoding::InitializeSourceOperandGetters() {
  // Source operand getters.
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kAAq),
                     [this]() -> SourceOperandInterface* {
                       if (encoding64::inst32_format::ExtractAq(inst_word_)) {
                         return new generic::IntLiteralOperand<1>();
                       }
                       return new generic::IntLiteralOperand<0>();
                     }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kARl),
                     [this]() -> SourceOperandInterface* {
                       if (encoding64::inst32_format::ExtractRl(inst_word_)) {
                         return new generic::IntLiteralOperand<1>();
                       }
                       return new generic::IntLiteralOperand<0>();
                     }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kIUimm6), [this]() {
        return new generic::ImmediateOperand<uint32_t>(
            encoding64::r_s_type::ExtractRUimm6(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kBImm12), [this]() {
        return new generic::ImmediateOperand<int32_t>(
            encoding64::inst32_format::ExtractBImm(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kC3drs2), [this]() {
        auto num = encoding64::inst16_format::ExtractCsRs2(inst_word_);
        return GetRegisterSourceOp<RVFpRegister>(
            state_, absl::StrCat(RiscVState::kFregPrefix, num));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kC3rs1), [this]() {
        auto num = encoding64::inst16_format::ExtractCsRs1(inst_word_);
        if (state_->xlen() == RiscVXlen::RV32) {
          return GetRegisterSourceOp<RV64Register>(
              state_, absl::StrCat(RiscVState::kXregPrefix, num),
              xreg_alias_[num]);
        }
        return GetRegisterSourceOp<RV64Register>(
            state_, absl::StrCat(RiscVState::kXregPrefix, num),
            xreg_alias_[num]);
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kC3rs2), [this]() {
        auto num = encoding64::inst16_format::ExtractCsRs2(inst_word_);
        if (state_->xlen() == RiscVXlen::RV32) {
          return GetRegisterSourceOp<RV64Register>(
              state_, absl::StrCat(RiscVState::kXregPrefix, num),
              xreg_alias_[num]);
        }
        return GetRegisterSourceOp<RV64Register>(
            state_, absl::StrCat(RiscVState::kXregPrefix, num),
            xreg_alias_[num]);
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kCSRUimm5), [this]() {
        return new generic::ImmediateOperand<uint32_t>(
            encoding64::inst32_format::ExtractIUimm5(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kCdrs2), [this]() {
        auto num = encoding64::c_r::ExtractRs2(inst_word_);
        return GetRegisterSourceOp<RVFpRegister>(
            state_, absl::StrCat(RiscVState::kFregPrefix, num));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kCrs1), [this]() {
        auto num = encoding64::c_r::ExtractRs1(inst_word_);
        if (state_->xlen() == RiscVXlen::RV32) {
          return GetRegisterSourceOp<RV64Register>(
              state_, absl::StrCat(RiscVState::kXregPrefix, num),
              xreg_alias_[num]);
        }
        return GetRegisterSourceOp<RV64Register>(
            state_, absl::StrCat(RiscVState::kXregPrefix, num),
            xreg_alias_[num]);
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kCrs2), [this]() {
        auto num = encoding64::c_r::ExtractRs2(inst_word_);
        if (state_->xlen() == RiscVXlen::RV32) {
          return GetRegisterSourceOp<RV64Register>(
              state_, absl::StrCat(RiscVState::kXregPrefix, num),
              xreg_alias_[num]);
        }
        return GetRegisterSourceOp<RV64Register>(
            state_, absl::StrCat(RiscVState::kXregPrefix, num),
            xreg_alias_[num]);
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kCsr), [this]() {
        auto csr_indx = encoding64::i_type::ExtractUImm12(inst_word_);
        auto res = state_->csr_set()->GetCsr(csr_indx);
        if (!res.ok()) {
          return new generic::ImmediateOperand<uint32_t>(csr_indx);
        }
        auto* csr = res.value();
        return new generic::ImmediateOperand<uint32_t>(csr_indx, csr->name());
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kDrs1), [this]() {
        int num = encoding64::r_type::ExtractRs1(inst_word_);
        return GetRegisterSourceOp<RVFpRegister>(
            state_, absl::StrCat(RiscVState::kFregPrefix, num));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kDrs2), [this]() {
        int num = encoding64::r_type::ExtractRs2(inst_word_);
        return GetRegisterSourceOp<RVFpRegister>(
            state_, absl::StrCat(RiscVState::kFregPrefix, num));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kDrs3), [this]() {
        int num = encoding64::r4_type::ExtractRs3(inst_word_);
        return GetRegisterSourceOp<RVFpRegister>(
            state_, absl::StrCat(RiscVState::kFregPrefix, num));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kFrs1), [this]() {
        int num = encoding64::r_type::ExtractRs1(inst_word_);
        return GetRegisterSourceOp<RVFpRegister>(
            state_, absl::StrCat(RiscVState::kFregPrefix, num));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kFrs2), [this]() {
        int num = encoding64::r_type::ExtractRs2(inst_word_);
        return GetRegisterSourceOp<RVFpRegister>(
            state_, absl::StrCat(RiscVState::kFregPrefix, num));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kFrs3), [this]() {
        int num = encoding64::r4_type::ExtractRs3(inst_word_);
        return GetRegisterSourceOp<RVFpRegister>(
            state_, absl::StrCat(RiscVState::kFregPrefix, num));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kICbImm8), [this]() {
        return new generic::ImmediateOperand<int32_t>(
            encoding64::inst16_format::ExtractBimm(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kICiImm6), [this]() {
        return new generic::ImmediateOperand<int32_t>(
            encoding64::c_i::ExtractImm6(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kICiImm612), [this]() {
        return new generic::ImmediateOperand<int32_t>(
            encoding64::inst16_format::ExtractImm18(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kICiUimm6), [this]() {
        return new generic::ImmediateOperand<uint32_t>(
            encoding64::inst16_format::ExtractUimm6(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kICiUimm6x4), [this]() {
        return new generic::ImmediateOperand<uint32_t>(
            encoding64::inst16_format::ExtractCiImmW(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kICiUimm6x8), [this]() {
        return new generic::ImmediateOperand<uint32_t>(
            encoding64::inst16_format::ExtractCiImmD(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kICiImm6x16), [this]() {
        return new generic::ImmediateOperand<int32_t>(
            encoding64::inst16_format::ExtractCiImm10(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kICiwUimm8x4), [this]() {
        return new generic::ImmediateOperand<uint32_t>(
            encoding64::inst16_format::ExtractCiwImm10(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kICjImm11), [this]() {
        return new generic::ImmediateOperand<int32_t>(
            encoding64::inst16_format::ExtractJimm(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kIClUimm5x4), [this]() {
        return new generic::ImmediateOperand<uint32_t>(
            encoding64::inst16_format::ExtractClImmW(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kIClUimm5x8), [this]() {
        return new generic::ImmediateOperand<uint32_t>(
            encoding64::inst16_format::ExtractClImmD(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kICssUimm6x4), [this]() {
        return new generic::ImmediateOperand<uint32_t>(
            encoding64::inst16_format::ExtractCssImmW(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kICssUimm6x8), [this]() {
        return new generic::ImmediateOperand<uint32_t>(
            encoding64::inst16_format::ExtractCssImmD(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kIImm12), [this]() {
        return new generic::ImmediateOperand<int32_t>(
            encoding64::inst32_format::ExtractImm12(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kIUimm5), [this]() {
        return new generic::ImmediateOperand<uint32_t>(
            encoding64::inst32_format::ExtractRUimm5(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kJImm12), [this]() {
        return new generic::ImmediateOperand<int32_t>(
            encoding64::inst32_format::ExtractImm12(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kJImm20), [this]() {
        return new generic::ImmediateOperand<int32_t>(
            encoding64::inst32_format::ExtractJImm(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kPred), [this]() {
        return new generic::ImmediateOperand<uint32_t>(
            encoding64::fence::ExtractPred(inst_word_));
      }));
  source_op_getters_.insert(std::make_pair(
      static_cast<int>(SourceOpEnum::kRm), [this]() -> SourceOperandInterface* {
        uint32_t rm = (inst_word_ >> 12) & 0x7;
        switch (rm) {
          case 0:
            return new generic::IntLiteralOperand<0>();
          case 1:
            return new generic::IntLiteralOperand<1>();
          case 2:
            return new generic::IntLiteralOperand<2>();
          case 3:
            return new generic::IntLiteralOperand<3>();
          case 4:
            return new generic::IntLiteralOperand<4>();
          case 5:
            return new generic::IntLiteralOperand<5>();
          case 6:
            return new generic::IntLiteralOperand<6>();
          case 7:
            return new generic::IntLiteralOperand<7>();
          default:
            return nullptr;
        }
      }));
  source_op_getters_.insert(std::make_pair(
      static_cast<int>(SourceOpEnum::kRd), [this]() -> SourceOperandInterface* {
        int num = encoding64::r_type::ExtractRd(inst_word_);
        if (num == 0)
          return new generic::IntLiteralOperand<0>({1}, xreg_alias_[0]);
        if (state_->xlen() == RiscVXlen::RV32) {
          return GetRegisterSourceOp<RV64Register>(
              state_, absl::StrCat(RiscVState::kXregPrefix, num),
              xreg_alias_[num]);
        }
        return GetRegisterSourceOp<RV64Register>(
            state_, absl::StrCat(RiscVState::kXregPrefix, num),
            xreg_alias_[num]);
      }));
  source_op_getters_.insert(std::make_pair(
      static_cast<int>(SourceOpEnum::kRs1),
      [this]() -> SourceOperandInterface* {
        int num = encoding64::r_type::ExtractRs1(inst_word_);
        if (num == 0)
          return new generic::IntLiteralOperand<0>({1}, xreg_alias_[0]);
        if (state_->xlen() == RiscVXlen::RV32) {
          return GetRegisterSourceOp<RV64Register>(
              state_, absl::StrCat(RiscVState::kXregPrefix, num),
              xreg_alias_[num]);
        }
        return GetRegisterSourceOp<RV64Register>(
            state_, absl::StrCat(RiscVState::kXregPrefix, num),
            xreg_alias_[num]);
      }));
  source_op_getters_.insert(std::make_pair(
      static_cast<int>(SourceOpEnum::kRs2),
      [this]() -> SourceOperandInterface* {
        int num = encoding64::r_type::ExtractRs2(inst_word_);
        if (num == 0)
          return new generic::IntLiteralOperand<0>({1}, xreg_alias_[0]);
        if (state_->xlen() == RiscVXlen::RV32) {
          return GetRegisterSourceOp<RV64Register>(
              state_, absl::StrCat(RiscVState::kXregPrefix, num),
              xreg_alias_[num]);
        }
        return GetRegisterSourceOp<RV64Register>(
            state_, absl::StrCat(RiscVState::kXregPrefix, num),
            xreg_alias_[num]);
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kSImm12), [this]() {
        return new generic::ImmediateOperand<int32_t>(
            encoding64::s_type::ExtractSImm(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kSucc), [this]() {
        return new generic::ImmediateOperand<uint32_t>(
            encoding64::fence::ExtractSucc(inst_word_));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kUImm20), [this]() {
        uint32_t uimm = encoding64::u_type::ExtractUImm(inst_word_);
        return new generic::ImmediateOperand<int32_t>(
            absl::bit_cast<int32_t>(uimm));
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kX0), [this]() {
        return new generic::IntLiteralOperand<0>({1}, xreg_alias_[0]);
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kX2), [this]() {
        if (state_->xlen() == RiscVXlen::RV32) {
          return GetRegisterSourceOp<RV64Register>(
              state_, absl::StrCat(RiscVState::kXregPrefix, 2), xreg_alias_[2]);
        }
        return GetRegisterSourceOp<RV64Register>(
            state_, absl::StrCat(RiscVState::kXregPrefix, 2), xreg_alias_[2]);
      }));
  source_op_getters_.insert(
      std::make_pair(static_cast<int>(SourceOpEnum::kFs1), [this]() {
        const int num = encoding64::v_arith::ExtractRs1(inst_word_);
        return GetRegisterSourceOp<RV64Register>(state_, freg_names_[num],
                                                 freg_abi_names_[num]);
      }));
  source_op_getters_.insert(std::make_pair(
      static_cast<int>(SourceOpEnum::kNone), []() { return nullptr; }));
}

void RiscV64GVecEncoding::InitializeDestinationOperandGetters() {
  // Destination operand getters.
  dest_op_getters_.insert(
      std::make_pair(static_cast<int>(DestOpEnum::kC3drd), [this](int latency) {
        int num = encoding64::inst16_format::ExtractClRd(inst_word_);
        if (state_->xlen() == RiscVXlen::RV32) {
          return GetRegisterDestinationOp<RV64Register>(
              state_, absl::StrCat(RiscVState::kXregPrefix, num), latency,
              xreg_alias_[num]);
        }
        return GetRegisterDestinationOp<RV64Register>(
            state_, absl::StrCat(RiscVState::kXregPrefix, num), latency,
            xreg_alias_[num]);
      }));
  dest_op_getters_.insert(
      std::make_pair(static_cast<int>(DestOpEnum::kC3rd), [this](int latency) {
        int num = encoding64::inst16_format::ExtractClRd(inst_word_);
        return GetRegisterDestinationOp<RV64Register>(
            state_, absl::StrCat(RiscVState::kXregPrefix, num), latency,
            xreg_alias_[num]);
      }));
  dest_op_getters_.insert(
      std::make_pair(static_cast<int>(DestOpEnum::kC3rs1), [this](int latency) {
        int num = encoding64::inst16_format::ExtractClRs1(inst_word_);
        if (state_->xlen() == RiscVXlen::RV32) {
          return GetRegisterDestinationOp<RV64Register>(
              state_, absl::StrCat(RiscVState::kXregPrefix, num), latency,
              xreg_alias_[num]);
        }
        return GetRegisterDestinationOp<RV64Register>(
            state_, absl::StrCat(RiscVState::kXregPrefix, num), latency,
            xreg_alias_[num]);
      }));
  dest_op_getters_.insert(std::make_pair(static_cast<int>(DestOpEnum::kCsr),
                                         [](int latency) { return nullptr; }));
  dest_op_getters_.insert(
      std::make_pair(static_cast<int>(DestOpEnum::kDrd), [this](int latency) {
        int num = encoding64::r_type::ExtractRd(inst_word_);
        return GetRegisterDestinationOp<RVFpRegister>(
            state_, absl::StrCat(RiscVState::kFregPrefix, num), latency);
      }));
  dest_op_getters_.insert(
      std::make_pair(static_cast<int>(DestOpEnum::kFrd), [this](int latency) {
        int num = encoding64::r_type::ExtractRd(inst_word_);
        return GetRegisterDestinationOp<RVFpRegister>(
            state_, absl::StrCat(RiscVState::kFregPrefix, num), latency);
      }));
  dest_op_getters_.insert(std::make_pair(
      static_cast<int>(DestOpEnum::kNextPc), [this](int latency) {
        if (state_->xlen() == RiscVXlen::RV32) {
          return GetRegisterDestinationOp<RV64Register>(
              state_, RiscVState::kPcName, latency);
        }
        return GetRegisterDestinationOp<RV64Register>(
            state_, RiscVState::kPcName, latency);
      }));
  dest_op_getters_.insert(
      std::make_pair(static_cast<int>(DestOpEnum::kRd),
                     [this](int latency) -> DestinationOperandInterface* {
                       int num = encoding64::r_type::ExtractRd(inst_word_);
                       if (num == 0) {
                         return GetRegisterDestinationOp<RV64Register>(
                             state_, "X0Dest", 0, xreg_alias_[0]);
                       } else {
                         return GetRegisterDestinationOp<RVFpRegister>(
                             state_, absl::StrCat(RiscVState::kXregPrefix, num),
                             latency, xreg_alias_[num]);
                       }
                     }));
  dest_op_getters_.insert(
      std::make_pair(static_cast<int>(DestOpEnum::kX0), [this](int) {
        if (state_->xlen() == RiscVXlen::RV32) {
          return GetRegisterDestinationOp<RV64Register>(state_, "X0Dest", 0,
                                                        xreg_alias_[0]);
        }
        return GetRegisterDestinationOp<RV64Register>(state_, "X0Dest", 0,
                                                      xreg_alias_[0]);
      }));
  dest_op_getters_.insert(
      std::make_pair(static_cast<int>(DestOpEnum::kX1), [this](int latency) {
        if (state_->xlen() == RiscVXlen::RV32) {
          return GetRegisterDestinationOp<RV64Register>(
              state_, absl::StrCat(RiscVState::kXregPrefix, 1), latency,
              xreg_alias_[1]);
        }
        return GetRegisterDestinationOp<RV64Register>(
            state_, absl::StrCat(RiscVState::kXregPrefix, 1), latency,
            xreg_alias_[1]);
      }));
  dest_op_getters_.insert(
      std::make_pair(static_cast<int>(DestOpEnum::kX2), [this](int latency) {
        if (state_->xlen() == RiscVXlen::RV32) {
          return GetRegisterDestinationOp<RV64Register>(
              state_, absl::StrCat(RiscVState::kXregPrefix, 2), latency,
              xreg_alias_[2]);
        }
        return GetRegisterDestinationOp<RV64Register>(
            state_, absl::StrCat(RiscVState::kXregPrefix, 2), latency,
            xreg_alias_[2]);
      }));
  dest_op_getters_.insert(std::make_pair(
      static_cast<int>(DestOpEnum::kFflags), [this](int latency) {
        return GetCSRSetBitsDestinationOp<uint32_t>(state_, "fflags", latency,
                                                    "");
      }));
  dest_op_getters_.insert(
      std::make_pair(static_cast<int>(DestOpEnum::kFd), [this](int latency) {
        const int num = encoding64::v_arith::ExtractRd(inst_word_);
        return GetRegisterDestinationOp<RV64Register>(
            state_, freg_names_[num], latency, freg_abi_names_[num]);
      }));
  dest_op_getters_.insert(std::make_pair(static_cast<int>(DestOpEnum::kNone),
                                         [](int latency) { return nullptr; }));
}

void RiscV64GVecEncoding::InitializeVectorSourceOperandGetters() {
  Insert(source_op_getters_, SourceOpEnum::kVd,
         [this]() -> SourceOperandInterface* {
           auto num = encoding64::v_arith::ExtractVd(inst_word_);
           return GetVectorRegisterSourceOp<RVVectorRegister>(state_, num);
         });
  Insert(source_op_getters_, SourceOpEnum::kVmask,
         [this]() -> SourceOperandInterface* {
           auto vm = encoding64::v_arith::ExtractVm(inst_word_);
           if (vm == 1) {
             // Unmasked, return the True mask.
             return new RV32VectorTrueOperand(state_);
           }
           // Masked. Return the mask register.
           return GetVectorMaskRegisterSourceOp<RVVectorRegister>(state_, 0);
         });
  Insert(source_op_getters_, SourceOpEnum::kVmaskTrue,
         [this]() -> SourceOperandInterface* {
           return new RV32VectorTrueOperand(state_);
         });
  Insert(source_op_getters_, SourceOpEnum::kVm,
         [this]() -> SourceOperandInterface* {
           auto vm = encoding64::v_arith::ExtractVm(inst_word_);
           return new generic::ImmediateOperand<bool>(
               vm, absl::StrCat("vm.", vm ? "t" : "f"));
         });
  Insert(source_op_getters_, SourceOpEnum::kVs1,
         [this]() -> SourceOperandInterface* {
           auto num = encoding64::v_arith::ExtractVs1(inst_word_);
           return GetVectorRegisterSourceOp<RVVectorRegister>(state_, num);
         });
  Insert(source_op_getters_, SourceOpEnum::kVs2,
         [this]() -> SourceOperandInterface* {
           auto num = encoding64::v_arith::ExtractVs2(inst_word_);
           return GetVectorRegisterSourceOp<RVVectorRegister>(state_, num);
         });
  Insert(source_op_getters_, SourceOpEnum::kVs3,
         [this]() -> SourceOperandInterface* {
           auto num = encoding64::v_mem::ExtractVs3(inst_word_);
           return GetVectorRegisterSourceOp<RVVectorRegister>(state_, num);
         });
  Insert(source_op_getters_, SourceOpEnum::kVs3Nf,
         [this]() -> SourceOperandInterface* {
           auto nf = encoding64::v_mem::ExtractNf(inst_word_) + 1;
           auto num = encoding64::v_mem::ExtractVs3(inst_word_);
           return GetVectorRegisterSourceOpNf<RVVectorRegister>(state_, num,
                                                                nf);
         });

  Insert(source_op_getters_, SourceOpEnum::kSimm5,
         [this]() -> SourceOperandInterface* {
           const auto num = encoding64::inst32_format::ExtractSimm5(inst_word_);
           return new generic::ImmediateOperand<int32_t>(num);
         });

  Insert(source_op_getters_, SourceOpEnum::kUimm5,
         [this]() -> SourceOperandInterface* {
           const auto num = encoding64::inst32_format::ExtractUimm5(inst_word_);
           return new generic::ImmediateOperand<int32_t>(num);
         });

  Insert(source_op_getters_, SourceOpEnum::kZimm10,
         [this]() -> SourceOperandInterface* {
           const auto num =
               encoding64::inst32_format::ExtractZimm10(inst_word_);
           return new generic::ImmediateOperand<int32_t>(num);
         });

  Insert(source_op_getters_, SourceOpEnum::kZimm11,
         [this]() -> SourceOperandInterface* {
           const auto num =
               encoding64::inst32_format::ExtractZimm11(inst_word_);
           return new generic::ImmediateOperand<int32_t>(num);
         });

  Insert(source_op_getters_, SourceOpEnum::kConst1,
         []() -> SourceOperandInterface* {
           return new generic::ImmediateOperand<int32_t>(1);
         });

  Insert(source_op_getters_, SourceOpEnum::kConst2,
         []() -> SourceOperandInterface* {
           return new generic::ImmediateOperand<int32_t>(2);
         });

  Insert(source_op_getters_, SourceOpEnum::kConst4,
         []() -> SourceOperandInterface* {
           return new generic::ImmediateOperand<int32_t>(4);
         });

  Insert(source_op_getters_, SourceOpEnum::kConst8,
         []() -> SourceOperandInterface* {
           return new generic::ImmediateOperand<int32_t>(8);
         });

  Insert(source_op_getters_, SourceOpEnum::kNf,
         [this]() -> SourceOperandInterface* {
           auto num_fields = encoding64::v_mem::ExtractNf(inst_word_);
           return new generic::ImmediateOperand<uint8_t>(
               num_fields, absl::StrCat(num_fields + 1));
         });
}

void RiscV64GVecEncoding::InitializeVectorDestinationOperandGetters() {
  Insert(dest_op_getters_, DestOpEnum::kVd,
         [this](int latency) -> DestinationOperandInterface* {
           auto num = encoding64::v_arith::ExtractVd(inst_word_);
           return GetVectorRegisterDestinationOp<RVVectorRegister>(
               state_, latency, num);
         });
  Insert(dest_op_getters_, DestOpEnum::kVdNf,
         [this](int latency) -> DestinationOperandInterface* {
           auto nf = encoding64::v_mem::ExtractNf(inst_word_) + 1;
           auto num = encoding64::v_mem::ExtractVd(inst_word_);
           return GetVectorRegisterDestinationOpNf<RVVectorRegister>(
               state_, latency, num, nf);
         });
}

// Parse the instruction word to determine the opcode.
void RiscV64GVecEncoding::ParseInstruction(uint32_t inst_word) {
  inst_word_ = inst_word;
  if ((inst_word_ & 0x3) == 3) {
    opcode_ = mpact::sim::riscv::encoding64::DecodeRiscV64GVInst32(inst_word_);
    return;
  }

  opcode_ = mpact::sim::riscv::encoding64::DecodeRiscVCInst16(
      static_cast<uint16_t>(inst_word_ & 0xffff));
}

void RiscV64GVecEncoding::InitializeComplexResourceOperandGetters() {
  complex_resource_getters_.insert(
      std::make_pair(static_cast<int>(ComplexResourceEnum::kNone),
                     [](int begin, int end) { return nullptr; }));
}

ResourceOperandInterface* RiscV64GVecEncoding::GetComplexResourceOperand(
    SlotEnum, int, OpcodeEnum, ComplexResourceEnum resource, int begin,
    int end) {
  int index = static_cast<int>(resource);
  auto iter = complex_resource_getters_.find(index);
  if (iter == complex_resource_getters_.end()) {
    LOG(WARNING) << "No complex resource getter found for resource: " << index;
    return nullptr;
  }
  return (iter->second)(begin, end);
}

void RiscV64GVecEncoding::InitializeSimpleResourceGetters() {
  simple_resource_getters_.insert(std::make_pair(
      static_cast<int>(SimpleResourceEnum::kNone), []() { return nullptr; }));
  simple_resource_getters_.insert(std::make_pair(
      static_cast<int>(SimpleResourceEnum::kC3drd),
      [this]() -> generic::SimpleResource* {
        int num = encoding64::inst16_format::ExtractClRd(inst_word_);
        return resource_pool_->GetOrAddResource(absl::StrCat("d", num));
      }));
  simple_resource_getters_.insert(std::make_pair(
      static_cast<int>(SimpleResourceEnum::kC3drs2),
      [this]() -> generic::SimpleResource* {
        int num = encoding64::inst16_format::ExtractCsRs2(inst_word_);
        return resource_pool_->GetOrAddResource(absl::StrCat("d", num));
      }));
  simple_resource_getters_.insert(std::make_pair(
      static_cast<int>(SimpleResourceEnum::kC3rd),
      [this]() -> generic::SimpleResource* {
        int num = encoding64::inst16_format::ExtractClRd(inst_word_);
        // If num is 0 it refers to the zero register. No resource.
        if (num == 0) return nullptr;
        return resource_pool_->GetOrAddResource(absl::StrCat("x", num));
      }));
  simple_resource_getters_.insert(std::make_pair(
      static_cast<int>(SimpleResourceEnum::kC3rs1),
      [this]() -> generic::SimpleResource* {
        int num = encoding64::inst16_format::ExtractClRs1(inst_word_);
        // If num is 0 it refers to the zero register. No resource.
        if (num == 0) return nullptr;
        return resource_pool_->GetOrAddResource(absl::StrCat("x", num));
      }));
  simple_resource_getters_.insert(std::make_pair(
      static_cast<int>(SimpleResourceEnum::kC3rs2),
      [this]() -> generic::SimpleResource* {
        int num = encoding64::inst16_format::ExtractCsRs2(inst_word_);
        // If num is 0 it refers to the zero register. No resource.
        if (num == 0) return nullptr;
        return resource_pool_->GetOrAddResource(absl::StrCat("x", num));
      }));
  simple_resource_getters_.insert(std::make_pair(
      static_cast<int>(SimpleResourceEnum::kCdrs2),
      [this]() -> generic::SimpleResource* {
        auto num = encoding64::c_r::ExtractRs2(inst_word_);
        return resource_pool_->GetOrAddResource(absl::StrCat("d", num));
      }));
  simple_resource_getters_.insert(std::make_pair(
      static_cast<int>(SimpleResourceEnum::kCrs1),
      [this]() -> generic::SimpleResource* {
        auto num = encoding64::c_r::ExtractRs1(inst_word_);
        // If num is 0 it refers to the zero register. No resource.
        if (num == 0) return nullptr;
        return resource_pool_->GetOrAddResource(absl::StrCat("x", num));
      }));
  simple_resource_getters_.insert(std::make_pair(
      static_cast<int>(SimpleResourceEnum::kCrs2),
      [this]() -> generic::SimpleResource* {
        auto num = encoding64::c_r::ExtractRs2(inst_word_);
        // If num is 0 it refers to the zero register. No resource.
        if (num == 0) return nullptr;
        return resource_pool_->GetOrAddResource(absl::StrCat("x", num));
      }));
  simple_resource_getters_.insert(
      std::make_pair(static_cast<int>(SimpleResourceEnum::kCsr),
                     [this]() -> generic::SimpleResource* {
                       return resource_pool_->GetOrAddResource("csr");
                     }));
  simple_resource_getters_.insert(std::make_pair(
      static_cast<int>(SimpleResourceEnum::kDrd),
      [this]() -> generic::SimpleResource* {
        auto num = encoding64::r4_type::ExtractRd(inst_word_);
        return resource_pool_->GetOrAddResource(absl::StrCat("d", num));
      }));
  simple_resource_getters_.insert(std::make_pair(
      static_cast<int>(SimpleResourceEnum::kDrs1),
      [this]() -> generic::SimpleResource* {
        auto num = encoding64::a_type::ExtractRs1(inst_word_);
        return resource_pool_->GetOrAddResource(absl::StrCat("d", num));
      }));
  simple_resource_getters_.insert(std::make_pair(
      static_cast<int>(SimpleResourceEnum::kDrs2),
      [this]() -> generic::SimpleResource* {
        auto num = encoding64::a_type::ExtractRs2(inst_word_);
        return resource_pool_->GetOrAddResource(absl::StrCat("d", num));
      }));
  simple_resource_getters_.insert(std::make_pair(
      static_cast<int>(SimpleResourceEnum::kDrs3),
      [this]() -> generic::SimpleResource* {
        auto num = encoding64::r4_type::ExtractRs3(inst_word_);
        return resource_pool_->GetOrAddResource(absl::StrCat("d", num));
      }));
  simple_resource_getters_.insert(std::make_pair(
      static_cast<int>(SimpleResourceEnum::kFrd),
      [this]() -> generic::SimpleResource* {
        auto num = encoding64::r4_type::ExtractRd(inst_word_);
        return resource_pool_->GetOrAddResource(absl::StrCat("d", num));
      }));
  simple_resource_getters_.insert(std::make_pair(
      static_cast<int>(SimpleResourceEnum::kFrs1),
      [this]() -> generic::SimpleResource* {
        auto num = encoding64::r4_type::ExtractRs1(inst_word_);
        return resource_pool_->GetOrAddResource(absl::StrCat("d", num));
      }));
  simple_resource_getters_.insert(std::make_pair(
      static_cast<int>(SimpleResourceEnum::kFrs2),
      [this]() -> generic::SimpleResource* {
        auto num = encoding64::r4_type::ExtractRs2(inst_word_);
        return resource_pool_->GetOrAddResource(absl::StrCat("d", num));
      }));
  simple_resource_getters_.insert(std::make_pair(
      static_cast<int>(SimpleResourceEnum::kFrs3),
      [this]() -> generic::SimpleResource* {
        auto num = encoding64::r4_type::ExtractRs3(inst_word_);
        return resource_pool_->GetOrAddResource(absl::StrCat("d", num));
      }));
  simple_resource_getters_.insert(
      std::make_pair(static_cast<int>(SimpleResourceEnum::kNextPc),
                     [this]() -> generic::SimpleResource* {
                       return resource_pool_->GetOrAddResource("next_pc");
                     }));
  simple_resource_getters_.insert(std::make_pair(
      static_cast<int>(SimpleResourceEnum::kRd),
      [this]() -> generic::SimpleResource* {
        auto num = encoding64::a_type::ExtractRd(inst_word_);
        // If num is 0 it refers to the zero register. No resource.
        if (num == 0) return nullptr;
        return resource_pool_->GetOrAddResource(absl::StrCat("x", num));
      }));
  simple_resource_getters_.insert(std::make_pair(
      static_cast<int>(SimpleResourceEnum::kRs1),
      [this]() -> generic::SimpleResource* {
        auto num = encoding64::a_type::ExtractRs1(inst_word_);
        // If num is 0 it refers to the zero register. No resource.
        if (num == 0) return nullptr;
        return resource_pool_->GetOrAddResource(absl::StrCat("x", num));
      }));
  simple_resource_getters_.insert(std::make_pair(
      static_cast<int>(SimpleResourceEnum::kRs2),
      [this]() -> generic::SimpleResource* {
        auto num = encoding64::a_type::ExtractRs2(inst_word_);
        // If num is 0 it refers to the zero register. No resource.
        if (num == 0) return nullptr;
        return resource_pool_->GetOrAddResource(absl::StrCat("x", num));
      }));
  // X0 is constant 0, so no resource issue.
  simple_resource_getters_.insert(
      std::make_pair(static_cast<int>(SimpleResourceEnum::kX0),
                     []() -> generic::SimpleResource* { return nullptr; }));
  simple_resource_getters_.insert(
      std::make_pair(static_cast<int>(SimpleResourceEnum::kX1),
                     [this]() -> generic::SimpleResource* {
                       return resource_pool_->GetOrAddResource("x1");
                     }));
  simple_resource_getters_.insert(
      std::make_pair(static_cast<int>(SimpleResourceEnum::kX2),
                     [this]() -> generic::SimpleResource* {
                       return resource_pool_->GetOrAddResource("x2");
                     }));
}

ResourceOperandInterface* RiscV64GVecEncoding::GetSimpleResourceOperand(
    SlotEnum, int, OpcodeEnum, SimpleResourceVector& resource_vec, int end) {
  if (resource_vec.empty()) return nullptr;
  auto* resource_set = resource_pool_->CreateResourceSet();
  for (auto resource_enum : resource_vec) {
    int index = static_cast<int>(resource_enum);
    auto iter = simple_resource_getters_.find(index);
    if (iter == simple_resource_getters_.end()) {
      LOG(WARNING) << "No getter for simple resource " << index;
      continue;
    }
    auto* resource = (iter->second)();
    auto status = resource_set->AddResource(resource);
    if (!status.ok()) {
      LOG(ERROR) << "Unable to add resource to resource set ("
                 << static_cast<int>(resource_enum) << ")";
    }
  }
  auto* op = new SimpleResourceOperand(resource_set, end, resource_delay_line_);
  return op;
}

DestinationOperandInterface* RiscV64GVecEncoding::GetDestination(
    SlotEnum, int, OpcodeEnum, DestOpEnum dest_op, int dest_no, int latency) {
  int index = static_cast<int>(dest_op);
  auto iter = dest_op_getters_.find(index);
  if (iter == dest_op_getters_.end()) {
    LOG(ERROR) << "No getter for destination op " << index;
    return nullptr;
  }
  return (iter->second)(latency);
}

SourceOperandInterface* RiscV64GVecEncoding::GetSource(SlotEnum, int,
                                                       OpcodeEnum,
                                                       SourceOpEnum source_op,
                                                       int source_no) {
  int index = static_cast<int>(source_op);
  auto iter = source_op_getters_.find(index);
  if (iter == source_op_getters_.end()) {
    LOG(ERROR) << "No getter for source op " << index;
    return nullptr;
  }
  return (iter->second)();
}

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