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

#include "cheriot/riscv_cheriot_encoding.h"

#include <cstdint>
#include <string>

#include "absl/log/log.h"
#include "absl/strings/str_cat.h"
#include "cheriot/cheriot_register.h"
#include "cheriot/cheriot_state.h"
#include "cheriot/riscv_cheriot_bin_decoder.h"
#include "cheriot/riscv_cheriot_decoder.h"
#include "cheriot/riscv_cheriot_enums.h"
#include "cheriot/riscv_cheriot_register_aliases.h"
#include "mpact/sim/generic/immediate_operand.h"
#include "mpact/sim/generic/literal_operand.h"
#include "mpact/sim/generic/type_helpers.h"
#include "riscv//riscv_register.h"

namespace mpact {
namespace sim {
namespace cheriot {
namespace isa32 {

using ::mpact::sim::generic::operator*;  // NOLINT: is used below (clang error).
using ::mpact::sim::riscv::RVFpRegister;

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

template <typename RegType>
inline DestinationOperandInterface *GetRegisterDestinationOp(
    CheriotState *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(
    CheriotState *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(CheriotState *state,
                                                   std::string name) {
  auto *reg = state->GetRegister<RegType>(name).first;
  auto *op = reg->CreateSourceOperand();
  return op;
}

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

RiscVCheriotEncoding::RiscVCheriotEncoding(CheriotState *state)
    : state_(state) {
  InitializeSourceOperandGetters();
  InitializeDestinationOperandGetters();
}

void RiscVCheriotEncoding::InitializeSourceOperandGetters() {
  // Source operand getters.
  source_op_getters_.emplace(
      *SourceOpEnum::kAAq, [this]() -> SourceOperandInterface * {
        if (encoding::inst32_format::ExtractAq(inst_word_)) {
          return new generic::IntLiteralOperand<1>();
        }
        return new generic::IntLiteralOperand<0>();
      });
  source_op_getters_.emplace(
      *SourceOpEnum::kARl, [this]() -> SourceOperandInterface * {
        if (encoding::inst32_format::ExtractRl(inst_word_)) {
          return new generic::IntLiteralOperand<1>();
        }
        return new generic::IntLiteralOperand<0>();
      });
  source_op_getters_.emplace(*SourceOpEnum::kBImm12, [this]() {
    return new generic::ImmediateOperand<int32_t>(
        encoding::inst32_format::ExtractBImm(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kC2, [this]() {
    return GetRegisterSourceOp<CheriotRegister>(state_, "c2", "csp");
  });
  source_op_getters_.emplace(*SourceOpEnum::kC3cs1, [this]() {
    auto num = encoding::c_s::ExtractRs1(inst_word_);
    return GetRegisterSourceOp<CheriotRegister>(
        state_, absl::StrCat(CheriotState::kCregPrefix, num),
        kCRegisterAliases[num]);
  });
  source_op_getters_.emplace(*SourceOpEnum::kC3cs2, [this]() {
    auto num = encoding::c_s::ExtractRs2(inst_word_);
    return GetRegisterSourceOp<CheriotRegister>(
        state_, absl::StrCat(CheriotState::kCregPrefix, num),
        kCRegisterAliases[num]);
  });
  source_op_getters_.emplace(*SourceOpEnum::kC3rs1, [this]() {
    auto num = encoding::c_s::ExtractRs1(inst_word_);
    return GetRegisterSourceOp<CheriotRegister>(
        state_, absl::StrCat(CheriotState::kXregPrefix, num),
        kXRegisterAliases[num]);
  });
  source_op_getters_.emplace(*SourceOpEnum::kC3rs2, [this]() {
    auto num = encoding::c_s::ExtractRs2(inst_word_);
    return GetRegisterSourceOp<CheriotRegister>(
        state_, absl::StrCat(CheriotState::kXregPrefix, num),
        kXRegisterAliases[num]);
  });
  source_op_getters_.emplace(*SourceOpEnum::kCcs2, [this]() {
    auto num = encoding::c_s_s::ExtractRs2(inst_word_);
    return GetRegisterSourceOp<CheriotRegister>(
        state_, absl::StrCat(CheriotState::kCregPrefix, num),
        kCRegisterAliases[num]);
  });
  source_op_getters_.emplace(*SourceOpEnum::kCgp, [this]() {
    return GetRegisterSourceOp<CheriotRegister>(state_, "c3", "c3");
  });
  source_op_getters_.emplace(*SourceOpEnum::kCSRUimm5, [this]() {
    return new generic::ImmediateOperand<uint32_t>(
        encoding::inst32_format::ExtractIUimm5(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kCfrs2, [this]() {
    auto num = encoding::c_r::ExtractRs2(inst_word_);
    return GetRegisterSourceOp<RVFpRegister>(
        state_, absl::StrCat(CheriotState::kFregPrefix, num),
        kFRegisterAliases[num]);
  });
  source_op_getters_.emplace(*SourceOpEnum::kCrs1, [this]() {
    auto num = encoding::c_r::ExtractRs1(inst_word_);
    return GetRegisterSourceOp<CheriotRegister>(
        state_, absl::StrCat(CheriotState::kXregPrefix, num),
        kXRegisterAliases[num]);
  });
  source_op_getters_.emplace(*SourceOpEnum::kCrs2, [this]() {
    auto num = encoding::c_r::ExtractRs2(inst_word_);
    return GetRegisterSourceOp<CheriotRegister>(
        state_, absl::StrCat(CheriotState::kXregPrefix, num),
        kXRegisterAliases[num]);
  });
  source_op_getters_.emplace(*SourceOpEnum::kCs1, [this]() {
    auto num = encoding::r_type::ExtractRs1(inst_word_);
    return GetRegisterSourceOp<CheriotRegister>(
        state_, absl::StrCat(CheriotState::kCregPrefix, num),
        kCRegisterAliases[num]);
  });
  source_op_getters_.emplace(*SourceOpEnum::kCs2, [this]() {
    auto num = encoding::r_type::ExtractRs2(inst_word_);
    return GetRegisterSourceOp<CheriotRegister>(
        state_, absl::StrCat(CheriotState::kCregPrefix, num),
        kCRegisterAliases[num]);
  });
  source_op_getters_.emplace(*SourceOpEnum::kCsr, [this]() {
    auto csr_indx = encoding::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_.emplace(*SourceOpEnum::kFrs1, [this]() {
    int num = encoding::r_type::ExtractRs1(inst_word_);
    return GetRegisterSourceOp<RVFpRegister>(
        state_, absl::StrCat(CheriotState::kFregPrefix, num),
        kFRegisterAliases[num]);
  });
  source_op_getters_.emplace(*SourceOpEnum::kFrs2, [this]() {
    int num = encoding::r_type::ExtractRs2(inst_word_);
    return GetRegisterSourceOp<RVFpRegister>(
        state_, absl::StrCat(CheriotState::kFregPrefix, num),
        kFRegisterAliases[num]);
  });
  source_op_getters_.emplace(*SourceOpEnum::kFrs3, [this]() {
    int num = encoding::r4_type::ExtractRs3(inst_word_);
    return GetRegisterSourceOp<RVFpRegister>(
        state_, absl::StrCat(CheriotState::kFregPrefix, num),
        kFRegisterAliases[num]);
  });
  source_op_getters_.emplace(*SourceOpEnum::kICbImm8, [this]() {
    return new generic::ImmediateOperand<int32_t>(
        encoding::inst16_format::ExtractBimm(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kICiImm6, [this]() {
    return new generic::ImmediateOperand<int32_t>(
        encoding::c_i::ExtractImm6(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kICiImm612, [this]() {
    return new generic::ImmediateOperand<int32_t>(
        encoding::inst16_format::ExtractImm18(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kICiUimm6, [this]() {
    return new generic::ImmediateOperand<uint32_t>(
        encoding::inst16_format::ExtractUimm6(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kICiUimm6x4, [this]() {
    return new generic::ImmediateOperand<uint32_t>(
        encoding::inst16_format::ExtractCiImmW(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kICiImm6x16, [this]() {
    return new generic::ImmediateOperand<int32_t>(
        encoding::inst16_format::ExtractCiImm10(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kICiUimm6x8, [this]() {
    return new generic::ImmediateOperand<uint32_t>(
        encoding::inst16_format::ExtractCiImmD(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kICiwUimm8x4, [this]() {
    return new generic::ImmediateOperand<uint32_t>(
        encoding::inst16_format::ExtractCiwImm10(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kICjImm11, [this]() {
    return new generic::ImmediateOperand<int32_t>(
        encoding::inst16_format::ExtractJimm(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kIClUimm5x4, [this]() {
    return new generic::ImmediateOperand<uint32_t>(
        encoding::inst16_format::ExtractClImmW(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kIClUimm5x8, [this]() {
    return new generic::ImmediateOperand<uint32_t>(
        encoding::inst16_format::ExtractClImmD(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kICshUimm6, [this]() {
    return new generic::ImmediateOperand<uint32_t>(
        encoding::c_s_h::ExtractUimm6(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kICshImm6, [this]() {
    return new generic::ImmediateOperand<uint32_t>(
        encoding::c_s_h::ExtractImm6(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kICssUimm6x4, [this]() {
    return new generic::ImmediateOperand<uint32_t>(
        encoding::inst16_format::ExtractCssImmW(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kICssUimm6x8, [this]() {
    return new generic::ImmediateOperand<uint32_t>(
        encoding::inst16_format::ExtractCssImmD(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kIImm12, [this]() {
    return new generic::ImmediateOperand<int32_t>(
        encoding::inst32_format::ExtractImm12(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kIUimm5, [this]() {
    return new generic::ImmediateOperand<uint32_t>(
        encoding::i5_type::ExtractRUimm5(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kIUimm12, [this]() {
    return new generic::ImmediateOperand<uint32_t>(
        encoding::inst32_format::ExtractUImm12(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kJImm12, [this]() {
    return new generic::ImmediateOperand<int32_t>(
        encoding::inst32_format::ExtractImm12(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kJImm20, [this]() {
    return new generic::ImmediateOperand<int32_t>(
        encoding::inst32_format::ExtractJImm(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kPcc, [this]() {
    return GetRegisterSourceOp<CheriotRegister>(state_, "pcc", "pcc");
  });
  source_op_getters_.emplace(*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_.emplace(
      *SourceOpEnum::kRd, [this]() -> SourceOperandInterface * {
        int num = encoding::r_type::ExtractRd(inst_word_);
        if (num == 0) return new generic::IntLiteralOperand<0>({1});
        return GetRegisterSourceOp<CheriotRegister>(
            state_, absl::StrCat(CheriotState::kXregPrefix, num),
            kXRegisterAliases[num]);
      });
  source_op_getters_.emplace(
      *SourceOpEnum::kRs1, [this]() -> SourceOperandInterface * {
        int num = encoding::r_type::ExtractRs1(inst_word_);
        if (num == 0) return new generic::IntLiteralOperand<0>({1});
        return GetRegisterSourceOp<CheriotRegister>(
            state_, absl::StrCat(CheriotState::kXregPrefix, num),
            kXRegisterAliases[num]);
      });
  source_op_getters_.emplace(
      *SourceOpEnum::kRs2, [this]() -> SourceOperandInterface * {
        int num = encoding::r_type::ExtractRs2(inst_word_);
        if (num == 0) return new generic::IntLiteralOperand<0>({1});
        return GetRegisterSourceOp<CheriotRegister>(
            state_, absl::StrCat(CheriotState::kXregPrefix, num),
            kXRegisterAliases[num]);
      });
  source_op_getters_.emplace(*SourceOpEnum::kSImm12, [this]() {
    return new generic::ImmediateOperand<int32_t>(
        encoding::s_type::ExtractSImm(inst_word_));
  });
  source_op_getters_.emplace(
      *SourceOpEnum::kScr, [this]() -> SourceOperandInterface * {
        int csr_indx = encoding::r_type::ExtractRs2(inst_word_);
        std::string csr_name;
        switch (csr_indx) {
          case 28:
            csr_name = "mtcc";
            break;
          case 29:
            csr_name = "mtdc";
            break;
          case 30:
            csr_name = "mscratchc";
            break;
          case 31:
            csr_name = "mepcc";
            break;
          default:
            return nullptr;
        }
        auto res = state_->csr_set()->GetCsr(csr_name);
        if (!res.ok()) {
          return GetRegisterSourceOp<CheriotRegister>(state_, csr_name,
                                                      csr_name);
        }
        auto *csr = res.value();
        auto *op = csr->CreateSourceOperand();
        return op;
      });
  source_op_getters_.emplace(*SourceOpEnum::kSImm20, [this]() {
    return new generic::ImmediateOperand<int32_t>(
        encoding::u_type::ExtractSImm(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kUImm20, [this]() {
    return new generic::ImmediateOperand<int32_t>(
        encoding::inst32_format::ExtractUImm(inst_word_));
  });
  source_op_getters_.emplace(*SourceOpEnum::kX0, []() {
    return new generic::IntLiteralOperand<0>({1});
  });
  source_op_getters_.emplace(*SourceOpEnum::kX2, [this]() {
    return GetRegisterSourceOp<CheriotRegister>(
        state_, absl::StrCat(CheriotState::kXregPrefix, 2),
        kXRegisterAliases[2]);
  });
  source_op_getters_.emplace(*SourceOpEnum::kNone, []() { return nullptr; });
}

void RiscVCheriotEncoding::InitializeDestinationOperandGetters() {
  // Destination operand getters.
  dest_op_getters_.emplace(*DestOpEnum::kC2, [this](int latency) {
    return GetRegisterDestinationOp<CheriotRegister>(state_, "c2", latency,
                                                     "csp");
  });
  dest_op_getters_.emplace(*DestOpEnum::kC3cd, [this](int latency) {
    int num = encoding::c_l::ExtractRd(inst_word_);
    return GetRegisterDestinationOp<CheriotRegister>(
        state_, absl::StrCat(CheriotState::kCregPrefix, num), latency,
        kCRegisterAliases[num]);
  });
  dest_op_getters_.emplace(*DestOpEnum::kC3rd, [this](int latency) {
    int num = encoding::c_l::ExtractRd(inst_word_);
    if (num == 0) {
      return GetRegisterDestinationOp<CheriotRegister>(state_, "X0Dest",
                                                       latency);
    }
    return GetRegisterDestinationOp<CheriotRegister>(
        state_, absl::StrCat(CheriotState::kXregPrefix, num), latency,
        kXRegisterAliases[num]);
  });
  dest_op_getters_.emplace(*DestOpEnum::kC3rs1, [this](int latency) {
    int num = encoding::c_l::ExtractRs1(inst_word_);
    return GetRegisterDestinationOp<CheriotRegister>(
        state_, absl::StrCat(CheriotState::kXregPrefix, num), latency,
        kXRegisterAliases[num]);
  });
  dest_op_getters_.emplace(*DestOpEnum::kCd, [this](int latency) {
    int num = encoding::r_type::ExtractRd(inst_word_);
    if (num == 0) {
      return GetRegisterDestinationOp<CheriotRegister>(state_, "X0Dest",
                                                       latency);
    }
    return GetRegisterDestinationOp<CheriotRegister>(
        state_, absl::StrCat(CheriotState::kCregPrefix, num), latency,
        kCRegisterAliases[num]);
  });
  dest_op_getters_.emplace(*DestOpEnum::kCsr, [this](int latency) {
    return GetRegisterDestinationOp<CheriotRegister>(
        state_, CheriotState::kCsrName, latency);
  });
  dest_op_getters_.emplace(*DestOpEnum::kFrd, [this](int latency) {
    int num = encoding::r_type::ExtractRd(inst_word_);
    return GetRegisterDestinationOp<RVFpRegister>(
        state_, absl::StrCat(CheriotState::kFregPrefix, num), latency,
        kFRegisterAliases[num]);
  });
  dest_op_getters_.emplace(
      *DestOpEnum::kScr, [this](int latency) -> DestinationOperandInterface * {
        int csr_indx = encoding::r_type::ExtractRs2(inst_word_);
        std::string csr_name;
        switch (csr_indx) {
          case 28:
            csr_name = "mtcc";
            break;
          case 29:
            csr_name = "mtdc";
            break;
          case 30:
            csr_name = "mscratchc";
            break;
          case 31:
            csr_name = "mepcc";
            break;
          default:
            return nullptr;
        }
        auto res = state_->csr_set()->GetCsr(csr_name);
        if (!res.ok()) {
          return GetRegisterDestinationOp<CheriotRegister>(state_, csr_name,
                                                           latency);
        }
        auto *csr = res.value();
        auto *op = csr->CreateWriteDestinationOperand(latency, csr_name);
        return op;
      });
  dest_op_getters_.emplace(
      *DestOpEnum::kRd, [this](int latency) -> DestinationOperandInterface * {
        int num = encoding::r_type::ExtractRd(inst_word_);
        if (num == 0) {
          return GetRegisterDestinationOp<CheriotRegister>(state_, "X0Dest", 0);
        } else {
          return GetRegisterDestinationOp<RVFpRegister>(
              state_, absl::StrCat(CheriotState::kXregPrefix, num), latency,
              kXRegisterAliases[num]);
        }
      });
  dest_op_getters_.emplace(*DestOpEnum::kX1, [this](int latency) {
    return GetRegisterDestinationOp<CheriotRegister>(
        state_, absl::StrCat(CheriotState::kXregPrefix, 1), latency,
        kXRegisterAliases[1]);
  });
  dest_op_getters_.emplace(*DestOpEnum::kFflags, [this](int latency) {
    return GetCSRSetBitsDestinationOp<uint32_t>(state_, "fflags", latency, "");
  });
  dest_op_getters_.emplace(*DestOpEnum::kNone,
                           [](int latency) { return nullptr; });
}

// Parse the instruction word to determine the opcode.
void RiscVCheriotEncoding::ParseInstruction(uint32_t inst_word) {
  inst_word_ = inst_word;
  if ((inst_word_ & 0x3) == 3) {
    auto [opcode, format] =
        mpact::sim::cheriot::encoding::DecodeRiscVCheriotInst32WithFormat(
            inst_word_);
    opcode_ = opcode;
    format_ = format;
    return;
  }

  auto [opcode, format] =
      mpact::sim::cheriot::encoding::DecodeRiscVCheriotInst16WithFormat(
          static_cast<uint16_t>(inst_word_ & 0xffff));
  opcode_ = opcode;
  format_ = format;
}

DestinationOperandInterface *RiscVCheriotEncoding::GetDestination(
    SlotEnum, int, OpcodeEnum opcode, 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) << absl::StrCat("No getter for destination op enum value ",
                               index, " for instruction ",
                               kOpcodeNames[static_cast<int>(opcode)]);
    return nullptr;
  }
  return (iter->second)(latency);
}

SourceOperandInterface *RiscVCheriotEncoding::GetSource(SlotEnum, int,
                                                        OpcodeEnum opcode,
                                                        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) << absl::StrCat("No getter for source op enum value ", index,
                               " for instruction ",
                               kOpcodeNames[static_cast<int>(opcode)]);
    return nullptr;
  }
  return (iter->second)();
}

}  // namespace isa32
}  // namespace cheriot
}  // namespace sim
}  // namespace mpact
