/*
 * Copyright (c) 2010-2014, 2016-2020 ARM Limited
 * Copyright (c) 2013 Advanced Micro Devices, Inc.
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2007-2008 The Florida State University
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "arch/arm/insts/static_inst.hh"

#include "arch/arm/faults.hh"
#include "arch/arm/isa.hh"
#include "arch/arm/self_debug.hh"
#include "arch/arm/utility.hh"
#include "base/condcodes.hh"
#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
#include "cpu/reg_class.hh"

namespace gem5
{

namespace ArmISA
{
// Shift Rm by an immediate value
int32_t
ArmStaticInst::shift_rm_imm(uint32_t base, uint32_t shamt,
                                uint32_t type, uint32_t cfval) const
{
    assert(shamt < 32);
    ArmShiftType shiftType;
    shiftType = (ArmShiftType)type;

    switch (shiftType)
    {
      case LSL:
        return base << shamt;
      case LSR:
        if (shamt == 0)
            return 0;
        else
            return base >> shamt;
      case ASR:
        if (shamt == 0)
            return (base >> 31) | -((base & (1 << 31)) >> 31);
        else
            return (base >> shamt) | -((base & (1 << 31)) >> shamt);
      case ROR:
        if (shamt == 0)
            return (cfval << 31) | (base >> 1); // RRX
        else
            return (base << (32 - shamt)) | (base >> shamt);
      default:
        ccprintf(std::cerr, "Unhandled shift type\n");
        exit(1);
        break;
    }
    return 0;
}

int64_t
ArmStaticInst::shiftReg64(uint64_t base, uint64_t shiftAmt,
                          ArmShiftType type, uint8_t width) const
{
    shiftAmt = shiftAmt % width;
    ArmShiftType shiftType;
    shiftType = (ArmShiftType)type;

    switch (shiftType)
    {
      case LSL:
        return base << shiftAmt;
      case LSR:
        if (shiftAmt == 0)
            return base;
        else
            return (base & mask(width)) >> shiftAmt;
      case ASR:
        if (shiftAmt == 0) {
            return base;
        } else {
            int sign_bit = bits(base, intWidth - 1);
            base >>= shiftAmt;
            base = sign_bit ? (base | ~mask(intWidth - shiftAmt)) : base;
            return base & mask(intWidth);
        }
      case ROR:
        if (shiftAmt == 0)
            return base;
        else
            return (base << (width - shiftAmt)) | (base >> shiftAmt);
      default:
        ccprintf(std::cerr, "Unhandled shift type\n");
        exit(1);
        break;
    }
    return 0;
}

int64_t
ArmStaticInst::extendReg64(uint64_t base, ArmExtendType type,
                           uint64_t shiftAmt, uint8_t width) const
{
    bool sign_extend = false;
    int len = 0;
    switch (type) {
      case UXTB:
        len = 8;
        break;
      case UXTH:
        len = 16;
        break;
      case UXTW:
        len = 32;
        break;
      case UXTX:
        len = 64;
        break;
      case SXTB:
        len = 8;
        sign_extend = true;
        break;
      case SXTH:
        len = 16;
        sign_extend = true;
        break;
      case SXTW:
        len = 32;
        sign_extend = true;
        break;
      case SXTX:
        len = 64;
        sign_extend = true;
        break;
    }
    len = len <= width - shiftAmt ? len : width - shiftAmt;
    uint64_t tmp = (uint64_t) bits(base, len - 1, 0) << shiftAmt;
    if (sign_extend) {
        int sign_bit = bits(tmp, len + shiftAmt - 1);
        tmp = sign_bit ? (tmp | ~mask(len + shiftAmt)) : tmp;
    }
    return tmp & mask(width);
}

// Shift Rm by Rs
int32_t
ArmStaticInst::shift_rm_rs(uint32_t base, uint32_t shamt,
                               uint32_t type, uint32_t cfval) const
{
    enum ArmShiftType shiftType;
    shiftType = (enum ArmShiftType) type;

    switch (shiftType)
    {
      case LSL:
        if (shamt >= 32)
            return 0;
        else
            return base << shamt;
      case LSR:
        if (shamt >= 32)
            return 0;
        else
            return base >> shamt;
      case ASR:
        if (shamt >= 32)
            return (base >> 31) | -((base & (1 << 31)) >> 31);
        else
            return (base >> shamt) | -((base & (1 << 31)) >> shamt);
      case ROR:
        shamt = shamt & 0x1f;
        if (shamt == 0)
            return base;
        else
            return (base << (32 - shamt)) | (base >> shamt);
      default:
        ccprintf(std::cerr, "Unhandled shift type\n");
        exit(1);
        break;
    }
    return 0;
}


// Generate C for a shift by immediate
bool
ArmStaticInst::shift_carry_imm(uint32_t base, uint32_t shamt,
                                   uint32_t type, uint32_t cfval) const
{
    enum ArmShiftType shiftType;
    shiftType = (enum ArmShiftType) type;

    switch (shiftType)
    {
      case LSL:
        if (shamt == 0)
            return cfval;
        else
            return (base >> (32 - shamt)) & 1;
      case LSR:
        if (shamt == 0)
            return (base >> 31);
        else
            return (base >> (shamt - 1)) & 1;
      case ASR:
        if (shamt == 0)
            return (base >> 31);
        else
            return (base >> (shamt - 1)) & 1;
      case ROR:
        shamt = shamt & 0x1f;
        if (shamt == 0)
            return (base & 1); // RRX
        else
            return (base >> (shamt - 1)) & 1;
      default:
        ccprintf(std::cerr, "Unhandled shift type\n");
        exit(1);
        break;
    }
    return 0;
}


// Generate C for a shift by Rs
bool
ArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt,
                                  uint32_t type, uint32_t cfval) const
{
    enum ArmShiftType shiftType;
    shiftType = (enum ArmShiftType) type;

    if (shamt == 0)
        return cfval;

    switch (shiftType)
    {
      case LSL:
        if (shamt > 32)
            return 0;
        else
            return (base >> (32 - shamt)) & 1;
      case LSR:
        if (shamt > 32)
            return 0;
        else
            return (base >> (shamt - 1)) & 1;
      case ASR:
        if (shamt > 32)
            shamt = 32;
        return (base >> (shamt - 1)) & 1;
      case ROR:
        shamt = shamt & 0x1f;
        if (shamt == 0)
            shamt = 32;
        return (base >> (shamt - 1)) & 1;
      default:
        ccprintf(std::cerr, "Unhandled shift type\n");
        exit(1);
        break;
    }
    return 0;
}

void
ArmStaticInst::printIntReg(std::ostream &os, RegIndex reg_idx,
                           uint8_t opWidth) const
{
    if (opWidth == 0)
        opWidth = intWidth;
    if (aarch64) {
        if (reg_idx == int_reg::Ureg0)
            ccprintf(os, "ureg0");
        else if (reg_idx == int_reg::Spx)
            ccprintf(os, "%s%s", (opWidth == 32) ? "w" : "", "sp");
        else if (reg_idx == int_reg::X31)
            ccprintf(os, "%szr", (opWidth == 32) ? "w" : "x");
        else
            ccprintf(os, "%s%d", (opWidth == 32) ? "w" : "x", reg_idx);
    } else {
        switch (reg_idx) {
          case int_reg::Pc:
            ccprintf(os, "pc");
            break;
          case StackPointerReg:
            ccprintf(os, "sp");
            break;
          case FramePointerReg:
             ccprintf(os, "fp");
             break;
          case ReturnAddressReg:
             ccprintf(os, "lr");
             break;
          default:
             ccprintf(os, "r%d", reg_idx);
             break;
        }
    }
}

void ArmStaticInst::printPFflags(std::ostream &os, int flag) const
{
    const char *flagtoprfop[]= { "PLD", "PLI", "PST", "Reserved"};
    const char *flagtotarget[] = { "L1", "L2", "L3", "Reserved"};
    const char *flagtopolicy[] = { "KEEP", "STRM"};

    ccprintf(os, "%s%s%s", flagtoprfop[(flag>>3)&3],
             flagtotarget[(flag>>1)&3], flagtopolicy[flag&1]);
}

void
ArmStaticInst::printFloatReg(std::ostream &os, RegIndex reg_idx) const
{
    ccprintf(os, "f%d", reg_idx);
}

void
ArmStaticInst::printVecReg(std::ostream &os, RegIndex reg_idx,
                           bool isSveVecReg) const
{
    ccprintf(os, "%s%d", isSveVecReg ? "z" : "v", reg_idx);
}

void
ArmStaticInst::printVecPredReg(std::ostream &os, RegIndex reg_idx) const
{
    ccprintf(os, "p%d", reg_idx);
}

void
ArmStaticInst::printCCReg(std::ostream &os, RegIndex reg_idx) const
{
    ccprintf(os, "cc_%s", ArmISA::ccRegName[reg_idx]);
}

void
ArmStaticInst::printMiscReg(std::ostream &os, RegIndex reg_idx) const
{
    assert(reg_idx < NUM_MISCREGS);
    ccprintf(os, "%s", ArmISA::miscRegName[reg_idx]);
}

void
ArmStaticInst::printMnemonic(std::ostream &os,
                             const std::string &suffix,
                             bool withPred,
                             bool withCond64,
                             ConditionCode cond64) const
{
    os << "  " << mnemonic;
    if (withPred && !aarch64) {
        printCondition(os, machInst.condCode);
        os << suffix;
    } else if (withCond64) {
        os << ".";
        printCondition(os, cond64);
        os << suffix;
    }
    if (machInst.bigThumb)
        os << ".w";
    os << "   ";
}

void
ArmStaticInst::printTarget(std::ostream &os, Addr target,
                           const loader::SymbolTable *symtab) const
{
    if (symtab) {
        auto it = symtab->findNearest(target);
        if (it != symtab->end()) {
            ccprintf(os, "<%s", it->name);
            Addr delta = target - it->address;
            if (delta)
                ccprintf(os, "+%d>", delta);
            else
                ccprintf(os, ">");
            return;
        }
    }
    ccprintf(os, "%#x", target);
}

void
ArmStaticInst::printCondition(std::ostream &os,
                              unsigned code,
                              bool noImplicit) const
{
    switch (code) {
      case COND_EQ:
        os << "eq";
        break;
      case COND_NE:
        os << "ne";
        break;
      case COND_CS:
        os << "cs";
        break;
      case COND_CC:
        os << "cc";
        break;
      case COND_MI:
        os << "mi";
        break;
      case COND_PL:
        os << "pl";
        break;
      case COND_VS:
        os << "vs";
        break;
      case COND_VC:
        os << "vc";
        break;
      case COND_HI:
        os << "hi";
        break;
      case COND_LS:
        os << "ls";
        break;
      case COND_GE:
        os << "ge";
        break;
      case COND_LT:
        os << "lt";
        break;
      case COND_GT:
        os << "gt";
        break;
      case COND_LE:
        os << "le";
        break;
      case COND_AL:
        // This one is implicit.
        if (noImplicit)
            os << "al";
        break;
      case COND_UC:
        // Unconditional.
        if (noImplicit)
            os << "uc";
        break;
      default:
        panic("Unrecognized condition code %d.\n", code);
    }
}

void
ArmStaticInst::printMemSymbol(std::ostream &os,
                              const loader::SymbolTable *symtab,
                              const std::string &prefix,
                              const Addr addr,
                              const std::string &suffix) const
{
    if (symtab) {
        auto it = symtab->findNearest(addr);
        if (it != symtab->end()) {
            ccprintf(os, "%s%s", prefix, it->name);
            if (it->address != addr)
                ccprintf(os, "+%d", addr - it->address);
            ccprintf(os, suffix);
        }
    }
}

void
ArmStaticInst::printShiftOperand(std::ostream &os,
                                     RegIndex rm,
                                     bool immShift,
                                     uint32_t shiftAmt,
                                     RegIndex rs,
                                     ArmShiftType type) const
{
    bool firstOp = false;

    if (rm != int_reg::Zero) {
        printIntReg(os, rm);
    }

    bool done = false;

    if ((type == LSR || type == ASR) && immShift && shiftAmt == 0)
        shiftAmt = 32;

    switch (type) {
      case LSL:
        if (immShift && shiftAmt == 0) {
            done = true;
            break;
        }
        if (!firstOp)
            os << ", ";
        os << "LSL";
        break;
      case LSR:
        if (!firstOp)
            os << ", ";
        os << "LSR";
        break;
      case ASR:
        if (!firstOp)
            os << ", ";
        os << "ASR";
        break;
      case ROR:
        if (immShift && shiftAmt == 0) {
            if (!firstOp)
                os << ", ";
            os << "RRX";
            done = true;
            break;
        }
        if (!firstOp)
            os << ", ";
        os << "ROR";
        break;
      default:
        panic("Tried to disassemble unrecognized shift type.\n");
    }
    if (!done) {
        if (!firstOp)
            os << " ";
        if (immShift)
            os << "#" << shiftAmt;
        else
            printIntReg(os, rs);
    }
}

void
ArmStaticInst::printExtendOperand(bool firstOperand, std::ostream &os,
                                  RegIndex rm, ArmExtendType type,
                                  int64_t shiftAmt) const
{
    if (!firstOperand)
        ccprintf(os, ", ");
    printIntReg(os, rm);
    if (type == UXTX && shiftAmt == 0)
        return;
    switch (type) {
      case UXTB: ccprintf(os, ", UXTB");
        break;
      case UXTH: ccprintf(os, ", UXTH");
        break;
      case UXTW: ccprintf(os, ", UXTW");
        break;
      case UXTX: ccprintf(os, ", LSL");
        break;
      case SXTB: ccprintf(os, ", SXTB");
        break;
      case SXTH: ccprintf(os, ", SXTH");
        break;
      case SXTW: ccprintf(os, ", SXTW");
        break;
      case SXTX: ccprintf(os, ", SXTW");
        break;
    }
    if (type == UXTX || shiftAmt)
        ccprintf(os, " #%d", shiftAmt);
}

void
ArmStaticInst::printDataInst(std::ostream &os, bool withImm,
        bool immShift, bool s, RegIndex rd, RegIndex rn,
        RegIndex rm, RegIndex rs, uint32_t shiftAmt,
        ArmShiftType type, uint64_t imm) const
{
    printMnemonic(os, s ? "s" : "");
    bool firstOp = true;

    // Destination
    if (rd != int_reg::Zero) {
        firstOp = false;
        printIntReg(os, rd);
    }

    // Source 1.
    if (rn != int_reg::Zero) {
        if (!firstOp)
            os << ", ";
        firstOp = false;
        printIntReg(os, rn);
    }

    if (!firstOp)
        os << ", ";
    if (withImm) {
        ccprintf(os, "#%ld", imm);
    } else {
        printShiftOperand(os, rm, immShift, shiftAmt, rs, type);
    }
}

std::string
ArmStaticInst::generateDisassembly(Addr pc,
                                   const loader::SymbolTable *symtab) const
{
    std::stringstream ss;
    printMnemonic(ss);
    return ss.str();
}

Fault
ArmStaticInst::softwareBreakpoint32(ExecContext *xc, uint16_t imm) const
{
    const auto tc = xc->tcBase();
    const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
    const HDCR mdcr = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
    if ((EL2Enabled(tc) && !ELIs32(tc, EL2) &&
         (hcr.tge || mdcr.tde)) || !ELIs32(tc, EL1)) {
        // Route to AArch64 Software Breakpoint
        return std::make_shared<SoftwareBreakpoint>(machInst, imm);
    } else {
        // Execute AArch32 Software Breakpoint
        return std::make_shared<PrefetchAbort>(readPC(xc),
                                               ArmFault::DebugEvent,
                                               false,
                                               ArmFault::UnknownTran,
                                               ArmFault::BRKPOINT);
    }
}

Fault
ArmStaticInst::advSIMDFPAccessTrap64(ExceptionLevel el) const
{
    switch (el) {
      case EL1:
        return std::make_shared<SupervisorTrap>(machInst, 0x1E00000,
                                                EC_TRAPPED_SIMD_FP);
      case EL2:
        return std::make_shared<HypervisorTrap>(machInst, 0x1E00000,
                                                EC_TRAPPED_SIMD_FP);
      case EL3:
        return std::make_shared<SecureMonitorTrap>(machInst, 0x1E00000,
                                                   EC_TRAPPED_SIMD_FP);

      default:
        panic("Illegal EL in advSIMDFPAccessTrap64\n");
    }
}


Fault
ArmStaticInst::checkFPAdvSIMDTrap64(ThreadContext *tc, CPSR cpsr) const
{
    if (currEL(tc) <= EL2 && EL2Enabled(tc)) {
        bool trap_el2 = false;
        CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL2);
        HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
        if (HaveExt(tc, ArmExtension::FEAT_VHE) && hcr.e2h == 0x1) {
            switch (cptr_en_check.fpen) {
              case 0:
              case 2:
                trap_el2 = !(currEL(tc) == EL1 && hcr.tge == 1);
                break;
              case 1:
                trap_el2 = (currEL(tc) == EL0 && hcr.tge == 1);
                break;
              default:
                trap_el2 = false;
                break;
            }
        } else if (cptr_en_check.tfp) {
            trap_el2 = true;
        }

        if (trap_el2) {
            return advSIMDFPAccessTrap64(EL2);
        }
    }

    if (ArmSystem::haveEL(tc, EL3)) {
        CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
        if (cptr_en_check.tfp) {
            return advSIMDFPAccessTrap64(EL3);
        }
    }

    return NoFault;
}

Fault
ArmStaticInst::checkFPAdvSIMDEnabled64(ThreadContext *tc,
                                       CPSR cpsr, CPACR cpacr) const
{
    const ExceptionLevel el = currEL(tc);
    if ((el == EL0 && cpacr.fpen != 0x3) ||
        (el == EL1 && !(cpacr.fpen & 0x1)))
        return advSIMDFPAccessTrap64(EL1);

    return checkFPAdvSIMDTrap64(tc, cpsr);
}

Fault
ArmStaticInst::checkAdvSIMDOrFPEnabled32(ThreadContext *tc,
                                         CPSR cpsr, CPACR cpacr,
                                         NSACR nsacr, FPEXC fpexc,
                                         bool fpexc_check, bool advsimd) const
{
    const bool have_virtualization = ArmSystem::haveEL(tc, EL2);
    const bool have_security = ArmSystem::haveEL(tc, EL3);
    const bool is_secure = isSecure(tc);
    const ExceptionLevel cur_el = currEL(tc);

    if (cur_el == EL0 && ELIs64(tc, EL1))
        return checkFPAdvSIMDEnabled64(tc, cpsr, cpacr);

    uint8_t cpacr_cp10 = cpacr.cp10;
    bool cpacr_asedis = cpacr.asedis;

    if (have_security && !ELIs64(tc, EL3) && !is_secure) {
        if (nsacr.nsasedis)
            cpacr_asedis = true;
        if (nsacr.cp10 == 0)
            cpacr_cp10 = 0;
    }

    if (cur_el != EL2) {
        if (advsimd && cpacr_asedis)
            return disabledFault();

        if ((cur_el == EL0 && cpacr_cp10 != 0x3) ||
            (cur_el != EL0 && !(cpacr_cp10 & 0x1)))
            return disabledFault();
    }

    if (fpexc_check && !fpexc.en)
        return disabledFault();

    // -- aarch32/exceptions/traps/AArch32.CheckFPAdvSIMDTrap --

    if (have_virtualization && !is_secure && ELIs64(tc, EL2))
        return checkFPAdvSIMDTrap64(tc, cpsr);

    if (have_virtualization && !is_secure) {
        HCPTR hcptr = tc->readMiscReg(MISCREG_HCPTR);
        bool hcptr_cp10 = hcptr.tcp10;
        bool hcptr_tase = hcptr.tase;

        if (have_security && !ELIs64(tc, EL3) && !is_secure) {
            if (nsacr.nsasedis)
                hcptr_tase = true;
            if (nsacr.cp10)
                hcptr_cp10 = true;
        }

        if ((advsimd && hcptr_tase) || hcptr_cp10) {
            const uint32_t iss = advsimd ? (1 << 5) : 0xA;
            if (cur_el == EL2) {
                return std::make_shared<UndefinedInstruction>(
                    machInst, iss,
                    EC_TRAPPED_HCPTR, mnemonic);
            } else {
                return std::make_shared<HypervisorTrap>(
                    machInst, iss,
                    EC_TRAPPED_HCPTR);
            }

        }
    }

    if (have_security && ELIs64(tc, EL3)) {
        HCPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
        if (cptr_en_check.tfp)
            return advSIMDFPAccessTrap64(EL3);
    }

    return NoFault;
}

inline bool
ArmStaticInst::isWFxTrapping(ThreadContext *tc,
                             ExceptionLevel tgtEl,
                             bool isWfe) const
{
    bool trap = false;
    SCTLR sctlr = ((SCTLR)tc->readMiscReg(MISCREG_SCTLR_EL1));
    HCR hcr = ((HCR)tc->readMiscReg(MISCREG_HCR_EL2));
    SCR scr = ((SCR)tc->readMiscReg(MISCREG_SCR_EL3));

    switch (tgtEl) {
      case EL1:
        trap = isWfe? !sctlr.ntwe : !sctlr.ntwi;
        break;
      case EL2:
        trap = isWfe? hcr.twe : hcr.twi;
        break;
      case EL3:
        trap = isWfe? scr.twe : scr.twi;
        break;
      default:
        break;
    }

    return trap;
}

Fault
ArmStaticInst::checkForWFxTrap32(ThreadContext *tc,
                                 ExceptionLevel targetEL,
                                 bool isWfe) const
{
    // Check if target exception level is implemented.
    assert(ArmSystem::haveEL(tc, targetEL));

    // Check for routing to AArch64: this happens if the
    // target exception level (where the trap will be handled)
    // is using aarch64
    if (ELIs64(tc, targetEL)) {
        return checkForWFxTrap64(tc, targetEL, isWfe);
    }

    // Check if processor needs to trap at selected exception level
    bool trap = isWFxTrapping(tc, targetEL, isWfe);

    if (trap) {
        uint32_t iss = isWfe? 0x1E00001 : /* WFE Instruction syndrome */
                              0x1E00000;  /* WFI Instruction syndrome */
        switch (targetEL) {
          case EL1:
            return std::make_shared<UndefinedInstruction>(
                machInst, iss,
                EC_TRAPPED_WFI_WFE, mnemonic);
          case EL2:
            return std::make_shared<HypervisorTrap>(machInst, iss,
                                                    EC_TRAPPED_WFI_WFE);
          case EL3:
            return std::make_shared<SecureMonitorTrap>(machInst, iss,
                                                       EC_TRAPPED_WFI_WFE);
          default:
            panic("Unrecognized Exception Level: %d\n", targetEL);
        }
    }

    return NoFault;
}

Fault
ArmStaticInst::checkForWFxTrap64(ThreadContext *tc,
                                 ExceptionLevel targetEL,
                                 bool isWfe) const
{
    // Check if target exception level is implemented.
    assert(ArmSystem::haveEL(tc, targetEL));

    // Check if processor needs to trap at selected exception level
    bool trap = isWFxTrapping(tc, targetEL, isWfe);

    if (trap) {
        uint32_t iss = isWfe? 0x1E00001 : /* WFE Instruction syndrome */
                              0x1E00000;  /* WFI Instruction syndrome */
        switch (targetEL) {
          case EL1:
            return std::make_shared<SupervisorTrap>(machInst, iss,
                                                    EC_TRAPPED_WFI_WFE);
          case EL2:
            return std::make_shared<HypervisorTrap>(machInst, iss,
                                                    EC_TRAPPED_WFI_WFE);
          case EL3:
            return std::make_shared<SecureMonitorTrap>(machInst, iss,
                                                       EC_TRAPPED_WFI_WFE);
          default:
            panic("Unrecognized Exception Level: %d\n", targetEL);
        }
    }

    return NoFault;
}

Fault
ArmStaticInst::trapWFx(ThreadContext *tc,
                       CPSR cpsr, SCR scr,
                       bool isWfe) const
{
    Fault fault = NoFault;
    ExceptionLevel curr_el = currEL(tc);

    if (curr_el == EL0) {
        fault = checkForWFxTrap32(tc, EL1, isWfe);
    }

    if ((fault == NoFault) && EL2Enabled(tc) &&
        ((curr_el == EL0) || (curr_el == EL1))) {

        fault = checkForWFxTrap32(tc, EL2, isWfe);
    }

    if ((fault == NoFault) &&
        ArmSystem::haveEL(tc, EL3) && curr_el != EL3) {
        fault = checkForWFxTrap32(tc, EL3, isWfe);
    }

    return fault;
}

Fault
ArmStaticInst::checkSETENDEnabled(ThreadContext *tc, CPSR cpsr) const
{
    bool setend_disabled(false);
    ExceptionLevel pstate_el = currEL(tc);

    if (pstate_el == EL2) {
       setend_disabled = ((SCTLR)tc->readMiscRegNoEffect(MISCREG_HSCTLR)).sed;
    } else {
        // Please note: in the armarm pseudocode there is a distinction
        // whether EL1 is aarch32 or aarch64:
        // if ELUsingAArch32(EL1) then SCTLR.SED else SCTLR[].SED;
        // Considering that SETEND is aarch32 only, ELUsingAArch32(EL1)
        // will always be true (hence using SCTLR.SED) except for
        // instruction executed at EL0, and with an AArch64 EL1.
        // In this case SCTLR_EL1 will be used. In gem5 the register is
        // mapped to SCTLR_ns. We can safely use SCTLR and choose the
        // appropriate bank version.

        // Get the index of the banked version of SCTLR:
        // SCTLR_s or SCTLR_ns.
        auto banked_sctlr = snsBankedIndex(
            MISCREG_SCTLR, tc, !isSecure(tc));

        // SCTLR.SED bit is enabling/disabling the ue of SETEND instruction.
        setend_disabled = ((SCTLR)tc->readMiscRegNoEffect(banked_sctlr)).sed;
    }

    return setend_disabled ? undefinedFault32(tc, pstate_el) :
                             NoFault;
}

Fault
ArmStaticInst::undefinedFault32(ThreadContext *tc,
                                ExceptionLevel pstateEL) const
{
    // Even if we are running in aarch32, the fault might be dealt with in
    // aarch64 ISA.
    if (generalExceptionsToAArch64(tc, pstateEL)) {
        return undefinedFault64(tc, pstateEL);
    } else {
        // Please note: according to the ARM ARM pseudocode we should handle
        // the case when EL2 is aarch64 and HCR.TGE is 1 as well.
        // However this case is already handled by the routeToHyp method in
        // ArmFault class.
        return std::make_shared<UndefinedInstruction>(
            machInst, 0,
            EC_UNKNOWN, mnemonic);
    }
}

Fault
ArmStaticInst::undefinedFault64(ThreadContext *tc,
                                ExceptionLevel pstateEL) const
{
    switch (pstateEL) {
      case EL0:
      case EL1:
        return std::make_shared<SupervisorTrap>(machInst, 0, EC_UNKNOWN);
      case EL2:
        return std::make_shared<HypervisorTrap>(machInst, 0, EC_UNKNOWN);
      case EL3:
        return std::make_shared<SecureMonitorTrap>(machInst, 0, EC_UNKNOWN);
      default:
        panic("Unrecognized Exception Level: %d\n", pstateEL);
        break;
    }

    return NoFault;
}

Fault
ArmStaticInst::sveAccessTrap(ExceptionLevel el) const
{
    switch (el) {
      case EL1:
        return std::make_shared<SupervisorTrap>(machInst, 0, EC_TRAPPED_SVE);
      case EL2:
        return std::make_shared<HypervisorTrap>(machInst, 0, EC_TRAPPED_SVE);
      case EL3:
        return std::make_shared<SecureMonitorTrap>(machInst, 0,
                                                   EC_TRAPPED_SVE);

      default:
        panic("Illegal EL in sveAccessTrap\n");
    }
}

Fault
ArmStaticInst::checkSveEnabled(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
{
    const ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
    // Check if access disabled in CPACR_EL1
    if (el <= EL1 && !ELIsInHost(tc, el)) {
        if ((el == EL0 && cpacr.zen == 0x1) ||
            (!(cpacr.zen & 0x1)))
            return sveAccessTrap(EL1);

        if ((el == EL0 && cpacr.fpen == 0x1) ||
            (!(cpacr.fpen & 0x1)))
            return advSIMDFPAccessTrap64(EL1);
    }

    // Check if access disabled in CPTR_EL2
    if (el <= EL2 && EL2Enabled(tc)) {
        CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL2);
        HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
        if (HaveExt(tc, ArmExtension::FEAT_VHE) && hcr.e2h) {
            if (((cptr_en_check.zen & 0x1) == 0x0) ||
                (cptr_en_check.zen == 0x1 && el == EL0 &&
                 hcr.tge == 0x1)) {
                return sveAccessTrap(EL2);
            }
            if (((cptr_en_check.fpen & 0x1) == 0x0) ||
                (cptr_en_check.fpen == 0x1 && el == EL0 &&
                 hcr.tge == 0x1)) {
                return advSIMDFPAccessTrap64(EL2);
            }
        } else {
            if (cptr_en_check.tz == 1)
                return sveAccessTrap(EL2);
            if (cptr_en_check.tfp == 1)
                return advSIMDFPAccessTrap64(EL2);
        }
    }

    // Check if access disabled in CPTR_EL3
    if (ArmSystem::haveEL(tc, EL3)) {
        CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
        if (!cptr_en_check.ez)
            return sveAccessTrap(EL3);
        if (cptr_en_check.tfp)
            return advSIMDFPAccessTrap64(EL3);
    }

    return NoFault;
}

static uint8_t
getRestoredITBits(ThreadContext *tc, CPSR spsr)
{
    // See: shared/functions/system/RestoredITBits in the ARM ARM

    const ExceptionLevel el = opModeToEL((OperatingMode) (uint8_t)spsr.mode);
    const uint8_t it = itState(spsr);

    if (!spsr.t || spsr.il)
        return 0;

    // The IT bits are forced to zero when they are set to a reserved
    // value.
    if (bits(it, 7, 4) != 0 && bits(it, 3, 0) == 0)
        return 0;

    const bool itd = el == EL2 ?
        ((SCTLR)tc->readMiscReg(MISCREG_HSCTLR)).itd :
        ((SCTLR)tc->readMiscReg(MISCREG_SCTLR)).itd;

    // The IT bits are forced to zero when returning to A32 state, or
    // when returning to an EL with the ITD bit set to 1, and the IT
    // bits are describing a multi-instruction block.
    if (itd && bits(it, 2, 0) != 0)
        return 0;

    return it;
}

static bool
illegalExceptionReturn(ThreadContext *tc, CPSR cpsr, CPSR spsr)
{
    const OperatingMode mode = (OperatingMode) (uint8_t)spsr.mode;
    if (unknownMode(mode))
        return true;

    SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
    HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);

    //ELFromSPSR
    bool valid;
    ExceptionLevel target_el = opModeToEL(mode);
    if (!spsr.width) {
        if (!ArmSystem::highestELIs64(tc)) {
            valid = false;
        } else if (!ArmSystem::haveEL(tc, target_el)) {
            valid = false;
        } else if (spsr & 0x2) {
            valid = false;
        } else if (target_el == EL0 && spsr.sp) {
            valid = false;
        } else if (target_el == EL2 && ArmSystem::haveEL(tc, EL3) &&
                   !scr.ns && !IsSecureEL2Enabled(tc)) {
            valid = false;
        } else {
            valid = true;
        }
    } else {
        valid = !unknownMode32(mode);
    }
    if (!valid)
        return true;

    if (target_el > currEL(tc))
        return true;

    bool spsr_mode_is_aarch32 = (spsr.width == 1);
    auto [known, target_el_is_aarch32] = ELUsingAArch32K(tc, target_el);
    assert(known || (target_el == EL0 && ELIs64(tc, EL1)));

    if (known && (spsr_mode_is_aarch32 != target_el_is_aarch32))
        return true;

    if (target_el == EL1 && ArmSystem::haveEL(tc, EL2) && hcr.tge &&
            (IsSecureEL2Enabled(tc) || !isSecureBelowEL3(tc))) {
        return true;
    }

    return false;
}

CPSR
ArmStaticInst::getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr) const
{
    CPSR new_cpsr = 0;
    ExceptionLevel dest;

    if (illegalExceptionReturn(tc, cpsr, spsr)) {
        // If the SPSR specifies an illegal exception return,
        // then PSTATE.{M, nRW, EL, SP} are unchanged and PSTATE.IL
        // is set to 1.
        new_cpsr.il = 1;
        if (cpsr.width) {
            new_cpsr.mode = cpsr.mode;
        } else {
            new_cpsr.width = cpsr.width;
            new_cpsr.el = cpsr.el;
            new_cpsr.sp = cpsr.sp;
        }
        dest = currEL(tc);
    } else {
        new_cpsr.il = spsr.il;
        if (spsr.width && unknownMode32((OperatingMode)(uint8_t)spsr.mode)) {
            new_cpsr.il = 1;
        } else if (spsr.width) {
            new_cpsr.mode = spsr.mode;
        } else {
            new_cpsr.el = spsr.el;
            new_cpsr.sp = spsr.sp;
        }
        dest = (ExceptionLevel)(uint8_t) spsr.el;
    }

    new_cpsr.nz = spsr.nz;
    new_cpsr.c = spsr.c;
    new_cpsr.v = spsr.v;
    new_cpsr.pan = spsr.pan;
    if (new_cpsr.width) {
        // aarch32
        const ITSTATE it = getRestoredITBits(tc, spsr);
        new_cpsr.q = spsr.q;
        new_cpsr.ge = spsr.ge;
        new_cpsr.e = spsr.e;
        new_cpsr.aif = spsr.aif;
        new_cpsr.t = spsr.t;
        new_cpsr.it2 = it.top6;
        new_cpsr.it1 = it.bottom2;
    } else {
        // aarch64
        new_cpsr.daif = spsr.daif;
        new_cpsr.uao = spsr.uao;
    }

    SelfDebug *sd = ArmISA::ISA::getSelfDebug(tc);
    SoftwareStep *ss = sd->getSstep();
    new_cpsr.ss = ss->debugExceptionReturnSS(tc, spsr, dest);

    return new_cpsr;
}

bool
ArmStaticInst::generalExceptionsToAArch64(ThreadContext *tc,
                                          ExceptionLevel pstateEL) const
{
    // Returns TRUE if exceptions normally routed to EL1 are being handled
    // at an Exception level using AArch64, because either EL1 is using
    // AArch64 or TGE is in force and EL2 is using AArch64.
    HCR hcr = ((HCR)tc->readMiscReg(MISCREG_HCR_EL2));
    return (pstateEL == EL0 && !ELIs32(tc, EL1)) ||
           (ArmSystem::haveEL(tc, EL2) && !isSecure(tc) &&
               !ELIs32(tc, EL2) && hcr.tge);
}

unsigned
ArmStaticInst::getCurSveVecLenInBits(ThreadContext *tc)
{
    auto *isa = static_cast<ArmISA::ISA *>(tc->getIsaPtr());
    return isa->getCurSveVecLenInBits();
}

} // namespace ArmISA
} // namespace gem5
