58 uint32_t
type, uint32_t cfval)
const 75 return (base >> 31) | -((base & (1 << 31)) >> 31);
77 return (base >> shamt) | -((base & (1 << 31)) >> shamt);
80 return (cfval << 31) | (base >> 1);
82 return (base << (32 - shamt)) | (base >> shamt);
84 ccprintf(std::cerr,
"Unhandled shift type\n");
95 shiftAmt = shiftAmt %
width;
102 return base << shiftAmt;
107 return (base &
mask(width)) >> shiftAmt;
114 base = sign_bit ? (base | ~
mask(
intWidth - shiftAmt)) : base;
121 return (base << (width - shiftAmt)) | (base >> shiftAmt);
123 ccprintf(std::cerr,
"Unhandled shift type\n");
132 uint64_t shiftAmt, uint8_t
width)
const 134 bool sign_extend =
false;
166 len = len <= width - shiftAmt ?
len : width - shiftAmt;
167 uint64_t tmp = (uint64_t)
bits(base, len - 1, 0) << shiftAmt;
169 int sign_bit =
bits(tmp, len + shiftAmt - 1);
170 tmp = sign_bit ? (tmp | ~
mask(len + shiftAmt)) : tmp;
172 return tmp &
mask(width);
178 uint32_t
type, uint32_t cfval)
const 189 return base << shamt;
194 return base >> shamt;
197 return (base >> 31) | -((base & (1 << 31)) >> 31);
199 return (base >> shamt) | -((base & (1 << 31)) >> shamt);
201 shamt = shamt & 0x1f;
205 return (base << (32 - shamt)) | (base >> shamt);
207 ccprintf(std::cerr,
"Unhandled shift type\n");
218 uint32_t
type, uint32_t cfval)
const 229 return (base >> (32 - shamt)) & 1;
234 return (base >> (shamt - 1)) & 1;
239 return (base >> (shamt - 1)) & 1;
241 shamt = shamt & 0x1f;
245 return (base >> (shamt - 1)) & 1;
247 ccprintf(std::cerr,
"Unhandled shift type\n");
258 uint32_t
type, uint32_t cfval)
const 272 return (base >> (32 - shamt)) & 1;
277 return (base >> (shamt - 1)) & 1;
281 return (base >> (shamt - 1)) & 1;
283 shamt = shamt & 0x1f;
286 return (base >> (shamt - 1)) & 1;
288 ccprintf(std::cerr,
"Unhandled shift type\n");
297 uint8_t opWidth)
const 305 ccprintf(os,
"%s%s", (opWidth == 32) ?
"w" :
"",
"sp");
307 ccprintf(os,
"%szr", (opWidth == 32) ?
"w" :
"x");
309 ccprintf(os,
"%s%d", (opWidth == 32) ?
"w" :
"x", reg_idx);
333 const char *flagtoprfop[]= {
"PLD",
"PLI",
"PST",
"Reserved"};
334 const char *flagtotarget[] = {
"L1",
"L2",
"L3",
"Reserved"};
335 const char *flagtopolicy[] = {
"KEEP",
"STRM"};
337 ccprintf(os,
"%s%s%s", flagtoprfop[(flag>>3)&3],
338 flagtotarget[(flag>>1)&3], flagtopolicy[flag&1]);
349 bool isSveVecReg)
const 351 ccprintf(os,
"%s%d", isSveVecReg ?
"z" :
"v", reg_idx);
375 const std::string &suffix,
384 }
else if (withCond64) {
403 if (symbolAddr != target)
404 ccprintf(os,
"+%d>", target - symbolAddr);
415 bool noImplicit)
const 471 panic(
"Unrecognized condition code %d.\n", code);
478 const std::string &prefix,
480 const std::string &suffix)
const 485 ccprintf(os,
"%s%s", prefix, symbol);
486 if (symbolAddr != addr)
487 ccprintf(os,
"+%d", addr - symbolAddr);
500 bool firstOp =
false;
508 if ((type ==
LSR || type ==
ASR) && immShift && shiftAmt == 0)
513 if (immShift && shiftAmt == 0) {
532 if (immShift && shiftAmt == 0) {
544 panic(
"Tried to disassemble unrecognized shift type.\n");
550 os <<
"#" << shiftAmt;
559 int64_t shiftAmt)
const 564 if (type ==
UXTX && shiftAmt == 0)
584 if (type ==
UXTX || shiftAmt)
624 std::stringstream
ss;
632 const auto tc = xc->
tcBase();
636 !
ELIs32(tc,
EL2) && (hcr.tge == 1 || mdcr.tde == 1)) ||
639 return std::make_shared<SoftwareBreakpoint>(
machInst,
imm);
642 return std::make_shared<PrefetchAbort>(
readPC(xc),
652 return std::make_shared<SupervisorTrap>(
machInst, 0x1E00000,
655 return std::make_shared<HypervisorTrap>(
machInst, 0x1E00000,
658 return std::make_shared<SecureMonitorTrap>(
machInst, 0x1E00000,
662 panic(
"Illegal EL in advSIMDFPAccessTrap64\n");
687 CPSR cpsr, CPACR cpacr)
const 690 if ((el ==
EL0 && cpacr.fpen != 0x3) ||
691 (el ==
EL1 && !(cpacr.fpen & 0x1)))
699 CPSR cpsr, CPACR cpacr,
700 NSACR nsacr, FPEXC fpexc,
701 bool fpexc_check,
bool advsimd)
const 711 uint8_t cpacr_cp10 = cpacr.cp10;
712 bool cpacr_asedis = cpacr.asedis;
714 if (have_security && !
ELIs64(tc,
EL3) && !is_secure) {
722 if (advsimd && cpacr_asedis)
725 if ((cur_el ==
EL0 && cpacr_cp10 != 0x3) ||
726 (cur_el !=
EL0 && !(cpacr_cp10 & 0x1)))
730 if (fpexc_check && !fpexc.en)
735 if (have_virtualization && !is_secure &&
ELIs64(tc,
EL2))
738 if (have_virtualization && !is_secure) {
740 bool hcptr_cp10 = hcptr.tcp10;
741 bool hcptr_tase = hcptr.tase;
743 if (have_security && !
ELIs64(tc,
EL3) && !is_secure) {
750 if ((advsimd && hcptr_tase) || hcptr_cp10) {
751 const uint32_t iss = advsimd ? (1 << 5) : 0xA;
753 return std::make_shared<UndefinedInstruction>(
757 return std::make_shared<HypervisorTrap>(
786 trap = isWfe? !sctlr.ntwe : !sctlr.ntwi;
789 trap = isWfe? hcr.twe : hcr.twi;
792 trap = isWfe? scr.twe : scr.twi;
812 if (
ELIs64(tc, targetEL)) {
820 uint32_t iss = isWfe? 0x1E00001 :
824 return std::make_shared<UndefinedInstruction>(
828 return std::make_shared<HypervisorTrap>(
machInst, iss,
831 return std::make_shared<SecureMonitorTrap>(
machInst, iss,
834 panic(
"Unrecognized Exception Level: %d\n", targetEL);
853 uint32_t iss = isWfe? 0x1E00001 :
857 return std::make_shared<SupervisorTrap>(
machInst, iss,
860 return std::make_shared<HypervisorTrap>(
machInst, iss,
863 return std::make_shared<SecureMonitorTrap>(
machInst, iss,
866 panic(
"Unrecognized Exception Level: %d\n", targetEL);
881 if (curr_el ==
EL0) {
887 ((curr_el ==
EL0) || (curr_el ==
EL1))) {
903 bool setend_disabled(
false);
906 if (pstate_el ==
EL2) {
945 return std::make_shared<UndefinedInstruction>(
964 panic(
"Unrecognized Exception Level: %d\n", pstateEL);
980 return std::make_shared<SecureMonitorTrap>(
machInst, 0,
984 panic(
"Illegal EL in sveAccessTrap\n");
1001 if (!cptrEnCheck.ez)
1012 if ((el ==
EL0 && cpacr.zen != 0x3) ||
1013 (el ==
EL1 && !(cpacr.zen & 0x1)))
1026 const uint8_t it =
itState(spsr);
1028 if (!spsr.t || spsr.il)
1033 if (
bits(it, 7, 4) != 0 &&
bits(it, 3, 0) == 0)
1036 const bool itd = el ==
EL2 ?
1043 if (itd &&
bits(it, 2, 0) != 0)
1074 bool spsr_mode_is_aarch32 = (spsr.width == 1);
1075 bool known, target_el_is_aarch32;
1076 std::tie(known, target_el_is_aarch32) =
ELUsingAArch32K(tc, target_el);
1077 assert(known || (target_el ==
EL0 &&
ELIs64(tc,
EL1)));
1079 if (known && (spsr_mode_is_aarch32 != target_el_is_aarch32))
1088 if (target_el ==
EL0 && spsr.sp)
1113 new_cpsr.mode = cpsr.mode;
1115 new_cpsr.width = cpsr.width;
1116 new_cpsr.el = cpsr.el;
1117 new_cpsr.sp = cpsr.sp;
1120 new_cpsr.il = spsr.il;
1123 }
else if (spsr.width) {
1124 new_cpsr.mode = spsr.mode;
1126 new_cpsr.el = spsr.el;
1127 new_cpsr.sp = spsr.sp;
1131 new_cpsr.nz = spsr.nz;
1132 new_cpsr.c = spsr.c;
1133 new_cpsr.v = spsr.v;
1134 new_cpsr.pan = spsr.pan;
1135 if (new_cpsr.width) {
1138 new_cpsr.q = spsr.q;
1139 new_cpsr.ge = spsr.ge;
1140 new_cpsr.e = spsr.e;
1141 new_cpsr.aif = spsr.aif;
1142 new_cpsr.t = spsr.t;
1143 new_cpsr.it2 = it.top6;
1144 new_cpsr.it1 = it.bottom2;
1147 new_cpsr.daif = spsr.daif;
int32_t shift_rm_imm(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval) const
CPSR getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr) const
Get the new PSTATE from a SPSR register in preparation for an exception return.
#define panic(...)
This implements a cprintf based panic() function.
void ccprintf(cp::Print &print)
void printMnemonic(std::ostream &os, const std::string &suffix="", bool withPred=true, bool withCond64=false, ConditionCode cond64=COND_UC) const
static bool unknownMode(OperatingMode mode)
decltype(nullptr) constexpr NoFault
static ExceptionLevel currEL(ThreadContext *tc)
Fault checkSveTrap(ThreadContext *tc, CPSR cpsr) const
Check an SVE access against CPTR_EL2 and CPTR_EL3.
bool haveSecurity() const
Returns true if this system implements the Security Extensions.
Fault checkForWFxTrap32(ThreadContext *tc, ExceptionLevel tgtEl, bool isWfe) const
Check if WFE/WFI instruction execution in aarch32 should be trapped.
void printExtendOperand(bool firstOperand, std::ostream &os, IntRegIndex rm, ArmExtendType type, int64_t shiftAmt) const
Fault checkSveEnabled(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
Check an SVE access against CPACR_EL1, CPTR_EL2, and CPTR_EL3.
static uint8_t itState(CPSR psr)
const char * mnemonic
Base mnemonic (e.g., "add").
bool shift_carry_imm(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval) const
bool highestELIs64() const
Returns true if the register width of the highest implemented exception level is 64 bits (ARMv8) ...
Fault undefinedFault64(ThreadContext *tc, ExceptionLevel el) const
UNDEFINED behaviour in AArch64.
const char *const miscRegName[]
static Addr readPC(ExecContext *xc)
bool isWFxTrapping(ThreadContext *tc, ExceptionLevel targetEL, bool isWfe) const
ThreadContext is the external interface to all thread state for anything outside of the CPU...
unsigned getCurSveVecLenInBits(ThreadContext *tc) const
static unsigned getCurSveVecLenInBits(ThreadContext *tc)
Fault checkFPAdvSIMDEnabled64(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
Check an Advaned SIMD access against CPACR_EL1, CPTR_EL2, and CPTR_EL3.
static bool haveEL(ThreadContext *tc, ExceptionLevel el)
Return true if the system implements a specific exception level.
Fault undefinedFault32(ThreadContext *tc, ExceptionLevel el) const
UNDEFINED behaviour in AArch32.
void printVecPredReg(std::ostream &os, RegIndex reg_idx) const
bool ELIs64(ThreadContext *tc, ExceptionLevel el)
const ExtMachInst machInst
The binary machine instruction.
The ExecContext is an abstract base class the provides the interface used by the ISA to manipulate th...
Fault checkForWFxTrap64(ThreadContext *tc, ExceptionLevel tgtEl, bool isWfe) const
Check if WFE/WFI instruction execution in aarch64 should be trapped.
Fault sveAccessTrap(ExceptionLevel el) const
Trap an access to SVE registers due to access control bits.
const int ReturnAddressReg
void printCondition(std::ostream &os, unsigned code, bool noImplicit=false) const
const char *const ccRegName[NUM_CCREGS]
const int StackPointerReg
void printVecReg(std::ostream &os, RegIndex reg_idx, bool isSveVecReg=false) const
const int FramePointerReg
void printIntReg(std::ostream &os, RegIndex reg_idx, uint8_t opWidth=0) const
Print a register name for disassembly given the unique dependence tag number (FP or int)...
int64_t shiftReg64(uint64_t base, uint64_t shiftAmt, ArmShiftType type, uint8_t width) const
bool findNearestSymbol(Addr addr, std::string &symbol, Addr &symaddr, Addr &nextaddr) const
Find the nearest symbol equal to or less than the supplied address (e.g., the label for the enclosing...
static ExceptionLevel opModeToEL(OperatingMode mode)
Fault softwareBreakpoint32(ExecContext *xc, uint16_t imm) const
Trigger a Software Breakpoint.
bool ELIs32(ThreadContext *tc, ExceptionLevel el)
void printShiftOperand(std::ostream &os, IntRegIndex rm, bool immShift, uint32_t shiftAmt, IntRegIndex rs, ArmShiftType type) const
static bool illegalExceptionReturn(ThreadContext *tc, CPSR cpsr, CPSR spsr)
std::pair< bool, bool > ELUsingAArch32K(ThreadContext *tc, ExceptionLevel el)
This function checks whether selected EL provided as an argument is using the AArch32 ISA...
bool haveVirtualization() const
Returns true if this system implements the virtualization Extensions.
virtual BaseISA * getIsaPtr()=0
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Fault checkSETENDEnabled(ThreadContext *tc, CPSR cpsr) const
Check if SETEND instruction execution in aarch32 should be trapped.
int64_t extendReg64(uint64_t base, ArmExtendType type, uint64_t shiftAmt, uint8_t width) const
void printMiscReg(std::ostream &os, RegIndex reg_idx) const
bool shift_carry_rs(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval) const
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
static bool unknownMode32(OperatingMode mode)
int32_t shift_rm_rs(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval) const
void printPFflags(std::ostream &os, int flag) const
int snsBankedIndex(MiscRegIndex reg, ThreadContext *tc)
Bitfield< 23, 20 > advsimd
virtual ThreadContext * tcBase()=0
Returns a pointer to the ThreadContext.
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const override
Internal function to generate disassembly string.
Fault disabledFault() const
Fault checkAdvSIMDOrFPEnabled32(ThreadContext *tc, CPSR cpsr, CPACR cpacr, NSACR nsacr, FPEXC fpexc, bool fpexc_check, bool advsimd) const
Check if a VFP/SIMD access from aarch32 should be allowed.
void printFloatReg(std::ostream &os, RegIndex reg_idx) const
Fault checkFPAdvSIMDTrap64(ThreadContext *tc, CPSR cpsr) const
Check an Advaned SIMD access against CPTR_EL2 and CPTR_EL3.
static uint8_t getRestoredITBits(ThreadContext *tc, CPSR spsr)
bool inSecureState(ThreadContext *tc)
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
virtual RegVal readMiscReg(RegIndex misc_reg)=0
void printMemSymbol(std::ostream &os, const SymbolTable *symtab, const std::string &prefix, const Addr addr, const std::string &suffix) const
Fault trapWFx(ThreadContext *tc, CPSR cpsr, SCR scr, bool isWfe) const
WFE/WFI trapping helper function.
std::shared_ptr< FaultBase > Fault
void printCCReg(std::ostream &os, RegIndex reg_idx) const
bool generalExceptionsToAArch64(ThreadContext *tc, ExceptionLevel pstateEL) const
Return true if exceptions normally routed to EL1 are being handled at an Exception level using AArch6...
void printTarget(std::ostream &os, Addr target, const SymbolTable *symtab) const
void printDataInst(std::ostream &os, bool withImm) const
Fault advSIMDFPAccessTrap64(ExceptionLevel el) const
Trap an access to Advanced SIMD or FP registers due to access control bits.