isa.hh revision 13759:9941fca869a9
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        /** MiscReg metadata **/
109        struct MiscRegLUTEntry {
110            uint32_t lower;  // Lower half mapped to this register
111            uint32_t upper;  // Upper half mapped to this register
112            uint64_t _reset; // value taken on reset (i.e. initialization)
113            uint64_t _res0;  // reserved
114            uint64_t _res1;  // reserved
115            uint64_t _raz;   // read as zero (fixed at 0)
116            uint64_t _rao;   // read as one (fixed at 1)
117          public:
118            MiscRegLUTEntry() :
119              lower(0), upper(0),
120              _reset(0), _res0(0), _res1(0), _raz(0), _rao(0) {}
121            uint64_t reset() const { return _reset; }
122            uint64_t res0()  const { return _res0; }
123            uint64_t res1()  const { return _res1; }
124            uint64_t raz()   const { return _raz; }
125            uint64_t rao()   const { return _rao; }
126            // raz/rao implies writes ignored
127            uint64_t wi()    const { return _raz | _rao; }
128        };
129
130        /** Metadata table accessible via the value of the register */
131        static std::vector<struct MiscRegLUTEntry> lookUpMiscReg;
132
133        class MiscRegLUTEntryInitializer {
134            struct MiscRegLUTEntry &entry;
135            std::bitset<NUM_MISCREG_INFOS> &info;
136            typedef const MiscRegLUTEntryInitializer& chain;
137          public:
138            chain mapsTo(uint32_t l, uint32_t u = 0) const {
139                entry.lower = l;
140                entry.upper = u;
141                return *this;
142            }
143            chain res0(uint64_t mask) const {
144                entry._res0 = mask;
145                return *this;
146            }
147            chain res1(uint64_t mask) const {
148                entry._res1 = mask;
149                return *this;
150            }
151            chain raz(uint64_t mask) const {
152                entry._raz  = mask;
153                return *this;
154            }
155            chain rao(uint64_t mask) const {
156                entry._rao  = mask;
157                return *this;
158            }
159            chain implemented(bool v = true) const {
160                info[MISCREG_IMPLEMENTED] = v;
161                return *this;
162            }
163            chain unimplemented() const {
164                return implemented(false);
165            }
166            chain unverifiable(bool v = true) const {
167                info[MISCREG_UNVERIFIABLE] = v;
168                return *this;
169            }
170            chain warnNotFail(bool v = true) const {
171                info[MISCREG_WARN_NOT_FAIL] = v;
172                return *this;
173            }
174            chain mutex(bool v = true) const {
175                info[MISCREG_MUTEX] = v;
176                return *this;
177            }
178            chain banked(bool v = true) const {
179                info[MISCREG_BANKED] = v;
180                return *this;
181            }
182            chain bankedChild(bool v = true) const {
183                info[MISCREG_BANKED_CHILD] = v;
184                return *this;
185            }
186            chain userNonSecureRead(bool v = true) const {
187                info[MISCREG_USR_NS_RD] = v;
188                return *this;
189            }
190            chain userNonSecureWrite(bool v = true) const {
191                info[MISCREG_USR_NS_WR] = v;
192                return *this;
193            }
194            chain userSecureRead(bool v = true) const {
195                info[MISCREG_USR_S_RD] = v;
196                return *this;
197            }
198            chain userSecureWrite(bool v = true) const {
199                info[MISCREG_USR_S_WR] = v;
200                return *this;
201            }
202            chain user(bool v = true) const {
203                userNonSecureRead(v);
204                userNonSecureWrite(v);
205                userSecureRead(v);
206                userSecureWrite(v);
207                return *this;
208            }
209            chain privNonSecureRead(bool v = true) const {
210                info[MISCREG_PRI_NS_RD] = v;
211                return *this;
212            }
213            chain privNonSecureWrite(bool v = true) const {
214                info[MISCREG_PRI_NS_WR] = v;
215                return *this;
216            }
217            chain privNonSecure(bool v = true) const {
218                privNonSecureRead(v);
219                privNonSecureWrite(v);
220                return *this;
221            }
222            chain privSecureRead(bool v = true) const {
223                info[MISCREG_PRI_S_RD] = v;
224                return *this;
225            }
226            chain privSecureWrite(bool v = true) const {
227                info[MISCREG_PRI_S_WR] = v;
228                return *this;
229            }
230            chain privSecure(bool v = true) const {
231                privSecureRead(v);
232                privSecureWrite(v);
233                return *this;
234            }
235            chain priv(bool v = true) const {
236                privSecure(v);
237                privNonSecure(v);
238                return *this;
239            }
240            chain privRead(bool v = true) const {
241                privSecureRead(v);
242                privNonSecureRead(v);
243                return *this;
244            }
245            chain hypRead(bool v = true) const {
246                info[MISCREG_HYP_RD] = v;
247                return *this;
248            }
249            chain hypWrite(bool v = true) const {
250                info[MISCREG_HYP_WR] = v;
251                return *this;
252            }
253            chain hyp(bool v = true) const {
254                hypRead(v);
255                hypWrite(v);
256                return *this;
257            }
258            chain monSecureRead(bool v = true) const {
259                info[MISCREG_MON_NS0_RD] = v;
260                return *this;
261            }
262            chain monSecureWrite(bool v = true) const {
263                info[MISCREG_MON_NS0_WR] = v;
264                return *this;
265            }
266            chain monNonSecureRead(bool v = true) const {
267                info[MISCREG_MON_NS1_RD] = v;
268                return *this;
269            }
270            chain monNonSecureWrite(bool v = true) const {
271                info[MISCREG_MON_NS1_WR] = v;
272                return *this;
273            }
274            chain mon(bool v = true) const {
275                monSecureRead(v);
276                monSecureWrite(v);
277                monNonSecureRead(v);
278                monNonSecureWrite(v);
279                return *this;
280            }
281            chain monSecure(bool v = true) const {
282                monSecureRead(v);
283                monSecureWrite(v);
284                return *this;
285            }
286            chain monNonSecure(bool v = true) const {
287                monNonSecureRead(v);
288                monNonSecureWrite(v);
289                return *this;
290            }
291            chain allPrivileges(bool v = true) const {
292                userNonSecureRead(v);
293                userNonSecureWrite(v);
294                userSecureRead(v);
295                userSecureWrite(v);
296                privNonSecureRead(v);
297                privNonSecureWrite(v);
298                privSecureRead(v);
299                privSecureWrite(v);
300                hypRead(v);
301                hypWrite(v);
302                monSecureRead(v);
303                monSecureWrite(v);
304                monNonSecureRead(v);
305                monNonSecureWrite(v);
306                return *this;
307            }
308            chain nonSecure(bool v = true) const {
309                userNonSecureRead(v);
310                userNonSecureWrite(v);
311                privNonSecureRead(v);
312                privNonSecureWrite(v);
313                hypRead(v);
314                hypWrite(v);
315                monNonSecureRead(v);
316                monNonSecureWrite(v);
317                return *this;
318            }
319            chain secure(bool v = true) const {
320                userSecureRead(v);
321                userSecureWrite(v);
322                privSecureRead(v);
323                privSecureWrite(v);
324                monSecureRead(v);
325                monSecureWrite(v);
326                return *this;
327            }
328            chain reads(bool v) const {
329                userNonSecureRead(v);
330                userSecureRead(v);
331                privNonSecureRead(v);
332                privSecureRead(v);
333                hypRead(v);
334                monSecureRead(v);
335                monNonSecureRead(v);
336                return *this;
337            }
338            chain writes(bool v) const {
339                userNonSecureWrite(v);
340                userSecureWrite(v);
341                privNonSecureWrite(v);
342                privSecureWrite(v);
343                hypWrite(v);
344                monSecureWrite(v);
345                monNonSecureWrite(v);
346                return *this;
347            }
348            chain exceptUserMode() const {
349                user(0);
350                return *this;
351            }
352            MiscRegLUTEntryInitializer(struct MiscRegLUTEntry &e,
353                                       std::bitset<NUM_MISCREG_INFOS> &i)
354              : entry(e),
355                info(i)
356            {
357                // force unimplemented registers to be thusly declared
358                implemented(1);
359            }
360        };
361
362        const MiscRegLUTEntryInitializer InitReg(uint32_t reg) {
363            return MiscRegLUTEntryInitializer(lookUpMiscReg[reg],
364                                              miscRegInfo[reg]);
365        }
366
367        void initializeMiscRegMetadata();
368
369        RegVal miscRegs[NumMiscRegs];
370        const IntRegIndex *intRegMap;
371
372        void
373        updateRegMap(CPSR cpsr)
374        {
375            if (cpsr.width == 0) {
376                intRegMap = IntReg64Map;
377            } else {
378                switch (cpsr.mode) {
379                  case MODE_USER:
380                  case MODE_SYSTEM:
381                    intRegMap = IntRegUsrMap;
382                    break;
383                  case MODE_FIQ:
384                    intRegMap = IntRegFiqMap;
385                    break;
386                  case MODE_IRQ:
387                    intRegMap = IntRegIrqMap;
388                    break;
389                  case MODE_SVC:
390                    intRegMap = IntRegSvcMap;
391                    break;
392                  case MODE_MON:
393                    intRegMap = IntRegMonMap;
394                    break;
395                  case MODE_ABORT:
396                    intRegMap = IntRegAbtMap;
397                    break;
398                  case MODE_HYP:
399                    intRegMap = IntRegHypMap;
400                    break;
401                  case MODE_UNDEFINED:
402                    intRegMap = IntRegUndMap;
403                    break;
404                  default:
405                    panic("Unrecognized mode setting in CPSR.\n");
406                }
407            }
408        }
409
410        BaseISADevice &getGenericTimer(ThreadContext *tc);
411        BaseISADevice &getGICv3CPUInterface(ThreadContext *tc);
412
413
414      private:
415        inline void assert32(ThreadContext *tc) {
416            CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
417            assert(cpsr.width);
418        }
419
420        inline void assert64(ThreadContext *tc) {
421            CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
422            assert(!cpsr.width);
423        }
424
425      public:
426        void clear();
427
428      protected:
429        void clear32(const ArmISAParams *p, const SCTLR &sctlr_rst);
430        void clear64(const ArmISAParams *p);
431        void initID32(const ArmISAParams *p);
432        void initID64(const ArmISAParams *p);
433
434      public:
435        RegVal readMiscRegNoEffect(int misc_reg) const;
436        RegVal readMiscReg(int misc_reg, ThreadContext *tc);
437        void setMiscRegNoEffect(int misc_reg, RegVal val);
438        void setMiscReg(int misc_reg, RegVal val, ThreadContext *tc);
439
440        RegId
441        flattenRegId(const RegId& regId) const
442        {
443            switch (regId.classValue()) {
444              case IntRegClass:
445                return RegId(IntRegClass, flattenIntIndex(regId.index()));
446              case FloatRegClass:
447                return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
448              case VecRegClass:
449                return RegId(VecRegClass, flattenVecIndex(regId.index()));
450              case VecElemClass:
451                return RegId(VecElemClass, flattenVecElemIndex(regId.index()),
452                             regId.elemIndex());
453              case VecPredRegClass:
454                return RegId(VecPredRegClass,
455                             flattenVecPredIndex(regId.index()));
456              case CCRegClass:
457                return RegId(CCRegClass, flattenCCIndex(regId.index()));
458              case MiscRegClass:
459                return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
460            }
461            return RegId();
462        }
463
464        int
465        flattenIntIndex(int reg) const
466        {
467            assert(reg >= 0);
468            if (reg < NUM_ARCH_INTREGS) {
469                return intRegMap[reg];
470            } else if (reg < NUM_INTREGS) {
471                return reg;
472            } else if (reg == INTREG_SPX) {
473                CPSR cpsr = miscRegs[MISCREG_CPSR];
474                ExceptionLevel el = opModeToEL(
475                    (OperatingMode) (uint8_t) cpsr.mode);
476                if (!cpsr.sp && el != EL0)
477                    return INTREG_SP0;
478                switch (el) {
479                  case EL3:
480                    return INTREG_SP3;
481                  case EL2:
482                    return INTREG_SP2;
483                  case EL1:
484                    return INTREG_SP1;
485                  case EL0:
486                    return INTREG_SP0;
487                  default:
488                    panic("Invalid exception level");
489                    return 0;  // Never happens.
490                }
491            } else {
492                return flattenIntRegModeIndex(reg);
493            }
494        }
495
496        int
497        flattenFloatIndex(int reg) const
498        {
499            assert(reg >= 0);
500            return reg;
501        }
502
503        int
504        flattenVecIndex(int reg) const
505        {
506            assert(reg >= 0);
507            return reg;
508        }
509
510        int
511        flattenVecElemIndex(int reg) const
512        {
513            assert(reg >= 0);
514            return reg;
515        }
516
517        int
518        flattenVecPredIndex(int reg) const
519        {
520            assert(reg >= 0);
521            return reg;
522        }
523
524        int
525        flattenCCIndex(int reg) const
526        {
527            assert(reg >= 0);
528            return reg;
529        }
530
531        int
532        flattenMiscIndex(int reg) const
533        {
534            assert(reg >= 0);
535            int flat_idx = reg;
536
537            if (reg == MISCREG_SPSR) {
538                CPSR cpsr = miscRegs[MISCREG_CPSR];
539                switch (cpsr.mode) {
540                  case MODE_EL0T:
541                    warn("User mode does not have SPSR\n");
542                    flat_idx = MISCREG_SPSR;
543                    break;
544                  case MODE_EL1T:
545                  case MODE_EL1H:
546                    flat_idx = MISCREG_SPSR_EL1;
547                    break;
548                  case MODE_EL2T:
549                  case MODE_EL2H:
550                    flat_idx = MISCREG_SPSR_EL2;
551                    break;
552                  case MODE_EL3T:
553                  case MODE_EL3H:
554                    flat_idx = MISCREG_SPSR_EL3;
555                    break;
556                  case MODE_USER:
557                    warn("User mode does not have SPSR\n");
558                    flat_idx = MISCREG_SPSR;
559                    break;
560                  case MODE_FIQ:
561                    flat_idx = MISCREG_SPSR_FIQ;
562                    break;
563                  case MODE_IRQ:
564                    flat_idx = MISCREG_SPSR_IRQ;
565                    break;
566                  case MODE_SVC:
567                    flat_idx = MISCREG_SPSR_SVC;
568                    break;
569                  case MODE_MON:
570                    flat_idx = MISCREG_SPSR_MON;
571                    break;
572                  case MODE_ABORT:
573                    flat_idx = MISCREG_SPSR_ABT;
574                    break;
575                  case MODE_HYP:
576                    flat_idx = MISCREG_SPSR_HYP;
577                    break;
578                  case MODE_UNDEFINED:
579                    flat_idx = MISCREG_SPSR_UND;
580                    break;
581                  default:
582                    warn("Trying to access SPSR in an invalid mode: %d\n",
583                         cpsr.mode);
584                    flat_idx = MISCREG_SPSR;
585                    break;
586                }
587            } else if (miscRegInfo[reg][MISCREG_MUTEX]) {
588                // Mutually exclusive CP15 register
589                switch (reg) {
590                  case MISCREG_PRRR_MAIR0:
591                  case MISCREG_PRRR_MAIR0_NS:
592                  case MISCREG_PRRR_MAIR0_S:
593                    {
594                        TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
595                        // If the muxed reg has been flattened, work out the
596                        // offset and apply it to the unmuxed reg
597                        int idxOffset = reg - MISCREG_PRRR_MAIR0;
598                        if (ttbcr.eae)
599                            flat_idx = flattenMiscIndex(MISCREG_MAIR0 +
600                                                        idxOffset);
601                        else
602                            flat_idx = flattenMiscIndex(MISCREG_PRRR +
603                                                        idxOffset);
604                    }
605                    break;
606                  case MISCREG_NMRR_MAIR1:
607                  case MISCREG_NMRR_MAIR1_NS:
608                  case MISCREG_NMRR_MAIR1_S:
609                    {
610                        TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
611                        // If the muxed reg has been flattened, work out the
612                        // offset and apply it to the unmuxed reg
613                        int idxOffset = reg - MISCREG_NMRR_MAIR1;
614                        if (ttbcr.eae)
615                            flat_idx = flattenMiscIndex(MISCREG_MAIR1 +
616                                                        idxOffset);
617                        else
618                            flat_idx = flattenMiscIndex(MISCREG_NMRR +
619                                                        idxOffset);
620                    }
621                    break;
622                  case MISCREG_PMXEVTYPER_PMCCFILTR:
623                    {
624                        PMSELR pmselr = miscRegs[MISCREG_PMSELR];
625                        if (pmselr.sel == 31)
626                            flat_idx = flattenMiscIndex(MISCREG_PMCCFILTR);
627                        else
628                            flat_idx = flattenMiscIndex(MISCREG_PMXEVTYPER);
629                    }
630                    break;
631                  default:
632                    panic("Unrecognized misc. register.\n");
633                    break;
634                }
635            } else {
636                if (miscRegInfo[reg][MISCREG_BANKED]) {
637                    bool secureReg = haveSecurity && !highestELIs64 &&
638                                     inSecureState(miscRegs[MISCREG_SCR],
639                                                   miscRegs[MISCREG_CPSR]);
640                    flat_idx += secureReg ? 2 : 1;
641                }
642            }
643            return flat_idx;
644        }
645
646        std::pair<int,int> getMiscIndices(int misc_reg) const
647        {
648            // Note: indexes of AArch64 registers are left unchanged
649            int flat_idx = flattenMiscIndex(misc_reg);
650
651            if (lookUpMiscReg[flat_idx].lower == 0) {
652                return std::make_pair(flat_idx, 0);
653            }
654
655            // do additional S/NS flattenings if mapped to NS while in S
656            bool S = haveSecurity && !highestELIs64 &&
657                     inSecureState(miscRegs[MISCREG_SCR],
658                                   miscRegs[MISCREG_CPSR]);
659            int lower = lookUpMiscReg[flat_idx].lower;
660            int upper = lookUpMiscReg[flat_idx].upper;
661            // upper == 0, which is CPSR, is not MISCREG_BANKED_CHILD (no-op)
662            lower += S && miscRegInfo[lower][MISCREG_BANKED_CHILD];
663            upper += S && miscRegInfo[upper][MISCREG_BANKED_CHILD];
664            return std::make_pair(lower, upper);
665        }
666
667        unsigned getCurSveVecLenInBits(ThreadContext *tc) const;
668
669        unsigned getCurSveVecLenInBitsAtReset() const { return sveVL * 128; }
670
671        static void zeroSveVecRegUpperPart(VecRegContainer &vc,
672                                           unsigned eCount);
673
674        void serialize(CheckpointOut &cp) const
675        {
676            DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
677            SERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
678
679            SERIALIZE_SCALAR(highestELIs64);
680            SERIALIZE_SCALAR(haveSecurity);
681            SERIALIZE_SCALAR(haveLPAE);
682            SERIALIZE_SCALAR(haveVirtualization);
683            SERIALIZE_SCALAR(haveLargeAsid64);
684            SERIALIZE_SCALAR(physAddrRange);
685            SERIALIZE_SCALAR(haveSVE);
686            SERIALIZE_SCALAR(sveVL);
687        }
688        void unserialize(CheckpointIn &cp)
689        {
690            DPRINTF(Checkpoint, "Unserializing Arm Misc Registers\n");
691            UNSERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
692            CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
693            updateRegMap(tmp_cpsr);
694
695            UNSERIALIZE_SCALAR(highestELIs64);
696            UNSERIALIZE_SCALAR(haveSecurity);
697            UNSERIALIZE_SCALAR(haveLPAE);
698            UNSERIALIZE_SCALAR(haveVirtualization);
699            UNSERIALIZE_SCALAR(haveLargeAsid64);
700            UNSERIALIZE_SCALAR(physAddrRange);
701            UNSERIALIZE_SCALAR(haveSVE);
702            UNSERIALIZE_SCALAR(sveVL);
703        }
704
705        void startup(ThreadContext *tc);
706
707        Enums::DecoderFlavour decoderFlavour() const { return _decoderFlavour; }
708
709        Enums::VecRegRenameMode
710        vecRegRenameMode() const
711        {
712            return _vecRegRenameMode;
713        }
714
715        /// Explicitly import the otherwise hidden startup
716        using SimObject::startup;
717
718        typedef ArmISAParams Params;
719
720        const Params *params() const;
721
722        ISA(Params *p);
723    };
724}
725
726template<>
727struct RenameMode<ArmISA::ISA>
728{
729    static Enums::VecRegRenameMode
730    init(const ArmISA::ISA* isa)
731    {
732        return isa->vecRegRenameMode();
733    }
734
735    static Enums::VecRegRenameMode
736    mode(const ArmISA::PCState& pc)
737    {
738        if (pc.aarch64()) {
739            return Enums::Full;
740        } else {
741            return Enums::Elem;
742        }
743    }
744
745    static bool
746    equalsInit(const ArmISA::ISA* isa1, const ArmISA::ISA* isa2)
747    {
748        return init(isa1) == init(isa2);
749    }
750};
751
752#endif
753