gem5 [DEVELOP-FOR-25.1]
Loading...
Searching...
No Matches
static_inst.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010-2014, 2016-2020,2022,2025 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
359 bool is_png) const
360{
361 ccprintf(os, "%s%d", is_png ? "pn" : "p", reg_idx);
362}
363
364void
365ArmStaticInst::printCCReg(std::ostream &os, RegIndex reg_idx) const
366{
367 ccprintf(os, "cc_%s", ArmISA::cc_reg::RegName[reg_idx]);
368}
369
370void
371ArmStaticInst::printMiscReg(std::ostream &os, RegIndex reg_idx) const
372{
373 assert(reg_idx < NUM_MISCREGS);
374 ccprintf(os, "%s", ArmISA::miscRegName[reg_idx]);
375}
376
377void
379 const std::string &suffix,
380 bool withPred,
381 bool withCond64,
382 ConditionCode cond64) const
383{
384 os << " " << mnemonic;
385 if (withPred && !aarch64) {
386 printCondition(os, machInst.condCode);
387 os << suffix;
388 } else if (withCond64) {
389 os << ".";
390 printCondition(os, cond64);
391 os << suffix;
392 }
393 if (machInst.bigThumb)
394 os << ".w";
395 os << " ";
396}
397
398void
399ArmStaticInst::printTarget(std::ostream &os, Addr target,
400 const loader::SymbolTable *symtab) const
401{
402 if (symtab) {
403 auto it = symtab->findNearest(target);
404 if (it != symtab->end()) {
405 ccprintf(os, "<%s", it->name());
406 Addr delta = target - it->address();
407 if (delta)
408 ccprintf(os, "+%d>", delta);
409 else
410 ccprintf(os, ">");
411 return;
412 }
413 }
414 ccprintf(os, "%#x", target);
415}
416
417void
419 unsigned code,
420 bool noImplicit) const
421{
422 switch (code) {
423 case COND_EQ:
424 os << "eq";
425 break;
426 case COND_NE:
427 os << "ne";
428 break;
429 case COND_CS:
430 os << "cs";
431 break;
432 case COND_CC:
433 os << "cc";
434 break;
435 case COND_MI:
436 os << "mi";
437 break;
438 case COND_PL:
439 os << "pl";
440 break;
441 case COND_VS:
442 os << "vs";
443 break;
444 case COND_VC:
445 os << "vc";
446 break;
447 case COND_HI:
448 os << "hi";
449 break;
450 case COND_LS:
451 os << "ls";
452 break;
453 case COND_GE:
454 os << "ge";
455 break;
456 case COND_LT:
457 os << "lt";
458 break;
459 case COND_GT:
460 os << "gt";
461 break;
462 case COND_LE:
463 os << "le";
464 break;
465 case COND_AL:
466 // This one is implicit.
467 if (noImplicit)
468 os << "al";
469 break;
470 case COND_UC:
471 // Unconditional.
472 if (noImplicit)
473 os << "uc";
474 break;
475 default:
476 panic("Unrecognized condition code %d.\n", code);
477 }
478}
479
480void
482 const loader::SymbolTable *symtab,
483 const std::string &prefix,
484 const Addr addr,
485 const std::string &suffix) const
486{
487 if (symtab) {
488 auto it = symtab->findNearest(addr);
489 if (it != symtab->end()) {
490 ccprintf(os, "%s%s", prefix, it->name());
491 if (it->address() != addr)
492 ccprintf(os, "+%d", addr - it->address());
493 ccprintf(os, suffix);
494 }
495 }
496}
497
498void
500 RegIndex rm,
501 bool immShift,
502 uint32_t shiftAmt,
503 RegIndex rs,
504 ArmShiftType type) const
505{
506 bool firstOp = false;
507
508 if (rm != int_reg::Zero) {
509 printIntReg(os, rm);
510 }
511
512 bool done = false;
513
514 if ((type == LSR || type == ASR) && immShift && shiftAmt == 0)
515 shiftAmt = 32;
516
517 switch (type) {
518 case LSL:
519 if (immShift && shiftAmt == 0) {
520 done = true;
521 break;
522 }
523 if (!firstOp)
524 os << ", ";
525 os << "LSL";
526 break;
527 case LSR:
528 if (!firstOp)
529 os << ", ";
530 os << "LSR";
531 break;
532 case ASR:
533 if (!firstOp)
534 os << ", ";
535 os << "ASR";
536 break;
537 case ROR:
538 if (immShift && shiftAmt == 0) {
539 if (!firstOp)
540 os << ", ";
541 os << "RRX";
542 done = true;
543 break;
544 }
545 if (!firstOp)
546 os << ", ";
547 os << "ROR";
548 break;
549 default:
550 panic("Tried to disassemble unrecognized shift type.\n");
551 }
552 if (!done) {
553 if (!firstOp)
554 os << " ";
555 if (immShift)
556 os << "#" << shiftAmt;
557 else
558 printIntReg(os, rs);
559 }
560}
561
562void
563ArmStaticInst::printExtendOperand(bool firstOperand, std::ostream &os,
565 int64_t shiftAmt) const
566{
567 if (!firstOperand)
568 ccprintf(os, ", ");
569 printIntReg(os, rm);
570 if (type == UXTX && shiftAmt == 0)
571 return;
572 switch (type) {
573 case UXTB: ccprintf(os, ", UXTB");
574 break;
575 case UXTH: ccprintf(os, ", UXTH");
576 break;
577 case UXTW: ccprintf(os, ", UXTW");
578 break;
579 case UXTX: ccprintf(os, ", LSL");
580 break;
581 case SXTB: ccprintf(os, ", SXTB");
582 break;
583 case SXTH: ccprintf(os, ", SXTH");
584 break;
585 case SXTW: ccprintf(os, ", SXTW");
586 break;
587 case SXTX: ccprintf(os, ", SXTW");
588 break;
589 }
590 if (type == UXTX || shiftAmt)
591 ccprintf(os, " #%d", shiftAmt);
592}
593
594void
595ArmStaticInst::printDataInst(std::ostream &os, bool withImm,
596 bool immShift, bool s, RegIndex rd, RegIndex rn,
597 RegIndex rm, RegIndex rs, uint32_t shiftAmt,
598 ArmShiftType type, uint64_t imm) const
599{
600 printMnemonic(os, s ? "s" : "");
601 bool firstOp = true;
602
603 // Destination
604 if (rd != int_reg::Zero) {
605 firstOp = false;
606 printIntReg(os, rd);
607 }
608
609 // Source 1.
610 if (rn != int_reg::Zero) {
611 if (!firstOp)
612 os << ", ";
613 firstOp = false;
614 printIntReg(os, rn);
615 }
616
617 if (!firstOp)
618 os << ", ";
619 if (withImm) {
620 ccprintf(os, "#%ld", imm);
621 } else {
622 printShiftOperand(os, rm, immShift, shiftAmt, rs, type);
623 }
624}
625
626std::string
628 const loader::SymbolTable *symtab) const
629{
630 std::stringstream ss;
632 return ss.str();
633}
634
635Fault
637{
638 const auto tc = xc->tcBase();
639 const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
640 const HDCR mdcr = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
641 if ((EL2Enabled(tc) && !ELIs32(tc, EL2) &&
642 (hcr.tge || mdcr.tde)) || !ELIs32(tc, EL1)) {
643 // Route to AArch64 Software Breakpoint
644 return std::make_shared<SoftwareBreakpoint>(machInst, imm);
645 } else {
646 // Execute AArch32 Software Breakpoint
647 return std::make_shared<PrefetchAbort>(readPC(xc),
649 false,
652 }
653}
654
655Fault
660
661Fault
663{
664 if (currEL(tc) <= EL2 && EL2Enabled(tc)) {
665 bool trap_el2 = false;
666 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL2);
667 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
668 if (HaveExt(tc, ArmExtension::FEAT_VHE) && hcr.e2h == 0x1) {
669 switch (cptr_en_check.fpen) {
670 case 0:
671 case 2:
672 trap_el2 = !(currEL(tc) == EL1 && hcr.tge == 1);
673 break;
674 case 1:
675 trap_el2 = (currEL(tc) == EL0 && hcr.tge == 1);
676 break;
677 default:
678 trap_el2 = false;
679 break;
680 }
681 } else if (cptr_en_check.tfp) {
682 trap_el2 = true;
683 }
684
685 if (trap_el2) {
687 }
688 }
689
690 if (ArmSystem::haveEL(tc, EL3)) {
691 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
692 if (cptr_en_check.tfp) {
694 }
695 }
696
697 return NoFault;
698}
699
700Fault
702 CPSR cpsr, CPACR cpacr) const
703{
704 const ExceptionLevel el = currEL(tc);
705 if (((el == EL0 && cpacr.fpen != 0x3) ||
706 (el == EL1 && !(cpacr.fpen & 0x1))) &&
707 !ELIsInHost(tc, el))
709
710 return checkFPAdvSIMDTrap64(tc, cpsr);
711}
712
713Fault
715 CPSR cpsr, CPACR cpacr,
716 NSACR nsacr, FPEXC fpexc,
717 bool fpexc_check, bool advsimd) const
718{
719 const bool have_virtualization = ArmSystem::haveEL(tc, EL2);
720 const bool have_security = ArmSystem::haveEL(tc, EL3);
721 const bool is_secure = isSecure(tc);
722 const ExceptionLevel cur_el = currEL(tc);
723
724 if (cur_el == EL0 && ELIs64(tc, EL1))
725 return checkFPAdvSIMDEnabled64(tc, cpsr, cpacr);
726
727 uint8_t cpacr_cp10 = cpacr.cp10;
728 bool cpacr_asedis = cpacr.asedis;
729
730 if (have_security && !ELIs64(tc, EL3) && !is_secure) {
731 if (nsacr.nsasedis)
732 cpacr_asedis = true;
733 if (nsacr.cp10 == 0)
734 cpacr_cp10 = 0;
735 }
736
737 if (cur_el != EL2) {
738 if (advsimd && cpacr_asedis)
739 return disabledFault();
740
741 if ((cur_el == EL0 && cpacr_cp10 != 0x3) ||
742 (cur_el != EL0 && !(cpacr_cp10 & 0x1)))
743 return disabledFault();
744 }
745
746 if (fpexc_check && !fpexc.en)
747 return disabledFault();
748
749 // -- aarch32/exceptions/traps/AArch32.CheckFPAdvSIMDTrap --
750
751 if (have_virtualization && !is_secure && ELIs64(tc, EL2))
752 return checkFPAdvSIMDTrap64(tc, cpsr);
753
754 if (have_virtualization && !is_secure) {
755 HCPTR hcptr = tc->readMiscReg(MISCREG_HCPTR);
756 bool hcptr_tcp10 = hcptr.tcp10;
757 bool hcptr_tase = hcptr.tase;
758
759 if (have_security && !ELIs64(tc, EL3) && !is_secure) {
760 if (nsacr.nsasedis)
761 hcptr_tase = true;
762 if (!nsacr.cp10)
763 hcptr_tcp10 = true;
764 }
765
766 if ((advsimd && hcptr_tase) || hcptr_tcp10) {
767 const uint32_t iss = advsimd ? (1 << 5) : 0xA;
768 if (cur_el == EL2) {
769 return std::make_shared<UndefinedInstruction>(
770 machInst, iss,
772 } else {
773 return std::make_shared<HypervisorTrap>(
774 machInst, iss,
776 }
777
778 }
779 }
780
781 if (have_security && ELIs64(tc, EL3)) {
782 HCPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
783 if (cptr_en_check.tfp)
785 }
786
787 return NoFault;
788}
789
790inline bool
792 ExceptionLevel tgtEl,
793 bool isWfe) const
794{
795 bool trap = false;
796 SCTLR sctlr = ((SCTLR)tc->readMiscReg(MISCREG_SCTLR_EL1));
797 HCR hcr = ((HCR)tc->readMiscReg(MISCREG_HCR_EL2));
798 SCR scr = ((SCR)tc->readMiscReg(MISCREG_SCR_EL3));
799
800 switch (tgtEl) {
801 case EL1:
802 trap = isWfe? !sctlr.ntwe : !sctlr.ntwi;
803 break;
804 case EL2:
805 trap = isWfe? hcr.twe : hcr.twi;
806 break;
807 case EL3:
808 trap = isWfe? scr.twe : scr.twi;
809 break;
810 default:
811 break;
812 }
813
814 return trap;
815}
816
817Fault
819 ExceptionLevel targetEL,
820 bool isWfe) const
821{
822 // Check if target exception level is implemented.
823 assert(ArmSystem::haveEL(tc, targetEL));
824
825 // Check for routing to AArch64: this happens if the
826 // target exception level (where the trap will be handled)
827 // is using aarch64
828 if (ELIs64(tc, targetEL)) {
829 return checkForWFxTrap64(tc, targetEL, isWfe);
830 }
831
832 // Check if processor needs to trap at selected exception level
833 bool trap = isWFxTrapping(tc, targetEL, isWfe);
834
835 if (trap) {
836 uint32_t iss = isWfe? 0x1E00001 : /* WFE Instruction syndrome */
837 0x1E00000; /* WFI Instruction syndrome */
838 switch (targetEL) {
839 case EL1:
840 return std::make_shared<UndefinedInstruction>(
841 machInst, iss,
843 case EL2:
844 return std::make_shared<HypervisorTrap>(
845 machInst, iss,
847 case EL3:
848 return std::make_shared<SecureMonitorTrap>(
849 machInst, iss,
851 default:
852 panic("Unrecognized Exception Level: %d\n", targetEL);
853 }
854 }
855
856 return NoFault;
857}
858
859Fault
861 ExceptionLevel target_el,
862 bool is_wfe) const
863{
864 // Check if target exception level is implemented.
865 assert(ArmSystem::haveEL(tc, target_el));
866
867 // Check if processor needs to trap at selected exception level
868 if (isWFxTrapping(tc, target_el, is_wfe)) {
869 uint32_t iss = is_wfe? 0x1E00001 : /* WFE Instruction syndrome */
870 0x1E00000; /* WFI Instruction syndrome */
872 } else {
873 return NoFault;
874 }
875}
876
877Fault
879 CPSR cpsr, SCR scr,
880 bool isWfe) const
881{
882 Fault fault = NoFault;
883 ExceptionLevel curr_el = currEL(tc);
884
885 if (curr_el == EL0) {
886 fault = checkForWFxTrap32(tc, EL1, isWfe);
887 }
888
889 if ((fault == NoFault) && EL2Enabled(tc) &&
890 ((curr_el == EL0) || (curr_el == EL1))) {
891
892 fault = checkForWFxTrap32(tc, EL2, isWfe);
893 }
894
895 if ((fault == NoFault) &&
896 ArmSystem::haveEL(tc, EL3) && curr_el != EL3) {
897 fault = checkForWFxTrap32(tc, EL3, isWfe);
898 }
899
900 return fault;
901}
902
903Fault
905{
906 bool setend_disabled(false);
907 ExceptionLevel pstate_el = currEL(tc);
908
909 if (pstate_el == EL2) {
910 setend_disabled = ((SCTLR)tc->readMiscRegNoEffect(MISCREG_HSCTLR)).sed;
911 } else {
912 // Please note: in the armarm pseudocode there is a distinction
913 // whether EL1 is aarch32 or aarch64:
914 // if ELUsingAArch32(EL1) then SCTLR.SED else SCTLR[].SED;
915 // Considering that SETEND is aarch32 only, ELUsingAArch32(EL1)
916 // will always be true (hence using SCTLR.SED) except for
917 // instruction executed at EL0, and with an AArch64 EL1.
918 // In this case SCTLR_EL1 will be used. In gem5 the register is
919 // mapped to SCTLR_ns. We can safely use SCTLR and choose the
920 // appropriate bank version.
921
922 // Get the index of the banked version of SCTLR:
923 // SCTLR_s or SCTLR_ns.
924 auto banked_sctlr = snsBankedIndex(
925 MISCREG_SCTLR, tc, !isSecure(tc));
926
927 // SCTLR.SED bit is enabling/disabling the ue of SETEND instruction.
928 setend_disabled = ((SCTLR)tc->readMiscRegNoEffect(banked_sctlr)).sed;
929 }
930
931 return setend_disabled ? undefinedFault32(tc, pstate_el) :
932 NoFault;
933}
934
935Fault
937 ExceptionLevel pstateEL) const
938{
939 // Even if we are running in aarch32, the fault might be dealt with in
940 // aarch64 ISA.
941 if (generalExceptionsToAArch64(tc, pstateEL)) {
942 return undefinedFault64(tc, pstateEL);
943 } else {
944 // Please note: according to the ARM ARM pseudocode we should handle
945 // the case when EL2 is aarch64 and HCR.TGE is 1 as well.
946 // However this case is already handled by the routeToHyp method in
947 // ArmFault class.
948 return std::make_shared<UndefinedInstruction>(
949 machInst, 0,
951 }
952}
953
954Fault
956 ExceptionLevel pstateEL) const
957{
958 switch (pstateEL) {
959 case EL0:
960 case EL1:
961 return std::make_shared<SupervisorTrap>(
963 case EL2:
964 return std::make_shared<HypervisorTrap>(
966 case EL3:
967 return std::make_shared<SecureMonitorTrap>(
969 default:
970 panic("Unrecognized Exception Level: %d\n", pstateEL);
971 break;
972 }
973
974 return NoFault;
975}
976
977Fault
982
983Fault
984ArmStaticInst::checkSveEnabled(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
985{
986 // We first check if we are in streaming mode or not. If we are in
987 // streaming mode, we actually check the SME traps, not the SVE traps!
988 SVCR svcr_sm_check = tc->readMiscReg(MISCREG_SVCR);
989 if (svcr_sm_check.sm) {
990 return checkSmeEnabled(tc, cpsr, cpacr);
991 }
992
993 const ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
994 // Check if access disabled in CPACR_EL1
995 if (el <= EL1 && !ELIsInHost(tc, el)) {
996 if ((el == EL0 && cpacr.zen == 0x1) ||
997 (!(cpacr.zen & 0x1)))
998 return sveAccessTrap(EL1);
999
1000 if ((el == EL0 && cpacr.fpen == 0x1) ||
1001 (!(cpacr.fpen & 0x1)))
1002 return advSIMDFPAccessTrap64(EL1);
1003 }
1004
1005 // Check if access disabled in CPTR_EL2
1006 if (el <= EL2 && EL2Enabled(tc)) {
1007 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL2);
1008 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
1009 if (HaveExt(tc, ArmExtension::FEAT_VHE) && hcr.e2h) {
1010 if (((cptr_en_check.zen & 0x1) == 0x0) ||
1011 (cptr_en_check.zen == 0x1 && el == EL0 &&
1012 hcr.tge == 0x1)) {
1013 return sveAccessTrap(EL2);
1014 }
1015 if (((cptr_en_check.fpen & 0x1) == 0x0) ||
1016 (cptr_en_check.fpen == 0x1 && el == EL0 &&
1017 hcr.tge == 0x1)) {
1018 return advSIMDFPAccessTrap64(EL2);
1019 }
1020 } else {
1021 if (cptr_en_check.tz == 1)
1022 return sveAccessTrap(EL2);
1023 if (cptr_en_check.tfp == 1)
1024 return advSIMDFPAccessTrap64(EL2);
1025 }
1026 }
1027
1028 // Check if access disabled in CPTR_EL3
1029 if (ArmSystem::haveEL(tc, EL3)) {
1030 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
1031 if (!cptr_en_check.ez)
1032 return sveAccessTrap(EL3);
1033 if (cptr_en_check.tfp)
1034 return advSIMDFPAccessTrap64(EL3);
1035 }
1036
1037 return NoFault;
1038}
1039
1040Fault
1045
1046Fault
1047ArmStaticInst::checkSmeEnabled(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
1048{
1049 const ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
1050 // Check if access disabled in CPACR_EL1
1051 if (el <= EL1 && !ELIsInHost(tc, el)) {
1052 if ((el == EL0 && cpacr.smen == 0x1) ||
1053 (!(cpacr.smen & 0x1)))
1054 return smeAccessTrap(EL1);
1055
1056 if ((el == EL0 && cpacr.fpen == 0x1) ||
1057 (!(cpacr.fpen & 0x1)))
1058 return advSIMDFPAccessTrap64(EL1);
1059 }
1060
1061 // Check if access disabled in CPTR_EL2
1062 if (el <= EL2 && EL2Enabled(tc)) {
1063 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL2);
1064 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
1065 if (HaveExt(tc, ArmExtension::FEAT_VHE) && hcr.e2h) {
1066 if (((cptr_en_check.smen & 0x1) == 0x0) ||
1067 (cptr_en_check.smen == 0x1 && el == EL0 &&
1068 hcr.tge == 0x1)) {
1069 return smeAccessTrap(EL2);
1070 }
1071 if (((cptr_en_check.fpen & 0x1) == 0x0) ||
1072 (cptr_en_check.fpen == 0x1 && el == EL0 &&
1073 hcr.tge == 0x1)) {
1074 return advSIMDFPAccessTrap64(EL2);
1075 }
1076 } else {
1077 if (cptr_en_check.tsm == 1)
1078 return smeAccessTrap(EL2);
1079 if (cptr_en_check.tfp == 1)
1080 return advSIMDFPAccessTrap64(EL2);
1081 }
1082 }
1083
1084 // Check if access disabled in CPTR_EL3
1085 if (ArmSystem::haveEL(tc, EL3)) {
1086 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
1087 if (!cptr_en_check.esm)
1088 return smeAccessTrap(EL3);
1089 if (cptr_en_check.tfp)
1090 return advSIMDFPAccessTrap64(EL3);
1091 }
1092
1093 return NoFault;
1094}
1095
1096Fault
1097ArmStaticInst::checkSmeAccess(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
1098{
1099 const ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
1100 // Check if access disabled in CPACR_EL1
1101 if (el <= EL1 && !ELIsInHost(tc, el)) {
1102 if ((el == EL0 && cpacr.smen == 0x1) || (!(cpacr.smen & 0x1))) {
1103 return smeAccessTrap(EL1);
1104 }
1105 }
1106
1107 // Check if access disabled in CPTR_EL2
1108 if (el <= EL2 && EL2Enabled(tc)) {
1109 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL2);
1110 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
1111 if (HaveExt(tc, ArmExtension::FEAT_VHE) && hcr.e2h) {
1112 if (((cptr_en_check.smen & 0x1) == 0x0) ||
1113 (cptr_en_check.smen == 0x1 && el == EL0 &&
1114 hcr.tge == 0x1)) {
1115 return smeAccessTrap(EL2);
1116 }
1117 } else {
1118 if (cptr_en_check.tsm == 1)
1119 return smeAccessTrap(EL2);
1120 }
1121 }
1122
1123 // Check if access disabled in CPTR_EL3
1124 if (ArmSystem::haveEL(tc, EL3)) {
1125 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
1126 if (!cptr_en_check.esm)
1127 return smeAccessTrap(EL3);
1128 }
1129
1130 return NoFault;
1131}
1132
1133Fault
1135 CPACR cpacr) const
1136{
1137 // If we are not in streaming mode, check the SVE traps, else check the SME
1138 // traps.
1139 SVCR svcr = tc->readMiscReg(MISCREG_SVCR);
1140 if (!svcr.sm) {
1141 return checkSveEnabled(tc, cpsr, cpacr);
1142 } else {
1143 return checkSmeEnabled(tc, cpsr, cpacr);
1144 }
1145}
1146
1147static uint8_t
1149{
1150 // See: shared/functions/system/RestoredITBits in the ARM ARM
1151
1152 const ExceptionLevel el = opModeToEL((OperatingMode) (uint8_t)spsr.mode);
1153 const uint8_t it = itState(spsr);
1154
1155 if (!spsr.t || spsr.il)
1156 return 0;
1157
1158 // The IT bits are forced to zero when they are set to a reserved
1159 // value.
1160 if (bits(it, 7, 4) != 0 && bits(it, 3, 0) == 0)
1161 return 0;
1162
1163 const bool itd = el == EL2 ?
1164 ((SCTLR)tc->readMiscReg(MISCREG_HSCTLR)).itd :
1165 ((SCTLR)tc->readMiscReg(MISCREG_SCTLR)).itd;
1166
1167 // The IT bits are forced to zero when returning to A32 state, or
1168 // when returning to an EL with the ITD bit set to 1, and the IT
1169 // bits are describing a multi-instruction block.
1170 if (itd && bits(it, 2, 0) != 0)
1171 return 0;
1172
1173 return it;
1174}
1175
1176static bool
1177illegalExceptionReturn(ThreadContext *tc, CPSR cpsr, CPSR spsr)
1178{
1179 const OperatingMode mode = (OperatingMode) (uint8_t)spsr.mode;
1180 if (unknownMode(mode))
1181 return true;
1182
1183 SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
1184 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
1185
1186 //ELFromSPSR
1187 bool valid;
1188 ExceptionLevel target_el = opModeToEL(mode);
1189 if (!spsr.width) {
1190 if (!ArmSystem::highestELIs64(tc)) {
1191 valid = false;
1192 } else if (!ArmSystem::haveEL(tc, target_el)) {
1193 valid = false;
1194 } else if (spsr & 0x2) {
1195 valid = false;
1196 } else if (target_el == EL0 && spsr.sp) {
1197 valid = false;
1198 } else if (target_el == EL2 && ArmSystem::haveEL(tc, EL3) &&
1199 !scr.ns && !IsSecureEL2Enabled(tc)) {
1200 valid = false;
1201 } else {
1202 valid = true;
1203 }
1204 } else {
1205 valid = !unknownMode32(mode);
1206 }
1207 if (!valid)
1208 return true;
1209
1210 if (target_el > currEL(tc))
1211 return true;
1212
1213 bool spsr_mode_is_aarch32 = (spsr.width == 1);
1214 auto [known, target_el_is_aarch32] = ELUsingAArch32K(tc, target_el);
1215 assert(known || (target_el == EL0 && ELIs64(tc, EL1)));
1216
1217 if (known && (spsr_mode_is_aarch32 != target_el_is_aarch32))
1218 return true;
1219
1220 if (target_el == EL1 && ArmSystem::haveEL(tc, EL2) && hcr.tge &&
1221 (IsSecureEL2Enabled(tc) || !isSecureBelowEL3(tc))) {
1222 return true;
1223 }
1224
1225 return false;
1226}
1227
1228CPSR
1229ArmStaticInst::getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr) const
1230{
1231 CPSR new_cpsr = 0;
1232 ExceptionLevel dest;
1233
1234 if (illegalExceptionReturn(tc, cpsr, spsr)) {
1235 // If the SPSR specifies an illegal exception return,
1236 // then PSTATE.{M, nRW, EL, SP} are unchanged and PSTATE.IL
1237 // is set to 1.
1238 new_cpsr.il = 1;
1239 if (cpsr.width) {
1240 new_cpsr.mode = cpsr.mode;
1241 } else {
1242 new_cpsr.width = cpsr.width;
1243 new_cpsr.el = cpsr.el;
1244 new_cpsr.sp = cpsr.sp;
1245 }
1246 dest = currEL(tc);
1247 } else {
1248 new_cpsr.il = spsr.il;
1249 if (spsr.width && unknownMode32((OperatingMode)(uint8_t)spsr.mode)) {
1250 new_cpsr.il = 1;
1251 } else if (spsr.width) {
1252 new_cpsr.mode = spsr.mode;
1253 } else {
1254 new_cpsr.el = spsr.el;
1255 new_cpsr.sp = spsr.sp;
1256 }
1257 dest = (ExceptionLevel)(uint8_t) spsr.el;
1258 }
1259
1260 new_cpsr.nz = spsr.nz;
1261 new_cpsr.c = spsr.c;
1262 new_cpsr.v = spsr.v;
1263 new_cpsr.pan = spsr.pan;
1264 if (new_cpsr.width) {
1265 // aarch32
1266 const ITSTATE it = getRestoredITBits(tc, spsr);
1267 new_cpsr.q = spsr.q;
1268 new_cpsr.ge = spsr.ge;
1269 new_cpsr.e = spsr.e;
1270 new_cpsr.aif = spsr.aif;
1271 new_cpsr.t = spsr.t;
1272 new_cpsr.it2 = it.top6;
1273 new_cpsr.it1 = it.bottom2;
1274 } else {
1275 // aarch64
1276 new_cpsr.daif = spsr.daif;
1277 new_cpsr.uao = spsr.uao;
1278 }
1279
1281 SoftwareStep *ss = sd->getSstep();
1282 new_cpsr.ss = ss->debugExceptionReturnSS(tc, spsr, dest);
1283
1284 return new_cpsr;
1285}
1286
1287bool
1289 ExceptionLevel pstateEL) const
1290{
1291 // Returns TRUE if exceptions normally routed to EL1 are being handled
1292 // at an Exception level using AArch64, because either EL1 is using
1293 // AArch64 or TGE is in force and EL2 is using AArch64.
1294 HCR hcr = ((HCR)tc->readMiscReg(MISCREG_HCR_EL2));
1295 return (pstateEL == EL0 && !ELIs32(tc, EL1)) ||
1296 (ArmSystem::haveEL(tc, EL2) && !isSecure(tc) &&
1297 !ELIs32(tc, EL2) && hcr.tge);
1298}
1299
1300unsigned
1302{
1303 auto *isa = static_cast<ArmISA::ISA *>(tc->getIsaPtr());
1304 return isa->getCurSveVecLenInBits();
1305}
1306
1307unsigned
1309{
1310 auto *isa = static_cast<ArmISA::ISA *>(tc->getIsaPtr());
1311 return isa->getCurSmeVecLenInBits();
1312}
1313
1314Fault
1316 uint32_t iss) const
1317{
1318 switch (el) {
1319 case EL1:
1320 return std::make_shared<SupervisorTrap>(getEMI(), iss, ec);
1321 case EL2:
1322 return std::make_shared<HypervisorTrap>(getEMI(), iss, ec);
1323 case EL3:
1324 return std::make_shared<SecureMonitorTrap>(getEMI(), iss, ec);
1325 default:
1326 panic("Invalid EL: %d\n", el);
1327 }
1328}
1329
1330} // namespace ArmISA
1331} // 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
void printVecPredReg(std::ostream &os, RegIndex reg_idx, bool is_png=false) 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.
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:1442
SelfDebug * getSelfDebug() const
Definition isa.hh:182
unsigned getCurSmeVecLenInBits() const
Definition isa.cc:1493
bool highestELIs64() const
Returns true if the register width of the highest implemented exception level is 64 bits (ARMv8)
Definition system.hh:188
static bool haveEL(ThreadContext *tc, ArmISA::ExceptionLevel el)
Return true if the system implements a specific exception level.
Definition system.cc:133
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:220
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
static ExceptionLevel opModeToEL(OperatingMode mode)
Definition types.hh:429
const char *const miscRegName[]
Definition misc.hh:1849
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< 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
uint16_t RegIndex
Definition types.hh:176
std::shared_ptr< FaultBase > Fault
Definition types.hh:249
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 Oct 27 2025 04:13:01 for gem5 by doxygen 1.14.0