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

#ifndef MPACT_CHERIOT_CHERIOT_GETTERS_H_
#define MPACT_CHERIOT_CHERIOT_GETTERS_H_

#include <cstdint>
#include <string>

#include "absl/container/flat_hash_map.h"
#include "absl/functional/any_invocable.h"
#include "absl/strings/str_cat.h"
#include "cheriot/cheriot_getter_helpers.h"
#include "cheriot/cheriot_register.h"
#include "cheriot/cheriot_state.h"
#include "cheriot/riscv_cheriot_encoding_common.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/operand_interface.h"

namespace mpact {
namespace sim {
namespace cheriot {

using ::mpact::sim::cheriot::RiscVCheriotEncodingCommon;
using ::mpact::sim::generic::DestinationOperandInterface;
using ::mpact::sim::generic::ImmediateOperand;
using ::mpact::sim::generic::IntLiteralOperand;
using ::mpact::sim::generic::SourceOperandInterface;

using SourceOpGetterMap =
    absl::flat_hash_map<int, absl::AnyInvocable<SourceOperandInterface *()>>;
using DestOpGetterMap =
    absl::flat_hash_map<int,
                        absl::AnyInvocable<DestinationOperandInterface *(int)>>;

template <typename Enum, typename Extractors>
void AddCheriotSourceGetters(SourceOpGetterMap &getter_map,
                             RiscVCheriotEncodingCommon *common) {
  // Source operand getters.
  Insert(getter_map, *Enum::kAAq, [common]() -> SourceOperandInterface * {
    if (Extractors::Inst32Format::ExtractAq(common->inst_word())) {
      return new IntLiteralOperand<1>();
    }
    return new IntLiteralOperand<0>();
  });
  Insert(getter_map, *Enum::kARl, [common]() -> SourceOperandInterface * {
    if (Extractors::Inst32Format::ExtractRl(common->inst_word())) {
      return new generic::IntLiteralOperand<1>();
    }
    return new generic::IntLiteralOperand<0>();
  });
  Insert(getter_map, *Enum::kBImm12, [common]() {
    return new ImmediateOperand<int32_t>(
        Extractors::Inst32Format::ExtractBImm(common->inst_word()));
  });
  Insert(getter_map, *Enum::kC2, [common]() {
    return GetRegisterSourceOp<CheriotRegister>(common->state(), "c2", "csp");
  });
  Insert(getter_map, *Enum::kC3cs1, [common]() {
    auto num = Extractors::CS::ExtractRs1(common->inst_word());
    return GetRegisterSourceOp<CheriotRegister>(
        common->state(), absl::StrCat(CheriotState::kCregPrefix, num),
        kCRegisterAliases[num]);
  });
  Insert(getter_map, *Enum::kC3cs2, [common]() {
    auto num = Extractors::CS::ExtractRs2(common->inst_word());
    return GetRegisterSourceOp<CheriotRegister>(
        common->state(), absl::StrCat(CheriotState::kCregPrefix, num),
        kCRegisterAliases[num]);
  });
  Insert(getter_map, *Enum::kC3rs1, [common]() {
    auto num = Extractors::CS::ExtractRs1(common->inst_word());
    return GetRegisterSourceOp<CheriotRegister>(
        common->state(), absl::StrCat(CheriotState::kXregPrefix, num),
        kXRegisterAliases[num]);
  });
  Insert(getter_map, *Enum::kC3rs2, [common]() {
    auto num = Extractors::CS::ExtractRs2(common->inst_word());
    return GetRegisterSourceOp<CheriotRegister>(
        common->state(), absl::StrCat(CheriotState::kXregPrefix, num),
        kXRegisterAliases[num]);
  });
  Insert(getter_map, *Enum::kCcs2, [common]() {
    auto num = Extractors::CSS::ExtractRs2(common->inst_word());
    return GetRegisterSourceOp<CheriotRegister>(
        common->state(), absl::StrCat(CheriotState::kCregPrefix, num),
        kCRegisterAliases[num]);
  });
  Insert(getter_map, *Enum::kCgp, [common]() {
    return GetRegisterSourceOp<CheriotRegister>(common->state(), "c3", "c3");
  });
  Insert(getter_map, *Enum::kCSRUimm5, [common]() {
    return new ImmediateOperand<uint32_t>(
        Extractors::Inst32Format::ExtractIUimm5(common->inst_word()));
  });
  Insert(getter_map, *Enum::kCrs1, [common]() {
    auto num = Extractors::CR::ExtractRs1(common->inst_word());
    return GetRegisterSourceOp<CheriotRegister>(
        common->state(), absl::StrCat(CheriotState::kXregPrefix, num),
        kXRegisterAliases[num]);
  });
  Insert(getter_map, *Enum::kCrs2, [common]() {
    auto num = Extractors::CR::ExtractRs2(common->inst_word());
    return GetRegisterSourceOp<CheriotRegister>(
        common->state(), absl::StrCat(CheriotState::kXregPrefix, num),
        kXRegisterAliases[num]);
  });
  Insert(getter_map, *Enum::kCs1, [common]() {
    auto num = Extractors::RType::ExtractRs1(common->inst_word());
    return GetRegisterSourceOp<CheriotRegister>(
        common->state(), absl::StrCat(CheriotState::kCregPrefix, num),
        kCRegisterAliases[num]);
  });
  Insert(getter_map, *Enum::kCs2, [common]() {
    auto num = Extractors::RType::ExtractRs2(common->inst_word());
    return GetRegisterSourceOp<CheriotRegister>(
        common->state(), absl::StrCat(CheriotState::kCregPrefix, num),
        kCRegisterAliases[num]);
  });
  Insert(getter_map, *Enum::kCsr, [common]() {
    auto csr_indx = Extractors::IType::ExtractUImm12(common->inst_word());
    auto res = common->state()->csr_set()->GetCsr(csr_indx);
    if (!res.ok()) {
      return new ImmediateOperand<uint32_t>(csr_indx);
    }
    auto *csr = res.value();
    return new ImmediateOperand<uint32_t>(csr_indx, csr->name());
  });
  Insert(getter_map, *Enum::kICbImm8, [common]() {
    return new ImmediateOperand<int32_t>(
        Extractors::Inst16Format::ExtractBimm(common->inst_word()));
  });
  Insert(getter_map, *Enum::kICiImm6, [common]() {
    return new ImmediateOperand<int32_t>(
        Extractors::CI::ExtractImm6(common->inst_word()));
  });
  Insert(getter_map, *Enum::kICiImm612, [common]() {
    return new ImmediateOperand<int32_t>(
        Extractors::Inst16Format::ExtractImm18(common->inst_word()));
  });
  Insert(getter_map, *Enum::kICiUimm6, [common]() {
    return new ImmediateOperand<uint32_t>(
        Extractors::Inst16Format::ExtractUimm6(common->inst_word()));
  });
  Insert(getter_map, *Enum::kICiUimm6x4, [common]() {
    return new ImmediateOperand<uint32_t>(
        Extractors::Inst16Format::ExtractCiImmW(common->inst_word()));
  });
  Insert(getter_map, *Enum::kICiImm6x16, [common]() {
    return new ImmediateOperand<int32_t>(
        Extractors::Inst16Format::ExtractCiImm10(common->inst_word()));
  });
  Insert(getter_map, *Enum::kICiUimm6x8, [common]() {
    return new ImmediateOperand<uint32_t>(
        Extractors::Inst16Format::ExtractCiImmD(common->inst_word()));
  });
  Insert(getter_map, *Enum::kICiwUimm8x4, [common]() {
    return new ImmediateOperand<uint32_t>(
        Extractors::Inst16Format::ExtractCiwImm10(common->inst_word()));
  });
  Insert(getter_map, *Enum::kICjImm11, [common]() {
    return new ImmediateOperand<int32_t>(
        Extractors::Inst16Format::ExtractJimm(common->inst_word()));
  });
  Insert(getter_map, *Enum::kIClUimm5x4, [common]() {
    return new ImmediateOperand<uint32_t>(
        Extractors::Inst16Format::ExtractClImmW(common->inst_word()));
  });
  Insert(getter_map, *Enum::kIClUimm5x8, [common]() {
    return new ImmediateOperand<uint32_t>(
        Extractors::Inst16Format::ExtractClImmD(common->inst_word()));
  });
  Insert(getter_map, *Enum::kICshUimm6, [common]() {
    return new ImmediateOperand<uint32_t>(
        Extractors::CSH::ExtractUimm6(common->inst_word()));
  });
  Insert(getter_map, *Enum::kICshImm6, [common]() {
    return new ImmediateOperand<uint32_t>(
        Extractors::CSH::ExtractImm6(common->inst_word()));
  });
  Insert(getter_map, *Enum::kICssUimm6x4, [common]() {
    return new ImmediateOperand<uint32_t>(
        Extractors::Inst16Format::ExtractCssImmW(common->inst_word()));
  });
  Insert(getter_map, *Enum::kICssUimm6x8, [common]() {
    return new ImmediateOperand<uint32_t>(
        Extractors::Inst16Format::ExtractCssImmD(common->inst_word()));
  });
  Insert(getter_map, *Enum::kIImm12, [common]() {
    return new ImmediateOperand<int32_t>(
        Extractors::Inst32Format::ExtractImm12(common->inst_word()));
  });
  Insert(getter_map, *Enum::kIUimm5, [common]() {
    return new ImmediateOperand<uint32_t>(
        Extractors::I5Type::ExtractRUimm5(common->inst_word()));
  });
  Insert(getter_map, *Enum::kIUimm12, [common]() {
    return new ImmediateOperand<uint32_t>(
        Extractors::Inst32Format::ExtractUImm12(common->inst_word()));
  });
  Insert(getter_map, *Enum::kJImm12, [common]() {
    return new ImmediateOperand<int32_t>(
        Extractors::Inst32Format::ExtractImm12(common->inst_word()));
  });
  Insert(getter_map, *Enum::kJImm20, [common]() {
    return new ImmediateOperand<int32_t>(
        Extractors::Inst32Format::ExtractJImm(common->inst_word()));
  });
  Insert(getter_map, *Enum::kPcc, [common]() {
    return GetRegisterSourceOp<CheriotRegister>(common->state(), "pcc", "pcc");
  });
  Insert(getter_map, *Enum::kRd, [common]() -> SourceOperandInterface * {
    int num = Extractors::RType::ExtractRd(common->inst_word());
    if (num == 0) return new generic::IntLiteralOperand<0>({1});
    return GetRegisterSourceOp<CheriotRegister>(
        common->state(), absl::StrCat(CheriotState::kXregPrefix, num),
        kXRegisterAliases[num]);
  });
  Insert(getter_map, *Enum::kRs1, [common]() -> SourceOperandInterface * {
    int num = Extractors::RType::ExtractRs1(common->inst_word());
    if (num == 0) return new generic::IntLiteralOperand<0>({1});
    return GetRegisterSourceOp<CheriotRegister>(
        common->state(), absl::StrCat(CheriotState::kXregPrefix, num),
        kXRegisterAliases[num]);
  });
  Insert(getter_map, *Enum::kRs2, [common]() -> SourceOperandInterface * {
    int num = Extractors::RType::ExtractRs2(common->inst_word());
    if (num == 0) return new generic::IntLiteralOperand<0>({1});
    return GetRegisterSourceOp<CheriotRegister>(
        common->state(), absl::StrCat(CheriotState::kXregPrefix, num),
        kXRegisterAliases[num]);
  });
  Insert(getter_map, *Enum::kSImm12, [common]() {
    return new ImmediateOperand<int32_t>(
        Extractors::SType::ExtractSImm(common->inst_word()));
  });
  Insert(getter_map, *Enum::kScr, [common]() -> SourceOperandInterface * {
    int csr_indx = Extractors::RType::ExtractRs2(common->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 = common->state()->csr_set()->GetCsr(csr_name);
    if (!res.ok()) {
      return GetRegisterSourceOp<CheriotRegister>(common->state(), csr_name,
                                                  csr_name);
    }
    auto *csr = res.value();
    auto *op = csr->CreateSourceOperand();
    return op;
  });
  Insert(getter_map, *Enum::kSImm20, [common]() {
    return new ImmediateOperand<int32_t>(
        Extractors::UType::ExtractSImm(common->inst_word()));
  });
  Insert(getter_map, *Enum::kUImm20, [common]() {
    return new ImmediateOperand<int32_t>(
        Extractors::Inst32Format::ExtractUImm(common->inst_word()));
  });
  Insert(getter_map, *Enum::kX0,
         []() { return new generic::IntLiteralOperand<0>({1}); });
  Insert(getter_map, *Enum::kX2, [common]() {
    return GetRegisterSourceOp<CheriotRegister>(
        common->state(), absl::StrCat(CheriotState::kXregPrefix, 2),
        kXRegisterAliases[2]);
  });
}

template <typename Enum, typename Extractors>
void AddCheriotDestGetters(DestOpGetterMap &getter_map,
                           RiscVCheriotEncodingCommon *common) {
  // Destination operand getters.
  Insert(getter_map, *Enum::kC2, [common](int latency) {
    return GetRegisterDestinationOp<CheriotRegister>(common->state(), "c2",
                                                     latency, "csp");
  });
  Insert(getter_map, *Enum::kC3cd, [common](int latency) {
    int num = Extractors::CL::ExtractRd(common->inst_word());
    return GetRegisterDestinationOp<CheriotRegister>(
        common->state(), absl::StrCat(CheriotState::kCregPrefix, num), latency,
        kCRegisterAliases[num]);
  });
  Insert(getter_map, *Enum::kC3rd, [common](int latency) {
    int num = Extractors::CL::ExtractRd(common->inst_word());
    if (num == 0) {
      return GetRegisterDestinationOp<CheriotRegister>(common->state(),
                                                       "X0Dest", latency);
    }
    return GetRegisterDestinationOp<CheriotRegister>(
        common->state(), absl::StrCat(CheriotState::kXregPrefix, num), latency,
        kXRegisterAliases[num]);
  });
  Insert(getter_map, *Enum::kC3rs1, [common](int latency) {
    int num = Extractors::CL::ExtractRs1(common->inst_word());
    return GetRegisterDestinationOp<CheriotRegister>(
        common->state(), absl::StrCat(CheriotState::kXregPrefix, num), latency,
        kXRegisterAliases[num]);
  });
  Insert(getter_map, *Enum::kCd, [common](int latency) {
    int num = Extractors::RType::ExtractRd(common->inst_word());
    if (num == 0) {
      return GetRegisterDestinationOp<CheriotRegister>(common->state(),
                                                       "X0Dest", latency);
    }
    return GetRegisterDestinationOp<CheriotRegister>(
        common->state(), absl::StrCat(CheriotState::kCregPrefix, num), latency,
        kCRegisterAliases[num]);
  });
  Insert(getter_map, *Enum::kCsr, [common](int latency) {
    return GetRegisterDestinationOp<CheriotRegister>(
        common->state(), CheriotState::kCsrName, latency);
  });
  Insert(getter_map, *Enum::kScr,
         [common](int latency) -> DestinationOperandInterface * {
           int csr_indx = Extractors::RType::ExtractRs2(common->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 = common->state()->csr_set()->GetCsr(csr_name);
           if (!res.ok()) {
             return GetRegisterDestinationOp<CheriotRegister>(
                 common->state(), csr_name, latency);
           }
           auto *csr = res.value();
           auto *op = csr->CreateWriteDestinationOperand(latency, csr_name);
           return op;
         });
  Insert(getter_map, *Enum::kRd,
         [common](int latency) -> DestinationOperandInterface * {
           int num = Extractors::RType::ExtractRd(common->inst_word());
           if (num == 0) {
             return GetRegisterDestinationOp<CheriotRegister>(common->state(),
                                                              "X0Dest", 0);
           } else {
             return GetRegisterDestinationOp<CheriotRegister>(
                 common->state(), absl::StrCat(CheriotState::kXregPrefix, num),
                 latency, kXRegisterAliases[num]);
           }
         });
  Insert(getter_map, *Enum::kX1, [common](int latency) {
    return GetRegisterDestinationOp<CheriotRegister>(
        common->state(), absl::StrCat(CheriotState::kXregPrefix, 1), latency,
        kXRegisterAliases[1]);
  });
}

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

#endif  // MPACT_CHERIOT_CHERIOT_GETTERS_H_
