// 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,
                         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.
  int num_regs = kNumRegTable[reg_num % 8];
  for (int i = 0; i < num_regs; 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, &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, &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::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);
         });
}

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