// 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/cheriot_test_rig_decoder.h"

#include <cstdint>
#include <string>

#include "cheriot/cheriot_state.h"
#include "cheriot/riscv_cheriot_bin_decoder.h"
#include "cheriot/riscv_cheriot_decoder.h"
#include "cheriot/riscv_cheriot_encoding.h"
#include "cheriot/riscv_cheriot_enums.h"
#include "mpact/sim/generic/instruction.h"
#include "mpact/sim/generic/program_error.h"
#include "mpact/sim/generic/type_helpers.h"
#include "riscv//riscv_state.h"

namespace mpact {
namespace sim {
namespace cheriot {

using ::mpact::sim::cheriot::encoding::FormatEnum;
using RV_EC = ::mpact::sim::riscv::ExceptionCode;
using ::mpact::sim::cheriot::isa32::OpcodeEnum;  // NOLINT: is used below.

CheriotTestRigDecoder::CheriotTestRigDecoder(CheriotState *state)
    : state_(state) {
  // Get a handle to the internal error in the program error controller.
  decode_error_ = state->program_error_controller()->GetProgramError(
      generic::ProgramErrorController::kInternalErrorName);
  // Allocate the isa factory class, the top level isa decoder instance, and
  // the encoding parser.
  cheriot_isa_factory_ = new CheriotTestRigIsaFactory();
  cheriot_isa_ =
      new isa32::RiscVCheriotInstructionSet(state, cheriot_isa_factory_);
  cheriot_encoding_ = new isa32::RiscVCheriotEncoding(state);
}

CheriotTestRigDecoder::~CheriotTestRigDecoder() {
  delete cheriot_isa_;
  delete cheriot_encoding_;
  delete cheriot_isa_factory_;
}

generic::Instruction *CheriotTestRigDecoder::DecodeInstruction(
    uint64_t address, uint32_t inst_word, DecodeInfo &decode_info) {
  uint16_t inst_word16 = static_cast<uint16_t>(inst_word & 0xffff);
  // First check that the address is aligned properly. If not, create and return
  // an instruction object that will raise an exception.
  if (address & 0x1) {
    auto *inst = new generic::Instruction(0, state_);
    inst->set_size(1);
    inst->SetDisassemblyString("Misaligned instruction address");
    inst->set_opcode(*isa32::OpcodeEnum::kNone);
    inst->set_address(address);
    inst->set_semantic_function([this](generic::Instruction *inst) {
      state_->Trap(/*is_interrupt*/ false, inst->address(),
                   *RV_EC::kInstructionAddressMisaligned, inst->address() ^ 0x1,
                   inst);
    });
    return inst;
  }
  // Parse the instruction in the encoding parser.
  cheriot_encoding_->ParseInstruction(inst_word);
  auto format = cheriot_encoding_->GetFormat(SlotEnum::kRiscv32Cheriot, 0);
  auto opcode = cheriot_encoding_->GetOpcode(SlotEnum::kRiscv32Cheriot, 0);
  // Extract the numerical register specifies of the instruction.
  int rd = 0;
  int rs1 = 0;
  int rs2 = 0;
  switch (format) {
    case FormatEnum::kAType:
      // Atomic Instructions. All use rd, rs1, and rs2.
      rd = encoding::a_type::ExtractRd(inst_word);
      rs1 = encoding::a_type::ExtractRs1(inst_word);
      rs2 = encoding::a_type::ExtractRs2(inst_word);
      break;
    case FormatEnum::kBType:
      // 32 bit branch type instructions. All use rs1 and rs2.
      // beq, bne, blt, bge, bltu, bgeu
      rd = 0;
      rs1 = encoding::b_type::ExtractRs1(inst_word);
      rs2 = encoding::b_type::ExtractRs2(inst_word);
      break;
    case FormatEnum::kIType:  // 2 reg operands: rd and rs1.
      // addi, slti, sltiu, xori, ori, andi
      // cincaddrimm, cjalr, crj, lc, setboundsimm
      // lb, lh, lw, lb, lhu
      // csrrw/s/c, csrr[swc]_n[rw]
      rd = encoding::i_type::ExtractRd(inst_word);
      rs1 = encoding::i_type::ExtractRs1(inst_word);
      rs2 = 0;
      break;
    case FormatEnum::kI2Type:  // 1 register operand: rd.
      // cssr[wsc]i, csrr[wsc]_n[rw]
      rd = encoding::i2_type::ExtractRd(inst_word);
      rs1 = 0;
      rs2 = 0;
      break;
    case FormatEnum::kI5Type:  // 2 reg operands.
      rd = encoding::i5_type::ExtractRd(inst_word);
      rs1 = encoding::i5_type::ExtractRs1(inst_word);
      rs2 = 0;
      break;
    case FormatEnum::kJType: {  // Jump type - immediate.
      rd = encoding::j_type::ExtractRd(inst_word);
      rs1 = 0;
      rs2 = 0;
      break;
    }
      /*
    case FormatEnum::kR4Type:  // 4 reg operands, rd, rs1, rs3, and rs4.
      rd = encoding::r4_type::ExtractRd(inst_word);
      rs1 = encoding::r4_type::ExtractRs1(inst_word);
      rs2 = encoding::r4_type::ExtractRs2(inst_word);
      break;
      */
    case FormatEnum::kRType:  // 3 reg operands: rd, rs1, and rs2.
      rd = encoding::r_type::ExtractRd(inst_word);
      rs1 = encoding::r_type::ExtractRs1(inst_word);
      rs2 = encoding::r_type::ExtractRs2(inst_word);
      break;
    case FormatEnum::kR2Type:
      rd = encoding::r_type::ExtractRd(inst_word);
      rs1 = encoding::r_type::ExtractRs1(inst_word);
      rs2 = 0;
      break;
    case FormatEnum::kSType:  // 2 reg operands: rs1 and rs2.
      // sb, sh, sw, csc.
      rd = 0;
      rs1 = encoding::s_type::ExtractRs1(inst_word);
      rs2 = encoding::s_type::ExtractRs2(inst_word);
      break;
    case FormatEnum::kUType:
      // lui, cauicgp, cauipcc.
      rd = encoding::u_type::ExtractRd(inst_word);
      rs1 = 0;
      rs2 = 0;
      break;
    case FormatEnum::kCA:  // 3 reg operands: rd, rs1, and rs2.
      // csub, cxor, cor, cand.
      rd = encoding::c_a::ExtractRd(inst_word16);
      rs1 = encoding::c_a::ExtractRs1(inst_word16);
      rs2 = encoding::c_a::ExtractRs2(inst_word16);
      break;
    case FormatEnum::kCSH:  // rs1 is source and dest.
      // csrli, csrai, candi.
      rd = encoding::c_s_h::ExtractRd(inst_word16);
      rs1 = encoding::c_s_h::ExtractRs1(inst_word16);
      rs2 = 0;
      break;
    case FormatEnum::kCB:  // rs1 is source.
      // cbeqz, cbnez.
      rd = 0;
      rs1 = encoding::c_b::ExtractRs1(inst_word16);
      rs2 = 0;
      break;
    case FormatEnum::kCI:  // 2 reg operands: rd, rs1.
      // cnop, caddi, cli, caddi16sp, clui, cslli, clwsp, clcsp.
      rd = encoding::c_i::ExtractRd(inst_word16);
      if ((opcode == OpcodeEnum::kClwsp) || (opcode == OpcodeEnum::kClcsp)) {
        rs1 = 2;
      } else {
        rs1 = encoding::c_i::ExtractRs1(inst_word16);
      }
      rs2 = 0;
      break;
    case FormatEnum::kCIW:  // 1 reg operand: rd.
      // caddi4spn.
      rd = encoding::c_i_w::ExtractRd(inst_word16);
      rs1 = 2;
      rs2 = 0;
      break;
    case FormatEnum::kCJ:  // Depends on opcode. jal/jalr use x1.
      // cj, cjal.
      rd = opcode == OpcodeEnum::kCheriotCj ? 0 : 1;
      rs1 = 0;
      rs2 = 0;
      break;
    case FormatEnum::kCL:  // 2 reg operands: cl_rs1 and cl_rd.
      // clw, cld.
      rd = encoding::c_l::ExtractRd(inst_word16);
      rs1 = encoding::c_l::ExtractRs1(inst_word16);
      rs2 = 0;
      break;
    case FormatEnum::kCR:  // 3 reg operands: rd(s), crs2, and rd(d).
      // cmv, cebreak, cadd, cheriot_cjr, cheriot_cjalr.
      switch (opcode) {
        case OpcodeEnum::kCmv:
          rd = encoding::c_r::ExtractRd(inst_word16);
          rs1 = 0;
          rs2 = encoding::c_r::ExtractRs2(inst_word16);
          break;
        case OpcodeEnum::kCebreak:
          rd = 0;
          rs1 = 0;
          rs2 = 0;
          break;
        case OpcodeEnum::kCadd:
          rd = encoding::c_r::ExtractRd(inst_word16);
          rs1 = encoding::c_r::ExtractRs1(inst_word16);
          rs2 = encoding::c_r::ExtractRs2(inst_word16);
          break;
        case OpcodeEnum::kCheriotCjr:
          rd = 0;
          rs1 = encoding::c_r::ExtractRs1(inst_word16);
          rs2 = 0;
          break;
        case OpcodeEnum::kCheriotCjalrCra:
          rd = 1;
          rs1 = encoding::c_r::ExtractRs1(inst_word16);
          rs2 = 0;
          break;
        default:
          break;
      }
      break;
    case FormatEnum::kCS:  // 2 reg operands: rs1p and rs2p.
      // sw, sd.
      rd = 0;
      rs1 = encoding::c_s::ExtractRs1(inst_word16);
      rs2 = encoding::c_s::ExtractRs2(inst_word16);
      break;
    case FormatEnum::kCSS:  // 1 reg operand: rs2.
      // cswsp, csdsp
      rd = 0;
      rs1 = 0;
      rs2 = encoding::c_s_s::ExtractRs2(inst_word16);
      break;
    default:
      break;
  }
  // Call the isa decoder to obtain a new instruction object for the instruction
  // word that was parsed above.
  auto *instruction = cheriot_isa_->Decode(address, cheriot_encoding_);
  // For these formats, sail does not populate the rs1/rs2 address fields.
  if (format == FormatEnum::kIType || format == FormatEnum::kI5Type ||
      format == FormatEnum::kR2Type || format == FormatEnum::kCB ||
      format == FormatEnum::kCSH || format == FormatEnum::kCIW ||
      format == FormatEnum::kCI) {
    rs1 = 0;
  }
  if (format == FormatEnum::kRType || format == FormatEnum::kBType ||
      format == FormatEnum::kCR || format == FormatEnum::kCA ||
      format == FormatEnum::kSType) {
    rs1 = 0;
    rs2 = 0;
  }
  if (opcode == OpcodeEnum::kCslli) {
    rs1 = 0;
  }
  if ((opcode == OpcodeEnum::kHint) || (opcode == OpcodeEnum::kChint)) {
    rs1 = 0;
    rs2 = 0;
    rd = 0;
  }
  decode_info.rd = rd;
  decode_info.rs1 = rs1;
  decode_info.rs2 = rs2;
  return instruction;
}

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