mem-cache: Add multiple eviction stats
[gem5.git] / src / arch / arm / miscregs.hh
index f87cc3ad5f9bb3984631113c779ab49e3d38c1cd..4f522f298b8ce05e563ba965fc669516e63c2577 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 ARM Limited
+ * Copyright (c) 2010-2019 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Authors: Gabe Black
+ *          Giacomo Gabrielli
  */
 #ifndef __ARCH_ARM_MISCREGS_HH__
 #define __ARCH_ARM_MISCREGS_HH__
 
-#include "base/bitunion.hh"
+#include <bitset>
+#include <tuple>
+
+#include "arch/arm/miscregs_types.hh"
+#include "base/compiler.hh"
+
+class ThreadContext;
+
 
 namespace ArmISA
 {
-    enum ConditionCode {
-        COND_EQ  =   0,
-        COND_NE, //  1
-        COND_CS, //  2
-        COND_CC, //  3
-        COND_MI, //  4
-        COND_PL, //  5
-        COND_VS, //  6
-        COND_VC, //  7
-        COND_HI, //  8
-        COND_LS, //  9
-        COND_GE, // 10
-        COND_LT, // 11
-        COND_GT, // 12
-        COND_LE, // 13
-        COND_AL, // 14
-        COND_UC  // 15
-    };
-
     enum MiscRegIndex {
         MISCREG_CPSR = 0,
         MISCREG_SPSR,
@@ -72,51 +61,205 @@ namespace ArmISA
         MISCREG_SPSR_IRQ,
         MISCREG_SPSR_SVC,
         MISCREG_SPSR_MON,
-        MISCREG_SPSR_UND,
         MISCREG_SPSR_ABT,
-        MISCREG_FPSR,
+        MISCREG_SPSR_HYP,
+        MISCREG_SPSR_UND,
+        MISCREG_ELR_HYP,
         MISCREG_FPSID,
         MISCREG_FPSCR,
-        MISCREG_FPSCR_QC,  // Cumulative saturation flag
-        MISCREG_FPSCR_EXC,  // Cumulative FP exception flags
-        MISCREG_FPEXC,
-        MISCREG_MVFR0,
         MISCREG_MVFR1,
+        MISCREG_MVFR0,
+        MISCREG_FPEXC,
+
+        // Helper registers
+        MISCREG_CPSR_MODE,
+        MISCREG_CPSR_Q,
+        MISCREG_FPSCR_EXC,
+        MISCREG_FPSCR_QC,
+        MISCREG_LOCKADDR,
+        MISCREG_LOCKFLAG,
+        MISCREG_PRRR_MAIR0,
+        MISCREG_PRRR_MAIR0_NS,
+        MISCREG_PRRR_MAIR0_S,
+        MISCREG_NMRR_MAIR1,
+        MISCREG_NMRR_MAIR1_NS,
+        MISCREG_NMRR_MAIR1_S,
+        MISCREG_PMXEVTYPER_PMCCFILTR,
         MISCREG_SCTLR_RST,
         MISCREG_SEV_MAILBOX,
 
-        // CP15 registers
-        MISCREG_CP15_START,
-        MISCREG_SCTLR = MISCREG_CP15_START,
-        MISCREG_DCCISW,
-        MISCREG_DCCIMVAC,
-        MISCREG_DCCMVAC,
-        MISCREG_CONTEXTIDR,
-        MISCREG_TPIDRURW,
-        MISCREG_TPIDRURO,
-        MISCREG_TPIDRPRW,
-        MISCREG_CP15ISB,
-        MISCREG_CP15DSB,
-        MISCREG_CP15DMB,
-        MISCREG_CPACR,
-        MISCREG_CLIDR,
+        // AArch32 CP14 registers (debug/trace/ThumbEE/Jazelle control)
+        MISCREG_DBGDIDR,
+        MISCREG_DBGDSCRint,
+        MISCREG_DBGDCCINT,
+        MISCREG_DBGDTRTXint,
+        MISCREG_DBGDTRRXint,
+        MISCREG_DBGWFAR,
+        MISCREG_DBGVCR,
+        MISCREG_DBGDTRRXext,
+        MISCREG_DBGDSCRext,
+        MISCREG_DBGDTRTXext,
+        MISCREG_DBGOSECCR,
+        MISCREG_DBGBVR0,
+        MISCREG_DBGBVR1,
+        MISCREG_DBGBVR2,
+        MISCREG_DBGBVR3,
+        MISCREG_DBGBVR4,
+        MISCREG_DBGBVR5,
+        MISCREG_DBGBCR0,
+        MISCREG_DBGBCR1,
+        MISCREG_DBGBCR2,
+        MISCREG_DBGBCR3,
+        MISCREG_DBGBCR4,
+        MISCREG_DBGBCR5,
+        MISCREG_DBGWVR0,
+        MISCREG_DBGWVR1,
+        MISCREG_DBGWVR2,
+        MISCREG_DBGWVR3,
+        MISCREG_DBGWCR0,
+        MISCREG_DBGWCR1,
+        MISCREG_DBGWCR2,
+        MISCREG_DBGWCR3,
+        MISCREG_DBGDRAR,
+        MISCREG_DBGBXVR4,
+        MISCREG_DBGBXVR5,
+        MISCREG_DBGOSLAR,
+        MISCREG_DBGOSLSR,
+        MISCREG_DBGOSDLR,
+        MISCREG_DBGPRCR,
+        MISCREG_DBGDSAR,
+        MISCREG_DBGCLAIMSET,
+        MISCREG_DBGCLAIMCLR,
+        MISCREG_DBGAUTHSTATUS,
+        MISCREG_DBGDEVID2,
+        MISCREG_DBGDEVID1,
+        MISCREG_DBGDEVID0,
+        MISCREG_TEECR,  // not in ARM DDI 0487A.b+
+        MISCREG_JIDR,
+        MISCREG_TEEHBR, // not in ARM DDI 0487A.b+
+        MISCREG_JOSCR,
+        MISCREG_JMCR,
+
+        // AArch32 CP15 registers (system control)
+        MISCREG_MIDR,
+        MISCREG_CTR,
+        MISCREG_TCMTR,
+        MISCREG_TLBTR,
+        MISCREG_MPIDR,
+        MISCREG_REVIDR,
+        MISCREG_ID_PFR0,
+        MISCREG_ID_PFR1,
+        MISCREG_ID_DFR0,
+        MISCREG_ID_AFR0,
+        MISCREG_ID_MMFR0,
+        MISCREG_ID_MMFR1,
+        MISCREG_ID_MMFR2,
+        MISCREG_ID_MMFR3,
+        MISCREG_ID_ISAR0,
+        MISCREG_ID_ISAR1,
+        MISCREG_ID_ISAR2,
+        MISCREG_ID_ISAR3,
+        MISCREG_ID_ISAR4,
+        MISCREG_ID_ISAR5,
         MISCREG_CCSIDR,
+        MISCREG_CLIDR,
+        MISCREG_AIDR,
         MISCREG_CSSELR,
+        MISCREG_CSSELR_NS,
+        MISCREG_CSSELR_S,
+        MISCREG_VPIDR,
+        MISCREG_VMPIDR,
+        MISCREG_SCTLR,
+        MISCREG_SCTLR_NS,
+        MISCREG_SCTLR_S,
+        MISCREG_ACTLR,
+        MISCREG_ACTLR_NS,
+        MISCREG_ACTLR_S,
+        MISCREG_CPACR,
+        MISCREG_SCR,
+        MISCREG_SDER,
+        MISCREG_NSACR,
+        MISCREG_HSCTLR,
+        MISCREG_HACTLR,
+        MISCREG_HCR,
+        MISCREG_HCR2,
+        MISCREG_HDCR,
+        MISCREG_HCPTR,
+        MISCREG_HSTR,
+        MISCREG_HACR,
+        MISCREG_TTBR0,
+        MISCREG_TTBR0_NS,
+        MISCREG_TTBR0_S,
+        MISCREG_TTBR1,
+        MISCREG_TTBR1_NS,
+        MISCREG_TTBR1_S,
+        MISCREG_TTBCR,
+        MISCREG_TTBCR_NS,
+        MISCREG_TTBCR_S,
+        MISCREG_HTCR,
+        MISCREG_VTCR,
+        MISCREG_DACR,
+        MISCREG_DACR_NS,
+        MISCREG_DACR_S,
+        MISCREG_DFSR,
+        MISCREG_DFSR_NS,
+        MISCREG_DFSR_S,
+        MISCREG_IFSR,
+        MISCREG_IFSR_NS,
+        MISCREG_IFSR_S,
+        MISCREG_ADFSR,
+        MISCREG_ADFSR_NS,
+        MISCREG_ADFSR_S,
+        MISCREG_AIFSR,
+        MISCREG_AIFSR_NS,
+        MISCREG_AIFSR_S,
+        MISCREG_HADFSR,
+        MISCREG_HAIFSR,
+        MISCREG_HSR,
+        MISCREG_DFAR,
+        MISCREG_DFAR_NS,
+        MISCREG_DFAR_S,
+        MISCREG_IFAR,
+        MISCREG_IFAR_NS,
+        MISCREG_IFAR_S,
+        MISCREG_HDFAR,
+        MISCREG_HIFAR,
+        MISCREG_HPFAR,
         MISCREG_ICIALLUIS,
+        MISCREG_BPIALLIS,
+        MISCREG_PAR,
+        MISCREG_PAR_NS,
+        MISCREG_PAR_S,
         MISCREG_ICIALLU,
         MISCREG_ICIMVAU,
-        MISCREG_BPIMVA,
-        MISCREG_BPIALLIS,
+        MISCREG_CP15ISB,
         MISCREG_BPIALL,
-        MISCREG_MIDR,
-        MISCREG_TTBR0,
-        MISCREG_TTBR1,
-        MISCREG_TLBTR,
-        MISCREG_DACR,
+        MISCREG_BPIMVA,
+        MISCREG_DCIMVAC,
+        MISCREG_DCISW,
+        MISCREG_ATS1CPR,
+        MISCREG_ATS1CPW,
+        MISCREG_ATS1CUR,
+        MISCREG_ATS1CUW,
+        MISCREG_ATS12NSOPR,
+        MISCREG_ATS12NSOPW,
+        MISCREG_ATS12NSOUR,
+        MISCREG_ATS12NSOUW,
+        MISCREG_DCCMVAC,
+        MISCREG_DCCSW,
+        MISCREG_CP15DSB,
+        MISCREG_CP15DMB,
+        MISCREG_DCCMVAU,
+        MISCREG_DCCIMVAC,
+        MISCREG_DCCISW,
+        MISCREG_ATS1HR,
+        MISCREG_ATS1HW,
         MISCREG_TLBIALLIS,
         MISCREG_TLBIMVAIS,
         MISCREG_TLBIASIDIS,
         MISCREG_TLBIMVAAIS,
+        MISCREG_TLBIMVALIS,
+        MISCREG_TLBIMVAALIS,
         MISCREG_ITLBIALL,
         MISCREG_ITLBIMVA,
         MISCREG_ITLBIASID,
@@ -127,32 +270,21 @@ namespace ArmISA
         MISCREG_TLBIMVA,
         MISCREG_TLBIASID,
         MISCREG_TLBIMVAA,
-        MISCREG_DFSR,
-        MISCREG_IFSR,
-        MISCREG_DFAR,
-        MISCREG_IFAR,
-        MISCREG_MPIDR,
-        MISCREG_PRRR,
-        MISCREG_NMRR,
-        MISCREG_TTBCR,
-        MISCREG_ID_PFR0,
-        MISCREG_CTR,
-        MISCREG_SCR,
-        MISCREG_SDER,
-        MISCREG_PAR,
-        MISCREG_V2PCWPR,
-        MISCREG_V2PCWPW,
-        MISCREG_V2PCWUR,
-        MISCREG_V2PCWUW,
-        MISCREG_V2POWPR,
-        MISCREG_V2POWPW,
-        MISCREG_V2POWUR,
-        MISCREG_V2POWUW,
-        MISCREG_ID_MMFR0,
-        MISCREG_ID_MMFR3,
-        MISCREG_ACTLR,
+        MISCREG_TLBIMVAL,
+        MISCREG_TLBIMVAAL,
+        MISCREG_TLBIIPAS2IS,
+        MISCREG_TLBIIPAS2LIS,
+        MISCREG_TLBIALLHIS,
+        MISCREG_TLBIMVAHIS,
+        MISCREG_TLBIALLNSNHIS,
+        MISCREG_TLBIMVALHIS,
+        MISCREG_TLBIIPAS2,
+        MISCREG_TLBIIPAS2L,
+        MISCREG_TLBIALLH,
+        MISCREG_TLBIMVAH,
+        MISCREG_TLBIALLNSNH,
+        MISCREG_TLBIMVALH,
         MISCREG_PMCR,
-        MISCREG_PMCCNTR,
         MISCREG_PMCNTENSET,
         MISCREG_PMCNTENCLR,
         MISCREG_PMOVSR,
@@ -160,198 +292,1599 @@ namespace ArmISA
         MISCREG_PMSELR,
         MISCREG_PMCEID0,
         MISCREG_PMCEID1,
-        MISCREG_PMC_OTHER,
+        MISCREG_PMCCNTR,
+        MISCREG_PMXEVTYPER,
+        MISCREG_PMCCFILTR,
         MISCREG_PMXEVCNTR,
         MISCREG_PMUSERENR,
         MISCREG_PMINTENSET,
         MISCREG_PMINTENCLR,
-        MISCREG_ID_ISAR0,
-        MISCREG_ID_ISAR1,
-        MISCREG_ID_ISAR2,
-        MISCREG_ID_ISAR3,
-        MISCREG_ID_ISAR4,
-        MISCREG_ID_ISAR5,
-        MISCREG_CPSR_MODE,
-        MISCREG_LOCKFLAG,
-        MISCREG_LOCKADDR,
-        MISCREG_CP15_UNIMP_START,
-        MISCREG_TCMTR = MISCREG_CP15_UNIMP_START,
-        MISCREG_ID_PFR1,
-        MISCREG_ID_DFR0,
-        MISCREG_ID_AFR0,
-        MISCREG_ID_MMFR1,
-        MISCREG_ID_MMFR2,
-        MISCREG_AIDR,
-        MISCREG_ADFSR,
-        MISCREG_AIFSR,
-        MISCREG_DCIMVAC,
-        MISCREG_DCISW,
-        MISCREG_MCCSW,
-        MISCREG_DCCMVAU,
-        MISCREG_NSACR,
+        MISCREG_PMOVSSET,
+        MISCREG_L2CTLR,
+        MISCREG_L2ECTLR,
+        MISCREG_PRRR,
+        MISCREG_PRRR_NS,
+        MISCREG_PRRR_S,
+        MISCREG_MAIR0,
+        MISCREG_MAIR0_NS,
+        MISCREG_MAIR0_S,
+        MISCREG_NMRR,
+        MISCREG_NMRR_NS,
+        MISCREG_NMRR_S,
+        MISCREG_MAIR1,
+        MISCREG_MAIR1_NS,
+        MISCREG_MAIR1_S,
+        MISCREG_AMAIR0,
+        MISCREG_AMAIR0_NS,
+        MISCREG_AMAIR0_S,
+        MISCREG_AMAIR1,
+        MISCREG_AMAIR1_NS,
+        MISCREG_AMAIR1_S,
+        MISCREG_HMAIR0,
+        MISCREG_HMAIR1,
+        MISCREG_HAMAIR0,
+        MISCREG_HAMAIR1,
         MISCREG_VBAR,
+        MISCREG_VBAR_NS,
+        MISCREG_VBAR_S,
         MISCREG_MVBAR,
+        MISCREG_RMR,
         MISCREG_ISR,
-        MISCREG_FCEIDR,
-        MISCREG_L2LATENCY,
+        MISCREG_HVBAR,
+        MISCREG_FCSEIDR,
+        MISCREG_CONTEXTIDR,
+        MISCREG_CONTEXTIDR_NS,
+        MISCREG_CONTEXTIDR_S,
+        MISCREG_TPIDRURW,
+        MISCREG_TPIDRURW_NS,
+        MISCREG_TPIDRURW_S,
+        MISCREG_TPIDRURO,
+        MISCREG_TPIDRURO_NS,
+        MISCREG_TPIDRURO_S,
+        MISCREG_TPIDRPRW,
+        MISCREG_TPIDRPRW_NS,
+        MISCREG_TPIDRPRW_S,
+        MISCREG_HTPIDR,
+        MISCREG_CNTFRQ,
+        MISCREG_CNTKCTL,
+        MISCREG_CNTP_TVAL,
+        MISCREG_CNTP_TVAL_NS,
+        MISCREG_CNTP_TVAL_S,
+        MISCREG_CNTP_CTL,
+        MISCREG_CNTP_CTL_NS,
+        MISCREG_CNTP_CTL_S,
+        MISCREG_CNTV_TVAL,
+        MISCREG_CNTV_CTL,
+        MISCREG_CNTHCTL,
+        MISCREG_CNTHP_TVAL,
+        MISCREG_CNTHP_CTL,
+        MISCREG_IL1DATA0,
+        MISCREG_IL1DATA1,
+        MISCREG_IL1DATA2,
+        MISCREG_IL1DATA3,
+        MISCREG_DL1DATA0,
+        MISCREG_DL1DATA1,
+        MISCREG_DL1DATA2,
+        MISCREG_DL1DATA3,
+        MISCREG_DL1DATA4,
+        MISCREG_RAMINDEX,
+        MISCREG_L2ACTLR,
+        MISCREG_CBAR,
+        MISCREG_HTTBR,
+        MISCREG_VTTBR,
+        MISCREG_CNTPCT,
+        MISCREG_CNTVCT,
+        MISCREG_CNTP_CVAL,
+        MISCREG_CNTP_CVAL_NS,
+        MISCREG_CNTP_CVAL_S,
+        MISCREG_CNTV_CVAL,
+        MISCREG_CNTVOFF,
+        MISCREG_CNTHP_CVAL,
+        MISCREG_CPUMERRSR,
+        MISCREG_L2MERRSR,
+
+        // AArch64 registers (Op0=2)
+        MISCREG_MDCCINT_EL1,
+        MISCREG_OSDTRRX_EL1,
+        MISCREG_MDSCR_EL1,
+        MISCREG_OSDTRTX_EL1,
+        MISCREG_OSECCR_EL1,
+        MISCREG_DBGBVR0_EL1,
+        MISCREG_DBGBVR1_EL1,
+        MISCREG_DBGBVR2_EL1,
+        MISCREG_DBGBVR3_EL1,
+        MISCREG_DBGBVR4_EL1,
+        MISCREG_DBGBVR5_EL1,
+        MISCREG_DBGBCR0_EL1,
+        MISCREG_DBGBCR1_EL1,
+        MISCREG_DBGBCR2_EL1,
+        MISCREG_DBGBCR3_EL1,
+        MISCREG_DBGBCR4_EL1,
+        MISCREG_DBGBCR5_EL1,
+        MISCREG_DBGWVR0_EL1,
+        MISCREG_DBGWVR1_EL1,
+        MISCREG_DBGWVR2_EL1,
+        MISCREG_DBGWVR3_EL1,
+        MISCREG_DBGWCR0_EL1,
+        MISCREG_DBGWCR1_EL1,
+        MISCREG_DBGWCR2_EL1,
+        MISCREG_DBGWCR3_EL1,
+        MISCREG_MDCCSR_EL0,
+        MISCREG_MDDTR_EL0,
+        MISCREG_MDDTRTX_EL0,
+        MISCREG_MDDTRRX_EL0,
+        MISCREG_DBGVCR32_EL2,
+        MISCREG_MDRAR_EL1,
+        MISCREG_OSLAR_EL1,
+        MISCREG_OSLSR_EL1,
+        MISCREG_OSDLR_EL1,
+        MISCREG_DBGPRCR_EL1,
+        MISCREG_DBGCLAIMSET_EL1,
+        MISCREG_DBGCLAIMCLR_EL1,
+        MISCREG_DBGAUTHSTATUS_EL1,
+        MISCREG_TEECR32_EL1, // not in ARM DDI 0487A.b+
+        MISCREG_TEEHBR32_EL1, // not in ARM DDI 0487A.b+
+
+        // AArch64 registers (Op0=1,3)
+        MISCREG_MIDR_EL1,
+        MISCREG_MPIDR_EL1,
+        MISCREG_REVIDR_EL1,
+        MISCREG_ID_PFR0_EL1,
+        MISCREG_ID_PFR1_EL1,
+        MISCREG_ID_DFR0_EL1,
+        MISCREG_ID_AFR0_EL1,
+        MISCREG_ID_MMFR0_EL1,
+        MISCREG_ID_MMFR1_EL1,
+        MISCREG_ID_MMFR2_EL1,
+        MISCREG_ID_MMFR3_EL1,
+        MISCREG_ID_ISAR0_EL1,
+        MISCREG_ID_ISAR1_EL1,
+        MISCREG_ID_ISAR2_EL1,
+        MISCREG_ID_ISAR3_EL1,
+        MISCREG_ID_ISAR4_EL1,
+        MISCREG_ID_ISAR5_EL1,
+        MISCREG_MVFR0_EL1,
+        MISCREG_MVFR1_EL1,
+        MISCREG_MVFR2_EL1,
+        MISCREG_ID_AA64PFR0_EL1,
+        MISCREG_ID_AA64PFR1_EL1,
+        MISCREG_ID_AA64DFR0_EL1,
+        MISCREG_ID_AA64DFR1_EL1,
+        MISCREG_ID_AA64AFR0_EL1,
+        MISCREG_ID_AA64AFR1_EL1,
+        MISCREG_ID_AA64ISAR0_EL1,
+        MISCREG_ID_AA64ISAR1_EL1,
+        MISCREG_ID_AA64MMFR0_EL1,
+        MISCREG_ID_AA64MMFR1_EL1,
+        MISCREG_CCSIDR_EL1,
+        MISCREG_CLIDR_EL1,
+        MISCREG_AIDR_EL1,
+        MISCREG_CSSELR_EL1,
+        MISCREG_CTR_EL0,
+        MISCREG_DCZID_EL0,
+        MISCREG_VPIDR_EL2,
+        MISCREG_VMPIDR_EL2,
+        MISCREG_SCTLR_EL1,
+        MISCREG_ACTLR_EL1,
+        MISCREG_CPACR_EL1,
+        MISCREG_SCTLR_EL2,
+        MISCREG_ACTLR_EL2,
+        MISCREG_HCR_EL2,
+        MISCREG_MDCR_EL2,
+        MISCREG_CPTR_EL2,
+        MISCREG_HSTR_EL2,
+        MISCREG_HACR_EL2,
+        MISCREG_SCTLR_EL3,
+        MISCREG_ACTLR_EL3,
+        MISCREG_SCR_EL3,
+        MISCREG_SDER32_EL3,
+        MISCREG_CPTR_EL3,
+        MISCREG_MDCR_EL3,
+        MISCREG_TTBR0_EL1,
+        MISCREG_TTBR1_EL1,
+        MISCREG_TCR_EL1,
+        MISCREG_TTBR0_EL2,
+        MISCREG_TCR_EL2,
+        MISCREG_VTTBR_EL2,
+        MISCREG_VTCR_EL2,
+        MISCREG_TTBR0_EL3,
+        MISCREG_TCR_EL3,
+        MISCREG_DACR32_EL2,
+        MISCREG_SPSR_EL1,
+        MISCREG_ELR_EL1,
+        MISCREG_SP_EL0,
+        MISCREG_SPSEL,
+        MISCREG_CURRENTEL,
+        MISCREG_NZCV,
+        MISCREG_DAIF,
+        MISCREG_FPCR,
+        MISCREG_FPSR,
+        MISCREG_DSPSR_EL0,
+        MISCREG_DLR_EL0,
+        MISCREG_SPSR_EL2,
+        MISCREG_ELR_EL2,
+        MISCREG_SP_EL1,
+        MISCREG_SPSR_IRQ_AA64,
+        MISCREG_SPSR_ABT_AA64,
+        MISCREG_SPSR_UND_AA64,
+        MISCREG_SPSR_FIQ_AA64,
+        MISCREG_SPSR_EL3,
+        MISCREG_ELR_EL3,
+        MISCREG_SP_EL2,
+        MISCREG_AFSR0_EL1,
+        MISCREG_AFSR1_EL1,
+        MISCREG_ESR_EL1,
+        MISCREG_IFSR32_EL2,
+        MISCREG_AFSR0_EL2,
+        MISCREG_AFSR1_EL2,
+        MISCREG_ESR_EL2,
+        MISCREG_FPEXC32_EL2,
+        MISCREG_AFSR0_EL3,
+        MISCREG_AFSR1_EL3,
+        MISCREG_ESR_EL3,
+        MISCREG_FAR_EL1,
+        MISCREG_FAR_EL2,
+        MISCREG_HPFAR_EL2,
+        MISCREG_FAR_EL3,
+        MISCREG_IC_IALLUIS,
+        MISCREG_PAR_EL1,
+        MISCREG_IC_IALLU,
+        MISCREG_DC_IVAC_Xt,
+        MISCREG_DC_ISW_Xt,
+        MISCREG_AT_S1E1R_Xt,
+        MISCREG_AT_S1E1W_Xt,
+        MISCREG_AT_S1E0R_Xt,
+        MISCREG_AT_S1E0W_Xt,
+        MISCREG_DC_CSW_Xt,
+        MISCREG_DC_CISW_Xt,
+        MISCREG_DC_ZVA_Xt,
+        MISCREG_IC_IVAU_Xt,
+        MISCREG_DC_CVAC_Xt,
+        MISCREG_DC_CVAU_Xt,
+        MISCREG_DC_CIVAC_Xt,
+        MISCREG_AT_S1E2R_Xt,
+        MISCREG_AT_S1E2W_Xt,
+        MISCREG_AT_S12E1R_Xt,
+        MISCREG_AT_S12E1W_Xt,
+        MISCREG_AT_S12E0R_Xt,
+        MISCREG_AT_S12E0W_Xt,
+        MISCREG_AT_S1E3R_Xt,
+        MISCREG_AT_S1E3W_Xt,
+        MISCREG_TLBI_VMALLE1IS,
+        MISCREG_TLBI_VAE1IS_Xt,
+        MISCREG_TLBI_ASIDE1IS_Xt,
+        MISCREG_TLBI_VAAE1IS_Xt,
+        MISCREG_TLBI_VALE1IS_Xt,
+        MISCREG_TLBI_VAALE1IS_Xt,
+        MISCREG_TLBI_VMALLE1,
+        MISCREG_TLBI_VAE1_Xt,
+        MISCREG_TLBI_ASIDE1_Xt,
+        MISCREG_TLBI_VAAE1_Xt,
+        MISCREG_TLBI_VALE1_Xt,
+        MISCREG_TLBI_VAALE1_Xt,
+        MISCREG_TLBI_IPAS2E1IS_Xt,
+        MISCREG_TLBI_IPAS2LE1IS_Xt,
+        MISCREG_TLBI_ALLE2IS,
+        MISCREG_TLBI_VAE2IS_Xt,
+        MISCREG_TLBI_ALLE1IS,
+        MISCREG_TLBI_VALE2IS_Xt,
+        MISCREG_TLBI_VMALLS12E1IS,
+        MISCREG_TLBI_IPAS2E1_Xt,
+        MISCREG_TLBI_IPAS2LE1_Xt,
+        MISCREG_TLBI_ALLE2,
+        MISCREG_TLBI_VAE2_Xt,
+        MISCREG_TLBI_ALLE1,
+        MISCREG_TLBI_VALE2_Xt,
+        MISCREG_TLBI_VMALLS12E1,
+        MISCREG_TLBI_ALLE3IS,
+        MISCREG_TLBI_VAE3IS_Xt,
+        MISCREG_TLBI_VALE3IS_Xt,
+        MISCREG_TLBI_ALLE3,
+        MISCREG_TLBI_VAE3_Xt,
+        MISCREG_TLBI_VALE3_Xt,
+        MISCREG_PMINTENSET_EL1,
+        MISCREG_PMINTENCLR_EL1,
+        MISCREG_PMCR_EL0,
+        MISCREG_PMCNTENSET_EL0,
+        MISCREG_PMCNTENCLR_EL0,
+        MISCREG_PMOVSCLR_EL0,
+        MISCREG_PMSWINC_EL0,
+        MISCREG_PMSELR_EL0,
+        MISCREG_PMCEID0_EL0,
+        MISCREG_PMCEID1_EL0,
+        MISCREG_PMCCNTR_EL0,
+        MISCREG_PMXEVTYPER_EL0,
+        MISCREG_PMCCFILTR_EL0,
+        MISCREG_PMXEVCNTR_EL0,
+        MISCREG_PMUSERENR_EL0,
+        MISCREG_PMOVSSET_EL0,
+        MISCREG_MAIR_EL1,
+        MISCREG_AMAIR_EL1,
+        MISCREG_MAIR_EL2,
+        MISCREG_AMAIR_EL2,
+        MISCREG_MAIR_EL3,
+        MISCREG_AMAIR_EL3,
+        MISCREG_L2CTLR_EL1,
+        MISCREG_L2ECTLR_EL1,
+        MISCREG_VBAR_EL1,
+        MISCREG_RVBAR_EL1,
+        MISCREG_ISR_EL1,
+        MISCREG_VBAR_EL2,
+        MISCREG_RVBAR_EL2,
+        MISCREG_VBAR_EL3,
+        MISCREG_RVBAR_EL3,
+        MISCREG_RMR_EL3,
+        MISCREG_CONTEXTIDR_EL1,
+        MISCREG_TPIDR_EL1,
+        MISCREG_TPIDR_EL0,
+        MISCREG_TPIDRRO_EL0,
+        MISCREG_TPIDR_EL2,
+        MISCREG_TPIDR_EL3,
+        MISCREG_CNTKCTL_EL1,
+        MISCREG_CNTFRQ_EL0,
+        MISCREG_CNTPCT_EL0,
+        MISCREG_CNTVCT_EL0,
+        MISCREG_CNTP_TVAL_EL0,
+        MISCREG_CNTP_CTL_EL0,
+        MISCREG_CNTP_CVAL_EL0,
+        MISCREG_CNTV_TVAL_EL0,
+        MISCREG_CNTV_CTL_EL0,
+        MISCREG_CNTV_CVAL_EL0,
+        MISCREG_PMEVCNTR0_EL0,
+        MISCREG_PMEVCNTR1_EL0,
+        MISCREG_PMEVCNTR2_EL0,
+        MISCREG_PMEVCNTR3_EL0,
+        MISCREG_PMEVCNTR4_EL0,
+        MISCREG_PMEVCNTR5_EL0,
+        MISCREG_PMEVTYPER0_EL0,
+        MISCREG_PMEVTYPER1_EL0,
+        MISCREG_PMEVTYPER2_EL0,
+        MISCREG_PMEVTYPER3_EL0,
+        MISCREG_PMEVTYPER4_EL0,
+        MISCREG_PMEVTYPER5_EL0,
+        MISCREG_CNTVOFF_EL2,
+        MISCREG_CNTHCTL_EL2,
+        MISCREG_CNTHP_TVAL_EL2,
+        MISCREG_CNTHP_CTL_EL2,
+        MISCREG_CNTHP_CVAL_EL2,
+        MISCREG_CNTPS_TVAL_EL1,
+        MISCREG_CNTPS_CTL_EL1,
+        MISCREG_CNTPS_CVAL_EL1,
+        MISCREG_IL1DATA0_EL1,
+        MISCREG_IL1DATA1_EL1,
+        MISCREG_IL1DATA2_EL1,
+        MISCREG_IL1DATA3_EL1,
+        MISCREG_DL1DATA0_EL1,
+        MISCREG_DL1DATA1_EL1,
+        MISCREG_DL1DATA2_EL1,
+        MISCREG_DL1DATA3_EL1,
+        MISCREG_DL1DATA4_EL1,
+        MISCREG_L2ACTLR_EL1,
+        MISCREG_CPUACTLR_EL1,
+        MISCREG_CPUECTLR_EL1,
+        MISCREG_CPUMERRSR_EL1,
+        MISCREG_L2MERRSR_EL1,
+        MISCREG_CBAR_EL1,
+        MISCREG_CONTEXTIDR_EL2,
+
+        // Introduced in ARMv8.1
+        MISCREG_TTBR1_EL2,
+        MISCREG_CNTHV_CTL_EL2,
+        MISCREG_CNTHV_CVAL_EL2,
+        MISCREG_CNTHV_TVAL_EL2,
+
+        MISCREG_ID_AA64MMFR2_EL1,
+
+        // GICv3, CPU interface
+        MISCREG_ICC_PMR_EL1,
+        MISCREG_ICC_IAR0_EL1,
+        MISCREG_ICC_EOIR0_EL1,
+        MISCREG_ICC_HPPIR0_EL1,
+        MISCREG_ICC_BPR0_EL1,
+        MISCREG_ICC_AP0R0_EL1,
+        MISCREG_ICC_AP0R1_EL1,
+        MISCREG_ICC_AP0R2_EL1,
+        MISCREG_ICC_AP0R3_EL1,
+        MISCREG_ICC_AP1R0_EL1,
+        MISCREG_ICC_AP1R0_EL1_NS,
+        MISCREG_ICC_AP1R0_EL1_S,
+        MISCREG_ICC_AP1R1_EL1,
+        MISCREG_ICC_AP1R1_EL1_NS,
+        MISCREG_ICC_AP1R1_EL1_S,
+        MISCREG_ICC_AP1R2_EL1,
+        MISCREG_ICC_AP1R2_EL1_NS,
+        MISCREG_ICC_AP1R2_EL1_S,
+        MISCREG_ICC_AP1R3_EL1,
+        MISCREG_ICC_AP1R3_EL1_NS,
+        MISCREG_ICC_AP1R3_EL1_S,
+        MISCREG_ICC_DIR_EL1,
+        MISCREG_ICC_RPR_EL1,
+        MISCREG_ICC_SGI1R_EL1,
+        MISCREG_ICC_ASGI1R_EL1,
+        MISCREG_ICC_SGI0R_EL1,
+        MISCREG_ICC_IAR1_EL1,
+        MISCREG_ICC_EOIR1_EL1,
+        MISCREG_ICC_HPPIR1_EL1,
+        MISCREG_ICC_BPR1_EL1,
+        MISCREG_ICC_BPR1_EL1_NS,
+        MISCREG_ICC_BPR1_EL1_S,
+        MISCREG_ICC_CTLR_EL1,
+        MISCREG_ICC_CTLR_EL1_NS,
+        MISCREG_ICC_CTLR_EL1_S,
+        MISCREG_ICC_SRE_EL1,
+        MISCREG_ICC_SRE_EL1_NS,
+        MISCREG_ICC_SRE_EL1_S,
+        MISCREG_ICC_IGRPEN0_EL1,
+        MISCREG_ICC_IGRPEN1_EL1,
+        MISCREG_ICC_IGRPEN1_EL1_NS,
+        MISCREG_ICC_IGRPEN1_EL1_S,
+        MISCREG_ICC_SRE_EL2,
+        MISCREG_ICC_CTLR_EL3,
+        MISCREG_ICC_SRE_EL3,
+        MISCREG_ICC_IGRPEN1_EL3,
 
+        // GICv3, CPU interface, virtualization
+        MISCREG_ICH_AP0R0_EL2,
+        MISCREG_ICH_AP0R1_EL2,
+        MISCREG_ICH_AP0R2_EL2,
+        MISCREG_ICH_AP0R3_EL2,
+        MISCREG_ICH_AP1R0_EL2,
+        MISCREG_ICH_AP1R1_EL2,
+        MISCREG_ICH_AP1R2_EL2,
+        MISCREG_ICH_AP1R3_EL2,
+        MISCREG_ICH_HCR_EL2,
+        MISCREG_ICH_VTR_EL2,
+        MISCREG_ICH_MISR_EL2,
+        MISCREG_ICH_EISR_EL2,
+        MISCREG_ICH_ELRSR_EL2,
+        MISCREG_ICH_VMCR_EL2,
+        MISCREG_ICH_LR0_EL2,
+        MISCREG_ICH_LR1_EL2,
+        MISCREG_ICH_LR2_EL2,
+        MISCREG_ICH_LR3_EL2,
+        MISCREG_ICH_LR4_EL2,
+        MISCREG_ICH_LR5_EL2,
+        MISCREG_ICH_LR6_EL2,
+        MISCREG_ICH_LR7_EL2,
+        MISCREG_ICH_LR8_EL2,
+        MISCREG_ICH_LR9_EL2,
+        MISCREG_ICH_LR10_EL2,
+        MISCREG_ICH_LR11_EL2,
+        MISCREG_ICH_LR12_EL2,
+        MISCREG_ICH_LR13_EL2,
+        MISCREG_ICH_LR14_EL2,
+        MISCREG_ICH_LR15_EL2,
 
-        MISCREG_CP15_END,
+        MISCREG_ICV_PMR_EL1,
+        MISCREG_ICV_IAR0_EL1,
+        MISCREG_ICV_EOIR0_EL1,
+        MISCREG_ICV_HPPIR0_EL1,
+        MISCREG_ICV_BPR0_EL1,
+        MISCREG_ICV_AP0R0_EL1,
+        MISCREG_ICV_AP0R1_EL1,
+        MISCREG_ICV_AP0R2_EL1,
+        MISCREG_ICV_AP0R3_EL1,
+        MISCREG_ICV_AP1R0_EL1,
+        MISCREG_ICV_AP1R0_EL1_NS,
+        MISCREG_ICV_AP1R0_EL1_S,
+        MISCREG_ICV_AP1R1_EL1,
+        MISCREG_ICV_AP1R1_EL1_NS,
+        MISCREG_ICV_AP1R1_EL1_S,
+        MISCREG_ICV_AP1R2_EL1,
+        MISCREG_ICV_AP1R2_EL1_NS,
+        MISCREG_ICV_AP1R2_EL1_S,
+        MISCREG_ICV_AP1R3_EL1,
+        MISCREG_ICV_AP1R3_EL1_NS,
+        MISCREG_ICV_AP1R3_EL1_S,
+        MISCREG_ICV_DIR_EL1,
+        MISCREG_ICV_RPR_EL1,
+        MISCREG_ICV_SGI1R_EL1,
+        MISCREG_ICV_ASGI1R_EL1,
+        MISCREG_ICV_SGI0R_EL1,
+        MISCREG_ICV_IAR1_EL1,
+        MISCREG_ICV_EOIR1_EL1,
+        MISCREG_ICV_HPPIR1_EL1,
+        MISCREG_ICV_BPR1_EL1,
+        MISCREG_ICV_BPR1_EL1_NS,
+        MISCREG_ICV_BPR1_EL1_S,
+        MISCREG_ICV_CTLR_EL1,
+        MISCREG_ICV_CTLR_EL1_NS,
+        MISCREG_ICV_CTLR_EL1_S,
+        MISCREG_ICV_SRE_EL1,
+        MISCREG_ICV_SRE_EL1_NS,
+        MISCREG_ICV_SRE_EL1_S,
+        MISCREG_ICV_IGRPEN0_EL1,
+        MISCREG_ICV_IGRPEN1_EL1,
+        MISCREG_ICV_IGRPEN1_EL1_NS,
+        MISCREG_ICV_IGRPEN1_EL1_S,
 
-        // Dummy indices
-        MISCREG_NOP = MISCREG_CP15_END,
+        MISCREG_ICC_AP0R0,
+        MISCREG_ICC_AP0R1,
+        MISCREG_ICC_AP0R2,
+        MISCREG_ICC_AP0R3,
+        MISCREG_ICC_AP1R0,
+        MISCREG_ICC_AP1R0_NS,
+        MISCREG_ICC_AP1R0_S,
+        MISCREG_ICC_AP1R1,
+        MISCREG_ICC_AP1R1_NS,
+        MISCREG_ICC_AP1R1_S,
+        MISCREG_ICC_AP1R2,
+        MISCREG_ICC_AP1R2_NS,
+        MISCREG_ICC_AP1R2_S,
+        MISCREG_ICC_AP1R3,
+        MISCREG_ICC_AP1R3_NS,
+        MISCREG_ICC_AP1R3_S,
+        MISCREG_ICC_ASGI1R,
+        MISCREG_ICC_BPR0,
+        MISCREG_ICC_BPR1,
+        MISCREG_ICC_BPR1_NS,
+        MISCREG_ICC_BPR1_S,
+        MISCREG_ICC_CTLR,
+        MISCREG_ICC_CTLR_NS,
+        MISCREG_ICC_CTLR_S,
+        MISCREG_ICC_DIR,
+        MISCREG_ICC_EOIR0,
+        MISCREG_ICC_EOIR1,
+        MISCREG_ICC_HPPIR0,
+        MISCREG_ICC_HPPIR1,
+        MISCREG_ICC_HSRE,
+        MISCREG_ICC_IAR0,
+        MISCREG_ICC_IAR1,
+        MISCREG_ICC_IGRPEN0,
+        MISCREG_ICC_IGRPEN1,
+        MISCREG_ICC_IGRPEN1_NS,
+        MISCREG_ICC_IGRPEN1_S,
+        MISCREG_ICC_MCTLR,
+        MISCREG_ICC_MGRPEN1,
+        MISCREG_ICC_MSRE,
+        MISCREG_ICC_PMR,
+        MISCREG_ICC_RPR,
+        MISCREG_ICC_SGI0R,
+        MISCREG_ICC_SGI1R,
+        MISCREG_ICC_SRE,
+        MISCREG_ICC_SRE_NS,
+        MISCREG_ICC_SRE_S,
+
+        MISCREG_ICH_AP0R0,
+        MISCREG_ICH_AP0R1,
+        MISCREG_ICH_AP0R2,
+        MISCREG_ICH_AP0R3,
+        MISCREG_ICH_AP1R0,
+        MISCREG_ICH_AP1R1,
+        MISCREG_ICH_AP1R2,
+        MISCREG_ICH_AP1R3,
+        MISCREG_ICH_HCR,
+        MISCREG_ICH_VTR,
+        MISCREG_ICH_MISR,
+        MISCREG_ICH_EISR,
+        MISCREG_ICH_ELRSR,
+        MISCREG_ICH_VMCR,
+        MISCREG_ICH_LR0,
+        MISCREG_ICH_LR1,
+        MISCREG_ICH_LR2,
+        MISCREG_ICH_LR3,
+        MISCREG_ICH_LR4,
+        MISCREG_ICH_LR5,
+        MISCREG_ICH_LR6,
+        MISCREG_ICH_LR7,
+        MISCREG_ICH_LR8,
+        MISCREG_ICH_LR9,
+        MISCREG_ICH_LR10,
+        MISCREG_ICH_LR11,
+        MISCREG_ICH_LR12,
+        MISCREG_ICH_LR13,
+        MISCREG_ICH_LR14,
+        MISCREG_ICH_LR15,
+        MISCREG_ICH_LRC0,
+        MISCREG_ICH_LRC1,
+        MISCREG_ICH_LRC2,
+        MISCREG_ICH_LRC3,
+        MISCREG_ICH_LRC4,
+        MISCREG_ICH_LRC5,
+        MISCREG_ICH_LRC6,
+        MISCREG_ICH_LRC7,
+        MISCREG_ICH_LRC8,
+        MISCREG_ICH_LRC9,
+        MISCREG_ICH_LRC10,
+        MISCREG_ICH_LRC11,
+        MISCREG_ICH_LRC12,
+        MISCREG_ICH_LRC13,
+        MISCREG_ICH_LRC14,
+        MISCREG_ICH_LRC15,
+
+        // SVE
+        MISCREG_ID_AA64ZFR0_EL1,
+        MISCREG_ZCR_EL3,
+        MISCREG_ZCR_EL2,
+        MISCREG_ZCR_EL12,
+        MISCREG_ZCR_EL1,
+
+        // NUM_PHYS_MISCREGS specifies the number of actual physical
+        // registers, not considering the following pseudo-registers
+        // (dummy registers), like UNKNOWN, CP15_UNIMPL, MISCREG_IMPDEF_UNIMPL.
+        // Checkpointing should use this physical index when
+        // saving/restoring register values.
+        NUM_PHYS_MISCREGS,
+
+        // Dummy registers
+        MISCREG_NOP,
         MISCREG_RAZ,
+        MISCREG_CP14_UNIMPL,
+        MISCREG_CP15_UNIMPL,
+        MISCREG_UNKNOWN,
+
+        // Implementation defined register: this represent
+        // a pool of unimplemented registers whose access can throw
+        // either UNDEFINED or hypervisor trap exception.
+        MISCREG_IMPDEF_UNIMPL,
+
+        // RAS extension (unimplemented)
+        MISCREG_ERRIDR_EL1,
+        MISCREG_ERRSELR_EL1,
+        MISCREG_ERXFR_EL1,
+        MISCREG_ERXCTLR_EL1,
+        MISCREG_ERXSTATUS_EL1,
+        MISCREG_ERXADDR_EL1,
+        MISCREG_ERXMISC0_EL1,
+        MISCREG_ERXMISC1_EL1,
+        MISCREG_DISR_EL1,
+        MISCREG_VSESR_EL2,
+        MISCREG_VDISR_EL2,
 
+        // PSTATE
+        MISCREG_PAN,
+
+        // Total number of Misc Registers: Physical + Dummy
         NUM_MISCREGS
     };
 
+    enum MiscRegInfo {
+        MISCREG_IMPLEMENTED,
+        MISCREG_UNVERIFIABLE,   // Does the value change on every read (e.g. a
+                                // arch generic counter)
+        MISCREG_WARN_NOT_FAIL,  // If MISCREG_IMPLEMENTED is deasserted, it
+                                // tells whether the instruction should raise a
+                                // warning or fail
+        MISCREG_MUTEX,  // True if the register corresponds to a pair of
+                        // mutually exclusive registers
+        MISCREG_BANKED,  // True if the register is banked between the two
+                         // security states, and this is the parent node of the
+                         // two banked registers
+        MISCREG_BANKED64, // True if the register is banked between the two
+                          // security states, and this is the parent node of
+                          // the two banked registers. Used in AA64 only.
+        MISCREG_BANKED_CHILD, // The entry is one of the child registers that
+                              // forms a banked set of regs (along with the
+                              // other child regs)
+
+        // Access permissions
+        // User mode
+        MISCREG_USR_NS_RD,
+        MISCREG_USR_NS_WR,
+        MISCREG_USR_S_RD,
+        MISCREG_USR_S_WR,
+        // Privileged modes other than hypervisor or monitor
+        MISCREG_PRI_NS_RD,
+        MISCREG_PRI_NS_WR,
+        MISCREG_PRI_S_RD,
+        MISCREG_PRI_S_WR,
+        // Hypervisor mode
+        MISCREG_HYP_RD,
+        MISCREG_HYP_WR,
+        // Monitor mode, SCR.NS == 0
+        MISCREG_MON_NS0_RD,
+        MISCREG_MON_NS0_WR,
+        // Monitor mode, SCR.NS == 1
+        MISCREG_MON_NS1_RD,
+        MISCREG_MON_NS1_WR,
+
+        NUM_MISCREG_INFOS
+    };
+
+    extern std::bitset<NUM_MISCREG_INFOS> miscRegInfo[NUM_MISCREGS];
+
+    // Decodes 32-bit CP14 registers accessible through MCR/MRC instructions
+    MiscRegIndex decodeCP14Reg(unsigned crn, unsigned opc1,
+                               unsigned crm, unsigned opc2);
+    MiscRegIndex decodeAArch64SysReg(unsigned op0, unsigned op1,
+                                     unsigned crn, unsigned crm,
+                                     unsigned op2);
+    // Whether a particular AArch64 system register is -always- read only.
+    bool aarch64SysRegReadOnly(MiscRegIndex miscReg);
+
+    // Decodes 32-bit CP15 registers accessible through MCR/MRC instructions
     MiscRegIndex decodeCP15Reg(unsigned crn, unsigned opc1,
                                unsigned crm, unsigned opc2);
 
-    const char * const miscRegName[NUM_MISCREGS] = {
-        "cpsr", "spsr", "spsr_fiq", "spsr_irq", "spsr_svc",
-        "spsr_mon", "spsr_und", "spsr_abt",
-        "fpsr", "fpsid", "fpscr", "fpscr_qc", "fpscr_exc", "fpexc",
-        "mvfr0", "mvfr1",
-        "sctlr_rst", "sev_mailbox",
-        "sctlr", "dccisw", "dccimvac", "dccmvac",
-        "contextidr", "tpidrurw", "tpidruro", "tpidrprw",
-        "cp15isb", "cp15dsb", "cp15dmb", "cpacr",
-        "clidr", "ccsidr", "csselr",
-        "icialluis", "iciallu", "icimvau",
-        "bpimva", "bpiallis", "bpiall",
-        "midr", "ttbr0", "ttbr1", "tlbtr", "dacr",
-        "tlbiallis", "tlbimvais", "tlbiasidis", "tlbimvaais",
-        "itlbiall", "itlbimva", "itlbiasid",
-        "dtlbiall", "dtlbimva", "dtlbiasid",
-        "tlbiall", "tlbimva", "tlbiasid", "tlbimvaa",
-        "dfsr", "ifsr", "dfar", "ifar", "mpidr",
-        "prrr", "nmrr",  "ttbcr", "id_pfr0", "ctr",
-        "scr", "sder", "par",
-        "v2pcwpr", "v2pcwpw", "v2pcwur", "v2pcwuw",
-        "v2powpr", "v2powpw", "v2powur", "v2powuw",
-        "id_mmfr0", "id_mmfr3", "actlr", "pmcr", "pmccntr",
-        "pmcntenset", "pmcntenclr", "pmovsr",
-        "pmswinc", "pmselr", "pmceid0",
-        "pmceid1", "pmc_other", "pmxevcntr",
-        "pmuserenr", "pmintenset", "pmintenclr",
-        "id_isar0", "id_isar1", "id_isar2", "id_isar3", "id_isar4", "id_isar5",
-        "cpsr_mode", "lockflag", "lockaddr",
-         // Unimplemented below
+    // Decodes 64-bit CP15 registers accessible through MCRR/MRRC instructions
+    MiscRegIndex decodeCP15Reg64(unsigned crm, unsigned opc1);
+
+
+    const char * const miscRegName[] = {
+        "cpsr",
+        "spsr",
+        "spsr_fiq",
+        "spsr_irq",
+        "spsr_svc",
+        "spsr_mon",
+        "spsr_abt",
+        "spsr_hyp",
+        "spsr_und",
+        "elr_hyp",
+        "fpsid",
+        "fpscr",
+        "mvfr1",
+        "mvfr0",
+        "fpexc",
+
+        // Helper registers
+        "cpsr_mode",
+        "cpsr_q",
+        "fpscr_exc",
+        "fpscr_qc",
+        "lockaddr",
+        "lockflag",
+        "prrr_mair0",
+        "prrr_mair0_ns",
+        "prrr_mair0_s",
+        "nmrr_mair1",
+        "nmrr_mair1_ns",
+        "nmrr_mair1_s",
+        "pmxevtyper_pmccfiltr",
+        "sctlr_rst",
+        "sev_mailbox",
+
+        // AArch32 CP14 registers
+        "dbgdidr",
+        "dbgdscrint",
+        "dbgdccint",
+        "dbgdtrtxint",
+        "dbgdtrrxint",
+        "dbgwfar",
+        "dbgvcr",
+        "dbgdtrrxext",
+        "dbgdscrext",
+        "dbgdtrtxext",
+        "dbgoseccr",
+        "dbgbvr0",
+        "dbgbvr1",
+        "dbgbvr2",
+        "dbgbvr3",
+        "dbgbvr4",
+        "dbgbvr5",
+        "dbgbcr0",
+        "dbgbcr1",
+        "dbgbcr2",
+        "dbgbcr3",
+        "dbgbcr4",
+        "dbgbcr5",
+        "dbgwvr0",
+        "dbgwvr1",
+        "dbgwvr2",
+        "dbgwvr3",
+        "dbgwcr0",
+        "dbgwcr1",
+        "dbgwcr2",
+        "dbgwcr3",
+        "dbgdrar",
+        "dbgbxvr4",
+        "dbgbxvr5",
+        "dbgoslar",
+        "dbgoslsr",
+        "dbgosdlr",
+        "dbgprcr",
+        "dbgdsar",
+        "dbgclaimset",
+        "dbgclaimclr",
+        "dbgauthstatus",
+        "dbgdevid2",
+        "dbgdevid1",
+        "dbgdevid0",
+        "teecr",
+        "jidr",
+        "teehbr",
+        "joscr",
+        "jmcr",
+
+        // AArch32 CP15 registers
+        "midr",
+        "ctr",
         "tcmtr",
-        "id_pfr1", "id_dfr0", "id_afr0",
-        "id_mmfr1", "id_mmfr2",
-        "aidr", "adfsr", "aifsr",
-        "dcimvac", "dcisw", "mccsw",
-        "dccmvau",
+        "tlbtr",
+        "mpidr",
+        "revidr",
+        "id_pfr0",
+        "id_pfr1",
+        "id_dfr0",
+        "id_afr0",
+        "id_mmfr0",
+        "id_mmfr1",
+        "id_mmfr2",
+        "id_mmfr3",
+        "id_isar0",
+        "id_isar1",
+        "id_isar2",
+        "id_isar3",
+        "id_isar4",
+        "id_isar5",
+        "ccsidr",
+        "clidr",
+        "aidr",
+        "csselr",
+        "csselr_ns",
+        "csselr_s",
+        "vpidr",
+        "vmpidr",
+        "sctlr",
+        "sctlr_ns",
+        "sctlr_s",
+        "actlr",
+        "actlr_ns",
+        "actlr_s",
+        "cpacr",
+        "scr",
+        "sder",
         "nsacr",
-        "vbar", "mvbar", "isr", "fceidr", "l2latency",
-        "nop", "raz"
+        "hsctlr",
+        "hactlr",
+        "hcr",
+        "hcr2",
+        "hdcr",
+        "hcptr",
+        "hstr",
+        "hacr",
+        "ttbr0",
+        "ttbr0_ns",
+        "ttbr0_s",
+        "ttbr1",
+        "ttbr1_ns",
+        "ttbr1_s",
+        "ttbcr",
+        "ttbcr_ns",
+        "ttbcr_s",
+        "htcr",
+        "vtcr",
+        "dacr",
+        "dacr_ns",
+        "dacr_s",
+        "dfsr",
+        "dfsr_ns",
+        "dfsr_s",
+        "ifsr",
+        "ifsr_ns",
+        "ifsr_s",
+        "adfsr",
+        "adfsr_ns",
+        "adfsr_s",
+        "aifsr",
+        "aifsr_ns",
+        "aifsr_s",
+        "hadfsr",
+        "haifsr",
+        "hsr",
+        "dfar",
+        "dfar_ns",
+        "dfar_s",
+        "ifar",
+        "ifar_ns",
+        "ifar_s",
+        "hdfar",
+        "hifar",
+        "hpfar",
+        "icialluis",
+        "bpiallis",
+        "par",
+        "par_ns",
+        "par_s",
+        "iciallu",
+        "icimvau",
+        "cp15isb",
+        "bpiall",
+        "bpimva",
+        "dcimvac",
+        "dcisw",
+        "ats1cpr",
+        "ats1cpw",
+        "ats1cur",
+        "ats1cuw",
+        "ats12nsopr",
+        "ats12nsopw",
+        "ats12nsour",
+        "ats12nsouw",
+        "dccmvac",
+        "dccsw",
+        "cp15dsb",
+        "cp15dmb",
+        "dccmvau",
+        "dccimvac",
+        "dccisw",
+        "ats1hr",
+        "ats1hw",
+        "tlbiallis",
+        "tlbimvais",
+        "tlbiasidis",
+        "tlbimvaais",
+        "tlbimvalis",
+        "tlbimvaalis",
+        "itlbiall",
+        "itlbimva",
+        "itlbiasid",
+        "dtlbiall",
+        "dtlbimva",
+        "dtlbiasid",
+        "tlbiall",
+        "tlbimva",
+        "tlbiasid",
+        "tlbimvaa",
+        "tlbimval",
+        "tlbimvaal",
+        "tlbiipas2is",
+        "tlbiipas2lis",
+        "tlbiallhis",
+        "tlbimvahis",
+        "tlbiallnsnhis",
+        "tlbimvalhis",
+        "tlbiipas2",
+        "tlbiipas2l",
+        "tlbiallh",
+        "tlbimvah",
+        "tlbiallnsnh",
+        "tlbimvalh",
+        "pmcr",
+        "pmcntenset",
+        "pmcntenclr",
+        "pmovsr",
+        "pmswinc",
+        "pmselr",
+        "pmceid0",
+        "pmceid1",
+        "pmccntr",
+        "pmxevtyper",
+        "pmccfiltr",
+        "pmxevcntr",
+        "pmuserenr",
+        "pmintenset",
+        "pmintenclr",
+        "pmovsset",
+        "l2ctlr",
+        "l2ectlr",
+        "prrr",
+        "prrr_ns",
+        "prrr_s",
+        "mair0",
+        "mair0_ns",
+        "mair0_s",
+        "nmrr",
+        "nmrr_ns",
+        "nmrr_s",
+        "mair1",
+        "mair1_ns",
+        "mair1_s",
+        "amair0",
+        "amair0_ns",
+        "amair0_s",
+        "amair1",
+        "amair1_ns",
+        "amair1_s",
+        "hmair0",
+        "hmair1",
+        "hamair0",
+        "hamair1",
+        "vbar",
+        "vbar_ns",
+        "vbar_s",
+        "mvbar",
+        "rmr",
+        "isr",
+        "hvbar",
+        "fcseidr",
+        "contextidr",
+        "contextidr_ns",
+        "contextidr_s",
+        "tpidrurw",
+        "tpidrurw_ns",
+        "tpidrurw_s",
+        "tpidruro",
+        "tpidruro_ns",
+        "tpidruro_s",
+        "tpidrprw",
+        "tpidrprw_ns",
+        "tpidrprw_s",
+        "htpidr",
+        "cntfrq",
+        "cntkctl",
+        "cntp_tval",
+        "cntp_tval_ns",
+        "cntp_tval_s",
+        "cntp_ctl",
+        "cntp_ctl_ns",
+        "cntp_ctl_s",
+        "cntv_tval",
+        "cntv_ctl",
+        "cnthctl",
+        "cnthp_tval",
+        "cnthp_ctl",
+        "il1data0",
+        "il1data1",
+        "il1data2",
+        "il1data3",
+        "dl1data0",
+        "dl1data1",
+        "dl1data2",
+        "dl1data3",
+        "dl1data4",
+        "ramindex",
+        "l2actlr",
+        "cbar",
+        "httbr",
+        "vttbr",
+        "cntpct",
+        "cntvct",
+        "cntp_cval",
+        "cntp_cval_ns",
+        "cntp_cval_s",
+        "cntv_cval",
+        "cntvoff",
+        "cnthp_cval",
+        "cpumerrsr",
+        "l2merrsr",
+
+        // AArch64 registers (Op0=2)
+        "mdccint_el1",
+        "osdtrrx_el1",
+        "mdscr_el1",
+        "osdtrtx_el1",
+        "oseccr_el1",
+        "dbgbvr0_el1",
+        "dbgbvr1_el1",
+        "dbgbvr2_el1",
+        "dbgbvr3_el1",
+        "dbgbvr4_el1",
+        "dbgbvr5_el1",
+        "dbgbcr0_el1",
+        "dbgbcr1_el1",
+        "dbgbcr2_el1",
+        "dbgbcr3_el1",
+        "dbgbcr4_el1",
+        "dbgbcr5_el1",
+        "dbgwvr0_el1",
+        "dbgwvr1_el1",
+        "dbgwvr2_el1",
+        "dbgwvr3_el1",
+        "dbgwcr0_el1",
+        "dbgwcr1_el1",
+        "dbgwcr2_el1",
+        "dbgwcr3_el1",
+        "mdccsr_el0",
+        "mddtr_el0",
+        "mddtrtx_el0",
+        "mddtrrx_el0",
+        "dbgvcr32_el2",
+        "mdrar_el1",
+        "oslar_el1",
+        "oslsr_el1",
+        "osdlr_el1",
+        "dbgprcr_el1",
+        "dbgclaimset_el1",
+        "dbgclaimclr_el1",
+        "dbgauthstatus_el1",
+        "teecr32_el1",
+        "teehbr32_el1",
+
+        // AArch64 registers (Op0=1,3)
+        "midr_el1",
+        "mpidr_el1",
+        "revidr_el1",
+        "id_pfr0_el1",
+        "id_pfr1_el1",
+        "id_dfr0_el1",
+        "id_afr0_el1",
+        "id_mmfr0_el1",
+        "id_mmfr1_el1",
+        "id_mmfr2_el1",
+        "id_mmfr3_el1",
+        "id_isar0_el1",
+        "id_isar1_el1",
+        "id_isar2_el1",
+        "id_isar3_el1",
+        "id_isar4_el1",
+        "id_isar5_el1",
+        "mvfr0_el1",
+        "mvfr1_el1",
+        "mvfr2_el1",
+        "id_aa64pfr0_el1",
+        "id_aa64pfr1_el1",
+        "id_aa64dfr0_el1",
+        "id_aa64dfr1_el1",
+        "id_aa64afr0_el1",
+        "id_aa64afr1_el1",
+        "id_aa64isar0_el1",
+        "id_aa64isar1_el1",
+        "id_aa64mmfr0_el1",
+        "id_aa64mmfr1_el1",
+        "ccsidr_el1",
+        "clidr_el1",
+        "aidr_el1",
+        "csselr_el1",
+        "ctr_el0",
+        "dczid_el0",
+        "vpidr_el2",
+        "vmpidr_el2",
+        "sctlr_el1",
+        "actlr_el1",
+        "cpacr_el1",
+        "sctlr_el2",
+        "actlr_el2",
+        "hcr_el2",
+        "mdcr_el2",
+        "cptr_el2",
+        "hstr_el2",
+        "hacr_el2",
+        "sctlr_el3",
+        "actlr_el3",
+        "scr_el3",
+        "sder32_el3",
+        "cptr_el3",
+        "mdcr_el3",
+        "ttbr0_el1",
+        "ttbr1_el1",
+        "tcr_el1",
+        "ttbr0_el2",
+        "tcr_el2",
+        "vttbr_el2",
+        "vtcr_el2",
+        "ttbr0_el3",
+        "tcr_el3",
+        "dacr32_el2",
+        "spsr_el1",
+        "elr_el1",
+        "sp_el0",
+        "spsel",
+        "currentel",
+        "nzcv",
+        "daif",
+        "fpcr",
+        "fpsr",
+        "dspsr_el0",
+        "dlr_el0",
+        "spsr_el2",
+        "elr_el2",
+        "sp_el1",
+        "spsr_irq_aa64",
+        "spsr_abt_aa64",
+        "spsr_und_aa64",
+        "spsr_fiq_aa64",
+        "spsr_el3",
+        "elr_el3",
+        "sp_el2",
+        "afsr0_el1",
+        "afsr1_el1",
+        "esr_el1",
+        "ifsr32_el2",
+        "afsr0_el2",
+        "afsr1_el2",
+        "esr_el2",
+        "fpexc32_el2",
+        "afsr0_el3",
+        "afsr1_el3",
+        "esr_el3",
+        "far_el1",
+        "far_el2",
+        "hpfar_el2",
+        "far_el3",
+        "ic_ialluis",
+        "par_el1",
+        "ic_iallu",
+        "dc_ivac_xt",
+        "dc_isw_xt",
+        "at_s1e1r_xt",
+        "at_s1e1w_xt",
+        "at_s1e0r_xt",
+        "at_s1e0w_xt",
+        "dc_csw_xt",
+        "dc_cisw_xt",
+        "dc_zva_xt",
+        "ic_ivau_xt",
+        "dc_cvac_xt",
+        "dc_cvau_xt",
+        "dc_civac_xt",
+        "at_s1e2r_xt",
+        "at_s1e2w_xt",
+        "at_s12e1r_xt",
+        "at_s12e1w_xt",
+        "at_s12e0r_xt",
+        "at_s12e0w_xt",
+        "at_s1e3r_xt",
+        "at_s1e3w_xt",
+        "tlbi_vmalle1is",
+        "tlbi_vae1is_xt",
+        "tlbi_aside1is_xt",
+        "tlbi_vaae1is_xt",
+        "tlbi_vale1is_xt",
+        "tlbi_vaale1is_xt",
+        "tlbi_vmalle1",
+        "tlbi_vae1_xt",
+        "tlbi_aside1_xt",
+        "tlbi_vaae1_xt",
+        "tlbi_vale1_xt",
+        "tlbi_vaale1_xt",
+        "tlbi_ipas2e1is_xt",
+        "tlbi_ipas2le1is_xt",
+        "tlbi_alle2is",
+        "tlbi_vae2is_xt",
+        "tlbi_alle1is",
+        "tlbi_vale2is_xt",
+        "tlbi_vmalls12e1is",
+        "tlbi_ipas2e1_xt",
+        "tlbi_ipas2le1_xt",
+        "tlbi_alle2",
+        "tlbi_vae2_xt",
+        "tlbi_alle1",
+        "tlbi_vale2_xt",
+        "tlbi_vmalls12e1",
+        "tlbi_alle3is",
+        "tlbi_vae3is_xt",
+        "tlbi_vale3is_xt",
+        "tlbi_alle3",
+        "tlbi_vae3_xt",
+        "tlbi_vale3_xt",
+        "pmintenset_el1",
+        "pmintenclr_el1",
+        "pmcr_el0",
+        "pmcntenset_el0",
+        "pmcntenclr_el0",
+        "pmovsclr_el0",
+        "pmswinc_el0",
+        "pmselr_el0",
+        "pmceid0_el0",
+        "pmceid1_el0",
+        "pmccntr_el0",
+        "pmxevtyper_el0",
+        "pmccfiltr_el0",
+        "pmxevcntr_el0",
+        "pmuserenr_el0",
+        "pmovsset_el0",
+        "mair_el1",
+        "amair_el1",
+        "mair_el2",
+        "amair_el2",
+        "mair_el3",
+        "amair_el3",
+        "l2ctlr_el1",
+        "l2ectlr_el1",
+        "vbar_el1",
+        "rvbar_el1",
+        "isr_el1",
+        "vbar_el2",
+        "rvbar_el2",
+        "vbar_el3",
+        "rvbar_el3",
+        "rmr_el3",
+        "contextidr_el1",
+        "tpidr_el1",
+        "tpidr_el0",
+        "tpidrro_el0",
+        "tpidr_el2",
+        "tpidr_el3",
+        "cntkctl_el1",
+        "cntfrq_el0",
+        "cntpct_el0",
+        "cntvct_el0",
+        "cntp_tval_el0",
+        "cntp_ctl_el0",
+        "cntp_cval_el0",
+        "cntv_tval_el0",
+        "cntv_ctl_el0",
+        "cntv_cval_el0",
+        "pmevcntr0_el0",
+        "pmevcntr1_el0",
+        "pmevcntr2_el0",
+        "pmevcntr3_el0",
+        "pmevcntr4_el0",
+        "pmevcntr5_el0",
+        "pmevtyper0_el0",
+        "pmevtyper1_el0",
+        "pmevtyper2_el0",
+        "pmevtyper3_el0",
+        "pmevtyper4_el0",
+        "pmevtyper5_el0",
+        "cntvoff_el2",
+        "cnthctl_el2",
+        "cnthp_tval_el2",
+        "cnthp_ctl_el2",
+        "cnthp_cval_el2",
+        "cntps_tval_el1",
+        "cntps_ctl_el1",
+        "cntps_cval_el1",
+        "il1data0_el1",
+        "il1data1_el1",
+        "il1data2_el1",
+        "il1data3_el1",
+        "dl1data0_el1",
+        "dl1data1_el1",
+        "dl1data2_el1",
+        "dl1data3_el1",
+        "dl1data4_el1",
+        "l2actlr_el1",
+        "cpuactlr_el1",
+        "cpuectlr_el1",
+        "cpumerrsr_el1",
+        "l2merrsr_el1",
+        "cbar_el1",
+        "contextidr_el2",
+
+        "ttbr1_el2",
+        "cnthv_ctl_el2",
+        "cnthv_cval_el2",
+        "cnthv_tval_el2",
+        "id_aa64mmfr2_el1",
+
+        // GICv3, CPU interface
+        "icc_pmr_el1",
+        "icc_iar0_el1",
+        "icc_eoir0_el1",
+        "icc_hppir0_el1",
+        "icc_bpr0_el1",
+        "icc_ap0r0_el1",
+        "icc_ap0r1_el1",
+        "icc_ap0r2_el1",
+        "icc_ap0r3_el1",
+        "icc_ap1r0_el1",
+        "icc_ap1r0_el1_ns",
+        "icc_ap1r0_el1_s",
+        "icc_ap1r1_el1",
+        "icc_ap1r1_el1_ns",
+        "icc_ap1r1_el1_s",
+        "icc_ap1r2_el1",
+        "icc_ap1r2_el1_ns",
+        "icc_ap1r2_el1_s",
+        "icc_ap1r3_el1",
+        "icc_ap1r3_el1_ns",
+        "icc_ap1r3_el1_s",
+        "icc_dir_el1",
+        "icc_rpr_el1",
+        "icc_sgi1r_el1",
+        "icc_asgi1r_el1",
+        "icc_sgi0r_el1",
+        "icc_iar1_el1",
+        "icc_eoir1_el1",
+        "icc_hppir1_el1",
+        "icc_bpr1_el1",
+        "icc_bpr1_el1_ns",
+        "icc_bpr1_el1_s",
+        "icc_ctlr_el1",
+        "icc_ctlr_el1_ns",
+        "icc_ctlr_el1_s",
+        "icc_sre_el1",
+        "icc_sre_el1_ns",
+        "icc_sre_el1_s",
+        "icc_igrpen0_el1",
+        "icc_igrpen1_el1",
+        "icc_igrpen1_el1_ns",
+        "icc_igrpen1_el1_s",
+        "icc_sre_el2",
+        "icc_ctlr_el3",
+        "icc_sre_el3",
+        "icc_igrpen1_el3",
+
+        // GICv3, CPU interface, virtualization
+        "ich_ap0r0_el2",
+        "ich_ap0r1_el2",
+        "ich_ap0r2_el2",
+        "ich_ap0r3_el2",
+        "ich_ap1r0_el2",
+        "ich_ap1r1_el2",
+        "ich_ap1r2_el2",
+        "ich_ap1r3_el2",
+        "ich_hcr_el2",
+        "ich_vtr_el2",
+        "ich_misr_el2",
+        "ich_eisr_el2",
+        "ich_elrsr_el2",
+        "ich_vmcr_el2",
+        "ich_lr0_el2",
+        "ich_lr1_el2",
+        "ich_lr2_el2",
+        "ich_lr3_el2",
+        "ich_lr4_el2",
+        "ich_lr5_el2",
+        "ich_lr6_el2",
+        "ich_lr7_el2",
+        "ich_lr8_el2",
+        "ich_lr9_el2",
+        "ich_lr10_el2",
+        "ich_lr11_el2",
+        "ich_lr12_el2",
+        "ich_lr13_el2",
+        "ich_lr14_el2",
+        "ich_lr15_el2",
+
+        "icv_pmr_el1",
+        "icv_iar0_el1",
+        "icv_eoir0_el1",
+        "icv_hppir0_el1",
+        "icv_bpr0_el1",
+        "icv_ap0r0_el1",
+        "icv_ap0r1_el1",
+        "icv_ap0r2_el1",
+        "icv_ap0r3_el1",
+        "icv_ap1r0_el1",
+        "icv_ap1r0_el1_ns",
+        "icv_ap1r0_el1_s",
+        "icv_ap1r1_el1",
+        "icv_ap1r1_el1_ns",
+        "icv_ap1r1_el1_s",
+        "icv_ap1r2_el1",
+        "icv_ap1r2_el1_ns",
+        "icv_ap1r2_el1_s",
+        "icv_ap1r3_el1",
+        "icv_ap1r3_el1_ns",
+        "icv_ap1r3_el1_s",
+        "icv_dir_el1",
+        "icv_rpr_el1",
+        "icv_sgi1r_el1",
+        "icv_asgi1r_el1",
+        "icv_sgi0r_el1",
+        "icv_iar1_el1",
+        "icv_eoir1_el1",
+        "icv_hppir1_el1",
+        "icv_bpr1_el1",
+        "icv_bpr1_el1_ns",
+        "icv_bpr1_el1_s",
+        "icv_ctlr_el1",
+        "icv_ctlr_el1_ns",
+        "icv_ctlr_el1_s",
+        "icv_sre_el1",
+        "icv_sre_el1_ns",
+        "icv_sre_el1_s",
+        "icv_igrpen0_el1",
+        "icv_igrpen1_el1",
+        "icv_igrpen1_el1_ns",
+        "icv_igrpen1_el1_s",
+
+        "icc_ap0r0",
+        "icc_ap0r1",
+        "icc_ap0r2",
+        "icc_ap0r3",
+        "icc_ap1r0",
+        "icc_ap1r0_ns",
+        "icc_ap1r0_s",
+        "icc_ap1r1",
+        "icc_ap1r1_ns",
+        "icc_ap1r1_s",
+        "icc_ap1r2",
+        "icc_ap1r2_ns",
+        "icc_ap1r2_s",
+        "icc_ap1r3",
+        "icc_ap1r3_ns",
+        "icc_ap1r3_s",
+        "icc_asgi1r",
+        "icc_bpr0",
+        "icc_bpr1",
+        "icc_bpr1_ns",
+        "icc_bpr1_s",
+        "icc_ctlr",
+        "icc_ctlr_ns",
+        "icc_ctlr_s",
+        "icc_dir",
+        "icc_eoir0",
+        "icc_eoir1",
+        "icc_hppir0",
+        "icc_hppir1",
+        "icc_hsre",
+        "icc_iar0",
+        "icc_iar1",
+        "icc_igrpen0",
+        "icc_igrpen1",
+        "icc_igrpen1_ns",
+        "icc_igrpen1_s",
+        "icc_mctlr",
+        "icc_mgrpen1",
+        "icc_msre",
+        "icc_pmr",
+        "icc_rpr",
+        "icc_sgi0r",
+        "icc_sgi1r",
+        "icc_sre",
+        "icc_sre_ns",
+        "icc_sre_s",
+
+        "ich_ap0r0",
+        "ich_ap0r1",
+        "ich_ap0r2",
+        "ich_ap0r3",
+        "ich_ap1r0",
+        "ich_ap1r1",
+        "ich_ap1r2",
+        "ich_ap1r3",
+        "ich_hcr",
+        "ich_vtr",
+        "ich_misr",
+        "ich_eisr",
+        "ich_elrsr",
+        "ich_vmcr",
+        "ich_lr0",
+        "ich_lr1",
+        "ich_lr2",
+        "ich_lr3",
+        "ich_lr4",
+        "ich_lr5",
+        "ich_lr6",
+        "ich_lr7",
+        "ich_lr8",
+        "ich_lr9",
+        "ich_lr10",
+        "ich_lr11",
+        "ich_lr12",
+        "ich_lr13",
+        "ich_lr14",
+        "ich_lr15",
+        "ich_lrc0",
+        "ich_lrc1",
+        "ich_lrc2",
+        "ich_lrc3",
+        "ich_lrc4",
+        "ich_lrc5",
+        "ich_lrc6",
+        "ich_lrc7",
+        "ich_lrc8",
+        "ich_lrc9",
+        "ich_lrc10",
+        "ich_lrc11",
+        "ich_lrc12",
+        "ich_lrc13",
+        "ich_lrc14",
+        "ich_lrc15",
+
+        "id_aa64zfr0_el1",
+        "zcr_el3",
+        "zcr_el2",
+        "zcr_el12",
+        "zcr_el1",
+
+        "num_phys_regs",
+
+        // Dummy registers
+        "nop",
+        "raz",
+        "cp14_unimpl",
+        "cp15_unimpl",
+        "unknown",
+        "impl_defined",
+        "erridr_el1",
+        "errselr_el1",
+        "erxfr_el1",
+        "erxctlr_el1",
+        "erxstatus_el1",
+        "erxaddr_el1",
+        "erxmisc0_el1",
+        "erxmisc1_el1",
+        "disr_el1",
+        "vsesr_el2",
+        "vdisr_el2",
+
+        // PSTATE
+        "pan",
     };
 
-    BitUnion32(CPSR)
-        Bitfield<31> n;
-        Bitfield<30> z;
-        Bitfield<29> c;
-        Bitfield<28> v;
-        Bitfield<27> q;
-        Bitfield<26,25> it1;
-        Bitfield<24> j;
-        Bitfield<19, 16> ge;
-        Bitfield<15,10> it2;
-        Bitfield<9> e;
-        Bitfield<8> a;
-        Bitfield<7> i;
-        Bitfield<6> f;
-        Bitfield<5> t;
-        Bitfield<4, 0> mode;
-    EndBitUnion(CPSR)
+    static_assert(sizeof(miscRegName) / sizeof(*miscRegName) == NUM_MISCREGS,
+                  "The miscRegName array and NUM_MISCREGS are inconsistent.");
 
     // This mask selects bits of the CPSR that actually go in the CondCodes
     // integer register to allow renaming.
-    static const uint32_t CondCodesMask = 0xF80F0000;
-
-    BitUnion32(SCTLR)
-        Bitfield<31> ie;  // Instruction endianness
-        Bitfield<30> te;  // Thumb Exception Enable
-        Bitfield<29> afe; // Access flag enable
-        Bitfield<28> tre; // TEX Remap bit 
-        Bitfield<27> nmfi;// Non-maskable fast interrupts enable
-        Bitfield<25> ee;  // Exception Endianness bit
-        Bitfield<24> ve;  // Interrupt vectors enable
-        Bitfield<23> xp; //  Extended page table enable bit
-        Bitfield<22> u;   // Alignment (now unused)
-        Bitfield<21> fi;  // Fast interrupts configuration enable
-        Bitfield<19> dz;  // Divide by Zero fault enable bit
-        Bitfield<18> rao2;// Read as one
-        Bitfield<17> br;  // Background region bit
-        Bitfield<16> rao3;// Read as one
-        Bitfield<14> rr;  // Round robin cache replacement
-        Bitfield<13> v;   // Base address for exception vectors
-        Bitfield<12> i;   // instruction cache enable
-        Bitfield<11> z;   // branch prediction enable bit
-        Bitfield<10> sw;  // Enable swp/swpb
-        Bitfield<9,8> rs;   // deprecated protection bits
-        Bitfield<6,3> rao4;// Read as one
-        Bitfield<7>  b;   // Endianness support (unused)  
-        Bitfield<2>  c;   // Cache enable bit
-        Bitfield<1>  a;   // Alignment fault checking
-        Bitfield<0>  m;   // MMU enable bit 
-    EndBitUnion(SCTLR)
-
-    BitUnion32(CPACR)
-        Bitfield<1, 0> cp0;
-        Bitfield<3, 2> cp1;
-        Bitfield<5, 4> cp2;
-        Bitfield<7, 6> cp3;
-        Bitfield<9, 8> cp4;
-        Bitfield<11, 10> cp5;
-        Bitfield<13, 12> cp6;
-        Bitfield<15, 14> cp7;
-        Bitfield<17, 16> cp8;
-        Bitfield<19, 18> cp9;
-        Bitfield<21, 20> cp10;
-        Bitfield<23, 22> cp11;
-        Bitfield<25, 24> cp12;
-        Bitfield<27, 26> cp13;
-        Bitfield<29, 28> rsvd;
-        Bitfield<30> d32dis;
-        Bitfield<31> asedis;
-    EndBitUnion(CPACR)
-
-    BitUnion32(FSR)
-        Bitfield<3, 0> fsLow;
-        Bitfield<7, 4> domain;
-        Bitfield<10> fsHigh;
-        Bitfield<11> wnr;
-        Bitfield<12> ext;
-    EndBitUnion(FSR)
-
-    BitUnion32(FPSCR)
-        Bitfield<0> ioc;
-        Bitfield<1> dzc;
-        Bitfield<2> ofc;
-        Bitfield<3> ufc;
-        Bitfield<4> ixc;
-        Bitfield<7> idc;
-        Bitfield<8> ioe;
-        Bitfield<9> dze;
-        Bitfield<10> ofe;
-        Bitfield<11> ufe;
-        Bitfield<12> ixe;
-        Bitfield<15> ide;
-        Bitfield<18, 16> len;
-        Bitfield<21, 20> stride;
-        Bitfield<23, 22> rMode;
-        Bitfield<24> fz;
-        Bitfield<25> dn;
-        Bitfield<26> ahp;
-        Bitfield<27> qc;
-        Bitfield<28> v;
-        Bitfield<29> c;
-        Bitfield<30> z;
-        Bitfield<31> n;
-    EndBitUnion(FPSCR)
+    static const uint32_t CondCodesMask   = 0xF00F0000;
+    static const uint32_t CpsrMaskQ       = 0x08000000;
+
+    // APSR (Application Program Status Register Mask). It is the user level
+    // alias for the CPSR. The APSR is a subset of the CPSR. Although
+    // bits[15:0] are UNKNOWN on reads, it is permitted that, on a read of
+    // APSR:
+    // Bit[9] returns the value of CPSR.E.
+    // Bits[8:6] return the value of CPSR.{A,I, F}, the mask bits.
+    static const uint32_t ApsrMask = CpsrMaskQ | CondCodesMask | 0x000001D0;
+
+    // CPSR (Current Program Status Register Mask).
+    static const uint32_t CpsrMask = ApsrMask | 0x00F003DF;
 
     // This mask selects bits of the FPSCR that actually go in the FpCondCodes
     // integer register to allow renaming.
@@ -361,76 +1894,69 @@ namespace ArmISA
     // This mask selects the cumulative saturation flag of the FPSCR.
     static const uint32_t FpscrQcMask = 0x08000000;
 
-    BitUnion32(FPEXC)
-        Bitfield<31> ex;
-        Bitfield<30> en;
-        Bitfield<29, 0> subArchDefined;
-    EndBitUnion(FPEXC)
-
-    BitUnion32(MVFR0)
-        Bitfield<3, 0> advSimdRegisters;
-        Bitfield<7, 4> singlePrecision;
-        Bitfield<11, 8> doublePrecision;
-        Bitfield<15, 12> vfpExceptionTrapping;
-        Bitfield<19, 16> divide;
-        Bitfield<23, 20> squareRoot;
-        Bitfield<27, 24> shortVectors;
-        Bitfield<31, 28> roundingModes;
-    EndBitUnion(MVFR0)
-
-    BitUnion32(MVFR1)
-        Bitfield<3, 0> flushToZero;
-        Bitfield<7, 4> defaultNaN;
-        Bitfield<11, 8> advSimdLoadStore;
-        Bitfield<15, 12> advSimdInteger;
-        Bitfield<19, 16> advSimdSinglePrecision;
-        Bitfield<23, 20> advSimdHalfPrecision;
-        Bitfield<27, 24> vfpHalfPrecision;
-        Bitfield<31, 28> raz;
-    EndBitUnion(MVFR1)
-
-    BitUnion32(PRRR)
-       Bitfield<1,0> tr0;
-       Bitfield<3,2> tr1;
-       Bitfield<5,4> tr2;
-       Bitfield<7,6> tr3;
-       Bitfield<9,8> tr4;
-       Bitfield<11,10> tr5;
-       Bitfield<13,12> tr6;
-       Bitfield<15,14> tr7;
-       Bitfield<16> ds0;
-       Bitfield<17> ds1;
-       Bitfield<18> ns0;
-       Bitfield<19> ns1;
-       Bitfield<24> nos0;
-       Bitfield<25> nos1;
-       Bitfield<26> nos2;
-       Bitfield<27> nos3;
-       Bitfield<28> nos4;
-       Bitfield<29> nos5;
-       Bitfield<30> nos6;
-       Bitfield<31> nos7;
-   EndBitUnion(PRRR)
-
-   BitUnion32(NMRR)
-       Bitfield<1,0> ir0;
-       Bitfield<3,2> ir1;
-       Bitfield<5,4> ir2;
-       Bitfield<7,6> ir3;
-       Bitfield<9,8> ir4;
-       Bitfield<11,10> ir5;
-       Bitfield<13,12> ir6;
-       Bitfield<15,14> ir7;
-       Bitfield<17,16> or0;
-       Bitfield<19,18> or1;
-       Bitfield<21,20> or2;
-       Bitfield<23,22> or3;
-       Bitfield<25,24> or4;
-       Bitfield<27,26> or5;
-       Bitfield<29,28> or6;
-       Bitfield<31,30> or7;
-   EndBitUnion(NMRR)
-
-};
+    /**
+     * Check for permission to read coprocessor registers.
+     *
+     * Checks whether an instruction at the current program mode has
+     * permissions to read the coprocessor registers. This function
+     * returns whether the check is undefined and if not whether the
+     * read access is permitted.
+     *
+     * @param the misc reg indicating the coprocessor
+     * @param the SCR
+     * @param the CPSR
+     * @return a tuple of booleans: can_read, undefined
+     */
+    std::tuple<bool, bool> canReadCoprocReg(MiscRegIndex reg, SCR scr,
+                                           CPSR cpsr);
+
+    /**
+     * Check for permission to write coprocessor registers.
+     *
+     * Checks whether an instruction at the current program mode has
+     * permissions to write the coprocessor registers. This function
+     * returns whether the check is undefined and if not whether the
+     * write access is permitted.
+     *
+     * @param the misc reg indicating the coprocessor
+     * @param the SCR
+     * @param the CPSR
+     * @return a tuple of booleans: can_write, undefined
+     */
+    std::tuple<bool, bool> canWriteCoprocReg(MiscRegIndex reg, SCR scr,
+                                             CPSR cpsr);
+
+    // Checks read access permissions to AArch64 system registers
+    bool canReadAArch64SysReg(MiscRegIndex reg, SCR scr, CPSR cpsr,
+                              ThreadContext *tc);
+
+    // Checks write access permissions to AArch64 system registers
+    bool canWriteAArch64SysReg(MiscRegIndex reg, SCR scr, CPSR cpsr,
+                               ThreadContext *tc);
+
+    // Uses just the scr.ns bit to pre flatten the misc regs. This is useful
+    // for MCR/MRC instructions
+    int
+    snsBankedIndex(MiscRegIndex reg, ThreadContext *tc);
+
+    // Flattens a misc reg index using the specified security state. This is
+    // used for opperations (eg address translations) where the security
+    // state of the register access may differ from the current state of the
+    // processor
+    int
+    snsBankedIndex(MiscRegIndex reg, ThreadContext *tc, bool ns);
+
+    int
+    snsBankedIndex64(MiscRegIndex reg, ThreadContext *tc);
+
+    // Takes a misc reg index and returns the root reg if its one of a set of
+    // banked registers
+    void
+    preUnflattenMiscReg();
+
+    int
+    unflattenMiscReg(int reg);
+
+}
 
 #endif // __ARCH_ARM_MISCREGS_HH__