Go to the documentation of this file.
61 uint32_t
type, uint32_t cfval)
const
64 ArmShiftType shiftType;
65 shiftType = (ArmShiftType)
type;
78 return (
base >> 31) | -((
base & (1 << 31)) >> 31);
80 return (
base >> shamt) | -((
base & (1 << 31)) >> shamt);
83 return (cfval << 31) | (
base >> 1);
85 return (
base << (32 - shamt)) | (
base >> shamt);
87 ccprintf(std::cerr,
"Unhandled shift type\n");
98 shiftAmt = shiftAmt %
width;
99 ArmShiftType shiftType;
100 shiftType = (ArmShiftType)
type;
105 return base << shiftAmt;
126 ccprintf(std::cerr,
"Unhandled shift type\n");
135 uint64_t shiftAmt, uint8_t
width)
const
137 bool sign_extend =
false;
170 uint64_t tmp = (uint64_t)
bits(
base,
len - 1, 0) << shiftAmt;
172 int sign_bit =
bits(tmp,
len + shiftAmt - 1);
173 tmp = sign_bit ? (tmp | ~
mask(
len + shiftAmt)) : tmp;
181 uint32_t
type, uint32_t cfval)
const
183 enum ArmShiftType shiftType;
184 shiftType = (
enum ArmShiftType)
type;
192 return base << shamt;
197 return base >> shamt;
200 return (
base >> 31) | -((
base & (1 << 31)) >> 31);
202 return (
base >> shamt) | -((
base & (1 << 31)) >> shamt);
204 shamt = shamt & 0x1f;
208 return (
base << (32 - shamt)) | (
base >> shamt);
210 ccprintf(std::cerr,
"Unhandled shift type\n");
221 uint32_t
type, uint32_t cfval)
const
223 enum ArmShiftType shiftType;
224 shiftType = (
enum ArmShiftType)
type;
232 return (
base >> (32 - shamt)) & 1;
237 return (
base >> (shamt - 1)) & 1;
242 return (
base >> (shamt - 1)) & 1;
244 shamt = shamt & 0x1f;
248 return (
base >> (shamt - 1)) & 1;
250 ccprintf(std::cerr,
"Unhandled shift type\n");
261 uint32_t
type, uint32_t cfval)
const
263 enum ArmShiftType shiftType;
264 shiftType = (
enum ArmShiftType)
type;
275 return (
base >> (32 - shamt)) & 1;
280 return (
base >> (shamt - 1)) & 1;
284 return (
base >> (shamt - 1)) & 1;
286 shamt = shamt & 0x1f;
289 return (
base >> (shamt - 1)) & 1;
291 ccprintf(std::cerr,
"Unhandled shift type\n");
300 uint8_t opWidth)
const
308 ccprintf(
os,
"%s%s", (opWidth == 32) ?
"w" :
"",
"sp");
310 ccprintf(
os,
"%szr", (opWidth == 32) ?
"w" :
"x");
312 ccprintf(
os,
"%s%d", (opWidth == 32) ?
"w" :
"x", reg_idx);
336 const char *flagtoprfop[]= {
"PLD",
"PLI",
"PST",
"Reserved"};
337 const char *flagtotarget[] = {
"L1",
"L2",
"L3",
"Reserved"};
338 const char *flagtopolicy[] = {
"KEEP",
"STRM"};
340 ccprintf(
os,
"%s%s%s", flagtoprfop[(flag>>3)&3],
341 flagtotarget[(flag>>1)&3], flagtopolicy[flag&1]);
352 bool isSveVecReg)
const
354 ccprintf(
os,
"%s%d", isSveVecReg ?
"z" :
"v", reg_idx);
378 const std::string &suffix,
387 }
else if (withCond64) {
403 if (it != symtab->
end()) {
405 Addr delta = target - it->address;
419 bool noImplicit)
const
475 panic(
"Unrecognized condition code %d.\n", code);
482 const std::string &prefix,
484 const std::string &suffix)
const
488 if (it != symtab->
end()) {
490 if (it->address !=
addr)
503 ArmShiftType
type)
const
505 bool firstOp =
false;
513 if ((
type == LSR ||
type == ASR) && immShift && shiftAmt == 0)
518 if (immShift && shiftAmt == 0) {
537 if (immShift && shiftAmt == 0) {
549 panic(
"Tried to disassemble unrecognized shift type.\n");
555 os <<
"#" << shiftAmt;
564 int64_t shiftAmt)
const
597 ArmShiftType
type, uint64_t
imm)
const
629 std::stringstream
ss;
637 const auto tc = xc->
tcBase();
641 (hcr.tge || mdcr.tde)) || !
ELIs32(tc,
EL1)) {
643 return std::make_shared<SoftwareBreakpoint>(
machInst,
imm);
646 return std::make_shared<PrefetchAbort>(
readPC(xc),
659 return std::make_shared<SupervisorTrap>(
662 return std::make_shared<HypervisorTrap>(
665 return std::make_shared<SecureMonitorTrap>(
669 panic(
"Illegal EL in advSIMDFPAccessTrap64\n");
678 bool trap_el2 =
false;
681 if (
HaveExt(tc, ArmExtension::FEAT_VHE) && hcr.e2h == 0x1) {
682 switch (cptr_en_check.fpen) {
685 trap_el2 = !(
currEL(tc) ==
EL1 && hcr.tge == 1);
688 trap_el2 = (
currEL(tc) ==
EL0 && hcr.tge == 1);
694 }
else if (cptr_en_check.tfp) {
705 if (cptr_en_check.tfp) {
715 CPSR cpsr, CPACR cpacr)
const
718 if (((
el ==
EL0 && cpacr.fpen != 0x3) ||
719 (
el ==
EL1 && !(cpacr.fpen & 0x1))) &&
728 CPSR cpsr, CPACR cpacr,
729 NSACR nsacr, FPEXC fpexc,
730 bool fpexc_check,
bool advsimd)
const
734 const bool is_secure =
isSecure(tc);
740 uint8_t cpacr_cp10 = cpacr.cp10;
741 bool cpacr_asedis = cpacr.asedis;
743 if (have_security && !
ELIs64(tc,
EL3) && !is_secure) {
754 if ((cur_el ==
EL0 && cpacr_cp10 != 0x3) ||
755 (cur_el !=
EL0 && !(cpacr_cp10 & 0x1)))
759 if (fpexc_check && !fpexc.en)
764 if (have_virtualization && !is_secure &&
ELIs64(tc,
EL2))
767 if (have_virtualization && !is_secure) {
769 bool hcptr_cp10 = hcptr.tcp10;
770 bool hcptr_tase = hcptr.tase;
772 if (have_security && !
ELIs64(tc,
EL3) && !is_secure) {
779 if ((
advsimd && hcptr_tase) || hcptr_cp10) {
780 const uint32_t
iss =
advsimd ? (1 << 5) : 0xA;
782 return std::make_shared<UndefinedInstruction>(
786 return std::make_shared<HypervisorTrap>(
796 if (cptr_en_check.tfp)
815 trap = isWfe? !sctlr.ntwe : !sctlr.ntwi;
818 trap = isWfe? hcr.twe : hcr.twi;
821 trap = isWfe? scr.twe : scr.twi;
841 if (
ELIs64(tc, targetEL)) {
849 uint32_t
iss = isWfe? 0x1E00001 :
853 return std::make_shared<UndefinedInstruction>(
857 return std::make_shared<HypervisorTrap>(
861 return std::make_shared<SecureMonitorTrap>(
865 panic(
"Unrecognized Exception Level: %d\n", targetEL);
884 uint32_t
iss = isWfe? 0x1E00001 :
888 return std::make_shared<SupervisorTrap>(
892 return std::make_shared<HypervisorTrap>(
896 return std::make_shared<SecureMonitorTrap>(
900 panic(
"Unrecognized Exception Level: %d\n", targetEL);
915 if (curr_el ==
EL0) {
920 ((curr_el ==
EL0) || (curr_el ==
EL1))) {
936 bool setend_disabled(
false);
939 if (pstate_el ==
EL2) {
978 return std::make_shared<UndefinedInstruction>(
991 return std::make_shared<SupervisorTrap>(
994 return std::make_shared<HypervisorTrap>(
997 return std::make_shared<SecureMonitorTrap>(
1000 panic(
"Unrecognized Exception Level: %d\n", pstateEL);
1012 return std::make_shared<SupervisorTrap>(
1015 return std::make_shared<HypervisorTrap>(
1018 return std::make_shared<SecureMonitorTrap>(
1022 panic(
"Illegal EL in sveAccessTrap\n");
1032 if (svcr_sm_check.sm) {
1039 if ((
el ==
EL0 && cpacr.zen == 0x1) ||
1040 (!(cpacr.zen & 0x1)))
1043 if ((
el ==
EL0 && cpacr.fpen == 0x1) ||
1044 (!(cpacr.fpen & 0x1)))
1052 if (
HaveExt(tc, ArmExtension::FEAT_VHE) && hcr.e2h) {
1053 if (((cptr_en_check.zen & 0x1) == 0x0) ||
1054 (cptr_en_check.zen == 0x1 &&
el ==
EL0 &&
1058 if (((cptr_en_check.fpen & 0x1) == 0x0) ||
1059 (cptr_en_check.fpen == 0x1 &&
el ==
EL0 &&
1064 if (cptr_en_check.tz == 1)
1066 if (cptr_en_check.tfp == 1)
1074 if (!cptr_en_check.ez)
1076 if (cptr_en_check.tfp)
1088 return std::make_shared<SupervisorTrap>(
1091 return std::make_shared<HypervisorTrap>(
1094 return std::make_shared<SecureMonitorTrap>(
1098 panic(
"Illegal EL in smeAccessTrap\n");
1108 if ((
el ==
EL0 && cpacr.smen == 0x1) ||
1109 (!(cpacr.smen & 0x1)))
1112 if ((
el ==
EL0 && cpacr.fpen == 0x1) ||
1113 (!(cpacr.fpen & 0x1)))
1121 if (
HaveExt(tc, ArmExtension::FEAT_VHE) && hcr.e2h) {
1122 if (((cptr_en_check.smen & 0x1) == 0x0) ||
1123 (cptr_en_check.smen == 0x1 &&
el ==
EL0 &&
1127 if (((cptr_en_check.fpen & 0x1) == 0x0) ||
1128 (cptr_en_check.fpen == 0x1 &&
el ==
EL0 &&
1133 if (cptr_en_check.tsm == 1)
1135 if (cptr_en_check.tfp == 1)
1143 if (!cptr_en_check.esm)
1145 if (cptr_en_check.tfp)
1158 if ((
el ==
EL0 && cpacr.smen == 0x1) || (!(cpacr.smen & 0x1))) {
1167 if (
HaveExt(tc, ArmExtension::FEAT_VHE) && hcr.e2h) {
1168 if (((cptr_en_check.smen & 0x1) == 0x0) ||
1169 (cptr_en_check.smen == 0x1 &&
el ==
EL0 &&
1174 if (cptr_en_check.tsm == 1)
1182 if (!cptr_en_check.esm)
1209 const uint8_t it =
itState(spsr);
1211 if (!spsr.t || spsr.il)
1216 if (
bits(it, 7, 4) != 0 &&
bits(it, 3, 0) == 0)
1226 if (
itd &&
bits(it, 2, 0) != 0)
1250 }
else if (spsr & 0x2) {
1252 }
else if (target_el ==
EL0 && spsr.sp) {
1266 if (target_el >
currEL(tc))
1269 bool spsr_mode_is_aarch32 = (spsr.width == 1);
1271 assert(known || (target_el ==
EL0 &&
ELIs64(tc,
EL1)));
1273 if (known && (spsr_mode_is_aarch32 != target_el_is_aarch32))
1296 new_cpsr.mode = cpsr.mode;
1298 new_cpsr.width = cpsr.width;
1299 new_cpsr.el = cpsr.el;
1300 new_cpsr.sp = cpsr.sp;
1304 new_cpsr.il = spsr.il;
1307 }
else if (spsr.width) {
1308 new_cpsr.mode = spsr.mode;
1310 new_cpsr.el = spsr.el;
1311 new_cpsr.sp = spsr.sp;
1316 new_cpsr.nz = spsr.nz;
1317 new_cpsr.c = spsr.c;
1318 new_cpsr.v = spsr.v;
1319 new_cpsr.pan = spsr.pan;
1320 if (new_cpsr.width) {
1323 new_cpsr.q = spsr.q;
1324 new_cpsr.ge = spsr.ge;
1325 new_cpsr.e = spsr.e;
1326 new_cpsr.aif = spsr.aif;
1327 new_cpsr.t = spsr.t;
1328 new_cpsr.it2 = it.top6;
1329 new_cpsr.it1 = it.bottom2;
1332 new_cpsr.daif = spsr.daif;
1333 new_cpsr.uao = spsr.uao;
1338 new_cpsr.ss =
ss->debugExceptionReturnSS(tc, spsr, dest);
void printVecReg(std::ostream &os, RegIndex reg_idx, bool isSveVecReg=false) const
virtual RegVal readMiscReg(RegIndex misc_reg)=0
constexpr decltype(nullptr) NoFault
bool ELIs64(ThreadContext *tc, ExceptionLevel el)
Fault advSIMDFPAccessTrap64(ExceptionLevel el) const
Trap an access to Advanced SIMD or FP registers due to access control bits.
CPSR getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr) const
Get the new PSTATE from a SPSR register in preparation for an exception return.
Fault checkSmeAccess(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
Check an SME access against CPACR_EL1, CPTR_EL2, and CPTR_EL3.
unsigned getCurSveVecLenInBits() const
Fault smeAccessTrap(ExceptionLevel el, uint32_t iss=0) const
Trap an access to SME registers due to access control bits.
bool highestELIs64() const
Returns true if the register width of the highest implemented exception level is 64 bits (ARMv8)
Bitfield< 23, 20 > advsimd
void printShiftOperand(std::ostream &os, RegIndex rm, bool immShift, uint32_t shiftAmt, RegIndex rs, ArmShiftType type) const
Fault undefinedFault32(ThreadContext *tc, ExceptionLevel el) const
UNDEFINED behaviour in AArch32.
constexpr auto & FramePointerReg
bool shift_carry_imm(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval) const
bool isSecureBelowEL3(ThreadContext *tc)
void printMnemonic(std::ostream &os, const std::string &suffix="", bool withPred=true, bool withCond64=false, ConditionCode cond64=COND_UC) const
static bool illegalExceptionReturn(ThreadContext *tc, CPSR cpsr, CPSR spsr)
const_iterator end() const
const char *const miscRegName[]
static ExceptionLevel opModeToEL(OperatingMode mode)
bool ELIsInHost(ThreadContext *tc, ExceptionLevel el)
Returns true if the current exception level el is executing a Host OS or an application of a Host OS ...
const char *const RegName[NumRegs]
Fault disabledFault() const
static unsigned getCurSveVecLenInBits(ThreadContext *tc)
void printCCReg(std::ostream &os, RegIndex reg_idx) const
Fault trapWFx(ThreadContext *tc, CPSR cpsr, SCR scr, bool isWfe) const
WFE/WFI trapping helper function.
int32_t shift_rm_rs(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval) const
Fault softwareBreakpoint32(ExecContext *xc, uint16_t imm) const
Trigger a Software Breakpoint.
std::pair< bool, bool > ELUsingAArch32K(ThreadContext *tc, ExceptionLevel el)
This function checks whether selected EL provided as an argument is using the AArch32 ISA.
void ccprintf(cp::Print &print)
void printTarget(std::ostream &os, Addr target, const loader::SymbolTable *symtab) const
constexpr auto & ReturnAddressReg
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 printCondition(std::ostream &os, unsigned code, bool noImplicit=false) const
static Addr readPC(ExecContext *xc)
static bool unknownMode32(OperatingMode mode)
static uint8_t getRestoredITBits(ThreadContext *tc, CPSR spsr)
Fault checkSETENDEnabled(ThreadContext *tc, CPSR cpsr) const
Check if SETEND instruction execution in aarch32 should be trapped.
ThreadContext is the external interface to all thread state for anything outside of the CPU.
std::shared_ptr< FaultBase > Fault
Fault undefinedFault64(ThreadContext *tc, ExceptionLevel el) const
UNDEFINED behaviour in AArch64.
void printMemSymbol(std::ostream &os, const loader::SymbolTable *symtab, const std::string &prefix, const Addr addr, const std::string &suffix) const
int64_t shiftReg64(uint64_t base, uint64_t shiftAmt, ArmShiftType type, uint8_t width) const
static bool unknownMode(OperatingMode mode)
Fault checkForWFxTrap64(ThreadContext *tc, ExceptionLevel tgtEl, bool isWfe) const
Check if WFE/WFI instruction execution in aarch64 should be trapped.
bool ELIs32(ThreadContext *tc, ExceptionLevel el)
bool isWFxTrapping(ThreadContext *tc, ExceptionLevel targetEL, bool isWfe) const
virtual ThreadContext * tcBase() const =0
Returns a pointer to the ThreadContext.
const_iterator findNearest(Addr addr, Addr &next_addr) const
Find the nearest symbol equal to or less than the supplied address (e.g., the label for the enclosing...
bool EL2Enabled(ThreadContext *tc)
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
bool shift_carry_rs(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval) const
Fault checkForWFxTrap32(ThreadContext *tc, ExceptionLevel tgtEl, bool isWfe) const
Check if WFE/WFI instruction execution in aarch32 should be trapped.
void printVecPredReg(std::ostream &os, RegIndex reg_idx) const
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
static unsigned getCurSmeVecLenInBits(ThreadContext *tc)
Fault checkSveEnabled(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
Check an SVE access against CPACR_EL1, CPTR_EL2, and CPTR_EL3.
bool isSecure(ThreadContext *tc)
unsigned getCurSmeVecLenInBits() const
Fault checkSveSmeEnabled(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
Check an SVE access against CPACR_EL1, CPTR_EL2, and CPTR_EL3, but choosing the correct set of traps ...
bool generalExceptionsToAArch64(ThreadContext *tc, ExceptionLevel pstateEL) const
Return true if exceptions normally routed to EL1 are being handled at an Exception level using AArch6...
ExceptionLevel currEL(const ThreadContext *tc)
Returns the current Exception Level (EL) of the provided ThreadContext.
int64_t extendReg64(uint64_t base, ArmExtendType type, uint64_t shiftAmt, uint8_t width) const
bool IsSecureEL2Enabled(ThreadContext *tc)
Fault checkFPAdvSIMDEnabled64(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
Check an Advaned SIMD access against CPACR_EL1, CPTR_EL2, and CPTR_EL3.
Fault checkSmeEnabled(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
Check if SME is enabled by checking the SME and FP bits of CPACR_EL1, CPTR_EL2, and CPTR_EL3.
void printDataInst(std::ostream &os, bool withImm) const
void printFloatReg(std::ostream &os, RegIndex reg_idx) const
int32_t shift_rm_imm(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval) const
SelfDebug * getSelfDebug() const
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
constexpr auto & StackPointerReg
The ExecContext is an abstract base class the provides the interface used by the ISA to manipulate th...
void printMiscReg(std::ostream &os, RegIndex reg_idx) const
void printExtendOperand(bool firstOperand, std::ostream &os, RegIndex rm, ArmExtendType type, int64_t shiftAmt) const
int snsBankedIndex(MiscRegIndex reg, ThreadContext *tc)
virtual BaseISA * getIsaPtr() const =0
static bool haveEL(ThreadContext *tc, ArmISA::ExceptionLevel el)
Return true if the system implements a specific exception level.
static uint8_t itState(CPSR psr)
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).
const char * mnemonic
Base mnemonic (e.g., "add").
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
bool HaveExt(ThreadContext *tc, ArmExtension ext)
Returns true if the provided ThreadContext supports the ArmExtension passed as a second argument.
Fault sveAccessTrap(ExceptionLevel el) const
Trap an access to SVE registers due to access control bits.
#define panic(...)
This implements a cprintf based panic() function.
void printPFflags(std::ostream &os, int flag) const
Fault checkFPAdvSIMDTrap64(ThreadContext *tc, CPSR cpsr) const
Check an Advaned SIMD access against CPTR_EL2 and CPTR_EL3.
Generated on Sun Jul 30 2023 01:56:48 for gem5 by doxygen 1.8.17