Deleted Added
sdiff udiff text old ( 14000:d85c61dc0b5c ) new ( 14128:6ed23d07d0d1 )
full compact
1/*
2 * Copyright (c) 2010, 2012-2018 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2009 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Gabe Black
41 */
42
43#ifndef __ARCH_ARM_ISA_HH__
44#define __ARCH_ARM_ISA_HH__
45
46#include "arch/arm/isa_device.hh"
47#include "arch/arm/miscregs.hh"
48#include "arch/arm/registers.hh"
49#include "arch/arm/system.hh"
50#include "arch/arm/tlb.hh"
51#include "arch/arm/types.hh"
52#include "arch/generic/traits.hh"
53#include "debug/Checkpoint.hh"
54#include "enums/VecRegRenameMode.hh"
55#include "sim/sim_object.hh"
56#include "enums/DecoderFlavour.hh"
57
58struct ArmISAParams;
59struct DummyArmISADeviceParams;
60class ThreadContext;
61class Checkpoint;
62class EventManager;
63
64namespace ArmISA
65{
66 class ISA : public SimObject
67 {
68 protected:
69 // Parent system
70 ArmSystem *system;
71
72 // Micro Architecture
73 const Enums::DecoderFlavour _decoderFlavour;
74 const Enums::VecRegRenameMode _vecRegRenameMode;
75
76 /** Dummy device for to handle non-existing ISA devices */
77 DummyISADevice dummyDevice;
78
79 // PMU belonging to this ISA
80 BaseISADevice *pmu;
81
82 // Generic timer interface belonging to this ISA
83 std::unique_ptr<BaseISADevice> timer;
84
85 // GICv3 CPU interface belonging to this ISA
86 std::unique_ptr<BaseISADevice> gicv3CpuInterface;
87
88 // Cached copies of system-level properties
89 bool highestELIs64;
90 bool haveSecurity;
91 bool haveLPAE;
92 bool haveVirtualization;
93 bool haveCrypto;
94 bool haveLargeAsid64;
95 bool haveGICv3CPUInterface;
96 uint8_t physAddrRange;
97 bool haveSVE;
98
99 /** SVE vector length in quadwords */
100 unsigned sveVL;
101
102 /**
103 * If true, accesses to IMPLEMENTATION DEFINED registers are treated
104 * as NOP hence not causing UNDEFINED INSTRUCTION.
105 */
106 bool impdefAsNop;
107
108 bool afterStartup;
109
110 /** MiscReg metadata **/
111 struct MiscRegLUTEntry {
112 uint32_t lower; // Lower half mapped to this register
113 uint32_t upper; // Upper half mapped to this register
114 uint64_t _reset; // value taken on reset (i.e. initialization)
115 uint64_t _res0; // reserved
116 uint64_t _res1; // reserved
117 uint64_t _raz; // read as zero (fixed at 0)
118 uint64_t _rao; // read as one (fixed at 1)
119 public:
120 MiscRegLUTEntry() :
121 lower(0), upper(0),
122 _reset(0), _res0(0), _res1(0), _raz(0), _rao(0) {}
123 uint64_t reset() const { return _reset; }
124 uint64_t res0() const { return _res0; }
125 uint64_t res1() const { return _res1; }
126 uint64_t raz() const { return _raz; }
127 uint64_t rao() const { return _rao; }
128 // raz/rao implies writes ignored
129 uint64_t wi() const { return _raz | _rao; }
130 };
131
132 /** Metadata table accessible via the value of the register */
133 static std::vector<struct MiscRegLUTEntry> lookUpMiscReg;
134
135 class MiscRegLUTEntryInitializer {
136 struct MiscRegLUTEntry &entry;
137 std::bitset<NUM_MISCREG_INFOS> &info;
138 typedef const MiscRegLUTEntryInitializer& chain;
139 public:
140 chain mapsTo(uint32_t l, uint32_t u = 0) const {
141 entry.lower = l;
142 entry.upper = u;
143 return *this;
144 }
145 chain res0(uint64_t mask) const {
146 entry._res0 = mask;
147 return *this;
148 }
149 chain res1(uint64_t mask) const {
150 entry._res1 = mask;
151 return *this;
152 }
153 chain raz(uint64_t mask) const {
154 entry._raz = mask;
155 return *this;
156 }
157 chain rao(uint64_t mask) const {
158 entry._rao = mask;
159 return *this;
160 }
161 chain implemented(bool v = true) const {
162 info[MISCREG_IMPLEMENTED] = v;
163 return *this;
164 }
165 chain unimplemented() const {
166 return implemented(false);
167 }
168 chain unverifiable(bool v = true) const {
169 info[MISCREG_UNVERIFIABLE] = v;
170 return *this;
171 }
172 chain warnNotFail(bool v = true) const {
173 info[MISCREG_WARN_NOT_FAIL] = v;
174 return *this;
175 }
176 chain mutex(bool v = true) const {
177 info[MISCREG_MUTEX] = v;
178 return *this;
179 }
180 chain banked(bool v = true) const {
181 info[MISCREG_BANKED] = v;
182 return *this;
183 }
184 chain bankedChild(bool v = true) const {
185 info[MISCREG_BANKED_CHILD] = v;
186 return *this;
187 }
188 chain userNonSecureRead(bool v = true) const {
189 info[MISCREG_USR_NS_RD] = v;
190 return *this;
191 }
192 chain userNonSecureWrite(bool v = true) const {
193 info[MISCREG_USR_NS_WR] = v;
194 return *this;
195 }
196 chain userSecureRead(bool v = true) const {
197 info[MISCREG_USR_S_RD] = v;
198 return *this;
199 }
200 chain userSecureWrite(bool v = true) const {
201 info[MISCREG_USR_S_WR] = v;
202 return *this;
203 }
204 chain user(bool v = true) const {
205 userNonSecureRead(v);
206 userNonSecureWrite(v);
207 userSecureRead(v);
208 userSecureWrite(v);
209 return *this;
210 }
211 chain privNonSecureRead(bool v = true) const {
212 info[MISCREG_PRI_NS_RD] = v;
213 return *this;
214 }
215 chain privNonSecureWrite(bool v = true) const {
216 info[MISCREG_PRI_NS_WR] = v;
217 return *this;
218 }
219 chain privNonSecure(bool v = true) const {
220 privNonSecureRead(v);
221 privNonSecureWrite(v);
222 return *this;
223 }
224 chain privSecureRead(bool v = true) const {
225 info[MISCREG_PRI_S_RD] = v;
226 return *this;
227 }
228 chain privSecureWrite(bool v = true) const {
229 info[MISCREG_PRI_S_WR] = v;
230 return *this;
231 }
232 chain privSecure(bool v = true) const {
233 privSecureRead(v);
234 privSecureWrite(v);
235 return *this;
236 }
237 chain priv(bool v = true) const {
238 privSecure(v);
239 privNonSecure(v);
240 return *this;
241 }
242 chain privRead(bool v = true) const {
243 privSecureRead(v);
244 privNonSecureRead(v);
245 return *this;
246 }
247 chain hypRead(bool v = true) const {
248 info[MISCREG_HYP_RD] = v;
249 return *this;
250 }
251 chain hypWrite(bool v = true) const {
252 info[MISCREG_HYP_WR] = v;
253 return *this;
254 }
255 chain hyp(bool v = true) const {
256 hypRead(v);
257 hypWrite(v);
258 return *this;
259 }
260 chain monSecureRead(bool v = true) const {
261 info[MISCREG_MON_NS0_RD] = v;
262 return *this;
263 }
264 chain monSecureWrite(bool v = true) const {
265 info[MISCREG_MON_NS0_WR] = v;
266 return *this;
267 }
268 chain monNonSecureRead(bool v = true) const {
269 info[MISCREG_MON_NS1_RD] = v;
270 return *this;
271 }
272 chain monNonSecureWrite(bool v = true) const {
273 info[MISCREG_MON_NS1_WR] = v;
274 return *this;
275 }
276 chain mon(bool v = true) const {
277 monSecureRead(v);
278 monSecureWrite(v);
279 monNonSecureRead(v);
280 monNonSecureWrite(v);
281 return *this;
282 }
283 chain monSecure(bool v = true) const {
284 monSecureRead(v);
285 monSecureWrite(v);
286 return *this;
287 }
288 chain monNonSecure(bool v = true) const {
289 monNonSecureRead(v);
290 monNonSecureWrite(v);
291 return *this;
292 }
293 chain allPrivileges(bool v = true) const {
294 userNonSecureRead(v);
295 userNonSecureWrite(v);
296 userSecureRead(v);
297 userSecureWrite(v);
298 privNonSecureRead(v);
299 privNonSecureWrite(v);
300 privSecureRead(v);
301 privSecureWrite(v);
302 hypRead(v);
303 hypWrite(v);
304 monSecureRead(v);
305 monSecureWrite(v);
306 monNonSecureRead(v);
307 monNonSecureWrite(v);
308 return *this;
309 }
310 chain nonSecure(bool v = true) const {
311 userNonSecureRead(v);
312 userNonSecureWrite(v);
313 privNonSecureRead(v);
314 privNonSecureWrite(v);
315 hypRead(v);
316 hypWrite(v);
317 monNonSecureRead(v);
318 monNonSecureWrite(v);
319 return *this;
320 }
321 chain secure(bool v = true) const {
322 userSecureRead(v);
323 userSecureWrite(v);
324 privSecureRead(v);
325 privSecureWrite(v);
326 monSecureRead(v);
327 monSecureWrite(v);
328 return *this;
329 }
330 chain reads(bool v) const {
331 userNonSecureRead(v);
332 userSecureRead(v);
333 privNonSecureRead(v);
334 privSecureRead(v);
335 hypRead(v);
336 monSecureRead(v);
337 monNonSecureRead(v);
338 return *this;
339 }
340 chain writes(bool v) const {
341 userNonSecureWrite(v);
342 userSecureWrite(v);
343 privNonSecureWrite(v);
344 privSecureWrite(v);
345 hypWrite(v);
346 monSecureWrite(v);
347 monNonSecureWrite(v);
348 return *this;
349 }
350 chain exceptUserMode() const {
351 user(0);
352 return *this;
353 }
354 MiscRegLUTEntryInitializer(struct MiscRegLUTEntry &e,
355 std::bitset<NUM_MISCREG_INFOS> &i)
356 : entry(e),
357 info(i)
358 {
359 // force unimplemented registers to be thusly declared
360 implemented(1);
361 }
362 };
363
364 const MiscRegLUTEntryInitializer InitReg(uint32_t reg) {
365 return MiscRegLUTEntryInitializer(lookUpMiscReg[reg],
366 miscRegInfo[reg]);
367 }
368
369 void initializeMiscRegMetadata();
370
371 RegVal miscRegs[NumMiscRegs];
372 const IntRegIndex *intRegMap;
373
374 void
375 updateRegMap(CPSR cpsr)
376 {
377 if (cpsr.width == 0) {
378 intRegMap = IntReg64Map;
379 } else {
380 switch (cpsr.mode) {
381 case MODE_USER:
382 case MODE_SYSTEM:
383 intRegMap = IntRegUsrMap;
384 break;
385 case MODE_FIQ:
386 intRegMap = IntRegFiqMap;
387 break;
388 case MODE_IRQ:
389 intRegMap = IntRegIrqMap;
390 break;
391 case MODE_SVC:
392 intRegMap = IntRegSvcMap;
393 break;
394 case MODE_MON:
395 intRegMap = IntRegMonMap;
396 break;
397 case MODE_ABORT:
398 intRegMap = IntRegAbtMap;
399 break;
400 case MODE_HYP:
401 intRegMap = IntRegHypMap;
402 break;
403 case MODE_UNDEFINED:
404 intRegMap = IntRegUndMap;
405 break;
406 default:
407 panic("Unrecognized mode setting in CPSR.\n");
408 }
409 }
410 }
411
412 BaseISADevice &getGenericTimer(ThreadContext *tc);
413 BaseISADevice &getGICv3CPUInterface(ThreadContext *tc);
414
415
416 private:
417 inline void assert32(ThreadContext *tc) {
418 CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
419 assert(cpsr.width);
420 }
421
422 inline void assert64(ThreadContext *tc) {
423 CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
424 assert(!cpsr.width);
425 }
426
427 public:
428 void clear();
429
430 protected:
431 void clear32(const ArmISAParams *p, const SCTLR &sctlr_rst);
432 void clear64(const ArmISAParams *p);
433 void initID32(const ArmISAParams *p);
434 void initID64(const ArmISAParams *p);
435
436 public:
437 RegVal readMiscRegNoEffect(int misc_reg) const;
438 RegVal readMiscReg(int misc_reg, ThreadContext *tc);
439 void setMiscRegNoEffect(int misc_reg, RegVal val);
440 void setMiscReg(int misc_reg, RegVal val, ThreadContext *tc);
441
442 RegId
443 flattenRegId(const RegId& regId) const
444 {
445 switch (regId.classValue()) {
446 case IntRegClass:
447 return RegId(IntRegClass, flattenIntIndex(regId.index()));
448 case FloatRegClass:
449 return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
450 case VecRegClass:
451 return RegId(VecRegClass, flattenVecIndex(regId.index()));
452 case VecElemClass:
453 return RegId(VecElemClass, flattenVecElemIndex(regId.index()),
454 regId.elemIndex());
455 case VecPredRegClass:
456 return RegId(VecPredRegClass,
457 flattenVecPredIndex(regId.index()));
458 case CCRegClass:
459 return RegId(CCRegClass, flattenCCIndex(regId.index()));
460 case MiscRegClass:
461 return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
462 }
463 return RegId();
464 }
465
466 int
467 flattenIntIndex(int reg) const
468 {
469 assert(reg >= 0);
470 if (reg < NUM_ARCH_INTREGS) {
471 return intRegMap[reg];
472 } else if (reg < NUM_INTREGS) {
473 return reg;
474 } else if (reg == INTREG_SPX) {
475 CPSR cpsr = miscRegs[MISCREG_CPSR];
476 ExceptionLevel el = opModeToEL(
477 (OperatingMode) (uint8_t) cpsr.mode);
478 if (!cpsr.sp && el != EL0)
479 return INTREG_SP0;
480 switch (el) {
481 case EL3:
482 return INTREG_SP3;
483 case EL2:
484 return INTREG_SP2;
485 case EL1:
486 return INTREG_SP1;
487 case EL0:
488 return INTREG_SP0;
489 default:
490 panic("Invalid exception level");
491 return 0; // Never happens.
492 }
493 } else {
494 return flattenIntRegModeIndex(reg);
495 }
496 }
497
498 int
499 flattenFloatIndex(int reg) const
500 {
501 assert(reg >= 0);
502 return reg;
503 }
504
505 int
506 flattenVecIndex(int reg) const
507 {
508 assert(reg >= 0);
509 return reg;
510 }
511
512 int
513 flattenVecElemIndex(int reg) const
514 {
515 assert(reg >= 0);
516 return reg;
517 }
518
519 int
520 flattenVecPredIndex(int reg) const
521 {
522 assert(reg >= 0);
523 return reg;
524 }
525
526 int
527 flattenCCIndex(int reg) const
528 {
529 assert(reg >= 0);
530 return reg;
531 }
532
533 int
534 flattenMiscIndex(int reg) const
535 {
536 assert(reg >= 0);
537 int flat_idx = reg;
538
539 if (reg == MISCREG_SPSR) {
540 CPSR cpsr = miscRegs[MISCREG_CPSR];
541 switch (cpsr.mode) {
542 case MODE_EL0T:
543 warn("User mode does not have SPSR\n");
544 flat_idx = MISCREG_SPSR;
545 break;
546 case MODE_EL1T:
547 case MODE_EL1H:
548 flat_idx = MISCREG_SPSR_EL1;
549 break;
550 case MODE_EL2T:
551 case MODE_EL2H:
552 flat_idx = MISCREG_SPSR_EL2;
553 break;
554 case MODE_EL3T:
555 case MODE_EL3H:
556 flat_idx = MISCREG_SPSR_EL3;
557 break;
558 case MODE_USER:
559 warn("User mode does not have SPSR\n");
560 flat_idx = MISCREG_SPSR;
561 break;
562 case MODE_FIQ:
563 flat_idx = MISCREG_SPSR_FIQ;
564 break;
565 case MODE_IRQ:
566 flat_idx = MISCREG_SPSR_IRQ;
567 break;
568 case MODE_SVC:
569 flat_idx = MISCREG_SPSR_SVC;
570 break;
571 case MODE_MON:
572 flat_idx = MISCREG_SPSR_MON;
573 break;
574 case MODE_ABORT:
575 flat_idx = MISCREG_SPSR_ABT;
576 break;
577 case MODE_HYP:
578 flat_idx = MISCREG_SPSR_HYP;
579 break;
580 case MODE_UNDEFINED:
581 flat_idx = MISCREG_SPSR_UND;
582 break;
583 default:
584 warn("Trying to access SPSR in an invalid mode: %d\n",
585 cpsr.mode);
586 flat_idx = MISCREG_SPSR;
587 break;
588 }
589 } else if (miscRegInfo[reg][MISCREG_MUTEX]) {
590 // Mutually exclusive CP15 register
591 switch (reg) {
592 case MISCREG_PRRR_MAIR0:
593 case MISCREG_PRRR_MAIR0_NS:
594 case MISCREG_PRRR_MAIR0_S:
595 {
596 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
597 // If the muxed reg has been flattened, work out the
598 // offset and apply it to the unmuxed reg
599 int idxOffset = reg - MISCREG_PRRR_MAIR0;
600 if (ttbcr.eae)
601 flat_idx = flattenMiscIndex(MISCREG_MAIR0 +
602 idxOffset);
603 else
604 flat_idx = flattenMiscIndex(MISCREG_PRRR +
605 idxOffset);
606 }
607 break;
608 case MISCREG_NMRR_MAIR1:
609 case MISCREG_NMRR_MAIR1_NS:
610 case MISCREG_NMRR_MAIR1_S:
611 {
612 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
613 // If the muxed reg has been flattened, work out the
614 // offset and apply it to the unmuxed reg
615 int idxOffset = reg - MISCREG_NMRR_MAIR1;
616 if (ttbcr.eae)
617 flat_idx = flattenMiscIndex(MISCREG_MAIR1 +
618 idxOffset);
619 else
620 flat_idx = flattenMiscIndex(MISCREG_NMRR +
621 idxOffset);
622 }
623 break;
624 case MISCREG_PMXEVTYPER_PMCCFILTR:
625 {
626 PMSELR pmselr = miscRegs[MISCREG_PMSELR];
627 if (pmselr.sel == 31)
628 flat_idx = flattenMiscIndex(MISCREG_PMCCFILTR);
629 else
630 flat_idx = flattenMiscIndex(MISCREG_PMXEVTYPER);
631 }
632 break;
633 default:
634 panic("Unrecognized misc. register.\n");
635 break;
636 }
637 } else {
638 if (miscRegInfo[reg][MISCREG_BANKED]) {
639 bool secureReg = haveSecurity && !highestELIs64 &&
640 inSecureState(miscRegs[MISCREG_SCR],
641 miscRegs[MISCREG_CPSR]);
642 flat_idx += secureReg ? 2 : 1;
643 }
644 }
645 return flat_idx;
646 }
647
648 std::pair<int,int> getMiscIndices(int misc_reg) const
649 {
650 // Note: indexes of AArch64 registers are left unchanged
651 int flat_idx = flattenMiscIndex(misc_reg);
652
653 if (lookUpMiscReg[flat_idx].lower == 0) {
654 return std::make_pair(flat_idx, 0);
655 }
656
657 // do additional S/NS flattenings if mapped to NS while in S
658 bool S = haveSecurity && !highestELIs64 &&
659 inSecureState(miscRegs[MISCREG_SCR],
660 miscRegs[MISCREG_CPSR]);
661 int lower = lookUpMiscReg[flat_idx].lower;
662 int upper = lookUpMiscReg[flat_idx].upper;
663 // upper == 0, which is CPSR, is not MISCREG_BANKED_CHILD (no-op)
664 lower += S && miscRegInfo[lower][MISCREG_BANKED_CHILD];
665 upper += S && miscRegInfo[upper][MISCREG_BANKED_CHILD];
666 return std::make_pair(lower, upper);
667 }
668
669 unsigned getCurSveVecLenInBits(ThreadContext *tc) const;
670
671 unsigned getCurSveVecLenInBitsAtReset() const { return sveVL * 128; }
672
673 static void zeroSveVecRegUpperPart(VecRegContainer &vc,
674 unsigned eCount);
675
676 void serialize(CheckpointOut &cp) const
677 {
678 DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
679 SERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
680
681 SERIALIZE_SCALAR(highestELIs64);
682 SERIALIZE_SCALAR(haveSecurity);
683 SERIALIZE_SCALAR(haveLPAE);
684 SERIALIZE_SCALAR(haveVirtualization);
685 SERIALIZE_SCALAR(haveLargeAsid64);
686 SERIALIZE_SCALAR(physAddrRange);
687 SERIALIZE_SCALAR(haveSVE);
688 SERIALIZE_SCALAR(sveVL);
689 }
690 void unserialize(CheckpointIn &cp)
691 {
692 DPRINTF(Checkpoint, "Unserializing Arm Misc Registers\n");
693 UNSERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
694 CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
695 updateRegMap(tmp_cpsr);
696
697 UNSERIALIZE_SCALAR(highestELIs64);
698 UNSERIALIZE_SCALAR(haveSecurity);
699 UNSERIALIZE_SCALAR(haveLPAE);
700 UNSERIALIZE_SCALAR(haveVirtualization);
701 UNSERIALIZE_SCALAR(haveLargeAsid64);
702 UNSERIALIZE_SCALAR(physAddrRange);
703 UNSERIALIZE_SCALAR(haveSVE);
704 UNSERIALIZE_SCALAR(sveVL);
705 }
706
707 void startup(ThreadContext *tc);
708
709 Enums::DecoderFlavour decoderFlavour() const { return _decoderFlavour; }
710
711 /** Getter for haveGICv3CPUInterface */
712 bool haveGICv3CpuIfc() const
713 {
714 // haveGICv3CPUInterface is initialized at startup time, hence
715 // trying to read its value before the startup stage will lead
716 // to an error
717 assert(afterStartup);
718 return haveGICv3CPUInterface;
719 }
720
721 Enums::VecRegRenameMode
722 vecRegRenameMode() const
723 {
724 return _vecRegRenameMode;
725 }
726
727 /// Explicitly import the otherwise hidden startup
728 using SimObject::startup;
729
730 typedef ArmISAParams Params;
731
732 const Params *params() const;
733
734 ISA(Params *p);
735 };
736}
737
738template<>
739struct RenameMode<ArmISA::ISA>
740{
741 static Enums::VecRegRenameMode
742 init(const ArmISA::ISA* isa)
743 {
744 return isa->vecRegRenameMode();
745 }
746
747 static Enums::VecRegRenameMode
748 mode(const ArmISA::PCState& pc)
749 {
750 if (pc.aarch64()) {
751 return Enums::Full;
752 } else {
753 return Enums::Elem;
754 }
755 }
756
757 static bool
758 equalsInit(const ArmISA::ISA* isa1, const ArmISA::ISA* isa2)
759 {
760 return init(isa1) == init(isa2);
761 }
762};
763
764#endif