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

#include <any>
#include <cstdint>
#include <type_traits>

#include "absl/log/log.h"
#include "absl/numeric/bits.h"
#include "cheriot/cheriot_register.h"
#include "cheriot/cheriot_state.h"
#include "mpact/sim/generic/data_buffer.h"
#include "mpact/sim/generic/instruction.h"
#include "mpact/sim/generic/operand_interface.h"
#include "mpact/sim/generic/register.h"
#include "mpact/sim/generic/type_helpers.h"
#include "riscv//riscv_register.h"
#include "riscv//riscv_state.h"

// This file contains the implementations of the RiscV CHERIoT instruction
// semantic functions. These instructions are defined in section 9 in the
// Microsoft Tech Report MSR-TR-2023-6 "CHERIoT: Rethinking security for
// low-cost embedded systems"."

namespace mpact {
namespace sim {
namespace cheriot {

using ::mpact::sim::generic::operator*;  // NOLINT: is used below (clang error).
using CapReg = CheriotRegister;
using EC = ::mpact::sim::cheriot::ExceptionCode;
using RV32Register = ::mpact::sim::riscv::RV32Register;
using ::mpact::sim::generic::RegisterBase;

// Helpers to get capability register source and destination registers.
static inline CapReg *GetCapSource(const Instruction *instruction, int i) {
  return static_cast<CapReg *>(
      std::any_cast<RegisterBase *>(instruction->Source(i)->GetObject()));
}

static inline CapReg *GetCapDest(const Instruction *instruction, int i) {
  return static_cast<CapReg *>(
      std::any_cast<RegisterBase *>(instruction->Destination(i)->GetObject()));
}
// Writing an integer result requires invalidating the capability and setting
// it to null.
template <typename Result>
static inline void WriteCapIntResult(const Instruction *instruction, int i,
                                     Result value) {
  auto *cap_reg = GetCapDest(instruction, i);
  cap_reg->data_buffer()->Set<Result>(0, value);
  cap_reg->Invalidate();
  cap_reg->set_is_null();
}

// Sign extension helper function.
template <typename T>
static inline T SignExtend(T value, int size) {
  using ST = typename std::make_signed<T>::type;
  ST svalue = value;
  int shift_amount = sizeof(T) * 8 - size;
  svalue = (svalue << shift_amount) >> shift_amount;
  return static_cast<T>(svalue);
}

// Instruction semantic function bodies.

void CheriotAuicap(const Instruction *instruction) {
  auto *cap_src = GetCapSource(instruction, 0);
  auto offset = generic::GetInstructionSource<uint32_t>(instruction, 1);
  auto *cap_dest = GetCapDest(instruction, 0);
  cap_dest->CopyFrom(*cap_src);
  uint32_t address = cap_src->address() + offset;
  cap_dest->data_buffer()->Set<uint32_t>(0, address);
  if (cap_dest->IsSealed()) {
    cap_dest->Invalidate();
  }
  if (!cap_dest->IsRepresentable()) cap_dest->Invalidate();
}

void CheriotCAndPerm(const Instruction *instruction) {
  auto *cap_src = GetCapSource(instruction, 0);
  auto perms = cap_src->permissions();
  auto perms_to_keep = generic::GetInstructionSource<uint32_t>(instruction, 1);
  auto new_perms = perms & perms_to_keep;
  auto *cap_dest = GetCapDest(instruction, 0);
  bool valid = !cap_src->IsSealed();
  cap_dest->CopyFrom(*cap_src);
  cap_dest->ClearPermissions(perms ^ new_perms);
  if (!valid) cap_dest->Invalidate();
}

void CheriotCClearTag(const Instruction *instruction) {
  auto *cs1 = GetCapSource(instruction, 0);
  auto *cd = GetCapDest(instruction, 0);
  if (cd != cs1) cd->CopyFrom(*cs1);
  cd->Invalidate();
}

void CheriotCGetAddr(const Instruction *instruction) {
  auto *cs1 = GetCapSource(instruction, 0);
  WriteCapIntResult<uint32_t>(instruction, 0, cs1->address());
}

void CheriotCGetBase(const Instruction *instruction) {
  auto *cs1 = GetCapSource(instruction, 0);
  auto [base, unused] = cs1->ComputeBounds();
  WriteCapIntResult(instruction, 0, base);
}

void CheriotCGetHigh(const Instruction *instruction) {
  auto *cs1 = GetCapSource(instruction, 0);
  WriteCapIntResult<uint32_t>(instruction, 0, cs1->Compress());
}

void CheriotCGetLen(const Instruction *instruction) {
  auto *cs1 = GetCapSource(instruction, 0);
  auto [base, top] = cs1->ComputeBounds();
  uint64_t length = top - base;
  if (length == 0x1'0000'0000ULL) length = 0xffff'ffff;
  WriteCapIntResult<uint32_t>(instruction, 0, length);
}

void CheriotCGetPerm(const Instruction *instruction) {
  auto *cs1 = GetCapSource(instruction, 0);
  WriteCapIntResult<uint32_t>(instruction, 0, cs1->permissions());
}

void CheriotCGetTag(const Instruction *instruction) {
  auto *cs1 = GetCapSource(instruction, 0);
  WriteCapIntResult<uint32_t>(instruction, 0, cs1->tag());
}

void CheriotCGetTop(const Instruction *instruction) {
  auto *cs1 = GetCapSource(instruction, 0);
  auto [unused, top] = cs1->ComputeBounds();
  // auto top = cs1->top();
  if (top == 0x1'0000'0000ULL) {
    top = 0xffff'ffff;
  }
  WriteCapIntResult<uint32_t>(instruction, 0, top);
}

void CheriotCGetType(const Instruction *instruction) {
  auto *cs1 = GetCapSource(instruction, 0);
  uint32_t object_type = cs1->object_type();
  object_type &= 0b0111;
  if ((object_type != 0) && (!cs1->HasPermission(CapReg::kPermitExecute))) {
    object_type |= 0b1000;
  }
  WriteCapIntResult<uint32_t>(instruction, 0, object_type);
}

void CheriotCIncAddr(const Instruction *instruction) {
  auto *cs1 = GetCapSource(instruction, 0);
  auto inc = generic::GetInstructionSource<uint32_t>(instruction, 1);
  auto *cd = GetCapDest(instruction, 0);
  uint32_t new_addr = cs1->address() + inc;
  bool valid = true;
  if (cs1->IsSealed()) valid = false;
  cd->CopyFrom(*cs1);
  cd->SetAddress(new_addr);
  if (!cd->IsRepresentable() || !valid) cd->Invalidate();
}

// Helper function to check for exceptions for Jal and J.
static bool CheriotCJChecks(const Instruction *instruction, uint64_t new_pc,
                            const CheriotRegister *pcc) {
  auto *state = static_cast<CheriotState *>(instruction->state());
  if (!state->has_compact() && (new_pc & 0b10)) {
    state->Trap(/*is_interrupt*/ false, new_pc,
                *riscv::ExceptionCode::kInstructionAddressMisaligned,
                instruction->address(), instruction);
    return false;
  }
  return true;
}

void CheriotCJal(const Instruction *instruction) {
  auto *state = static_cast<CheriotState *>(instruction->state());
  auto offset = generic::GetInstructionSource<uint32_t>(instruction, 0);
  uint64_t new_pc = offset + instruction->address();
  auto *pcc = state->pcc();
  if (!CheriotCJChecks(instruction, new_pc, pcc)) return;
  // Update link register.
  auto *cd = GetCapDest(instruction, 0);
  cd->CopyFrom(*pcc);
  cd->set_address(instruction->address() + instruction->size());
  bool interrupt_enable = state->mstatus()->mie();
  (void)cd->Seal(*state->sealing_root(),
                 interrupt_enable ? CapReg::kInterruptEnablingReturnSentry
                                  : CapReg::kInterruptDisablingReturnSentry);
  // Update pcc.
  pcc->set_address(new_pc);
  state->set_branch(true);
}

void CheriotCJ(const Instruction *instruction) {
  auto *state = static_cast<CheriotState *>(instruction->state());
  auto offset = generic::GetInstructionSource<uint32_t>(instruction, 0);
  uint64_t new_pc = offset + instruction->address();
  auto *pcc = state->pcc();
  if (!CheriotCJChecks(instruction, new_pc, pcc)) return;
  // Update pcc.
  pcc->set_address(new_pc);
  state->set_branch(true);
}

// Helper function to check for exceptions for Jr and Jalr.
static bool CheriotCJrCheck(const Instruction *instruction, uint64_t new_pc,
                            uint32_t offset, const CheriotRegister *cs1,
                            bool has_dest, bool uses_ra) {
  auto *state = static_cast<CheriotState *>(instruction->state());
  if (!cs1->tag()) {
    state->HandleCheriRegException(instruction, instruction->address(),
                                   EC::kCapExTagViolation, cs1);
    return false;
  }
  bool ok = false;
  ok |= !has_dest && uses_ra && cs1->IsBackwardSentry();
  ok |= !has_dest && !uses_ra &&
        ((cs1->object_type() == CapReg::kUnsealed) ||
         (cs1->object_type() == CapReg::kSentry));
  ok |= has_dest && ((cs1->object_type() == CapReg::kUnsealed) ||
                     (cs1->object_type() == CapReg::kSentry));
  ok |= has_dest && uses_ra && (cs1->object_type() >= CapReg::kUnsealed) &&
        (cs1->object_type() <= CapReg::kInterruptEnablingSentry);
  if ((cs1->IsSealed() && offset != 0) || !ok) {
    state->HandleCheriRegException(instruction, instruction->address(),
                                   EC::kCapExSealViolation, cs1);
    return false;
  }
  if (!cs1->HasPermission(CapReg::kPermitExecute)) {
    state->HandleCheriRegException(instruction, instruction->address(),
                                   EC::kCapExPermitExecuteViolation, cs1);
    return false;
  }
  if (!state->has_compact() && (new_pc & 0b10)) {
    state->Trap(/*is_interrupt*/ false, new_pc,
                *riscv::ExceptionCode::kInstructionAddressMisaligned,
                instruction->address(), instruction);
    return false;
  }
  return true;
}

static inline void CheriotCJalrHelper(const Instruction *instruction,
                                      bool has_dest, bool uses_ra) {
  auto *state = static_cast<CheriotState *>(instruction->state());
  auto *cs1 = GetCapSource(instruction, 0);
  auto offset = generic::GetInstructionSource<uint32_t>(instruction, 1);
  auto *pcc = state->pcc();
  auto new_pc = offset + cs1->address();
  new_pc &= ~0b1ULL;
  if (!CheriotCJrCheck(instruction, new_pc, offset, cs1, has_dest, uses_ra)) {
    return;
  }
  auto *mstatus = state->mstatus();
  if (has_dest) {
    // Update link register.
    state->temp_reg()->CopyFrom(*pcc);
    state->temp_reg()->set_address(instruction->address() +
                                   instruction->size());
    bool interrupt_enable = (mstatus->GetUint32() & 0b1000) != 0;
    auto status = state->temp_reg()->Seal(
        *state->sealing_root(), interrupt_enable
                                    ? CapReg::kInterruptEnablingReturnSentry
                                    : CapReg::kInterruptDisablingReturnSentry);
    if (!status.ok()) {
      LOG(ERROR) << "Failed to seal: " << status;
      return;
    }
  }
  // Update pcc.
  pcc->CopyFrom(*cs1);
  // If the new pcc is a sentry, unseal and set/clear mie accordingly.
  if (pcc->IsSentry()) {
    if (pcc->object_type() != CapReg::kSentry) {
      bool interrupt_enable =
          (pcc->object_type() == CapReg::kInterruptEnablingSentry) ||
          (pcc->object_type() == CapReg::kInterruptEnablingReturnSentry);
      mstatus->set_mie(interrupt_enable);
      mstatus->Submit();
    }
    (void)pcc->Unseal(*state->sealing_root(), pcc->object_type());
  }
  pcc->set_address(new_pc);
  state->set_branch(true);
  if (has_dest) {
    auto *cd = GetCapDest(instruction, 0);
    cd->CopyFrom(*state->temp_reg());
  }
}

void CheriotCJalr(const Instruction *instruction) {
  CheriotCJalrHelper(instruction, /*has_dest=*/true, /*uses_ra=*/false);
}

void CheriotCJalrCra(const Instruction *instruction) {
  CheriotCJalrHelper(instruction, /*has_dest=*/true, /*uses_ra=*/true);
}

void CheriotCJrCra(const Instruction *instruction) {
  CheriotCJalrHelper(instruction, /*has_dest=*/false, /*uses_ra=*/true);
}

void CheriotCJr(const Instruction *instruction) {
  CheriotCJalrHelper(instruction, /*has_dest=*/false, /*uses_ra=*/false);
}

void CheriotCJalrZero(const Instruction *instruction) {
  auto *state = static_cast<CheriotState *>(instruction->state());
  auto *cs1 = GetCapSource(instruction, 0);
  state->HandleCheriRegException(instruction, instruction->address(),
                                 EC::kCapExTagViolation, cs1);
}

void CheriotCLc(const Instruction *instruction) {
  auto *state = static_cast<CheriotState *>(instruction->state());
  auto offset = generic::GetInstructionSource<uint32_t>(instruction, 1);
  auto *cs1 = GetCapSource(instruction, 0);
  uint32_t address = cs1->address() + offset;
  if (!cs1->tag()) {
    state->HandleCheriRegException(instruction, instruction->address(),
                                   EC::kCapExTagViolation, cs1);
    return;
  }
  if (cs1->IsSealed()) {
    state->HandleCheriRegException(instruction, instruction->address(),
                                   EC::kCapExSealViolation, cs1);
    return;
  }
  if (!cs1->HasPermission(CapReg::kPermitLoad)) {
    state->HandleCheriRegException(instruction, instruction->address(),
                                   EC::kCapExPermitLoadViolation, cs1);
    return;
  }
  if (!cs1->IsInBounds(address, CapReg::kCapabilitySizeInBytes)) {
    state->HandleCheriRegException(instruction, instruction->address(),
                                   EC::kCapExBoundsViolation, cs1);
    return;
  }
  if ((address & ((1 << CapReg::kGranuleShift) - 1)) != 0) {
    state->Trap(/*is_interrupt*/ false, address,
                *riscv::ExceptionCode::kLoadAddressMisaligned,
                instruction->address(), instruction);
    return;
  }
  auto *db = state->db_factory()->Allocate(CapReg::kCapabilitySizeInBytes);
  db->set_latency(0);
  auto *tag_db = state->db_factory()->Allocate(1);
  auto *context = new CapabilityLoadContext32(db, tag_db, cs1->permissions(),
                                              /*clear_tag=*/false);
  state->LoadCapability(instruction, address, db, tag_db, instruction->child(),
                        context);
  context->DecRef();
}

void CheriotCLcChild(const Instruction *instruction) {
  auto *state = static_cast<CheriotState *>(instruction->state());
  auto *context =
      static_cast<CapabilityLoadContext32 *>(instruction->context());
  auto *cd = GetCapDest(instruction, 0);
  cd->Expand(context->db->Get<uint32_t>(0), context->db->Get<uint32_t>(1),
             context->tag_db->Get<uint8_t>(0));
  if (cd->tag()) {
    if ((context->permissions & CapReg::kPermitLoadGlobal) == 0) {
      cd->ClearPermissions(CapReg::kPermitGlobal | CapReg::kPermitLoadGlobal);
    }
    if (!cd->IsSealed() &&
        ((context->permissions & CapReg::kPermitLoadMutable) == 0)) {
      cd->ClearPermissions(CapReg::kPermitStore | CapReg::kPermitLoadMutable);
    }
    // If the source capability did not have load/store capability, invalidate.
    if ((context->permissions & CapReg::kPermitLoadStoreCapability) == 0) {
      cd->Invalidate();
    }
    // If it's not a sealing cap, check for revocation.
    if (cd->tag() &&
        ((cd->permissions() & (CapReg::kPermitSeal | CapReg::kPermitUnseal |
                               CapReg::kUserPerm0)) == 0)) {
      if (state->MustRevoke(cd->base())) {
        cd->Invalidate();
      }
    }
  }
}

void CheriotCMove(const Instruction *instruction) {
  auto *cs1 = GetCapSource(instruction, 0);
  auto *cd = GetCapDest(instruction, 0);
  cd->CopyFrom(*cs1);
}

static uint32_t GetExponent(uint32_t length) {
  constexpr uint32_t kMaxLenBase = (1 << 9) - 1;
  if (length > kMaxLenBase * (1 << 14)) return 24;
  // Compute the power of 2 value that is the ceiling of the rounded division
  uint32_t alignment = absl::bit_ceil((length + kMaxLenBase - 1) / kMaxLenBase);
  return absl::bit_width(alignment) - 1;
}

void CheriotCRepresentableAlignmentMask(const Instruction *instruction) {
  auto rs1 = generic::GetInstructionSource<uint32_t>(instruction, 0);
  auto exp = GetExponent(rs1);
  WriteCapIntResult<uint32_t>(instruction, 0, 0xffff'ffffU << exp);
}

void CheriotCRoundRepresentableLength(const Instruction *instruction) {
  auto rs1 = generic::GetInstructionSource<uint32_t>(instruction, 0);
  auto exp = GetExponent(rs1);
  uint32_t mask = (1 << exp) - 1;
  uint32_t length = ((rs1 + mask) / (mask + 1)) * (mask + 1);
  WriteCapIntResult(instruction, 0, length);
}

void CheriotCSc(const Instruction *instruction) {
  auto *state = static_cast<CheriotState *>(instruction->state());
  auto *cs1 = GetCapSource(instruction, 0);
  auto *cs2 = GetCapSource(instruction, 2);
  uint32_t imm = generic::GetInstructionSource<uint32_t>(instruction, 1);
  uint32_t address = cs1->address() + imm;
  uint8_t tag = cs2->tag();
  if (!cs1->tag()) {
    state->HandleCheriRegException(instruction, instruction->address(),
                                   EC::kCapExTagViolation, cs1);
    return;
  }
  if (cs1->IsSealed()) {
    state->HandleCheriRegException(instruction, instruction->address(),
                                   EC::kCapExSealViolation, cs1);
    return;
  }
  if (!cs1->HasPermission(CapReg::kPermitStore)) {
    state->HandleCheriRegException(instruction, instruction->address(),
                                   EC::kCapExPermitStoreViolation, cs1);
    return;
  }
  if (!cs1->HasPermission(CapReg::kPermitLoadStoreCapability) && cs2->tag()) {
    state->HandleCheriRegException(instruction, instruction->address(),
                                   EC::kCapExPermitStoreCapabilityViolation,
                                   cs1);
    return;
  }
  if (!cs1->HasPermission(CapReg::kPermitStoreLocalCapability) && cs2->tag() &&
      (!cs2->HasPermission(CapReg::kPermitGlobal) || cs2->IsBackwardSentry())) {
    tag = 0;
  }
  if (!cs1->IsInBounds(address, CapReg::kCapabilitySizeInBytes)) {
    state->HandleCheriRegException(instruction, instruction->address(),
                                   EC::kCapExBoundsViolation, cs1);
    return;
  }
  if ((address & ((1 << CapReg::kGranuleShift) - 1)) != 0) {
    state->Trap(/*is_interrupt*/ false, address,
                *riscv::ExceptionCode::kStoreAddressMisaligned,
                instruction->address(), instruction);
    return;
  }
  auto *db = state->db_factory()->Allocate(CapReg::kCapabilitySizeInBytes);
  auto *tag_db = state->db_factory()->Allocate(1);
  db->Set<uint32_t>(0, cs2->address());
  db->Set<uint32_t>(1, cs2->Compress());
  tag_db->Set<uint8_t>(0, tag);
  state->StoreCapability(instruction, address, db, tag_db);
  db->DecRef();
  tag_db->DecRef();
}

void CheriotCSeal(const Instruction *instruction) {
  auto *cs1 = GetCapSource(instruction, 0);
  auto *cs2 = GetCapSource(instruction, 1);
  auto *cd = GetCapDest(instruction, 0);
  bool valid = true;
  // If cs1 is sealed, invalidate cd.
  if (cs1->IsSealed()) valid = false;
  uint32_t object_type = cs2->address();
  bool permitted_otype = false;
  switch (object_type) {
    case CapReg::kSentry:
    case CapReg::kInterruptDisablingSentry:
    case CapReg::kInterruptEnablingSentry:
    case CapReg::kSealedExecutable6:
    case CapReg::kSealedExecutable7:
      permitted_otype = cs1->HasPermission(CapReg::kPermitExecute);
      break;
    default:
      permitted_otype = !cs1->HasPermission(CapReg::kPermitExecute) &&
                        (object_type > 8) && (object_type <= 15);
      break;
  }
  bool permitted = cs2->tag() && cs2->HasPermission(CapReg::kPermitSeal) &&
                   (object_type < cs2->top()) && (object_type >= cs2->base()) &&
                   permitted_otype && cs2->IsUnsealed();
  auto cs2_address = cs2->address();
  cd->CopyFrom(*cs1);
  cd->set_object_type(
      cs2_address &
      ((1 << (CapReg::kObjectType[0] - CapReg::kObjectType[1] + 1))) - 1);
  if (!permitted || !valid) cd->Invalidate();
}

void CheriotCSetAddr(const Instruction *instruction) {
  auto *cs1 = GetCapSource(instruction, 0);
  auto rs2 = generic::GetInstructionSource<uint32_t>(instruction, 1);
  auto *cd = GetCapDest(instruction, 0);
  auto valid = true;
  if (cs1->IsSealed()) valid = false;
  cd->CopyFrom(*cs1);
  cd->SetAddress(rs2);
  if (!cd->IsRepresentable() || !valid) cd->Invalidate();
}

void CheriotCSetBounds(const Instruction *instruction) {
  auto *cs1 = GetCapSource(instruction, 0);
  auto rs2 = generic::GetInstructionSource<uint32_t>(instruction, 1);
  auto *cd = GetCapDest(instruction, 0);
  auto cs1_address = cs1->address();
  bool valid = true;
  // If cs1 is sealed, then invalidate the capability.
  if (cs1->IsSealed()) valid = false;
  // If the bounds are such that the new requested capability is not
  // representable, invalidate.
  auto [cs1_base, cs1_top] = cs1->ComputeBounds();
  auto new_top =
      static_cast<uint64_t>(cs1_address) + static_cast<uint64_t>(rs2);
  valid &= (cs1_address >= cs1_base) && (new_top <= cs1_top);
  cd->CopyFrom(*cs1);
  (void)cd->SetBounds(cs1_address, rs2);
  if (!valid) cd->Invalidate();
}

void CheriotCSetBoundsExact(const Instruction *instruction) {
  auto *cs1 = GetCapSource(instruction, 0);
  auto rs2 = generic::GetInstructionSource<uint32_t>(instruction, 1);
  auto *cd = GetCapDest(instruction, 0);
  bool valid = true;
  auto cs1_address = cs1->address();
  // If cs1 is sealed, then invalidate the capability.
  if (cs1->IsSealed()) valid = false;
  // If outside the requested representable range, invalidate.
  auto [cs1_base, cs1_top] = cs1->ComputeBounds();
  auto new_top =
      static_cast<uint64_t>(cs1_address) + static_cast<uint64_t>(rs2);
  valid &= (cs1_address >= cs1_base) && (new_top <= cs1_top);
  // Invalidate if not exact.
  cd->CopyFrom(*cs1);
  bool exact = cd->SetBounds(cs1_address, rs2);
  if (!exact || !valid) cd->Invalidate();
}

void CheriotCSetEqualExact(const Instruction *instruction) {
  auto *cs1 = GetCapSource(instruction, 0);
  auto *cs2 = GetCapSource(instruction, 1);
  uint32_t equal =
      (cs1->tag() == cs2->tag()) && (cs1->Compress() == cs2->Compress());
  WriteCapIntResult(instruction, 0, equal);
}

void CheriotCSetHigh(const Instruction *instruction) {
  auto *cs1 = GetCapSource(instruction, 0);
  auto rs2 = generic::GetInstructionSource<uint32_t>(instruction, 1);
  auto *cd = GetCapDest(instruction, 0);
  cd->Expand(cs1->address(), rs2, false);
}

void CheriotCSpecialR(const Instruction *instruction) {
  auto *state = static_cast<CheriotState *>(instruction->state());
  // Decode will ensure that register scr is valid.
  auto *scr = GetCapSource(instruction, 0);
  auto *cd = GetCapDest(instruction, 0);
  if (!state->pcc()->HasPermission(CapReg::kPermitAccessSystemRegisters)) {
    state->HandleCheriRegException(
        instruction, instruction->address(),
        EC::kCapExPermitAccessSystemRegistersViolation, state->pcc());
    return;
  }
  cd->CopyFrom(*scr);
}

void CheriotCSpecialRW(const Instruction *instruction) {
  auto *state = static_cast<CheriotState *>(instruction->state());
  // Decode will ensure that register scr is valid.
  auto *cs1 = GetCapSource(instruction, 0);
  auto *scr = GetCapSource(instruction, 1);
  auto *cd = GetCapDest(instruction, 0);
  if (!state->pcc()->HasPermission(CapReg::kPermitAccessSystemRegisters)) {
    state->HandleCheriRegException(
        instruction, instruction->address(),
        EC::kCapExPermitAccessSystemRegistersViolation, state->pcc());
    return;
  }
  auto *temp_reg = state->temp_reg();
  temp_reg->CopyFrom(*cs1);
  cd->CopyFrom(*scr);
  // If it's the mepcc register, make sure to clear any lsb.
  if (scr->name() == "mepcc") {
    if (temp_reg->address() & 0x1ULL) {
      temp_reg->set_address(temp_reg->address() & ~0x1);
      temp_reg->Invalidate();
    } else if (temp_reg->IsSealed() ||
               !temp_reg->HasPermission(CapReg::kPermitExecute)) {
      temp_reg->Invalidate();
    }
  } else if (scr->name() == "mtcc") {
    if (temp_reg->address() & 0x3ULL) {
      temp_reg->set_address(temp_reg->address() & ~0x3ULL);
      temp_reg->Invalidate();
    } else if (temp_reg->IsSealed() ||
               !temp_reg->HasPermission(CapReg::kPermitExecute)) {
      temp_reg->Invalidate();
    }
  }
  scr->CopyFrom(*state->temp_reg());
}

void CheriotCSub(const Instruction *instruction) {
  auto *cs1 = GetCapSource(instruction, 0);
  auto *cs2 = GetCapSource(instruction, 1);
  WriteCapIntResult(instruction, 0, cs1->address() - cs2->address());
}

void CheriotCTestSubset(const Instruction *instruction) {
  auto *cs1 = GetCapSource(instruction, 0);
  auto *cs2 = GetCapSource(instruction, 1);
  auto [cs1_base, cs1_top] = cs1->ComputeBounds();
  auto [cs2_base, cs2_top] = cs2->ComputeBounds();
  // Verify that cs2 is a subset of cs1.
  bool result =
      cs1->tag() == cs2->tag() &&
      // cs2 has a valid range smaller or equal to cs1.
      cs1_base <= cs2_base && cs1_top >= cs2_top &&
      // cs2 permissions are a subset of cs1 permissions.
      ((cs1->permissions() & cs2->permissions()) == cs2->permissions());
  WriteCapIntResult(instruction, 0, static_cast<uint32_t>(result));
}

void CheriotCUnseal(const Instruction *instruction) {
  auto *cs1 = GetCapSource(instruction, 0);
  auto *cs2 = GetCapSource(instruction, 1);
  auto *cd = GetCapDest(instruction, 0);
  bool valid = true;
  if (!cs2->tag() || !cs1->IsSealed() || cs2->IsSealed() ||
      (cs2->address() != cs1->object_type()) ||
      !cs2->HasPermission(CapReg::kPermitUnseal) ||
      (cs2->address() < cs2->base()) || (cs2->address() >= cs2->top())) {
    valid = false;
  }
  auto cs2_permissions = cs2->permissions();
  cd->CopyFrom(*cs1);
  if ((cs2_permissions & CapReg::kPermitGlobal) == 0) {
    cd->ClearPermissions(CapReg::kPermitGlobal);
  }
  cd->set_object_type(CapReg::kUnsealed);
  if (!valid) cd->Invalidate();
}

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