gem5 v24.1.0.1
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
static_inst.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010-2014, 2016-2020,2022 Arm Limited
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
4 * All rights reserved
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder. You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
14 *
15 * Copyright (c) 2007-2008 The Florida State University
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 */
41
43
44#include "arch/arm/faults.hh"
45#include "arch/arm/isa.hh"
47#include "arch/arm/utility.hh"
48#include "base/condcodes.hh"
49#include "base/cprintf.hh"
50#include "base/loader/symtab.hh"
51#include "cpu/reg_class.hh"
52
53namespace gem5
54{
55
56namespace ArmISA
57{
58// Shift Rm by an immediate value
59int32_t
60ArmStaticInst::shift_rm_imm(uint32_t base, uint32_t shamt,
61 uint32_t type, uint32_t cfval) const
62{
63 assert(shamt < 32);
64 ArmShiftType shiftType;
65 shiftType = (ArmShiftType)type;
66
67 switch (shiftType)
68 {
69 case LSL:
70 return base << shamt;
71 case LSR:
72 if (shamt == 0)
73 return 0;
74 else
75 return base >> shamt;
76 case ASR:
77 if (shamt == 0)
78 return (base >> 31) | -((base & (1 << 31)) >> 31);
79 else
80 return (base >> shamt) | -((base & (1 << 31)) >> shamt);
81 case ROR:
82 if (shamt == 0)
83 return (cfval << 31) | (base >> 1); // RRX
84 else
85 return (base << (32 - shamt)) | (base >> shamt);
86 default:
87 ccprintf(std::cerr, "Unhandled shift type\n");
88 exit(1);
89 break;
90 }
91 return 0;
92}
93
94int64_t
95ArmStaticInst::shiftReg64(uint64_t base, uint64_t shiftAmt,
96 ArmShiftType type, uint8_t width) const
97{
98 shiftAmt = shiftAmt % width;
99 ArmShiftType shiftType;
100 shiftType = (ArmShiftType)type;
101
102 switch (shiftType)
103 {
104 case LSL:
105 return base << shiftAmt;
106 case LSR:
107 if (shiftAmt == 0)
108 return base;
109 else
110 return (base & mask(width)) >> shiftAmt;
111 case ASR:
112 if (shiftAmt == 0) {
113 return base;
114 } else {
115 int sign_bit = bits(base, intWidth - 1);
116 base >>= shiftAmt;
117 base = sign_bit ? (base | ~mask(intWidth - shiftAmt)) : base;
118 return base & mask(intWidth);
119 }
120 case ROR:
121 if (shiftAmt == 0)
122 return base;
123 else
124 return (base << (width - shiftAmt)) | (base >> shiftAmt);
125 default:
126 ccprintf(std::cerr, "Unhandled shift type\n");
127 exit(1);
128 break;
129 }
130 return 0;
131}
132
133int64_t
135 uint64_t shiftAmt, uint8_t width) const
136{
137 bool sign_extend = false;
138 int len = 0;
139 switch (type) {
140 case UXTB:
141 len = 8;
142 break;
143 case UXTH:
144 len = 16;
145 break;
146 case UXTW:
147 len = 32;
148 break;
149 case UXTX:
150 len = 64;
151 break;
152 case SXTB:
153 len = 8;
154 sign_extend = true;
155 break;
156 case SXTH:
157 len = 16;
158 sign_extend = true;
159 break;
160 case SXTW:
161 len = 32;
162 sign_extend = true;
163 break;
164 case SXTX:
165 len = 64;
166 sign_extend = true;
167 break;
168 }
169 len = len <= width - shiftAmt ? len : width - shiftAmt;
170 uint64_t tmp = (uint64_t) bits(base, len - 1, 0) << shiftAmt;
171 if (sign_extend) {
172 int sign_bit = bits(tmp, len + shiftAmt - 1);
173 tmp = sign_bit ? (tmp | ~mask(len + shiftAmt)) : tmp;
174 }
175 return tmp & mask(width);
176}
177
178// Shift Rm by Rs
179int32_t
180ArmStaticInst::shift_rm_rs(uint32_t base, uint32_t shamt,
181 uint32_t type, uint32_t cfval) const
182{
183 enum ArmShiftType shiftType;
184 shiftType = (enum ArmShiftType) type;
185
186 switch (shiftType)
187 {
188 case LSL:
189 if (shamt >= 32)
190 return 0;
191 else
192 return base << shamt;
193 case LSR:
194 if (shamt >= 32)
195 return 0;
196 else
197 return base >> shamt;
198 case ASR:
199 if (shamt >= 32)
200 return (base >> 31) | -((base & (1 << 31)) >> 31);
201 else
202 return (base >> shamt) | -((base & (1 << 31)) >> shamt);
203 case ROR:
204 shamt = shamt & 0x1f;
205 if (shamt == 0)
206 return base;
207 else
208 return (base << (32 - shamt)) | (base >> shamt);
209 default:
210 ccprintf(std::cerr, "Unhandled shift type\n");
211 exit(1);
212 break;
213 }
214 return 0;
215}
216
217
218// Generate C for a shift by immediate
219bool
220ArmStaticInst::shift_carry_imm(uint32_t base, uint32_t shamt,
221 uint32_t type, uint32_t cfval) const
222{
223 enum ArmShiftType shiftType;
224 shiftType = (enum ArmShiftType) type;
225
226 switch (shiftType)
227 {
228 case LSL:
229 if (shamt == 0)
230 return cfval;
231 else
232 return (base >> (32 - shamt)) & 1;
233 case LSR:
234 if (shamt == 0)
235 return (base >> 31);
236 else
237 return (base >> (shamt - 1)) & 1;
238 case ASR:
239 if (shamt == 0)
240 return (base >> 31);
241 else
242 return (base >> (shamt - 1)) & 1;
243 case ROR:
244 shamt = shamt & 0x1f;
245 if (shamt == 0)
246 return (base & 1); // RRX
247 else
248 return (base >> (shamt - 1)) & 1;
249 default:
250 ccprintf(std::cerr, "Unhandled shift type\n");
251 exit(1);
252 break;
253 }
254 return 0;
255}
256
257
258// Generate C for a shift by Rs
259bool
260ArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt,
261 uint32_t type, uint32_t cfval) const
262{
263 enum ArmShiftType shiftType;
264 shiftType = (enum ArmShiftType) type;
265
266 if (shamt == 0)
267 return cfval;
268
269 switch (shiftType)
270 {
271 case LSL:
272 if (shamt > 32)
273 return 0;
274 else
275 return (base >> (32 - shamt)) & 1;
276 case LSR:
277 if (shamt > 32)
278 return 0;
279 else
280 return (base >> (shamt - 1)) & 1;
281 case ASR:
282 if (shamt > 32)
283 shamt = 32;
284 return (base >> (shamt - 1)) & 1;
285 case ROR:
286 shamt = shamt & 0x1f;
287 if (shamt == 0)
288 shamt = 32;
289 return (base >> (shamt - 1)) & 1;
290 default:
291 ccprintf(std::cerr, "Unhandled shift type\n");
292 exit(1);
293 break;
294 }
295 return 0;
296}
297
298void
300 uint8_t opWidth) const
301{
302 if (opWidth == 0)
303 opWidth = intWidth;
304 if (aarch64) {
305 if (reg_idx == int_reg::Ureg0)
306 ccprintf(os, "ureg0");
307 else if (reg_idx == int_reg::Spx)
308 ccprintf(os, "%s%s", (opWidth == 32) ? "w" : "", "sp");
309 else if (reg_idx == int_reg::X31)
310 ccprintf(os, "%szr", (opWidth == 32) ? "w" : "x");
311 else
312 ccprintf(os, "%s%d", (opWidth == 32) ? "w" : "x", reg_idx);
313 } else {
314 switch (reg_idx) {
315 case int_reg::Pc:
316 ccprintf(os, "pc");
317 break;
318 case StackPointerReg:
319 ccprintf(os, "sp");
320 break;
321 case FramePointerReg:
322 ccprintf(os, "fp");
323 break;
324 case ReturnAddressReg:
325 ccprintf(os, "lr");
326 break;
327 default:
328 ccprintf(os, "r%d", reg_idx);
329 break;
330 }
331 }
332}
333
334void ArmStaticInst::printPFflags(std::ostream &os, int flag) const
335{
336 const char *flagtoprfop[]= { "PLD", "PLI", "PST", "Reserved"};
337 const char *flagtotarget[] = { "L1", "L2", "L3", "Reserved"};
338 const char *flagtopolicy[] = { "KEEP", "STRM"};
339
340 ccprintf(os, "%s%s%s", flagtoprfop[(flag>>3)&3],
341 flagtotarget[(flag>>1)&3], flagtopolicy[flag&1]);
342}
343
344void
345ArmStaticInst::printFloatReg(std::ostream &os, RegIndex reg_idx) const
346{
347 ccprintf(os, "f%d", reg_idx);
348}
349
350void
352 bool isSveVecReg) const
353{
354 ccprintf(os, "%s%d", isSveVecReg ? "z" : "v", reg_idx);
355}
356
357void
358ArmStaticInst::printVecPredReg(std::ostream &os, RegIndex reg_idx) const
359{
360 ccprintf(os, "p%d", reg_idx);
361}
362
363void
364ArmStaticInst::printCCReg(std::ostream &os, RegIndex reg_idx) const
365{
366 ccprintf(os, "cc_%s", ArmISA::cc_reg::RegName[reg_idx]);
367}
368
369void
370ArmStaticInst::printMiscReg(std::ostream &os, RegIndex reg_idx) const
371{
372 assert(reg_idx < NUM_MISCREGS);
373 ccprintf(os, "%s", ArmISA::miscRegName[reg_idx]);
374}
375
376void
378 const std::string &suffix,
379 bool withPred,
380 bool withCond64,
381 ConditionCode cond64) const
382{
383 os << " " << mnemonic;
384 if (withPred && !aarch64) {
385 printCondition(os, machInst.condCode);
386 os << suffix;
387 } else if (withCond64) {
388 os << ".";
389 printCondition(os, cond64);
390 os << suffix;
391 }
392 if (machInst.bigThumb)
393 os << ".w";
394 os << " ";
395}
396
397void
398ArmStaticInst::printTarget(std::ostream &os, Addr target,
399 const loader::SymbolTable *symtab) const
400{
401 if (symtab) {
402 auto it = symtab->findNearest(target);
403 if (it != symtab->end()) {
404 ccprintf(os, "<%s", it->name());
405 Addr delta = target - it->address();
406 if (delta)
407 ccprintf(os, "+%d>", delta);
408 else
409 ccprintf(os, ">");
410 return;
411 }
412 }
413 ccprintf(os, "%#x", target);
414}
415
416void
418 unsigned code,
419 bool noImplicit) const
420{
421 switch (code) {
422 case COND_EQ:
423 os << "eq";
424 break;
425 case COND_NE:
426 os << "ne";
427 break;
428 case COND_CS:
429 os << "cs";
430 break;
431 case COND_CC:
432 os << "cc";
433 break;
434 case COND_MI:
435 os << "mi";
436 break;
437 case COND_PL:
438 os << "pl";
439 break;
440 case COND_VS:
441 os << "vs";
442 break;
443 case COND_VC:
444 os << "vc";
445 break;
446 case COND_HI:
447 os << "hi";
448 break;
449 case COND_LS:
450 os << "ls";
451 break;
452 case COND_GE:
453 os << "ge";
454 break;
455 case COND_LT:
456 os << "lt";
457 break;
458 case COND_GT:
459 os << "gt";
460 break;
461 case COND_LE:
462 os << "le";
463 break;
464 case COND_AL:
465 // This one is implicit.
466 if (noImplicit)
467 os << "al";
468 break;
469 case COND_UC:
470 // Unconditional.
471 if (noImplicit)
472 os << "uc";
473 break;
474 default:
475 panic("Unrecognized condition code %d.\n", code);
476 }
477}
478
479void
481 const loader::SymbolTable *symtab,
482 const std::string &prefix,
483 const Addr addr,
484 const std::string &suffix) const
485{
486 if (symtab) {
487 auto it = symtab->findNearest(addr);
488 if (it != symtab->end()) {
489 ccprintf(os, "%s%s", prefix, it->name());
490 if (it->address() != addr)
491 ccprintf(os, "+%d", addr - it->address());
492 ccprintf(os, suffix);
493 }
494 }
495}
496
497void
499 RegIndex rm,
500 bool immShift,
501 uint32_t shiftAmt,
502 RegIndex rs,
503 ArmShiftType type) const
504{
505 bool firstOp = false;
506
507 if (rm != int_reg::Zero) {
508 printIntReg(os, rm);
509 }
510
511 bool done = false;
512
513 if ((type == LSR || type == ASR) && immShift && shiftAmt == 0)
514 shiftAmt = 32;
515
516 switch (type) {
517 case LSL:
518 if (immShift && shiftAmt == 0) {
519 done = true;
520 break;
521 }
522 if (!firstOp)
523 os << ", ";
524 os << "LSL";
525 break;
526 case LSR:
527 if (!firstOp)
528 os << ", ";
529 os << "LSR";
530 break;
531 case ASR:
532 if (!firstOp)
533 os << ", ";
534 os << "ASR";
535 break;
536 case ROR:
537 if (immShift && shiftAmt == 0) {
538 if (!firstOp)
539 os << ", ";
540 os << "RRX";
541 done = true;
542 break;
543 }
544 if (!firstOp)
545 os << ", ";
546 os << "ROR";
547 break;
548 default:
549 panic("Tried to disassemble unrecognized shift type.\n");
550 }
551 if (!done) {
552 if (!firstOp)
553 os << " ";
554 if (immShift)
555 os << "#" << shiftAmt;
556 else
557 printIntReg(os, rs);
558 }
559}
560
561void
562ArmStaticInst::printExtendOperand(bool firstOperand, std::ostream &os,
564 int64_t shiftAmt) const
565{
566 if (!firstOperand)
567 ccprintf(os, ", ");
568 printIntReg(os, rm);
569 if (type == UXTX && shiftAmt == 0)
570 return;
571 switch (type) {
572 case UXTB: ccprintf(os, ", UXTB");
573 break;
574 case UXTH: ccprintf(os, ", UXTH");
575 break;
576 case UXTW: ccprintf(os, ", UXTW");
577 break;
578 case UXTX: ccprintf(os, ", LSL");
579 break;
580 case SXTB: ccprintf(os, ", SXTB");
581 break;
582 case SXTH: ccprintf(os, ", SXTH");
583 break;
584 case SXTW: ccprintf(os, ", SXTW");
585 break;
586 case SXTX: ccprintf(os, ", SXTW");
587 break;
588 }
589 if (type == UXTX || shiftAmt)
590 ccprintf(os, " #%d", shiftAmt);
591}
592
593void
594ArmStaticInst::printDataInst(std::ostream &os, bool withImm,
595 bool immShift, bool s, RegIndex rd, RegIndex rn,
596 RegIndex rm, RegIndex rs, uint32_t shiftAmt,
597 ArmShiftType type, uint64_t imm) const
598{
599 printMnemonic(os, s ? "s" : "");
600 bool firstOp = true;
601
602 // Destination
603 if (rd != int_reg::Zero) {
604 firstOp = false;
605 printIntReg(os, rd);
606 }
607
608 // Source 1.
609 if (rn != int_reg::Zero) {
610 if (!firstOp)
611 os << ", ";
612 firstOp = false;
613 printIntReg(os, rn);
614 }
615
616 if (!firstOp)
617 os << ", ";
618 if (withImm) {
619 ccprintf(os, "#%ld", imm);
620 } else {
621 printShiftOperand(os, rm, immShift, shiftAmt, rs, type);
622 }
623}
624
625std::string
627 const loader::SymbolTable *symtab) const
628{
629 std::stringstream ss;
631 return ss.str();
632}
633
634Fault
636{
637 const auto tc = xc->tcBase();
638 const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
639 const HDCR mdcr = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
640 if ((EL2Enabled(tc) && !ELIs32(tc, EL2) &&
641 (hcr.tge || mdcr.tde)) || !ELIs32(tc, EL1)) {
642 // Route to AArch64 Software Breakpoint
643 return std::make_shared<SoftwareBreakpoint>(machInst, imm);
644 } else {
645 // Execute AArch32 Software Breakpoint
646 return std::make_shared<PrefetchAbort>(readPC(xc),
648 false,
651 }
652}
653
654Fault
659
660Fault
662{
663 if (currEL(tc) <= EL2 && EL2Enabled(tc)) {
664 bool trap_el2 = false;
665 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL2);
666 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
667 if (HaveExt(tc, ArmExtension::FEAT_VHE) && hcr.e2h == 0x1) {
668 switch (cptr_en_check.fpen) {
669 case 0:
670 case 2:
671 trap_el2 = !(currEL(tc) == EL1 && hcr.tge == 1);
672 break;
673 case 1:
674 trap_el2 = (currEL(tc) == EL0 && hcr.tge == 1);
675 break;
676 default:
677 trap_el2 = false;
678 break;
679 }
680 } else if (cptr_en_check.tfp) {
681 trap_el2 = true;
682 }
683
684 if (trap_el2) {
686 }
687 }
688
689 if (ArmSystem::haveEL(tc, EL3)) {
690 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
691 if (cptr_en_check.tfp) {
693 }
694 }
695
696 return NoFault;
697}
698
699Fault
701 CPSR cpsr, CPACR cpacr) const
702{
703 const ExceptionLevel el = currEL(tc);
704 if (((el == EL0 && cpacr.fpen != 0x3) ||
705 (el == EL1 && !(cpacr.fpen & 0x1))) &&
706 !ELIsInHost(tc, el))
708
709 return checkFPAdvSIMDTrap64(tc, cpsr);
710}
711
712Fault
714 CPSR cpsr, CPACR cpacr,
715 NSACR nsacr, FPEXC fpexc,
716 bool fpexc_check, bool advsimd) const
717{
718 const bool have_virtualization = ArmSystem::haveEL(tc, EL2);
719 const bool have_security = ArmSystem::haveEL(tc, EL3);
720 const bool is_secure = isSecure(tc);
721 const ExceptionLevel cur_el = currEL(tc);
722
723 if (cur_el == EL0 && ELIs64(tc, EL1))
724 return checkFPAdvSIMDEnabled64(tc, cpsr, cpacr);
725
726 uint8_t cpacr_cp10 = cpacr.cp10;
727 bool cpacr_asedis = cpacr.asedis;
728
729 if (have_security && !ELIs64(tc, EL3) && !is_secure) {
730 if (nsacr.nsasedis)
731 cpacr_asedis = true;
732 if (nsacr.cp10 == 0)
733 cpacr_cp10 = 0;
734 }
735
736 if (cur_el != EL2) {
737 if (advsimd && cpacr_asedis)
738 return disabledFault();
739
740 if ((cur_el == EL0 && cpacr_cp10 != 0x3) ||
741 (cur_el != EL0 && !(cpacr_cp10 & 0x1)))
742 return disabledFault();
743 }
744
745 if (fpexc_check && !fpexc.en)
746 return disabledFault();
747
748 // -- aarch32/exceptions/traps/AArch32.CheckFPAdvSIMDTrap --
749
750 if (have_virtualization && !is_secure && ELIs64(tc, EL2))
751 return checkFPAdvSIMDTrap64(tc, cpsr);
752
753 if (have_virtualization && !is_secure) {
754 HCPTR hcptr = tc->readMiscReg(MISCREG_HCPTR);
755 bool hcptr_cp10 = hcptr.tcp10;
756 bool hcptr_tase = hcptr.tase;
757
758 if (have_security && !ELIs64(tc, EL3) && !is_secure) {
759 if (nsacr.nsasedis)
760 hcptr_tase = true;
761 if (nsacr.cp10)
762 hcptr_cp10 = true;
763 }
764
765 if ((advsimd && hcptr_tase) || hcptr_cp10) {
766 const uint32_t iss = advsimd ? (1 << 5) : 0xA;
767 if (cur_el == EL2) {
768 return std::make_shared<UndefinedInstruction>(
769 machInst, iss,
771 } else {
772 return std::make_shared<HypervisorTrap>(
773 machInst, iss,
775 }
776
777 }
778 }
779
780 if (have_security && ELIs64(tc, EL3)) {
781 HCPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
782 if (cptr_en_check.tfp)
784 }
785
786 return NoFault;
787}
788
789inline bool
791 ExceptionLevel tgtEl,
792 bool isWfe) const
793{
794 bool trap = false;
795 SCTLR sctlr = ((SCTLR)tc->readMiscReg(MISCREG_SCTLR_EL1));
796 HCR hcr = ((HCR)tc->readMiscReg(MISCREG_HCR_EL2));
797 SCR scr = ((SCR)tc->readMiscReg(MISCREG_SCR_EL3));
798
799 switch (tgtEl) {
800 case EL1:
801 trap = isWfe? !sctlr.ntwe : !sctlr.ntwi;
802 break;
803 case EL2:
804 trap = isWfe? hcr.twe : hcr.twi;
805 break;
806 case EL3:
807 trap = isWfe? scr.twe : scr.twi;
808 break;
809 default:
810 break;
811 }
812
813 return trap;
814}
815
816Fault
818 ExceptionLevel targetEL,
819 bool isWfe) const
820{
821 // Check if target exception level is implemented.
822 assert(ArmSystem::haveEL(tc, targetEL));
823
824 // Check for routing to AArch64: this happens if the
825 // target exception level (where the trap will be handled)
826 // is using aarch64
827 if (ELIs64(tc, targetEL)) {
828 return checkForWFxTrap64(tc, targetEL, isWfe);
829 }
830
831 // Check if processor needs to trap at selected exception level
832 bool trap = isWFxTrapping(tc, targetEL, isWfe);
833
834 if (trap) {
835 uint32_t iss = isWfe? 0x1E00001 : /* WFE Instruction syndrome */
836 0x1E00000; /* WFI Instruction syndrome */
837 switch (targetEL) {
838 case EL1:
839 return std::make_shared<UndefinedInstruction>(
840 machInst, iss,
842 case EL2:
843 return std::make_shared<HypervisorTrap>(
844 machInst, iss,
846 case EL3:
847 return std::make_shared<SecureMonitorTrap>(
848 machInst, iss,
850 default:
851 panic("Unrecognized Exception Level: %d\n", targetEL);
852 }
853 }
854
855 return NoFault;
856}
857
858Fault
860 ExceptionLevel target_el,
861 bool is_wfe) const
862{
863 // Check if target exception level is implemented.
864 assert(ArmSystem::haveEL(tc, target_el));
865
866 // Check if processor needs to trap at selected exception level
867 if (isWFxTrapping(tc, target_el, is_wfe)) {
868 uint32_t iss = is_wfe? 0x1E00001 : /* WFE Instruction syndrome */
869 0x1E00000; /* WFI Instruction syndrome */
871 } else {
872 return NoFault;
873 }
874}
875
876Fault
878 CPSR cpsr, SCR scr,
879 bool isWfe) const
880{
881 Fault fault = NoFault;
882 ExceptionLevel curr_el = currEL(tc);
883
884 if (curr_el == EL0) {
885 fault = checkForWFxTrap32(tc, EL1, isWfe);
886 }
887
888 if ((fault == NoFault) && EL2Enabled(tc) &&
889 ((curr_el == EL0) || (curr_el == EL1))) {
890
891 fault = checkForWFxTrap32(tc, EL2, isWfe);
892 }
893
894 if ((fault == NoFault) &&
895 ArmSystem::haveEL(tc, EL3) && curr_el != EL3) {
896 fault = checkForWFxTrap32(tc, EL3, isWfe);
897 }
898
899 return fault;
900}
901
902Fault
904{
905 bool setend_disabled(false);
906 ExceptionLevel pstate_el = currEL(tc);
907
908 if (pstate_el == EL2) {
909 setend_disabled = ((SCTLR)tc->readMiscRegNoEffect(MISCREG_HSCTLR)).sed;
910 } else {
911 // Please note: in the armarm pseudocode there is a distinction
912 // whether EL1 is aarch32 or aarch64:
913 // if ELUsingAArch32(EL1) then SCTLR.SED else SCTLR[].SED;
914 // Considering that SETEND is aarch32 only, ELUsingAArch32(EL1)
915 // will always be true (hence using SCTLR.SED) except for
916 // instruction executed at EL0, and with an AArch64 EL1.
917 // In this case SCTLR_EL1 will be used. In gem5 the register is
918 // mapped to SCTLR_ns. We can safely use SCTLR and choose the
919 // appropriate bank version.
920
921 // Get the index of the banked version of SCTLR:
922 // SCTLR_s or SCTLR_ns.
923 auto banked_sctlr = snsBankedIndex(
924 MISCREG_SCTLR, tc, !isSecure(tc));
925
926 // SCTLR.SED bit is enabling/disabling the ue of SETEND instruction.
927 setend_disabled = ((SCTLR)tc->readMiscRegNoEffect(banked_sctlr)).sed;
928 }
929
930 return setend_disabled ? undefinedFault32(tc, pstate_el) :
931 NoFault;
932}
933
934Fault
936 ExceptionLevel pstateEL) const
937{
938 // Even if we are running in aarch32, the fault might be dealt with in
939 // aarch64 ISA.
940 if (generalExceptionsToAArch64(tc, pstateEL)) {
941 return undefinedFault64(tc, pstateEL);
942 } else {
943 // Please note: according to the ARM ARM pseudocode we should handle
944 // the case when EL2 is aarch64 and HCR.TGE is 1 as well.
945 // However this case is already handled by the routeToHyp method in
946 // ArmFault class.
947 return std::make_shared<UndefinedInstruction>(
948 machInst, 0,
950 }
951}
952
953Fault
955 ExceptionLevel pstateEL) const
956{
957 switch (pstateEL) {
958 case EL0:
959 case EL1:
960 return std::make_shared<SupervisorTrap>(
962 case EL2:
963 return std::make_shared<HypervisorTrap>(
965 case EL3:
966 return std::make_shared<SecureMonitorTrap>(
968 default:
969 panic("Unrecognized Exception Level: %d\n", pstateEL);
970 break;
971 }
972
973 return NoFault;
974}
975
976Fault
981
982Fault
983ArmStaticInst::checkSveEnabled(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
984{
985 // We first check if we are in streaming mode or not. If we are in
986 // streaming mode, we actually check the SME traps, not the SVE traps!
987 SVCR svcr_sm_check = tc->readMiscReg(MISCREG_SVCR);
988 if (svcr_sm_check.sm) {
989 return checkSmeEnabled(tc, cpsr, cpacr);
990 }
991
992 const ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
993 // Check if access disabled in CPACR_EL1
994 if (el <= EL1 && !ELIsInHost(tc, el)) {
995 if ((el == EL0 && cpacr.zen == 0x1) ||
996 (!(cpacr.zen & 0x1)))
997 return sveAccessTrap(EL1);
998
999 if ((el == EL0 && cpacr.fpen == 0x1) ||
1000 (!(cpacr.fpen & 0x1)))
1001 return advSIMDFPAccessTrap64(EL1);
1002 }
1003
1004 // Check if access disabled in CPTR_EL2
1005 if (el <= EL2 && EL2Enabled(tc)) {
1006 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL2);
1007 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
1008 if (HaveExt(tc, ArmExtension::FEAT_VHE) && hcr.e2h) {
1009 if (((cptr_en_check.zen & 0x1) == 0x0) ||
1010 (cptr_en_check.zen == 0x1 && el == EL0 &&
1011 hcr.tge == 0x1)) {
1012 return sveAccessTrap(EL2);
1013 }
1014 if (((cptr_en_check.fpen & 0x1) == 0x0) ||
1015 (cptr_en_check.fpen == 0x1 && el == EL0 &&
1016 hcr.tge == 0x1)) {
1017 return advSIMDFPAccessTrap64(EL2);
1018 }
1019 } else {
1020 if (cptr_en_check.tz == 1)
1021 return sveAccessTrap(EL2);
1022 if (cptr_en_check.tfp == 1)
1023 return advSIMDFPAccessTrap64(EL2);
1024 }
1025 }
1026
1027 // Check if access disabled in CPTR_EL3
1028 if (ArmSystem::haveEL(tc, EL3)) {
1029 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
1030 if (!cptr_en_check.ez)
1031 return sveAccessTrap(EL3);
1032 if (cptr_en_check.tfp)
1033 return advSIMDFPAccessTrap64(EL3);
1034 }
1035
1036 return NoFault;
1037}
1038
1039Fault
1044
1045Fault
1046ArmStaticInst::checkSmeEnabled(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
1047{
1048 const ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
1049 // Check if access disabled in CPACR_EL1
1050 if (el <= EL1 && !ELIsInHost(tc, el)) {
1051 if ((el == EL0 && cpacr.smen == 0x1) ||
1052 (!(cpacr.smen & 0x1)))
1053 return smeAccessTrap(EL1);
1054
1055 if ((el == EL0 && cpacr.fpen == 0x1) ||
1056 (!(cpacr.fpen & 0x1)))
1057 return advSIMDFPAccessTrap64(EL1);
1058 }
1059
1060 // Check if access disabled in CPTR_EL2
1061 if (el <= EL2 && EL2Enabled(tc)) {
1062 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL2);
1063 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
1064 if (HaveExt(tc, ArmExtension::FEAT_VHE) && hcr.e2h) {
1065 if (((cptr_en_check.smen & 0x1) == 0x0) ||
1066 (cptr_en_check.smen == 0x1 && el == EL0 &&
1067 hcr.tge == 0x1)) {
1068 return smeAccessTrap(EL2);
1069 }
1070 if (((cptr_en_check.fpen & 0x1) == 0x0) ||
1071 (cptr_en_check.fpen == 0x1 && el == EL0 &&
1072 hcr.tge == 0x1)) {
1073 return advSIMDFPAccessTrap64(EL2);
1074 }
1075 } else {
1076 if (cptr_en_check.tsm == 1)
1077 return smeAccessTrap(EL2);
1078 if (cptr_en_check.tfp == 1)
1079 return advSIMDFPAccessTrap64(EL2);
1080 }
1081 }
1082
1083 // Check if access disabled in CPTR_EL3
1084 if (ArmSystem::haveEL(tc, EL3)) {
1085 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
1086 if (!cptr_en_check.esm)
1087 return smeAccessTrap(EL3);
1088 if (cptr_en_check.tfp)
1089 return advSIMDFPAccessTrap64(EL3);
1090 }
1091
1092 return NoFault;
1093}
1094
1095Fault
1096ArmStaticInst::checkSmeAccess(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
1097{
1098 const ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
1099 // Check if access disabled in CPACR_EL1
1100 if (el <= EL1 && !ELIsInHost(tc, el)) {
1101 if ((el == EL0 && cpacr.smen == 0x1) || (!(cpacr.smen & 0x1))) {
1102 return smeAccessTrap(EL1);
1103 }
1104 }
1105
1106 // Check if access disabled in CPTR_EL2
1107 if (el <= EL2 && EL2Enabled(tc)) {
1108 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL2);
1109 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
1110 if (HaveExt(tc, ArmExtension::FEAT_VHE) && hcr.e2h) {
1111 if (((cptr_en_check.smen & 0x1) == 0x0) ||
1112 (cptr_en_check.smen == 0x1 && el == EL0 &&
1113 hcr.tge == 0x1)) {
1114 return smeAccessTrap(EL2);
1115 }
1116 } else {
1117 if (cptr_en_check.tsm == 1)
1118 return smeAccessTrap(EL2);
1119 }
1120 }
1121
1122 // Check if access disabled in CPTR_EL3
1123 if (ArmSystem::haveEL(tc, EL3)) {
1124 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
1125 if (!cptr_en_check.esm)
1126 return smeAccessTrap(EL3);
1127 }
1128
1129 return NoFault;
1130}
1131
1132Fault
1134 CPACR cpacr) const
1135{
1136 // If we are not in streaming mode, check the SVE traps, else check the SME
1137 // traps.
1138 SVCR svcr = tc->readMiscReg(MISCREG_SVCR);
1139 if (!svcr.sm) {
1140 return checkSveEnabled(tc, cpsr, cpacr);
1141 } else {
1142 return checkSmeEnabled(tc, cpsr, cpacr);
1143 }
1144}
1145
1146static uint8_t
1148{
1149 // See: shared/functions/system/RestoredITBits in the ARM ARM
1150
1151 const ExceptionLevel el = opModeToEL((OperatingMode) (uint8_t)spsr.mode);
1152 const uint8_t it = itState(spsr);
1153
1154 if (!spsr.t || spsr.il)
1155 return 0;
1156
1157 // The IT bits are forced to zero when they are set to a reserved
1158 // value.
1159 if (bits(it, 7, 4) != 0 && bits(it, 3, 0) == 0)
1160 return 0;
1161
1162 const bool itd = el == EL2 ?
1163 ((SCTLR)tc->readMiscReg(MISCREG_HSCTLR)).itd :
1164 ((SCTLR)tc->readMiscReg(MISCREG_SCTLR)).itd;
1165
1166 // The IT bits are forced to zero when returning to A32 state, or
1167 // when returning to an EL with the ITD bit set to 1, and the IT
1168 // bits are describing a multi-instruction block.
1169 if (itd && bits(it, 2, 0) != 0)
1170 return 0;
1171
1172 return it;
1173}
1174
1175static bool
1176illegalExceptionReturn(ThreadContext *tc, CPSR cpsr, CPSR spsr)
1177{
1178 const OperatingMode mode = (OperatingMode) (uint8_t)spsr.mode;
1179 if (unknownMode(mode))
1180 return true;
1181
1182 SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
1183 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
1184
1185 //ELFromSPSR
1186 bool valid;
1187 ExceptionLevel target_el = opModeToEL(mode);
1188 if (!spsr.width) {
1189 if (!ArmSystem::highestELIs64(tc)) {
1190 valid = false;
1191 } else if (!ArmSystem::haveEL(tc, target_el)) {
1192 valid = false;
1193 } else if (spsr & 0x2) {
1194 valid = false;
1195 } else if (target_el == EL0 && spsr.sp) {
1196 valid = false;
1197 } else if (target_el == EL2 && ArmSystem::haveEL(tc, EL3) &&
1198 !scr.ns && !IsSecureEL2Enabled(tc)) {
1199 valid = false;
1200 } else {
1201 valid = true;
1202 }
1203 } else {
1204 valid = !unknownMode32(mode);
1205 }
1206 if (!valid)
1207 return true;
1208
1209 if (target_el > currEL(tc))
1210 return true;
1211
1212 bool spsr_mode_is_aarch32 = (spsr.width == 1);
1213 auto [known, target_el_is_aarch32] = ELUsingAArch32K(tc, target_el);
1214 assert(known || (target_el == EL0 && ELIs64(tc, EL1)));
1215
1216 if (known && (spsr_mode_is_aarch32 != target_el_is_aarch32))
1217 return true;
1218
1219 if (target_el == EL1 && ArmSystem::haveEL(tc, EL2) && hcr.tge &&
1220 (IsSecureEL2Enabled(tc) || !isSecureBelowEL3(tc))) {
1221 return true;
1222 }
1223
1224 return false;
1225}
1226
1227CPSR
1228ArmStaticInst::getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr) const
1229{
1230 CPSR new_cpsr = 0;
1231 ExceptionLevel dest;
1232
1233 if (illegalExceptionReturn(tc, cpsr, spsr)) {
1234 // If the SPSR specifies an illegal exception return,
1235 // then PSTATE.{M, nRW, EL, SP} are unchanged and PSTATE.IL
1236 // is set to 1.
1237 new_cpsr.il = 1;
1238 if (cpsr.width) {
1239 new_cpsr.mode = cpsr.mode;
1240 } else {
1241 new_cpsr.width = cpsr.width;
1242 new_cpsr.el = cpsr.el;
1243 new_cpsr.sp = cpsr.sp;
1244 }
1245 dest = currEL(tc);
1246 } else {
1247 new_cpsr.il = spsr.il;
1248 if (spsr.width && unknownMode32((OperatingMode)(uint8_t)spsr.mode)) {
1249 new_cpsr.il = 1;
1250 } else if (spsr.width) {
1251 new_cpsr.mode = spsr.mode;
1252 } else {
1253 new_cpsr.el = spsr.el;
1254 new_cpsr.sp = spsr.sp;
1255 }
1256 dest = (ExceptionLevel)(uint8_t) spsr.el;
1257 }
1258
1259 new_cpsr.nz = spsr.nz;
1260 new_cpsr.c = spsr.c;
1261 new_cpsr.v = spsr.v;
1262 new_cpsr.pan = spsr.pan;
1263 if (new_cpsr.width) {
1264 // aarch32
1265 const ITSTATE it = getRestoredITBits(tc, spsr);
1266 new_cpsr.q = spsr.q;
1267 new_cpsr.ge = spsr.ge;
1268 new_cpsr.e = spsr.e;
1269 new_cpsr.aif = spsr.aif;
1270 new_cpsr.t = spsr.t;
1271 new_cpsr.it2 = it.top6;
1272 new_cpsr.it1 = it.bottom2;
1273 } else {
1274 // aarch64
1275 new_cpsr.daif = spsr.daif;
1276 new_cpsr.uao = spsr.uao;
1277 }
1278
1280 SoftwareStep *ss = sd->getSstep();
1281 new_cpsr.ss = ss->debugExceptionReturnSS(tc, spsr, dest);
1282
1283 return new_cpsr;
1284}
1285
1286bool
1288 ExceptionLevel pstateEL) const
1289{
1290 // Returns TRUE if exceptions normally routed to EL1 are being handled
1291 // at an Exception level using AArch64, because either EL1 is using
1292 // AArch64 or TGE is in force and EL2 is using AArch64.
1293 HCR hcr = ((HCR)tc->readMiscReg(MISCREG_HCR_EL2));
1294 return (pstateEL == EL0 && !ELIs32(tc, EL1)) ||
1295 (ArmSystem::haveEL(tc, EL2) && !isSecure(tc) &&
1296 !ELIs32(tc, EL2) && hcr.tge);
1297}
1298
1299unsigned
1301{
1302 auto *isa = static_cast<ArmISA::ISA *>(tc->getIsaPtr());
1303 return isa->getCurSveVecLenInBits();
1304}
1305
1306unsigned
1308{
1309 auto *isa = static_cast<ArmISA::ISA *>(tc->getIsaPtr());
1310 return isa->getCurSmeVecLenInBits();
1311}
1312
1313Fault
1315 uint32_t iss) const
1316{
1317 switch (el) {
1318 case EL1:
1319 return std::make_shared<SupervisorTrap>(getEMI(), iss, ec);
1320 case EL2:
1321 return std::make_shared<HypervisorTrap>(getEMI(), iss, ec);
1322 case EL3:
1323 return std::make_shared<SecureMonitorTrap>(getEMI(), iss, ec);
1324 default:
1325 panic("Invalid EL: %d\n", el);
1326 }
1327}
1328
1329} // namespace ArmISA
1330} // namespace gem5
void printMiscReg(std::ostream &os, RegIndex reg_idx) const
int64_t extendReg64(uint64_t base, ArmExtendType type, uint64_t shiftAmt, uint8_t width) 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 ...
void printExtendOperand(bool firstOperand, std::ostream &os, RegIndex rm, ArmExtendType type, int64_t shiftAmt) const
Fault softwareBreakpoint32(ExecContext *xc, uint16_t imm) const
Trigger a Software Breakpoint.
bool shift_carry_imm(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval) const
void printCondition(std::ostream &os, unsigned code, bool noImplicit=false) const
void printMnemonic(std::ostream &os, const std::string &suffix="", bool withPred=true, bool withCond64=false, ConditionCode cond64=COND_UC) const
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...
Fault checkSveEnabled(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
Check an SVE access against CPACR_EL1, CPTR_EL2, and CPTR_EL3.
void printMemSymbol(std::ostream &os, const loader::SymbolTable *symtab, const std::string &prefix, const Addr addr, const std::string &suffix) const
Fault undefinedFault32(ThreadContext *tc, ExceptionLevel el) const
UNDEFINED behaviour in AArch32.
static unsigned getCurSmeVecLenInBits(ThreadContext *tc)
Fault checkForWFxTrap64(ThreadContext *tc, ExceptionLevel tgtEl, bool isWfe) const
Check if WFE/WFI instruction execution in aarch64 should be trapped.
static unsigned getCurSveVecLenInBits(ThreadContext *tc)
bool isWFxTrapping(ThreadContext *tc, ExceptionLevel targetEL, bool isWfe) const
Fault generateTrap(ArmISA::ExceptionLevel el, ArmISA::ExceptionClass ec, uint32_t iss) const
Fault smeAccessTrap(ExceptionLevel el, uint32_t iss=0) const
Trap an access to SME registers due to access control bits.
int64_t shiftReg64(uint64_t base, uint64_t shiftAmt, ArmShiftType type, uint8_t width) 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.
int32_t shift_rm_rs(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval) const
void printDataInst(std::ostream &os, bool withImm) const
CPSR getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr) const
Get the new PSTATE from a SPSR register in preparation for an exception return.
void printPFflags(std::ostream &os, int flag) const
Fault trapWFx(ThreadContext *tc, CPSR cpsr, SCR scr, bool isWfe) const
WFE/WFI trapping helper function.
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.
Fault undefinedFault64(ThreadContext *tc, ExceptionLevel el) const
UNDEFINED behaviour in AArch64.
void printVecReg(std::ostream &os, RegIndex reg_idx, bool isSveVecReg=false) const
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).
void printShiftOperand(std::ostream &os, RegIndex rm, bool immShift, uint32_t shiftAmt, RegIndex rs, ArmShiftType type) const
uint64_t getEMI() const override
Fault advSIMDFPAccessTrap64(ExceptionLevel el) const
Trap an access to Advanced SIMD or FP registers due to access control bits.
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
static Addr readPC(ExecContext *xc)
Fault checkSmeAccess(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
Check an SME access against CPACR_EL1, CPTR_EL2, and CPTR_EL3.
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.
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
Fault sveAccessTrap(ExceptionLevel el) const
Trap an access to SVE registers due to access control bits.
Fault checkFPAdvSIMDEnabled64(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
Check an Advaned SIMD access against CPACR_EL1, CPTR_EL2, and CPTR_EL3.
int32_t shift_rm_imm(uint32_t base, uint32_t shamt, uint32_t type, uint32_t cfval) const
void printTarget(std::ostream &os, Addr target, const loader::SymbolTable *symtab) const
Fault checkSETENDEnabled(ThreadContext *tc, CPSR cpsr) const
Check if SETEND instruction execution in aarch32 should be trapped.
unsigned getCurSveVecLenInBits() const
Definition isa.cc:1429
SelfDebug * getSelfDebug() const
Definition isa.hh:182
unsigned getCurSmeVecLenInBits() const
Definition isa.cc:1480
bool debugExceptionReturnSS(ThreadContext *tc, CPSR spsr, ExceptionLevel dest)
bool highestELIs64() const
Returns true if the register width of the highest implemented exception level is 64 bits (ARMv8)
Definition system.hh:187
static bool haveEL(ThreadContext *tc, ArmISA::ExceptionLevel el)
Return true if the system implements a specific exception level.
Definition system.cc:132
The ExecContext is an abstract base class the provides the interface used by the ISA to manipulate th...
virtual ThreadContext * tcBase() const =0
Returns a pointer to the ThreadContext.
const char * mnemonic
Base mnemonic (e.g., "add").
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal readMiscReg(RegIndex misc_reg)=0
virtual BaseISA * getIsaPtr() const =0
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
const_iterator end() const
Definition symtab.hh:278
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...
Definition symtab.hh:474
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition bitfield.hh:79
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
const char *const RegName[NumRegs]
Definition cc.hh:64
constexpr RegId Ureg0
Definition int.hh:229
constexpr RegId Zero
Definition int.hh:228
constexpr auto & Pc
Definition int.hh:276
constexpr RegId Spx
Definition int.hh:238
constexpr RegId X31
Definition int.hh:271
bool ELIs32(ThreadContext *tc, ExceptionLevel el)
Definition utility.cc:283
Bitfield< 15, 12 > rd
Definition types.hh:114
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 ...
Definition utility.cc:291
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
Bitfield< 18, 16 > len
Bitfield< 4, 0 > mode
Definition misc_types.hh:74
Bitfield< 4 > width
Definition misc_types.hh:72
ExceptionLevel currEL(const ThreadContext *tc)
Returns the current Exception Level (EL) of the provided ThreadContext.
Definition utility.cc:134
bool isSecure(ThreadContext *tc)
Definition utility.cc:74
Bitfield< 3, 0 > rm
Definition types.hh:118
constexpr auto & StackPointerReg
Definition int.hh:654
Bitfield< 7, 0 > imm
Definition types.hh:132
Bitfield< 23, 20 > advsimd
static bool illegalExceptionReturn(ThreadContext *tc, CPSR cpsr, CPSR spsr)
Bitfield< 4 > s
static bool unknownMode32(OperatingMode mode)
Definition types.hh:484
static bool unknownMode(OperatingMode mode)
Definition types.hh:458
Bitfield< 9, 8 > rs
constexpr auto & ReturnAddressReg
Definition int.hh:655
Bitfield< 19, 16 > rn
Definition types.hh:113
bool ELIs64(ThreadContext *tc, ExceptionLevel el)
Definition utility.cc:277
bool isSecureBelowEL3(ThreadContext *tc)
Definition utility.cc:86
Bitfield< 7 > itd
ConditionCode
Definition cc.hh:104
@ COND_EQ
Definition cc.hh:105
@ COND_PL
Definition cc.hh:110
@ COND_MI
Definition cc.hh:109
@ COND_GE
Definition cc.hh:115
@ COND_LS
Definition cc.hh:114
@ COND_LE
Definition cc.hh:118
@ COND_VC
Definition cc.hh:112
@ COND_HI
Definition cc.hh:113
@ COND_CC
Definition cc.hh:108
@ COND_GT
Definition cc.hh:117
@ COND_UC
Definition cc.hh:120
@ COND_NE
Definition cc.hh:106
@ COND_VS
Definition cc.hh:111
@ COND_LT
Definition cc.hh:116
@ COND_AL
Definition cc.hh:119
@ COND_CS
Definition cc.hh:107
bool EL2Enabled(ThreadContext *tc)
Definition utility.cc:268
std::pair< bool, bool > ELUsingAArch32K(ThreadContext *tc, ExceptionLevel el)
This function checks whether selected EL provided as an argument is using the AArch32 ISA.
Definition utility.cc:302
bool IsSecureEL2Enabled(ThreadContext *tc)
Definition utility.cc:254
Bitfield< 24, 0 > iss
@ MISCREG_HCPTR
Definition misc.hh:269
@ MISCREG_SCTLR
Definition misc.hh:253
@ MISCREG_SCR_EL3
Definition misc.hh:628
@ MISCREG_SCTLR_EL1
Definition misc.hh:609
@ MISCREG_CPTR_EL2
Definition misc.hh:622
@ MISCREG_HCR_EL2
Definition misc.hh:619
@ MISCREG_MDCR_EL2
Definition misc.hh:621
@ MISCREG_HSCTLR
Definition misc.hh:264
@ MISCREG_CPTR_EL3
Definition misc.hh:630
static uint8_t getRestoredITBits(ThreadContext *tc, CPSR spsr)
Bitfield< 4 > sd
Bitfield< 3, 2 > el
Definition misc_types.hh:73
Bitfield< 8 > sed
static ExceptionLevel opModeToEL(OperatingMode mode)
Definition types.hh:429
const char *const miscRegName[]
Definition misc.hh:1840
int snsBankedIndex(MiscRegIndex reg, ThreadContext *tc)
Definition misc.cc:686
static uint8_t itState(CPSR psr)
Definition utility.hh:191
bool HaveExt(ThreadContext *tc, ArmExtension ext)
Returns true if the provided ThreadContext supports the ArmExtension passed as a second argument.
Definition utility.cc:232
Bitfield< 21 > ss
Definition misc_types.hh:60
constexpr auto & FramePointerReg
Definition int.hh:653
Bitfield< 4 > pc
Bitfield< 51, 12 > base
Definition pagetable.hh:141
Bitfield< 17 > os
Definition misc.hh:838
Bitfield< 3 > exit
Definition misc.hh:883
Bitfield< 3 > addr
Definition types.hh:84
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
std::shared_ptr< FaultBase > Fault
Definition types.hh:249
uint16_t RegIndex
Definition types.hh:176
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
constexpr decltype(nullptr) NoFault
Definition types.hh:253
void ccprintf(cp::Print &print)
Definition cprintf.hh:130

Generated on Mon Jan 13 2025 04:28:22 for gem5 by doxygen 1.9.8