gem5 v24.0.0.0
Loading...
Searching...
No Matches
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
656{
657 switch (el) {
658 case EL1:
659 return std::make_shared<SupervisorTrap>(
661 case EL2:
662 return std::make_shared<HypervisorTrap>(
664 case EL3:
665 return std::make_shared<SecureMonitorTrap>(
667
668 default:
669 panic("Illegal EL in advSIMDFPAccessTrap64\n");
670 }
671}
672
673
674Fault
676{
677 if (currEL(tc) <= EL2 && EL2Enabled(tc)) {
678 bool trap_el2 = false;
679 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL2);
680 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
681 if (HaveExt(tc, ArmExtension::FEAT_VHE) && hcr.e2h == 0x1) {
682 switch (cptr_en_check.fpen) {
683 case 0:
684 case 2:
685 trap_el2 = !(currEL(tc) == EL1 && hcr.tge == 1);
686 break;
687 case 1:
688 trap_el2 = (currEL(tc) == EL0 && hcr.tge == 1);
689 break;
690 default:
691 trap_el2 = false;
692 break;
693 }
694 } else if (cptr_en_check.tfp) {
695 trap_el2 = true;
696 }
697
698 if (trap_el2) {
700 }
701 }
702
703 if (ArmSystem::haveEL(tc, EL3)) {
704 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
705 if (cptr_en_check.tfp) {
707 }
708 }
709
710 return NoFault;
711}
712
713Fault
715 CPSR cpsr, CPACR cpacr) const
716{
717 const ExceptionLevel el = currEL(tc);
718 if (((el == EL0 && cpacr.fpen != 0x3) ||
719 (el == EL1 && !(cpacr.fpen & 0x1))) &&
720 !ELIsInHost(tc, el))
722
723 return checkFPAdvSIMDTrap64(tc, cpsr);
724}
725
726Fault
728 CPSR cpsr, CPACR cpacr,
729 NSACR nsacr, FPEXC fpexc,
730 bool fpexc_check, bool advsimd) const
731{
732 const bool have_virtualization = ArmSystem::haveEL(tc, EL2);
733 const bool have_security = ArmSystem::haveEL(tc, EL3);
734 const bool is_secure = isSecure(tc);
735 const ExceptionLevel cur_el = currEL(tc);
736
737 if (cur_el == EL0 && ELIs64(tc, EL1))
738 return checkFPAdvSIMDEnabled64(tc, cpsr, cpacr);
739
740 uint8_t cpacr_cp10 = cpacr.cp10;
741 bool cpacr_asedis = cpacr.asedis;
742
743 if (have_security && !ELIs64(tc, EL3) && !is_secure) {
744 if (nsacr.nsasedis)
745 cpacr_asedis = true;
746 if (nsacr.cp10 == 0)
747 cpacr_cp10 = 0;
748 }
749
750 if (cur_el != EL2) {
751 if (advsimd && cpacr_asedis)
752 return disabledFault();
753
754 if ((cur_el == EL0 && cpacr_cp10 != 0x3) ||
755 (cur_el != EL0 && !(cpacr_cp10 & 0x1)))
756 return disabledFault();
757 }
758
759 if (fpexc_check && !fpexc.en)
760 return disabledFault();
761
762 // -- aarch32/exceptions/traps/AArch32.CheckFPAdvSIMDTrap --
763
764 if (have_virtualization && !is_secure && ELIs64(tc, EL2))
765 return checkFPAdvSIMDTrap64(tc, cpsr);
766
767 if (have_virtualization && !is_secure) {
768 HCPTR hcptr = tc->readMiscReg(MISCREG_HCPTR);
769 bool hcptr_cp10 = hcptr.tcp10;
770 bool hcptr_tase = hcptr.tase;
771
772 if (have_security && !ELIs64(tc, EL3) && !is_secure) {
773 if (nsacr.nsasedis)
774 hcptr_tase = true;
775 if (nsacr.cp10)
776 hcptr_cp10 = true;
777 }
778
779 if ((advsimd && hcptr_tase) || hcptr_cp10) {
780 const uint32_t iss = advsimd ? (1 << 5) : 0xA;
781 if (cur_el == EL2) {
782 return std::make_shared<UndefinedInstruction>(
783 machInst, iss,
785 } else {
786 return std::make_shared<HypervisorTrap>(
787 machInst, iss,
789 }
790
791 }
792 }
793
794 if (have_security && ELIs64(tc, EL3)) {
795 HCPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
796 if (cptr_en_check.tfp)
798 }
799
800 return NoFault;
801}
802
803inline bool
805 ExceptionLevel tgtEl,
806 bool isWfe) const
807{
808 bool trap = false;
809 SCTLR sctlr = ((SCTLR)tc->readMiscReg(MISCREG_SCTLR_EL1));
810 HCR hcr = ((HCR)tc->readMiscReg(MISCREG_HCR_EL2));
811 SCR scr = ((SCR)tc->readMiscReg(MISCREG_SCR_EL3));
812
813 switch (tgtEl) {
814 case EL1:
815 trap = isWfe? !sctlr.ntwe : !sctlr.ntwi;
816 break;
817 case EL2:
818 trap = isWfe? hcr.twe : hcr.twi;
819 break;
820 case EL3:
821 trap = isWfe? scr.twe : scr.twi;
822 break;
823 default:
824 break;
825 }
826
827 return trap;
828}
829
830Fault
832 ExceptionLevel targetEL,
833 bool isWfe) const
834{
835 // Check if target exception level is implemented.
836 assert(ArmSystem::haveEL(tc, targetEL));
837
838 // Check for routing to AArch64: this happens if the
839 // target exception level (where the trap will be handled)
840 // is using aarch64
841 if (ELIs64(tc, targetEL)) {
842 return checkForWFxTrap64(tc, targetEL, isWfe);
843 }
844
845 // Check if processor needs to trap at selected exception level
846 bool trap = isWFxTrapping(tc, targetEL, isWfe);
847
848 if (trap) {
849 uint32_t iss = isWfe? 0x1E00001 : /* WFE Instruction syndrome */
850 0x1E00000; /* WFI Instruction syndrome */
851 switch (targetEL) {
852 case EL1:
853 return std::make_shared<UndefinedInstruction>(
854 machInst, iss,
856 case EL2:
857 return std::make_shared<HypervisorTrap>(
858 machInst, iss,
860 case EL3:
861 return std::make_shared<SecureMonitorTrap>(
862 machInst, iss,
864 default:
865 panic("Unrecognized Exception Level: %d\n", targetEL);
866 }
867 }
868
869 return NoFault;
870}
871
872Fault
874 ExceptionLevel targetEL,
875 bool isWfe) const
876{
877 // Check if target exception level is implemented.
878 assert(ArmSystem::haveEL(tc, targetEL));
879
880 // Check if processor needs to trap at selected exception level
881 bool trap = isWFxTrapping(tc, targetEL, isWfe);
882
883 if (trap) {
884 uint32_t iss = isWfe? 0x1E00001 : /* WFE Instruction syndrome */
885 0x1E00000; /* WFI Instruction syndrome */
886 switch (targetEL) {
887 case EL1:
888 return std::make_shared<SupervisorTrap>(
889 machInst, iss,
891 case EL2:
892 return std::make_shared<HypervisorTrap>(
893 machInst, iss,
895 case EL3:
896 return std::make_shared<SecureMonitorTrap>(
897 machInst, iss,
899 default:
900 panic("Unrecognized Exception Level: %d\n", targetEL);
901 }
902 }
903
904 return NoFault;
905}
906
907Fault
909 CPSR cpsr, SCR scr,
910 bool isWfe) const
911{
912 Fault fault = NoFault;
913 ExceptionLevel curr_el = currEL(tc);
914
915 if (curr_el == EL0) {
916 fault = checkForWFxTrap32(tc, EL1, isWfe);
917 }
918
919 if ((fault == NoFault) && EL2Enabled(tc) &&
920 ((curr_el == EL0) || (curr_el == EL1))) {
921
922 fault = checkForWFxTrap32(tc, EL2, isWfe);
923 }
924
925 if ((fault == NoFault) &&
926 ArmSystem::haveEL(tc, EL3) && curr_el != EL3) {
927 fault = checkForWFxTrap32(tc, EL3, isWfe);
928 }
929
930 return fault;
931}
932
933Fault
935{
936 bool setend_disabled(false);
937 ExceptionLevel pstate_el = currEL(tc);
938
939 if (pstate_el == EL2) {
940 setend_disabled = ((SCTLR)tc->readMiscRegNoEffect(MISCREG_HSCTLR)).sed;
941 } else {
942 // Please note: in the armarm pseudocode there is a distinction
943 // whether EL1 is aarch32 or aarch64:
944 // if ELUsingAArch32(EL1) then SCTLR.SED else SCTLR[].SED;
945 // Considering that SETEND is aarch32 only, ELUsingAArch32(EL1)
946 // will always be true (hence using SCTLR.SED) except for
947 // instruction executed at EL0, and with an AArch64 EL1.
948 // In this case SCTLR_EL1 will be used. In gem5 the register is
949 // mapped to SCTLR_ns. We can safely use SCTLR and choose the
950 // appropriate bank version.
951
952 // Get the index of the banked version of SCTLR:
953 // SCTLR_s or SCTLR_ns.
954 auto banked_sctlr = snsBankedIndex(
955 MISCREG_SCTLR, tc, !isSecure(tc));
956
957 // SCTLR.SED bit is enabling/disabling the ue of SETEND instruction.
958 setend_disabled = ((SCTLR)tc->readMiscRegNoEffect(banked_sctlr)).sed;
959 }
960
961 return setend_disabled ? undefinedFault32(tc, pstate_el) :
962 NoFault;
963}
964
965Fault
967 ExceptionLevel pstateEL) const
968{
969 // Even if we are running in aarch32, the fault might be dealt with in
970 // aarch64 ISA.
971 if (generalExceptionsToAArch64(tc, pstateEL)) {
972 return undefinedFault64(tc, pstateEL);
973 } else {
974 // Please note: according to the ARM ARM pseudocode we should handle
975 // the case when EL2 is aarch64 and HCR.TGE is 1 as well.
976 // However this case is already handled by the routeToHyp method in
977 // ArmFault class.
978 return std::make_shared<UndefinedInstruction>(
979 machInst, 0,
981 }
982}
983
984Fault
986 ExceptionLevel pstateEL) const
987{
988 switch (pstateEL) {
989 case EL0:
990 case EL1:
991 return std::make_shared<SupervisorTrap>(
993 case EL2:
994 return std::make_shared<HypervisorTrap>(
996 case EL3:
997 return std::make_shared<SecureMonitorTrap>(
999 default:
1000 panic("Unrecognized Exception Level: %d\n", pstateEL);
1001 break;
1002 }
1003
1004 return NoFault;
1005}
1006
1007Fault
1009{
1010 switch (el) {
1011 case EL1:
1012 return std::make_shared<SupervisorTrap>(
1014 case EL2:
1015 return std::make_shared<HypervisorTrap>(
1017 case EL3:
1018 return std::make_shared<SecureMonitorTrap>(
1020
1021 default:
1022 panic("Illegal EL in sveAccessTrap\n");
1023 }
1024}
1025
1026Fault
1027ArmStaticInst::checkSveEnabled(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
1028{
1029 // We first check if we are in streaming mode or not. If we are in
1030 // streaming mode, we actually check the SME traps, not the SVE traps!
1031 SVCR svcr_sm_check = tc->readMiscReg(MISCREG_SVCR);
1032 if (svcr_sm_check.sm) {
1033 return checkSmeEnabled(tc, cpsr, cpacr);
1034 }
1035
1036 const ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
1037 // Check if access disabled in CPACR_EL1
1038 if (el <= EL1 && !ELIsInHost(tc, el)) {
1039 if ((el == EL0 && cpacr.zen == 0x1) ||
1040 (!(cpacr.zen & 0x1)))
1041 return sveAccessTrap(EL1);
1042
1043 if ((el == EL0 && cpacr.fpen == 0x1) ||
1044 (!(cpacr.fpen & 0x1)))
1045 return advSIMDFPAccessTrap64(EL1);
1046 }
1047
1048 // Check if access disabled in CPTR_EL2
1049 if (el <= EL2 && EL2Enabled(tc)) {
1050 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL2);
1051 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
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 &&
1055 hcr.tge == 0x1)) {
1056 return sveAccessTrap(EL2);
1057 }
1058 if (((cptr_en_check.fpen & 0x1) == 0x0) ||
1059 (cptr_en_check.fpen == 0x1 && el == EL0 &&
1060 hcr.tge == 0x1)) {
1061 return advSIMDFPAccessTrap64(EL2);
1062 }
1063 } else {
1064 if (cptr_en_check.tz == 1)
1065 return sveAccessTrap(EL2);
1066 if (cptr_en_check.tfp == 1)
1067 return advSIMDFPAccessTrap64(EL2);
1068 }
1069 }
1070
1071 // Check if access disabled in CPTR_EL3
1072 if (ArmSystem::haveEL(tc, EL3)) {
1073 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
1074 if (!cptr_en_check.ez)
1075 return sveAccessTrap(EL3);
1076 if (cptr_en_check.tfp)
1077 return advSIMDFPAccessTrap64(EL3);
1078 }
1079
1080 return NoFault;
1081}
1082
1083Fault
1085{
1086 switch (el) {
1087 case EL1:
1088 return std::make_shared<SupervisorTrap>(
1090 case EL2:
1091 return std::make_shared<HypervisorTrap>(
1093 case EL3:
1094 return std::make_shared<SecureMonitorTrap>(
1096
1097 default:
1098 panic("Illegal EL in smeAccessTrap\n");
1099 }
1100}
1101
1102Fault
1103ArmStaticInst::checkSmeEnabled(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
1104{
1105 const ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
1106 // Check if access disabled in CPACR_EL1
1107 if (el <= EL1 && !ELIsInHost(tc, el)) {
1108 if ((el == EL0 && cpacr.smen == 0x1) ||
1109 (!(cpacr.smen & 0x1)))
1110 return smeAccessTrap(EL1);
1111
1112 if ((el == EL0 && cpacr.fpen == 0x1) ||
1113 (!(cpacr.fpen & 0x1)))
1114 return advSIMDFPAccessTrap64(EL1);
1115 }
1116
1117 // Check if access disabled in CPTR_EL2
1118 if (el <= EL2 && EL2Enabled(tc)) {
1119 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL2);
1120 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
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 &&
1124 hcr.tge == 0x1)) {
1125 return smeAccessTrap(EL2);
1126 }
1127 if (((cptr_en_check.fpen & 0x1) == 0x0) ||
1128 (cptr_en_check.fpen == 0x1 && el == EL0 &&
1129 hcr.tge == 0x1)) {
1130 return advSIMDFPAccessTrap64(EL2);
1131 }
1132 } else {
1133 if (cptr_en_check.tsm == 1)
1134 return smeAccessTrap(EL2);
1135 if (cptr_en_check.tfp == 1)
1136 return advSIMDFPAccessTrap64(EL2);
1137 }
1138 }
1139
1140 // Check if access disabled in CPTR_EL3
1141 if (ArmSystem::haveEL(tc, EL3)) {
1142 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
1143 if (!cptr_en_check.esm)
1144 return smeAccessTrap(EL3);
1145 if (cptr_en_check.tfp)
1146 return advSIMDFPAccessTrap64(EL3);
1147 }
1148
1149 return NoFault;
1150}
1151
1152Fault
1153ArmStaticInst::checkSmeAccess(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
1154{
1155 const ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
1156 // Check if access disabled in CPACR_EL1
1157 if (el <= EL1 && !ELIsInHost(tc, el)) {
1158 if ((el == EL0 && cpacr.smen == 0x1) || (!(cpacr.smen & 0x1))) {
1159 return smeAccessTrap(EL1);
1160 }
1161 }
1162
1163 // Check if access disabled in CPTR_EL2
1164 if (el <= EL2 && EL2Enabled(tc)) {
1165 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL2);
1166 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
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 &&
1170 hcr.tge == 0x1)) {
1171 return smeAccessTrap(EL2);
1172 }
1173 } else {
1174 if (cptr_en_check.tsm == 1)
1175 return smeAccessTrap(EL2);
1176 }
1177 }
1178
1179 // Check if access disabled in CPTR_EL3
1180 if (ArmSystem::haveEL(tc, EL3)) {
1181 CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
1182 if (!cptr_en_check.esm)
1183 return smeAccessTrap(EL3);
1184 }
1185
1186 return NoFault;
1187}
1188
1189Fault
1191 CPACR cpacr) const
1192{
1193 // If we are not in streaming mode, check the SVE traps, else check the SME
1194 // traps.
1195 SVCR svcr = tc->readMiscReg(MISCREG_SVCR);
1196 if (!svcr.sm) {
1197 return checkSveEnabled(tc, cpsr, cpacr);
1198 } else {
1199 return checkSmeEnabled(tc, cpsr, cpacr);
1200 }
1201}
1202
1203static uint8_t
1205{
1206 // See: shared/functions/system/RestoredITBits in the ARM ARM
1207
1208 const ExceptionLevel el = opModeToEL((OperatingMode) (uint8_t)spsr.mode);
1209 const uint8_t it = itState(spsr);
1210
1211 if (!spsr.t || spsr.il)
1212 return 0;
1213
1214 // The IT bits are forced to zero when they are set to a reserved
1215 // value.
1216 if (bits(it, 7, 4) != 0 && bits(it, 3, 0) == 0)
1217 return 0;
1218
1219 const bool itd = el == EL2 ?
1220 ((SCTLR)tc->readMiscReg(MISCREG_HSCTLR)).itd :
1221 ((SCTLR)tc->readMiscReg(MISCREG_SCTLR)).itd;
1222
1223 // The IT bits are forced to zero when returning to A32 state, or
1224 // when returning to an EL with the ITD bit set to 1, and the IT
1225 // bits are describing a multi-instruction block.
1226 if (itd && bits(it, 2, 0) != 0)
1227 return 0;
1228
1229 return it;
1230}
1231
1232static bool
1233illegalExceptionReturn(ThreadContext *tc, CPSR cpsr, CPSR spsr)
1234{
1235 const OperatingMode mode = (OperatingMode) (uint8_t)spsr.mode;
1236 if (unknownMode(mode))
1237 return true;
1238
1239 SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
1240 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
1241
1242 //ELFromSPSR
1243 bool valid;
1244 ExceptionLevel target_el = opModeToEL(mode);
1245 if (!spsr.width) {
1246 if (!ArmSystem::highestELIs64(tc)) {
1247 valid = false;
1248 } else if (!ArmSystem::haveEL(tc, target_el)) {
1249 valid = false;
1250 } else if (spsr & 0x2) {
1251 valid = false;
1252 } else if (target_el == EL0 && spsr.sp) {
1253 valid = false;
1254 } else if (target_el == EL2 && ArmSystem::haveEL(tc, EL3) &&
1255 !scr.ns && !IsSecureEL2Enabled(tc)) {
1256 valid = false;
1257 } else {
1258 valid = true;
1259 }
1260 } else {
1261 valid = !unknownMode32(mode);
1262 }
1263 if (!valid)
1264 return true;
1265
1266 if (target_el > currEL(tc))
1267 return true;
1268
1269 bool spsr_mode_is_aarch32 = (spsr.width == 1);
1270 auto [known, target_el_is_aarch32] = ELUsingAArch32K(tc, target_el);
1271 assert(known || (target_el == EL0 && ELIs64(tc, EL1)));
1272
1273 if (known && (spsr_mode_is_aarch32 != target_el_is_aarch32))
1274 return true;
1275
1276 if (target_el == EL1 && ArmSystem::haveEL(tc, EL2) && hcr.tge &&
1277 (IsSecureEL2Enabled(tc) || !isSecureBelowEL3(tc))) {
1278 return true;
1279 }
1280
1281 return false;
1282}
1283
1284CPSR
1285ArmStaticInst::getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr) const
1286{
1287 CPSR new_cpsr = 0;
1288 ExceptionLevel dest;
1289
1290 if (illegalExceptionReturn(tc, cpsr, spsr)) {
1291 // If the SPSR specifies an illegal exception return,
1292 // then PSTATE.{M, nRW, EL, SP} are unchanged and PSTATE.IL
1293 // is set to 1.
1294 new_cpsr.il = 1;
1295 if (cpsr.width) {
1296 new_cpsr.mode = cpsr.mode;
1297 } else {
1298 new_cpsr.width = cpsr.width;
1299 new_cpsr.el = cpsr.el;
1300 new_cpsr.sp = cpsr.sp;
1301 }
1302 dest = currEL(tc);
1303 } else {
1304 new_cpsr.il = spsr.il;
1305 if (spsr.width && unknownMode32((OperatingMode)(uint8_t)spsr.mode)) {
1306 new_cpsr.il = 1;
1307 } else if (spsr.width) {
1308 new_cpsr.mode = spsr.mode;
1309 } else {
1310 new_cpsr.el = spsr.el;
1311 new_cpsr.sp = spsr.sp;
1312 }
1313 dest = (ExceptionLevel)(uint8_t) spsr.el;
1314 }
1315
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) {
1321 // aarch32
1322 const ITSTATE it = getRestoredITBits(tc, spsr);
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;
1330 } else {
1331 // aarch64
1332 new_cpsr.daif = spsr.daif;
1333 new_cpsr.uao = spsr.uao;
1334 }
1335
1337 SoftwareStep *ss = sd->getSstep();
1338 new_cpsr.ss = ss->debugExceptionReturnSS(tc, spsr, dest);
1339
1340 return new_cpsr;
1341}
1342
1343bool
1345 ExceptionLevel pstateEL) const
1346{
1347 // Returns TRUE if exceptions normally routed to EL1 are being handled
1348 // at an Exception level using AArch64, because either EL1 is using
1349 // AArch64 or TGE is in force and EL2 is using AArch64.
1350 HCR hcr = ((HCR)tc->readMiscReg(MISCREG_HCR_EL2));
1351 return (pstateEL == EL0 && !ELIs32(tc, EL1)) ||
1352 (ArmSystem::haveEL(tc, EL2) && !isSecure(tc) &&
1353 !ELIs32(tc, EL2) && hcr.tge);
1354}
1355
1356unsigned
1358{
1359 auto *isa = static_cast<ArmISA::ISA *>(tc->getIsaPtr());
1360 return isa->getCurSveVecLenInBits();
1361}
1362
1363unsigned
1365{
1366 auto *isa = static_cast<ArmISA::ISA *>(tc->getIsaPtr());
1367 return isa->getCurSmeVecLenInBits();
1368}
1369
1370
1371} // namespace ArmISA
1372} // 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 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
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:1467
SelfDebug * getSelfDebug() const
Definition isa.hh:181
unsigned getCurSmeVecLenInBits() const
Definition isa.cc:1518
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:282
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:290
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:133
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:455
static bool unknownMode(OperatingMode mode)
Definition types.hh:429
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:276
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:267
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:301
bool IsSecureEL2Enabled(ThreadContext *tc)
Definition utility.cc:253
Bitfield< 24, 0 > iss
@ MISCREG_HCPTR
Definition misc.hh:257
@ MISCREG_SCTLR
Definition misc.hh:241
@ MISCREG_SCR_EL3
Definition misc.hh:604
@ MISCREG_SCTLR_EL1
Definition misc.hh:585
@ MISCREG_CPTR_EL2
Definition misc.hh:598
@ MISCREG_HCR_EL2
Definition misc.hh:595
@ MISCREG_MDCR_EL2
Definition misc.hh:597
@ MISCREG_HSCTLR
Definition misc.hh:252
@ MISCREG_CPTR_EL3
Definition misc.hh:606
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:400
const char *const miscRegName[]
Definition misc.hh:1815
int snsBankedIndex(MiscRegIndex reg, ThreadContext *tc)
Definition misc.cc:672
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:231
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 - Pranith Kumar Copyright (c) 2020 Inria 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 Tue Jun 18 2024 16:24:02 for gem5 by doxygen 1.11.0