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