Use std::bitset for SubtargetFeatures.

Previously, subtarget features were a bitfield with the underlying type being uint64_t. 
Since several targets (X86 and ARM, in particular) have hit or were very close to hitting this bound, switching the features to use a bitset.
No functional change.

The first several times this was committed (e.g. r229831, r233055), it caused several buildbot failures.
Apparently the reason for most failures was both clang and gcc's inability to deal with large numbers (> 10K) of bitset constructor calls in tablegen-generated initializers of instruction info tables. 
This should now be fixed.

llvm-svn: 238192
diff --git a/llvm/lib/MC/MCInstrDesc.cpp b/llvm/lib/MC/MCInstrDesc.cpp
index 0f942cd..decc2d8 100644
--- a/llvm/lib/MC/MCInstrDesc.cpp
+++ b/llvm/lib/MC/MCInstrDesc.cpp
@@ -23,7 +23,7 @@
                                     std::string &Info) const {
   if (ComplexDeprecationInfo)
     return ComplexDeprecationInfo(MI, STI, Info);
-  if ((DeprecatedFeatureMask & STI.getFeatureBits()) != 0) {
+  if (DeprecatedFeature != -1 && STI.getFeatureBits()[DeprecatedFeature]) {
     // FIXME: it would be nice to include the subtarget feature here.
     Info = "deprecated";
     return true;
diff --git a/llvm/lib/MC/MCSubtargetInfo.cpp b/llvm/lib/MC/MCSubtargetInfo.cpp
index daba321..6abdd3a 100644
--- a/llvm/lib/MC/MCSubtargetInfo.cpp
+++ b/llvm/lib/MC/MCSubtargetInfo.cpp
@@ -63,14 +63,19 @@
 
 /// ToggleFeature - Toggle a feature and returns the re-computed feature
 /// bits. This version does not change the implied bits.
-uint64_t MCSubtargetInfo::ToggleFeature(uint64_t FB) {
+FeatureBitset MCSubtargetInfo::ToggleFeature(uint64_t FB) {
+  FeatureBits.flip(FB);
+  return FeatureBits;
+}
+
+FeatureBitset MCSubtargetInfo::ToggleFeature(const FeatureBitset &FB) {
   FeatureBits ^= FB;
   return FeatureBits;
 }
 
 /// ToggleFeature - Toggle a feature and returns the re-computed feature
 /// bits. This version will also change all implied bits.
-uint64_t MCSubtargetInfo::ToggleFeature(StringRef FS) {
+FeatureBitset MCSubtargetInfo::ToggleFeature(StringRef FS) {
   SubtargetFeatures Features;
   FeatureBits = Features.ToggleFeature(FeatureBits, FS, ProcFeatures);
   return FeatureBits;
diff --git a/llvm/lib/MC/SubtargetFeature.cpp b/llvm/lib/MC/SubtargetFeature.cpp
index 3880d88..78006e0 100644
--- a/llvm/lib/MC/SubtargetFeature.cpp
+++ b/llvm/lib/MC/SubtargetFeature.cpp
@@ -151,12 +151,12 @@
 /// feature, set it.
 ///
 static
-void SetImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry,
+void SetImpliedBits(FeatureBitset &Bits, const SubtargetFeatureKV *FeatureEntry,
                     ArrayRef<SubtargetFeatureKV> FeatureTable) {
   for (auto &FE : FeatureTable) {
     if (FeatureEntry->Value == FE.Value) continue;
 
-    if (FeatureEntry->Implies & FE.Value) {
+    if ((FeatureEntry->Implies & FE.Value).any()) {
       Bits |= FE.Value;
       SetImpliedBits(Bits, &FE, FeatureTable);
     }
@@ -167,12 +167,13 @@
 /// feature, clear it.
 ///
 static
-void ClearImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry,
+void ClearImpliedBits(FeatureBitset &Bits, 
+                      const SubtargetFeatureKV *FeatureEntry,
                       ArrayRef<SubtargetFeatureKV> FeatureTable) {
   for (auto &FE : FeatureTable) {
     if (FeatureEntry->Value == FE.Value) continue;
 
-    if (FE.Implies & FeatureEntry->Value) {
+    if ((FE.Implies & FeatureEntry->Value).any()) {
       Bits &= ~FE.Value;
       ClearImpliedBits(Bits, &FE, FeatureTable);
     }
@@ -181,8 +182,8 @@
 
 /// ToggleFeature - Toggle a feature and returns the newly updated feature
 /// bits.
-uint64_t
-SubtargetFeatures::ToggleFeature(uint64_t Bits, StringRef Feature,
+FeatureBitset
+SubtargetFeatures::ToggleFeature(FeatureBitset Bits, StringRef Feature,
                                  ArrayRef<SubtargetFeatureKV> FeatureTable) {
 
   // Find feature in table.
@@ -192,7 +193,6 @@
   if (FeatureEntry) {
     if ((Bits & FeatureEntry->Value) == FeatureEntry->Value) {
       Bits &= ~FeatureEntry->Value;
-
       // For each feature that implies this, clear it.
       ClearImpliedBits(Bits, FeatureEntry, FeatureTable);
     } else {
@@ -213,13 +213,13 @@
 
 /// getFeatureBits - Get feature bits a CPU.
 ///
-uint64_t
+FeatureBitset
 SubtargetFeatures::getFeatureBits(StringRef CPU,
                                   ArrayRef<SubtargetFeatureKV> CPUTable,
                                   ArrayRef<SubtargetFeatureKV> FeatureTable) {
 
   if (CPUTable.empty() || FeatureTable.empty())
-    return 0;
+    return FeatureBitset();
 
 #ifndef NDEBUG
   for (size_t i = 1, e = CPUTable.size(); i != e; ++i) {
@@ -231,7 +231,8 @@
           "CPU features table is not sorted");
   }
 #endif
-  uint64_t Bits = 0;                    // Resulting bits
+  // Resulting bits
+  FeatureBitset Bits;
 
   // Check if help is needed
   if (CPU == "help")
@@ -248,7 +249,7 @@
 
       // Set the feature implied by this CPU feature, if any.
       for (auto &FE : FeatureTable) {
-        if (CPUEntry->Value & FE.Value)
+        if ((CPUEntry->Value & FE.Value).any())
           SetImpliedBits(Bits, &FE, FeatureTable);
       }
     } else {
diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
index 0f71e97..28b8e7e 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
@@ -18,8 +18,8 @@
 
 using namespace llvm;
 
-StringRef AArch64NamedImmMapper::toString(uint32_t Value, uint64_t FeatureBits,
-                                          bool &Valid) const {
+StringRef AArch64NamedImmMapper::toString(uint32_t Value,
+          const FeatureBitset& FeatureBits, bool &Valid) const {
   for (unsigned i = 0; i < NumMappings; ++i) {
     if (Mappings[i].isValueEqual(Value, FeatureBits)) {
       Valid = true;
@@ -31,8 +31,8 @@
   return StringRef();
 }
 
-uint32_t AArch64NamedImmMapper::fromString(StringRef Name, uint64_t FeatureBits,
-                                           bool &Valid) const {
+uint32_t AArch64NamedImmMapper::fromString(StringRef Name,
+         const FeatureBitset& FeatureBits, bool &Valid) const {
   std::string LowerCaseName = Name.lower();
   for (unsigned i = 0; i < NumMappings; ++i) {
     if (Mappings[i].isNameEqual(LowerCaseName, FeatureBits)) {
@@ -50,207 +50,207 @@
 }
 
 const AArch64NamedImmMapper::Mapping AArch64AT::ATMapper::ATMappings[] = {
-  {"s1e1r", S1E1R, 0},
-  {"s1e2r", S1E2R, 0},
-  {"s1e3r", S1E3R, 0},
-  {"s1e1w", S1E1W, 0},
-  {"s1e2w", S1E2W, 0},
-  {"s1e3w", S1E3W, 0},
-  {"s1e0r", S1E0R, 0},
-  {"s1e0w", S1E0W, 0},
-  {"s12e1r", S12E1R, 0},
-  {"s12e1w", S12E1W, 0},
-  {"s12e0r", S12E0R, 0},
-  {"s12e0w", S12E0W, 0},
+  {"s1e1r", S1E1R, {}},
+  {"s1e2r", S1E2R, {}},
+  {"s1e3r", S1E3R, {}},
+  {"s1e1w", S1E1W, {}},
+  {"s1e2w", S1E2W, {}},
+  {"s1e3w", S1E3W, {}},
+  {"s1e0r", S1E0R, {}},
+  {"s1e0w", S1E0W, {}},
+  {"s12e1r", S12E1R, {}},
+  {"s12e1w", S12E1W, {}},
+  {"s12e0r", S12E0R, {}},
+  {"s12e0w", S12E0W, {}},
 };
 
 AArch64AT::ATMapper::ATMapper()
   : AArch64NamedImmMapper(ATMappings, 0) {}
 
 const AArch64NamedImmMapper::Mapping AArch64DB::DBarrierMapper::DBarrierMappings[] = {
-  {"oshld", OSHLD, 0},
-  {"oshst", OSHST, 0},
-  {"osh", OSH, 0},
-  {"nshld", NSHLD, 0},
-  {"nshst", NSHST, 0},
-  {"nsh", NSH, 0},
-  {"ishld", ISHLD, 0},
-  {"ishst", ISHST, 0},
-  {"ish", ISH, 0},
-  {"ld", LD, 0},
-  {"st", ST, 0},
-  {"sy", SY, 0}
+  {"oshld", OSHLD, {}},
+  {"oshst", OSHST, {}},
+  {"osh", OSH, {}},
+  {"nshld", NSHLD, {}},
+  {"nshst", NSHST, {}},
+  {"nsh", NSH, {}},
+  {"ishld", ISHLD, {}},
+  {"ishst", ISHST, {}},
+  {"ish", ISH, {}},
+  {"ld", LD, {}},
+  {"st", ST, {}},
+  {"sy", SY, {}}
 };
 
 AArch64DB::DBarrierMapper::DBarrierMapper()
   : AArch64NamedImmMapper(DBarrierMappings, 16u) {}
 
 const AArch64NamedImmMapper::Mapping AArch64DC::DCMapper::DCMappings[] = {
-  {"zva", ZVA, 0},
-  {"ivac", IVAC, 0},
-  {"isw", ISW, 0},
-  {"cvac", CVAC, 0},
-  {"csw", CSW, 0},
-  {"cvau", CVAU, 0},
-  {"civac", CIVAC, 0},
-  {"cisw", CISW, 0}
+  {"zva", ZVA, {}},
+  {"ivac", IVAC, {}},
+  {"isw", ISW, {}},
+  {"cvac", CVAC, {}},
+  {"csw", CSW, {}},
+  {"cvau", CVAU, {}},
+  {"civac", CIVAC, {}},
+  {"cisw", CISW, {}}
 };
 
 AArch64DC::DCMapper::DCMapper()
   : AArch64NamedImmMapper(DCMappings, 0) {}
 
 const AArch64NamedImmMapper::Mapping AArch64IC::ICMapper::ICMappings[] = {
-  {"ialluis",  IALLUIS, 0},
-  {"iallu", IALLU, 0},
-  {"ivau", IVAU, 0}
+  {"ialluis",  IALLUIS, {}},
+  {"iallu", IALLU, {}},
+  {"ivau", IVAU, {}}
 };
 
 AArch64IC::ICMapper::ICMapper()
   : AArch64NamedImmMapper(ICMappings, 0) {}
 
 const AArch64NamedImmMapper::Mapping AArch64ISB::ISBMapper::ISBMappings[] = {
-  {"sy",  SY, 0},
+  {"sy",  SY, {}},
 };
 
 AArch64ISB::ISBMapper::ISBMapper()
   : AArch64NamedImmMapper(ISBMappings, 16) {}
 
 const AArch64NamedImmMapper::Mapping AArch64PRFM::PRFMMapper::PRFMMappings[] = {
-  {"pldl1keep", PLDL1KEEP, 0},
-  {"pldl1strm", PLDL1STRM, 0},
-  {"pldl2keep", PLDL2KEEP, 0},
-  {"pldl2strm", PLDL2STRM, 0},
-  {"pldl3keep", PLDL3KEEP, 0},
-  {"pldl3strm", PLDL3STRM, 0},
-  {"plil1keep", PLIL1KEEP, 0},
-  {"plil1strm", PLIL1STRM, 0},
-  {"plil2keep", PLIL2KEEP, 0},
-  {"plil2strm", PLIL2STRM, 0},
-  {"plil3keep", PLIL3KEEP, 0},
-  {"plil3strm", PLIL3STRM, 0},
-  {"pstl1keep", PSTL1KEEP, 0},
-  {"pstl1strm", PSTL1STRM, 0},
-  {"pstl2keep", PSTL2KEEP, 0},
-  {"pstl2strm", PSTL2STRM, 0},
-  {"pstl3keep", PSTL3KEEP, 0},
-  {"pstl3strm", PSTL3STRM, 0}
+  {"pldl1keep", PLDL1KEEP, {}},
+  {"pldl1strm", PLDL1STRM, {}},
+  {"pldl2keep", PLDL2KEEP, {}},
+  {"pldl2strm", PLDL2STRM, {}},
+  {"pldl3keep", PLDL3KEEP, {}},
+  {"pldl3strm", PLDL3STRM, {}},
+  {"plil1keep", PLIL1KEEP, {}},
+  {"plil1strm", PLIL1STRM, {}},
+  {"plil2keep", PLIL2KEEP, {}},
+  {"plil2strm", PLIL2STRM, {}},
+  {"plil3keep", PLIL3KEEP, {}},
+  {"plil3strm", PLIL3STRM, {}},
+  {"pstl1keep", PSTL1KEEP, {}},
+  {"pstl1strm", PSTL1STRM, {}},
+  {"pstl2keep", PSTL2KEEP, {}},
+  {"pstl2strm", PSTL2STRM, {}},
+  {"pstl3keep", PSTL3KEEP, {}},
+  {"pstl3strm", PSTL3STRM, {}}
 };
 
 AArch64PRFM::PRFMMapper::PRFMMapper()
   : AArch64NamedImmMapper(PRFMMappings, 32) {}
 
 const AArch64NamedImmMapper::Mapping AArch64PState::PStateMapper::PStateMappings[] = {
-  {"spsel", SPSel, 0},
-  {"daifset", DAIFSet, 0},
-  {"daifclr", DAIFClr, 0},
+  {"spsel", SPSel, {}},
+  {"daifset", DAIFSet, {}},
+  {"daifclr", DAIFClr, {}},
 
   // v8.1a "Privileged Access Never" extension-specific PStates
-  {"pan", PAN, AArch64::HasV8_1aOps},
+  {"pan", PAN, {AArch64::HasV8_1aOps}},
 };
 
 AArch64PState::PStateMapper::PStateMapper()
   : AArch64NamedImmMapper(PStateMappings, 0) {}
 
 const AArch64NamedImmMapper::Mapping AArch64SysReg::MRSMapper::MRSMappings[] = {
-  {"mdccsr_el0", MDCCSR_EL0, 0},
-  {"dbgdtrrx_el0", DBGDTRRX_EL0, 0},
-  {"mdrar_el1", MDRAR_EL1, 0},
-  {"oslsr_el1", OSLSR_EL1, 0},
-  {"dbgauthstatus_el1", DBGAUTHSTATUS_EL1, 0},
-  {"pmceid0_el0", PMCEID0_EL0, 0},
-  {"pmceid1_el0", PMCEID1_EL0, 0},
-  {"midr_el1", MIDR_EL1, 0},
-  {"ccsidr_el1", CCSIDR_EL1, 0},
-  {"clidr_el1", CLIDR_EL1, 0},
-  {"ctr_el0", CTR_EL0, 0},
-  {"mpidr_el1", MPIDR_EL1, 0},
-  {"revidr_el1", REVIDR_EL1, 0},
-  {"aidr_el1", AIDR_EL1, 0},
-  {"dczid_el0", DCZID_EL0, 0},
-  {"id_pfr0_el1", ID_PFR0_EL1, 0},
-  {"id_pfr1_el1", ID_PFR1_EL1, 0},
-  {"id_dfr0_el1", ID_DFR0_EL1, 0},
-  {"id_afr0_el1", ID_AFR0_EL1, 0},
-  {"id_mmfr0_el1", ID_MMFR0_EL1, 0},
-  {"id_mmfr1_el1", ID_MMFR1_EL1, 0},
-  {"id_mmfr2_el1", ID_MMFR2_EL1, 0},
-  {"id_mmfr3_el1", ID_MMFR3_EL1, 0},
-  {"id_isar0_el1", ID_ISAR0_EL1, 0},
-  {"id_isar1_el1", ID_ISAR1_EL1, 0},
-  {"id_isar2_el1", ID_ISAR2_EL1, 0},
-  {"id_isar3_el1", ID_ISAR3_EL1, 0},
-  {"id_isar4_el1", ID_ISAR4_EL1, 0},
-  {"id_isar5_el1", ID_ISAR5_EL1, 0},
-  {"id_aa64pfr0_el1", ID_A64PFR0_EL1, 0},
-  {"id_aa64pfr1_el1", ID_A64PFR1_EL1, 0},
-  {"id_aa64dfr0_el1", ID_A64DFR0_EL1, 0},
-  {"id_aa64dfr1_el1", ID_A64DFR1_EL1, 0},
-  {"id_aa64afr0_el1", ID_A64AFR0_EL1, 0},
-  {"id_aa64afr1_el1", ID_A64AFR1_EL1, 0},
-  {"id_aa64isar0_el1", ID_A64ISAR0_EL1, 0},
-  {"id_aa64isar1_el1", ID_A64ISAR1_EL1, 0},
-  {"id_aa64mmfr0_el1", ID_A64MMFR0_EL1, 0},
-  {"id_aa64mmfr1_el1", ID_A64MMFR1_EL1, 0},
-  {"mvfr0_el1", MVFR0_EL1, 0},
-  {"mvfr1_el1", MVFR1_EL1, 0},
-  {"mvfr2_el1", MVFR2_EL1, 0},
-  {"rvbar_el1", RVBAR_EL1, 0},
-  {"rvbar_el2", RVBAR_EL2, 0},
-  {"rvbar_el3", RVBAR_EL3, 0},
-  {"isr_el1", ISR_EL1, 0},
-  {"cntpct_el0", CNTPCT_EL0, 0},
-  {"cntvct_el0", CNTVCT_EL0, 0},
+  {"mdccsr_el0", MDCCSR_EL0, {}},
+  {"dbgdtrrx_el0", DBGDTRRX_EL0, {}},
+  {"mdrar_el1", MDRAR_EL1, {}},
+  {"oslsr_el1", OSLSR_EL1, {}},
+  {"dbgauthstatus_el1", DBGAUTHSTATUS_EL1, {}},
+  {"pmceid0_el0", PMCEID0_EL0, {}},
+  {"pmceid1_el0", PMCEID1_EL0, {}},
+  {"midr_el1", MIDR_EL1, {}},
+  {"ccsidr_el1", CCSIDR_EL1, {}},
+  {"clidr_el1", CLIDR_EL1, {}},
+  {"ctr_el0", CTR_EL0, {}},
+  {"mpidr_el1", MPIDR_EL1, {}},
+  {"revidr_el1", REVIDR_EL1, {}},
+  {"aidr_el1", AIDR_EL1, {}},
+  {"dczid_el0", DCZID_EL0, {}},
+  {"id_pfr0_el1", ID_PFR0_EL1, {}},
+  {"id_pfr1_el1", ID_PFR1_EL1, {}},
+  {"id_dfr0_el1", ID_DFR0_EL1, {}},
+  {"id_afr0_el1", ID_AFR0_EL1, {}},
+  {"id_mmfr0_el1", ID_MMFR0_EL1, {}},
+  {"id_mmfr1_el1", ID_MMFR1_EL1, {}},
+  {"id_mmfr2_el1", ID_MMFR2_EL1, {}},
+  {"id_mmfr3_el1", ID_MMFR3_EL1, {}},
+  {"id_isar0_el1", ID_ISAR0_EL1, {}},
+  {"id_isar1_el1", ID_ISAR1_EL1, {}},
+  {"id_isar2_el1", ID_ISAR2_EL1, {}},
+  {"id_isar3_el1", ID_ISAR3_EL1, {}},
+  {"id_isar4_el1", ID_ISAR4_EL1, {}},
+  {"id_isar5_el1", ID_ISAR5_EL1, {}},
+  {"id_aa64pfr0_el1", ID_A64PFR0_EL1, {}},
+  {"id_aa64pfr1_el1", ID_A64PFR1_EL1, {}},
+  {"id_aa64dfr0_el1", ID_A64DFR0_EL1, {}},
+  {"id_aa64dfr1_el1", ID_A64DFR1_EL1, {}},
+  {"id_aa64afr0_el1", ID_A64AFR0_EL1, {}},
+  {"id_aa64afr1_el1", ID_A64AFR1_EL1, {}},
+  {"id_aa64isar0_el1", ID_A64ISAR0_EL1, {}},
+  {"id_aa64isar1_el1", ID_A64ISAR1_EL1, {}},
+  {"id_aa64mmfr0_el1", ID_A64MMFR0_EL1, {}},
+  {"id_aa64mmfr1_el1", ID_A64MMFR1_EL1, {}},
+  {"mvfr0_el1", MVFR0_EL1, {}},
+  {"mvfr1_el1", MVFR1_EL1, {}},
+  {"mvfr2_el1", MVFR2_EL1, {}},
+  {"rvbar_el1", RVBAR_EL1, {}},
+  {"rvbar_el2", RVBAR_EL2, {}},
+  {"rvbar_el3", RVBAR_EL3, {}},
+  {"isr_el1", ISR_EL1, {}},
+  {"cntpct_el0", CNTPCT_EL0, {}},
+  {"cntvct_el0", CNTVCT_EL0, {}},
 
   // Trace registers
-  {"trcstatr", TRCSTATR, 0},
-  {"trcidr8", TRCIDR8, 0},
-  {"trcidr9", TRCIDR9, 0},
-  {"trcidr10", TRCIDR10, 0},
-  {"trcidr11", TRCIDR11, 0},
-  {"trcidr12", TRCIDR12, 0},
-  {"trcidr13", TRCIDR13, 0},
-  {"trcidr0", TRCIDR0, 0},
-  {"trcidr1", TRCIDR1, 0},
-  {"trcidr2", TRCIDR2, 0},
-  {"trcidr3", TRCIDR3, 0},
-  {"trcidr4", TRCIDR4, 0},
-  {"trcidr5", TRCIDR5, 0},
-  {"trcidr6", TRCIDR6, 0},
-  {"trcidr7", TRCIDR7, 0},
-  {"trcoslsr", TRCOSLSR, 0},
-  {"trcpdsr", TRCPDSR, 0},
-  {"trcdevaff0", TRCDEVAFF0, 0},
-  {"trcdevaff1", TRCDEVAFF1, 0},
-  {"trclsr", TRCLSR, 0},
-  {"trcauthstatus", TRCAUTHSTATUS, 0},
-  {"trcdevarch", TRCDEVARCH, 0},
-  {"trcdevid", TRCDEVID, 0},
-  {"trcdevtype", TRCDEVTYPE, 0},
-  {"trcpidr4", TRCPIDR4, 0},
-  {"trcpidr5", TRCPIDR5, 0},
-  {"trcpidr6", TRCPIDR6, 0},
-  {"trcpidr7", TRCPIDR7, 0},
-  {"trcpidr0", TRCPIDR0, 0},
-  {"trcpidr1", TRCPIDR1, 0},
-  {"trcpidr2", TRCPIDR2, 0},
-  {"trcpidr3", TRCPIDR3, 0},
-  {"trccidr0", TRCCIDR0, 0},
-  {"trccidr1", TRCCIDR1, 0},
-  {"trccidr2", TRCCIDR2, 0},
-  {"trccidr3", TRCCIDR3, 0},
+  {"trcstatr", TRCSTATR, {}},
+  {"trcidr8", TRCIDR8, {}},
+  {"trcidr9", TRCIDR9, {}},
+  {"trcidr10", TRCIDR10, {}},
+  {"trcidr11", TRCIDR11, {}},
+  {"trcidr12", TRCIDR12, {}},
+  {"trcidr13", TRCIDR13, {}},
+  {"trcidr0", TRCIDR0, {}},
+  {"trcidr1", TRCIDR1, {}},
+  {"trcidr2", TRCIDR2, {}},
+  {"trcidr3", TRCIDR3, {}},
+  {"trcidr4", TRCIDR4, {}},
+  {"trcidr5", TRCIDR5, {}},
+  {"trcidr6", TRCIDR6, {}},
+  {"trcidr7", TRCIDR7, {}},
+  {"trcoslsr", TRCOSLSR, {}},
+  {"trcpdsr", TRCPDSR, {}},
+  {"trcdevaff0", TRCDEVAFF0, {}},
+  {"trcdevaff1", TRCDEVAFF1, {}},
+  {"trclsr", TRCLSR, {}},
+  {"trcauthstatus", TRCAUTHSTATUS, {}},
+  {"trcdevarch", TRCDEVARCH, {}},
+  {"trcdevid", TRCDEVID, {}},
+  {"trcdevtype", TRCDEVTYPE, {}},
+  {"trcpidr4", TRCPIDR4, {}},
+  {"trcpidr5", TRCPIDR5, {}},
+  {"trcpidr6", TRCPIDR6, {}},
+  {"trcpidr7", TRCPIDR7, {}},
+  {"trcpidr0", TRCPIDR0, {}},
+  {"trcpidr1", TRCPIDR1, {}},
+  {"trcpidr2", TRCPIDR2, {}},
+  {"trcpidr3", TRCPIDR3, {}},
+  {"trccidr0", TRCCIDR0, {}},
+  {"trccidr1", TRCCIDR1, {}},
+  {"trccidr2", TRCCIDR2, {}},
+  {"trccidr3", TRCCIDR3, {}},
 
   // GICv3 registers
-  {"icc_iar1_el1", ICC_IAR1_EL1, 0},
-  {"icc_iar0_el1", ICC_IAR0_EL1, 0},
-  {"icc_hppir1_el1", ICC_HPPIR1_EL1, 0},
-  {"icc_hppir0_el1", ICC_HPPIR0_EL1, 0},
-  {"icc_rpr_el1", ICC_RPR_EL1, 0},
-  {"ich_vtr_el2", ICH_VTR_EL2, 0},
-  {"ich_eisr_el2", ICH_EISR_EL2, 0},
-  {"ich_elsr_el2", ICH_ELSR_EL2, 0},
+  {"icc_iar1_el1", ICC_IAR1_EL1, {}},
+  {"icc_iar0_el1", ICC_IAR0_EL1, {}},
+  {"icc_hppir1_el1", ICC_HPPIR1_EL1, {}},
+  {"icc_hppir0_el1", ICC_HPPIR0_EL1, {}},
+  {"icc_rpr_el1", ICC_RPR_EL1, {}},
+  {"ich_vtr_el2", ICH_VTR_EL2, {}},
+  {"ich_eisr_el2", ICH_EISR_EL2, {}},
+  {"ich_elsr_el2", ICH_ELSR_EL2, {}},
 
   // v8.1a "Limited Ordering Regions" extension-specific system registers
-  {"lorid_el1", LORID_EL1, AArch64::HasV8_1aOps},
+  {"lorid_el1", LORID_EL1, {AArch64::HasV8_1aOps}},
 };
 
 AArch64SysReg::MRSMapper::MRSMapper() {
@@ -259,24 +259,24 @@
 }
 
 const AArch64NamedImmMapper::Mapping AArch64SysReg::MSRMapper::MSRMappings[] = {
-  {"dbgdtrtx_el0", DBGDTRTX_EL0, 0},
-  {"oslar_el1", OSLAR_EL1, 0},
-  {"pmswinc_el0", PMSWINC_EL0, 0},
+  {"dbgdtrtx_el0", DBGDTRTX_EL0, {}},
+  {"oslar_el1", OSLAR_EL1, {}},
+  {"pmswinc_el0", PMSWINC_EL0, {}},
 
   // Trace registers
-  {"trcoslar", TRCOSLAR, 0},
-  {"trclar", TRCLAR, 0},
+  {"trcoslar", TRCOSLAR, {}},
+  {"trclar", TRCLAR, {}},
 
   // GICv3 registers
-  {"icc_eoir1_el1", ICC_EOIR1_EL1, 0},
-  {"icc_eoir0_el1", ICC_EOIR0_EL1, 0},
-  {"icc_dir_el1", ICC_DIR_EL1, 0},
-  {"icc_sgi1r_el1", ICC_SGI1R_EL1, 0},
-  {"icc_asgi1r_el1", ICC_ASGI1R_EL1, 0},
-  {"icc_sgi0r_el1", ICC_SGI0R_EL1, 0},
+  {"icc_eoir1_el1", ICC_EOIR1_EL1, {}},
+  {"icc_eoir0_el1", ICC_EOIR0_EL1, {}},
+  {"icc_dir_el1", ICC_DIR_EL1, {}},
+  {"icc_sgi1r_el1", ICC_SGI1R_EL1, {}},
+  {"icc_asgi1r_el1", ICC_ASGI1R_EL1, {}},
+  {"icc_sgi0r_el1", ICC_SGI0R_EL1, {}},
 
   // v8.1a "Privileged Access Never" extension-specific system registers
-  {"pan", PAN, AArch64::HasV8_1aOps},
+  {"pan", PAN, {AArch64::HasV8_1aOps}},
 };
 
 AArch64SysReg::MSRMapper::MSRMapper() {
@@ -286,528 +286,528 @@
 
 
 const AArch64NamedImmMapper::Mapping AArch64SysReg::SysRegMapper::SysRegMappings[] = {
-  {"osdtrrx_el1", OSDTRRX_EL1, 0},
-  {"osdtrtx_el1",  OSDTRTX_EL1, 0},
-  {"teecr32_el1", TEECR32_EL1, 0},
-  {"mdccint_el1", MDCCINT_EL1, 0},
-  {"mdscr_el1", MDSCR_EL1, 0},
-  {"dbgdtr_el0", DBGDTR_EL0, 0},
-  {"oseccr_el1", OSECCR_EL1, 0},
-  {"dbgvcr32_el2", DBGVCR32_EL2, 0},
-  {"dbgbvr0_el1", DBGBVR0_EL1, 0},
-  {"dbgbvr1_el1", DBGBVR1_EL1, 0},
-  {"dbgbvr2_el1", DBGBVR2_EL1, 0},
-  {"dbgbvr3_el1", DBGBVR3_EL1, 0},
-  {"dbgbvr4_el1", DBGBVR4_EL1, 0},
-  {"dbgbvr5_el1", DBGBVR5_EL1, 0},
-  {"dbgbvr6_el1", DBGBVR6_EL1, 0},
-  {"dbgbvr7_el1", DBGBVR7_EL1, 0},
-  {"dbgbvr8_el1", DBGBVR8_EL1, 0},
-  {"dbgbvr9_el1", DBGBVR9_EL1, 0},
-  {"dbgbvr10_el1", DBGBVR10_EL1, 0},
-  {"dbgbvr11_el1", DBGBVR11_EL1, 0},
-  {"dbgbvr12_el1", DBGBVR12_EL1, 0},
-  {"dbgbvr13_el1", DBGBVR13_EL1, 0},
-  {"dbgbvr14_el1", DBGBVR14_EL1, 0},
-  {"dbgbvr15_el1", DBGBVR15_EL1, 0},
-  {"dbgbcr0_el1", DBGBCR0_EL1, 0},
-  {"dbgbcr1_el1", DBGBCR1_EL1, 0},
-  {"dbgbcr2_el1", DBGBCR2_EL1, 0},
-  {"dbgbcr3_el1", DBGBCR3_EL1, 0},
-  {"dbgbcr4_el1", DBGBCR4_EL1, 0},
-  {"dbgbcr5_el1", DBGBCR5_EL1, 0},
-  {"dbgbcr6_el1", DBGBCR6_EL1, 0},
-  {"dbgbcr7_el1", DBGBCR7_EL1, 0},
-  {"dbgbcr8_el1", DBGBCR8_EL1, 0},
-  {"dbgbcr9_el1", DBGBCR9_EL1, 0},
-  {"dbgbcr10_el1", DBGBCR10_EL1, 0},
-  {"dbgbcr11_el1", DBGBCR11_EL1, 0},
-  {"dbgbcr12_el1", DBGBCR12_EL1, 0},
-  {"dbgbcr13_el1", DBGBCR13_EL1, 0},
-  {"dbgbcr14_el1", DBGBCR14_EL1, 0},
-  {"dbgbcr15_el1", DBGBCR15_EL1, 0},
-  {"dbgwvr0_el1", DBGWVR0_EL1, 0},
-  {"dbgwvr1_el1", DBGWVR1_EL1, 0},
-  {"dbgwvr2_el1", DBGWVR2_EL1, 0},
-  {"dbgwvr3_el1", DBGWVR3_EL1, 0},
-  {"dbgwvr4_el1", DBGWVR4_EL1, 0},
-  {"dbgwvr5_el1", DBGWVR5_EL1, 0},
-  {"dbgwvr6_el1", DBGWVR6_EL1, 0},
-  {"dbgwvr7_el1", DBGWVR7_EL1, 0},
-  {"dbgwvr8_el1", DBGWVR8_EL1, 0},
-  {"dbgwvr9_el1", DBGWVR9_EL1, 0},
-  {"dbgwvr10_el1", DBGWVR10_EL1, 0},
-  {"dbgwvr11_el1", DBGWVR11_EL1, 0},
-  {"dbgwvr12_el1", DBGWVR12_EL1, 0},
-  {"dbgwvr13_el1", DBGWVR13_EL1, 0},
-  {"dbgwvr14_el1", DBGWVR14_EL1, 0},
-  {"dbgwvr15_el1", DBGWVR15_EL1, 0},
-  {"dbgwcr0_el1", DBGWCR0_EL1, 0},
-  {"dbgwcr1_el1", DBGWCR1_EL1, 0},
-  {"dbgwcr2_el1", DBGWCR2_EL1, 0},
-  {"dbgwcr3_el1", DBGWCR3_EL1, 0},
-  {"dbgwcr4_el1", DBGWCR4_EL1, 0},
-  {"dbgwcr5_el1", DBGWCR5_EL1, 0},
-  {"dbgwcr6_el1", DBGWCR6_EL1, 0},
-  {"dbgwcr7_el1", DBGWCR7_EL1, 0},
-  {"dbgwcr8_el1", DBGWCR8_EL1, 0},
-  {"dbgwcr9_el1", DBGWCR9_EL1, 0},
-  {"dbgwcr10_el1", DBGWCR10_EL1, 0},
-  {"dbgwcr11_el1", DBGWCR11_EL1, 0},
-  {"dbgwcr12_el1", DBGWCR12_EL1, 0},
-  {"dbgwcr13_el1", DBGWCR13_EL1, 0},
-  {"dbgwcr14_el1", DBGWCR14_EL1, 0},
-  {"dbgwcr15_el1", DBGWCR15_EL1, 0},
-  {"teehbr32_el1", TEEHBR32_EL1, 0},
-  {"osdlr_el1", OSDLR_EL1, 0},
-  {"dbgprcr_el1", DBGPRCR_EL1, 0},
-  {"dbgclaimset_el1", DBGCLAIMSET_EL1, 0},
-  {"dbgclaimclr_el1", DBGCLAIMCLR_EL1, 0},
-  {"csselr_el1", CSSELR_EL1, 0},
-  {"vpidr_el2", VPIDR_EL2, 0},
-  {"vmpidr_el2", VMPIDR_EL2, 0},
-  {"sctlr_el1", SCTLR_EL1, 0},
-  {"sctlr_el2", SCTLR_EL2, 0},
-  {"sctlr_el3", SCTLR_EL3, 0},
-  {"actlr_el1", ACTLR_EL1, 0},
-  {"actlr_el2", ACTLR_EL2, 0},
-  {"actlr_el3", ACTLR_EL3, 0},
-  {"cpacr_el1", CPACR_EL1, 0},
-  {"hcr_el2", HCR_EL2, 0},
-  {"scr_el3", SCR_EL3, 0},
-  {"mdcr_el2", MDCR_EL2, 0},
-  {"sder32_el3", SDER32_EL3, 0},
-  {"cptr_el2", CPTR_EL2, 0},
-  {"cptr_el3", CPTR_EL3, 0},
-  {"hstr_el2", HSTR_EL2, 0},
-  {"hacr_el2", HACR_EL2, 0},
-  {"mdcr_el3", MDCR_EL3, 0},
-  {"ttbr0_el1", TTBR0_EL1, 0},
-  {"ttbr0_el2", TTBR0_EL2, 0},
-  {"ttbr0_el3", TTBR0_EL3, 0},
-  {"ttbr1_el1", TTBR1_EL1, 0},
-  {"tcr_el1", TCR_EL1, 0},
-  {"tcr_el2", TCR_EL2, 0},
-  {"tcr_el3", TCR_EL3, 0},
-  {"vttbr_el2", VTTBR_EL2, 0},
-  {"vtcr_el2", VTCR_EL2, 0},
-  {"dacr32_el2", DACR32_EL2, 0},
-  {"spsr_el1", SPSR_EL1, 0},
-  {"spsr_el2", SPSR_EL2, 0},
-  {"spsr_el3", SPSR_EL3, 0},
-  {"elr_el1", ELR_EL1, 0},
-  {"elr_el2", ELR_EL2, 0},
-  {"elr_el3", ELR_EL3, 0},
-  {"sp_el0", SP_EL0, 0},
-  {"sp_el1", SP_EL1, 0},
-  {"sp_el2", SP_EL2, 0},
-  {"spsel", SPSel, 0},
-  {"nzcv", NZCV, 0},
-  {"daif", DAIF, 0},
-  {"currentel", CurrentEL, 0},
-  {"spsr_irq", SPSR_irq, 0},
-  {"spsr_abt", SPSR_abt, 0},
-  {"spsr_und", SPSR_und, 0},
-  {"spsr_fiq", SPSR_fiq, 0},
-  {"fpcr", FPCR, 0},
-  {"fpsr", FPSR, 0},
-  {"dspsr_el0", DSPSR_EL0, 0},
-  {"dlr_el0", DLR_EL0, 0},
-  {"ifsr32_el2", IFSR32_EL2, 0},
-  {"afsr0_el1", AFSR0_EL1, 0},
-  {"afsr0_el2", AFSR0_EL2, 0},
-  {"afsr0_el3", AFSR0_EL3, 0},
-  {"afsr1_el1", AFSR1_EL1, 0},
-  {"afsr1_el2", AFSR1_EL2, 0},
-  {"afsr1_el3", AFSR1_EL3, 0},
-  {"esr_el1", ESR_EL1, 0},
-  {"esr_el2", ESR_EL2, 0},
-  {"esr_el3", ESR_EL3, 0},
-  {"fpexc32_el2", FPEXC32_EL2, 0},
-  {"far_el1", FAR_EL1, 0},
-  {"far_el2", FAR_EL2, 0},
-  {"far_el3", FAR_EL3, 0},
-  {"hpfar_el2", HPFAR_EL2, 0},
-  {"par_el1", PAR_EL1, 0},
-  {"pmcr_el0", PMCR_EL0, 0},
-  {"pmcntenset_el0", PMCNTENSET_EL0, 0},
-  {"pmcntenclr_el0", PMCNTENCLR_EL0, 0},
-  {"pmovsclr_el0", PMOVSCLR_EL0, 0},
-  {"pmselr_el0", PMSELR_EL0, 0},
-  {"pmccntr_el0", PMCCNTR_EL0, 0},
-  {"pmxevtyper_el0", PMXEVTYPER_EL0, 0},
-  {"pmxevcntr_el0", PMXEVCNTR_EL0, 0},
-  {"pmuserenr_el0", PMUSERENR_EL0, 0},
-  {"pmintenset_el1", PMINTENSET_EL1, 0},
-  {"pmintenclr_el1", PMINTENCLR_EL1, 0},
-  {"pmovsset_el0", PMOVSSET_EL0, 0},
-  {"mair_el1", MAIR_EL1, 0},
-  {"mair_el2", MAIR_EL2, 0},
-  {"mair_el3", MAIR_EL3, 0},
-  {"amair_el1", AMAIR_EL1, 0},
-  {"amair_el2", AMAIR_EL2, 0},
-  {"amair_el3", AMAIR_EL3, 0},
-  {"vbar_el1", VBAR_EL1, 0},
-  {"vbar_el2", VBAR_EL2, 0},
-  {"vbar_el3", VBAR_EL3, 0},
-  {"rmr_el1", RMR_EL1, 0},
-  {"rmr_el2", RMR_EL2, 0},
-  {"rmr_el3", RMR_EL3, 0},
-  {"contextidr_el1", CONTEXTIDR_EL1, 0},
-  {"tpidr_el0", TPIDR_EL0, 0},
-  {"tpidr_el2", TPIDR_EL2, 0},
-  {"tpidr_el3", TPIDR_EL3, 0},
-  {"tpidrro_el0", TPIDRRO_EL0, 0},
-  {"tpidr_el1", TPIDR_EL1, 0},
-  {"cntfrq_el0", CNTFRQ_EL0, 0},
-  {"cntvoff_el2", CNTVOFF_EL2, 0},
-  {"cntkctl_el1", CNTKCTL_EL1, 0},
-  {"cnthctl_el2", CNTHCTL_EL2, 0},
-  {"cntp_tval_el0", CNTP_TVAL_EL0, 0},
-  {"cnthp_tval_el2", CNTHP_TVAL_EL2, 0},
-  {"cntps_tval_el1", CNTPS_TVAL_EL1, 0},
-  {"cntp_ctl_el0", CNTP_CTL_EL0, 0},
-  {"cnthp_ctl_el2", CNTHP_CTL_EL2, 0},
-  {"cntps_ctl_el1", CNTPS_CTL_EL1, 0},
-  {"cntp_cval_el0", CNTP_CVAL_EL0, 0},
-  {"cnthp_cval_el2", CNTHP_CVAL_EL2, 0},
-  {"cntps_cval_el1", CNTPS_CVAL_EL1, 0},
-  {"cntv_tval_el0", CNTV_TVAL_EL0, 0},
-  {"cntv_ctl_el0", CNTV_CTL_EL0, 0},
-  {"cntv_cval_el0", CNTV_CVAL_EL0, 0},
-  {"pmevcntr0_el0", PMEVCNTR0_EL0, 0},
-  {"pmevcntr1_el0", PMEVCNTR1_EL0, 0},
-  {"pmevcntr2_el0", PMEVCNTR2_EL0, 0},
-  {"pmevcntr3_el0", PMEVCNTR3_EL0, 0},
-  {"pmevcntr4_el0", PMEVCNTR4_EL0, 0},
-  {"pmevcntr5_el0", PMEVCNTR5_EL0, 0},
-  {"pmevcntr6_el0", PMEVCNTR6_EL0, 0},
-  {"pmevcntr7_el0", PMEVCNTR7_EL0, 0},
-  {"pmevcntr8_el0", PMEVCNTR8_EL0, 0},
-  {"pmevcntr9_el0", PMEVCNTR9_EL0, 0},
-  {"pmevcntr10_el0", PMEVCNTR10_EL0, 0},
-  {"pmevcntr11_el0", PMEVCNTR11_EL0, 0},
-  {"pmevcntr12_el0", PMEVCNTR12_EL0, 0},
-  {"pmevcntr13_el0", PMEVCNTR13_EL0, 0},
-  {"pmevcntr14_el0", PMEVCNTR14_EL0, 0},
-  {"pmevcntr15_el0", PMEVCNTR15_EL0, 0},
-  {"pmevcntr16_el0", PMEVCNTR16_EL0, 0},
-  {"pmevcntr17_el0", PMEVCNTR17_EL0, 0},
-  {"pmevcntr18_el0", PMEVCNTR18_EL0, 0},
-  {"pmevcntr19_el0", PMEVCNTR19_EL0, 0},
-  {"pmevcntr20_el0", PMEVCNTR20_EL0, 0},
-  {"pmevcntr21_el0", PMEVCNTR21_EL0, 0},
-  {"pmevcntr22_el0", PMEVCNTR22_EL0, 0},
-  {"pmevcntr23_el0", PMEVCNTR23_EL0, 0},
-  {"pmevcntr24_el0", PMEVCNTR24_EL0, 0},
-  {"pmevcntr25_el0", PMEVCNTR25_EL0, 0},
-  {"pmevcntr26_el0", PMEVCNTR26_EL0, 0},
-  {"pmevcntr27_el0", PMEVCNTR27_EL0, 0},
-  {"pmevcntr28_el0", PMEVCNTR28_EL0, 0},
-  {"pmevcntr29_el0", PMEVCNTR29_EL0, 0},
-  {"pmevcntr30_el0", PMEVCNTR30_EL0, 0},
-  {"pmccfiltr_el0", PMCCFILTR_EL0, 0},
-  {"pmevtyper0_el0", PMEVTYPER0_EL0, 0},
-  {"pmevtyper1_el0", PMEVTYPER1_EL0, 0},
-  {"pmevtyper2_el0", PMEVTYPER2_EL0, 0},
-  {"pmevtyper3_el0", PMEVTYPER3_EL0, 0},
-  {"pmevtyper4_el0", PMEVTYPER4_EL0, 0},
-  {"pmevtyper5_el0", PMEVTYPER5_EL0, 0},
-  {"pmevtyper6_el0", PMEVTYPER6_EL0, 0},
-  {"pmevtyper7_el0", PMEVTYPER7_EL0, 0},
-  {"pmevtyper8_el0", PMEVTYPER8_EL0, 0},
-  {"pmevtyper9_el0", PMEVTYPER9_EL0, 0},
-  {"pmevtyper10_el0", PMEVTYPER10_EL0, 0},
-  {"pmevtyper11_el0", PMEVTYPER11_EL0, 0},
-  {"pmevtyper12_el0", PMEVTYPER12_EL0, 0},
-  {"pmevtyper13_el0", PMEVTYPER13_EL0, 0},
-  {"pmevtyper14_el0", PMEVTYPER14_EL0, 0},
-  {"pmevtyper15_el0", PMEVTYPER15_EL0, 0},
-  {"pmevtyper16_el0", PMEVTYPER16_EL0, 0},
-  {"pmevtyper17_el0", PMEVTYPER17_EL0, 0},
-  {"pmevtyper18_el0", PMEVTYPER18_EL0, 0},
-  {"pmevtyper19_el0", PMEVTYPER19_EL0, 0},
-  {"pmevtyper20_el0", PMEVTYPER20_EL0, 0},
-  {"pmevtyper21_el0", PMEVTYPER21_EL0, 0},
-  {"pmevtyper22_el0", PMEVTYPER22_EL0, 0},
-  {"pmevtyper23_el0", PMEVTYPER23_EL0, 0},
-  {"pmevtyper24_el0", PMEVTYPER24_EL0, 0},
-  {"pmevtyper25_el0", PMEVTYPER25_EL0, 0},
-  {"pmevtyper26_el0", PMEVTYPER26_EL0, 0},
-  {"pmevtyper27_el0", PMEVTYPER27_EL0, 0},
-  {"pmevtyper28_el0", PMEVTYPER28_EL0, 0},
-  {"pmevtyper29_el0", PMEVTYPER29_EL0, 0},
-  {"pmevtyper30_el0", PMEVTYPER30_EL0, 0},
+  {"osdtrrx_el1", OSDTRRX_EL1, {}},
+  {"osdtrtx_el1",  OSDTRTX_EL1, {}},
+  {"teecr32_el1", TEECR32_EL1, {}},
+  {"mdccint_el1", MDCCINT_EL1, {}},
+  {"mdscr_el1", MDSCR_EL1, {}},
+  {"dbgdtr_el0", DBGDTR_EL0, {}},
+  {"oseccr_el1", OSECCR_EL1, {}},
+  {"dbgvcr32_el2", DBGVCR32_EL2, {}},
+  {"dbgbvr0_el1", DBGBVR0_EL1, {}},
+  {"dbgbvr1_el1", DBGBVR1_EL1, {}},
+  {"dbgbvr2_el1", DBGBVR2_EL1, {}},
+  {"dbgbvr3_el1", DBGBVR3_EL1, {}},
+  {"dbgbvr4_el1", DBGBVR4_EL1, {}},
+  {"dbgbvr5_el1", DBGBVR5_EL1, {}},
+  {"dbgbvr6_el1", DBGBVR6_EL1, {}},
+  {"dbgbvr7_el1", DBGBVR7_EL1, {}},
+  {"dbgbvr8_el1", DBGBVR8_EL1, {}},
+  {"dbgbvr9_el1", DBGBVR9_EL1, {}},
+  {"dbgbvr10_el1", DBGBVR10_EL1, {}},
+  {"dbgbvr11_el1", DBGBVR11_EL1, {}},
+  {"dbgbvr12_el1", DBGBVR12_EL1, {}},
+  {"dbgbvr13_el1", DBGBVR13_EL1, {}},
+  {"dbgbvr14_el1", DBGBVR14_EL1, {}},
+  {"dbgbvr15_el1", DBGBVR15_EL1, {}},
+  {"dbgbcr0_el1", DBGBCR0_EL1, {}},
+  {"dbgbcr1_el1", DBGBCR1_EL1, {}},
+  {"dbgbcr2_el1", DBGBCR2_EL1, {}},
+  {"dbgbcr3_el1", DBGBCR3_EL1, {}},
+  {"dbgbcr4_el1", DBGBCR4_EL1, {}},
+  {"dbgbcr5_el1", DBGBCR5_EL1, {}},
+  {"dbgbcr6_el1", DBGBCR6_EL1, {}},
+  {"dbgbcr7_el1", DBGBCR7_EL1, {}},
+  {"dbgbcr8_el1", DBGBCR8_EL1, {}},
+  {"dbgbcr9_el1", DBGBCR9_EL1, {}},
+  {"dbgbcr10_el1", DBGBCR10_EL1, {}},
+  {"dbgbcr11_el1", DBGBCR11_EL1, {}},
+  {"dbgbcr12_el1", DBGBCR12_EL1, {}},
+  {"dbgbcr13_el1", DBGBCR13_EL1, {}},
+  {"dbgbcr14_el1", DBGBCR14_EL1, {}},
+  {"dbgbcr15_el1", DBGBCR15_EL1, {}},
+  {"dbgwvr0_el1", DBGWVR0_EL1, {}},
+  {"dbgwvr1_el1", DBGWVR1_EL1, {}},
+  {"dbgwvr2_el1", DBGWVR2_EL1, {}},
+  {"dbgwvr3_el1", DBGWVR3_EL1, {}},
+  {"dbgwvr4_el1", DBGWVR4_EL1, {}},
+  {"dbgwvr5_el1", DBGWVR5_EL1, {}},
+  {"dbgwvr6_el1", DBGWVR6_EL1, {}},
+  {"dbgwvr7_el1", DBGWVR7_EL1, {}},
+  {"dbgwvr8_el1", DBGWVR8_EL1, {}},
+  {"dbgwvr9_el1", DBGWVR9_EL1, {}},
+  {"dbgwvr10_el1", DBGWVR10_EL1, {}},
+  {"dbgwvr11_el1", DBGWVR11_EL1, {}},
+  {"dbgwvr12_el1", DBGWVR12_EL1, {}},
+  {"dbgwvr13_el1", DBGWVR13_EL1, {}},
+  {"dbgwvr14_el1", DBGWVR14_EL1, {}},
+  {"dbgwvr15_el1", DBGWVR15_EL1, {}},
+  {"dbgwcr0_el1", DBGWCR0_EL1, {}},
+  {"dbgwcr1_el1", DBGWCR1_EL1, {}},
+  {"dbgwcr2_el1", DBGWCR2_EL1, {}},
+  {"dbgwcr3_el1", DBGWCR3_EL1, {}},
+  {"dbgwcr4_el1", DBGWCR4_EL1, {}},
+  {"dbgwcr5_el1", DBGWCR5_EL1, {}},
+  {"dbgwcr6_el1", DBGWCR6_EL1, {}},
+  {"dbgwcr7_el1", DBGWCR7_EL1, {}},
+  {"dbgwcr8_el1", DBGWCR8_EL1, {}},
+  {"dbgwcr9_el1", DBGWCR9_EL1, {}},
+  {"dbgwcr10_el1", DBGWCR10_EL1, {}},
+  {"dbgwcr11_el1", DBGWCR11_EL1, {}},
+  {"dbgwcr12_el1", DBGWCR12_EL1, {}},
+  {"dbgwcr13_el1", DBGWCR13_EL1, {}},
+  {"dbgwcr14_el1", DBGWCR14_EL1, {}},
+  {"dbgwcr15_el1", DBGWCR15_EL1, {}},
+  {"teehbr32_el1", TEEHBR32_EL1, {}},
+  {"osdlr_el1", OSDLR_EL1, {}},
+  {"dbgprcr_el1", DBGPRCR_EL1, {}},
+  {"dbgclaimset_el1", DBGCLAIMSET_EL1, {}},
+  {"dbgclaimclr_el1", DBGCLAIMCLR_EL1, {}},
+  {"csselr_el1", CSSELR_EL1, {}},
+  {"vpidr_el2", VPIDR_EL2, {}},
+  {"vmpidr_el2", VMPIDR_EL2, {}},
+  {"sctlr_el1", SCTLR_EL1, {}},
+  {"sctlr_el2", SCTLR_EL2, {}},
+  {"sctlr_el3", SCTLR_EL3, {}},
+  {"actlr_el1", ACTLR_EL1, {}},
+  {"actlr_el2", ACTLR_EL2, {}},
+  {"actlr_el3", ACTLR_EL3, {}},
+  {"cpacr_el1", CPACR_EL1, {}},
+  {"hcr_el2", HCR_EL2, {}},
+  {"scr_el3", SCR_EL3, {}},
+  {"mdcr_el2", MDCR_EL2, {}},
+  {"sder32_el3", SDER32_EL3, {}},
+  {"cptr_el2", CPTR_EL2, {}},
+  {"cptr_el3", CPTR_EL3, {}},
+  {"hstr_el2", HSTR_EL2, {}},
+  {"hacr_el2", HACR_EL2, {}},
+  {"mdcr_el3", MDCR_EL3, {}},
+  {"ttbr0_el1", TTBR0_EL1, {}},
+  {"ttbr0_el2", TTBR0_EL2, {}},
+  {"ttbr0_el3", TTBR0_EL3, {}},
+  {"ttbr1_el1", TTBR1_EL1, {}},
+  {"tcr_el1", TCR_EL1, {}},
+  {"tcr_el2", TCR_EL2, {}},
+  {"tcr_el3", TCR_EL3, {}},
+  {"vttbr_el2", VTTBR_EL2, {}},
+  {"vtcr_el2", VTCR_EL2, {}},
+  {"dacr32_el2", DACR32_EL2, {}},
+  {"spsr_el1", SPSR_EL1, {}},
+  {"spsr_el2", SPSR_EL2, {}},
+  {"spsr_el3", SPSR_EL3, {}},
+  {"elr_el1", ELR_EL1, {}},
+  {"elr_el2", ELR_EL2, {}},
+  {"elr_el3", ELR_EL3, {}},
+  {"sp_el0", SP_EL0, {}},
+  {"sp_el1", SP_EL1, {}},
+  {"sp_el2", SP_EL2, {}},
+  {"spsel", SPSel, {}},
+  {"nzcv", NZCV, {}},
+  {"daif", DAIF, {}},
+  {"currentel", CurrentEL, {}},
+  {"spsr_irq", SPSR_irq, {}},
+  {"spsr_abt", SPSR_abt, {}},
+  {"spsr_und", SPSR_und, {}},
+  {"spsr_fiq", SPSR_fiq, {}},
+  {"fpcr", FPCR, {}},
+  {"fpsr", FPSR, {}},
+  {"dspsr_el0", DSPSR_EL0, {}},
+  {"dlr_el0", DLR_EL0, {}},
+  {"ifsr32_el2", IFSR32_EL2, {}},
+  {"afsr0_el1", AFSR0_EL1, {}},
+  {"afsr0_el2", AFSR0_EL2, {}},
+  {"afsr0_el3", AFSR0_EL3, {}},
+  {"afsr1_el1", AFSR1_EL1, {}},
+  {"afsr1_el2", AFSR1_EL2, {}},
+  {"afsr1_el3", AFSR1_EL3, {}},
+  {"esr_el1", ESR_EL1, {}},
+  {"esr_el2", ESR_EL2, {}},
+  {"esr_el3", ESR_EL3, {}},
+  {"fpexc32_el2", FPEXC32_EL2, {}},
+  {"far_el1", FAR_EL1, {}},
+  {"far_el2", FAR_EL2, {}},
+  {"far_el3", FAR_EL3, {}},
+  {"hpfar_el2", HPFAR_EL2, {}},
+  {"par_el1", PAR_EL1, {}},
+  {"pmcr_el0", PMCR_EL0, {}},
+  {"pmcntenset_el0", PMCNTENSET_EL0, {}},
+  {"pmcntenclr_el0", PMCNTENCLR_EL0, {}},
+  {"pmovsclr_el0", PMOVSCLR_EL0, {}},
+  {"pmselr_el0", PMSELR_EL0, {}},
+  {"pmccntr_el0", PMCCNTR_EL0, {}},
+  {"pmxevtyper_el0", PMXEVTYPER_EL0, {}},
+  {"pmxevcntr_el0", PMXEVCNTR_EL0, {}},
+  {"pmuserenr_el0", PMUSERENR_EL0, {}},
+  {"pmintenset_el1", PMINTENSET_EL1, {}},
+  {"pmintenclr_el1", PMINTENCLR_EL1, {}},
+  {"pmovsset_el0", PMOVSSET_EL0, {}},
+  {"mair_el1", MAIR_EL1, {}},
+  {"mair_el2", MAIR_EL2, {}},
+  {"mair_el3", MAIR_EL3, {}},
+  {"amair_el1", AMAIR_EL1, {}},
+  {"amair_el2", AMAIR_EL2, {}},
+  {"amair_el3", AMAIR_EL3, {}},
+  {"vbar_el1", VBAR_EL1, {}},
+  {"vbar_el2", VBAR_EL2, {}},
+  {"vbar_el3", VBAR_EL3, {}},
+  {"rmr_el1", RMR_EL1, {}},
+  {"rmr_el2", RMR_EL2, {}},
+  {"rmr_el3", RMR_EL3, {}},
+  {"contextidr_el1", CONTEXTIDR_EL1, {}},
+  {"tpidr_el0", TPIDR_EL0, {}},
+  {"tpidr_el2", TPIDR_EL2, {}},
+  {"tpidr_el3", TPIDR_EL3, {}},
+  {"tpidrro_el0", TPIDRRO_EL0, {}},
+  {"tpidr_el1", TPIDR_EL1, {}},
+  {"cntfrq_el0", CNTFRQ_EL0, {}},
+  {"cntvoff_el2", CNTVOFF_EL2, {}},
+  {"cntkctl_el1", CNTKCTL_EL1, {}},
+  {"cnthctl_el2", CNTHCTL_EL2, {}},
+  {"cntp_tval_el0", CNTP_TVAL_EL0, {}},
+  {"cnthp_tval_el2", CNTHP_TVAL_EL2, {}},
+  {"cntps_tval_el1", CNTPS_TVAL_EL1, {}},
+  {"cntp_ctl_el0", CNTP_CTL_EL0, {}},
+  {"cnthp_ctl_el2", CNTHP_CTL_EL2, {}},
+  {"cntps_ctl_el1", CNTPS_CTL_EL1, {}},
+  {"cntp_cval_el0", CNTP_CVAL_EL0, {}},
+  {"cnthp_cval_el2", CNTHP_CVAL_EL2, {}},
+  {"cntps_cval_el1", CNTPS_CVAL_EL1, {}},
+  {"cntv_tval_el0", CNTV_TVAL_EL0, {}},
+  {"cntv_ctl_el0", CNTV_CTL_EL0, {}},
+  {"cntv_cval_el0", CNTV_CVAL_EL0, {}},
+  {"pmevcntr0_el0", PMEVCNTR0_EL0, {}},
+  {"pmevcntr1_el0", PMEVCNTR1_EL0, {}},
+  {"pmevcntr2_el0", PMEVCNTR2_EL0, {}},
+  {"pmevcntr3_el0", PMEVCNTR3_EL0, {}},
+  {"pmevcntr4_el0", PMEVCNTR4_EL0, {}},
+  {"pmevcntr5_el0", PMEVCNTR5_EL0, {}},
+  {"pmevcntr6_el0", PMEVCNTR6_EL0, {}},
+  {"pmevcntr7_el0", PMEVCNTR7_EL0, {}},
+  {"pmevcntr8_el0", PMEVCNTR8_EL0, {}},
+  {"pmevcntr9_el0", PMEVCNTR9_EL0, {}},
+  {"pmevcntr10_el0", PMEVCNTR10_EL0, {}},
+  {"pmevcntr11_el0", PMEVCNTR11_EL0, {}},
+  {"pmevcntr12_el0", PMEVCNTR12_EL0, {}},
+  {"pmevcntr13_el0", PMEVCNTR13_EL0, {}},
+  {"pmevcntr14_el0", PMEVCNTR14_EL0, {}},
+  {"pmevcntr15_el0", PMEVCNTR15_EL0, {}},
+  {"pmevcntr16_el0", PMEVCNTR16_EL0, {}},
+  {"pmevcntr17_el0", PMEVCNTR17_EL0, {}},
+  {"pmevcntr18_el0", PMEVCNTR18_EL0, {}},
+  {"pmevcntr19_el0", PMEVCNTR19_EL0, {}},
+  {"pmevcntr20_el0", PMEVCNTR20_EL0, {}},
+  {"pmevcntr21_el0", PMEVCNTR21_EL0, {}},
+  {"pmevcntr22_el0", PMEVCNTR22_EL0, {}},
+  {"pmevcntr23_el0", PMEVCNTR23_EL0, {}},
+  {"pmevcntr24_el0", PMEVCNTR24_EL0, {}},
+  {"pmevcntr25_el0", PMEVCNTR25_EL0, {}},
+  {"pmevcntr26_el0", PMEVCNTR26_EL0, {}},
+  {"pmevcntr27_el0", PMEVCNTR27_EL0, {}},
+  {"pmevcntr28_el0", PMEVCNTR28_EL0, {}},
+  {"pmevcntr29_el0", PMEVCNTR29_EL0, {}},
+  {"pmevcntr30_el0", PMEVCNTR30_EL0, {}},
+  {"pmccfiltr_el0", PMCCFILTR_EL0, {}},
+  {"pmevtyper0_el0", PMEVTYPER0_EL0, {}},
+  {"pmevtyper1_el0", PMEVTYPER1_EL0, {}},
+  {"pmevtyper2_el0", PMEVTYPER2_EL0, {}},
+  {"pmevtyper3_el0", PMEVTYPER3_EL0, {}},
+  {"pmevtyper4_el0", PMEVTYPER4_EL0, {}},
+  {"pmevtyper5_el0", PMEVTYPER5_EL0, {}},
+  {"pmevtyper6_el0", PMEVTYPER6_EL0, {}},
+  {"pmevtyper7_el0", PMEVTYPER7_EL0, {}},
+  {"pmevtyper8_el0", PMEVTYPER8_EL0, {}},
+  {"pmevtyper9_el0", PMEVTYPER9_EL0, {}},
+  {"pmevtyper10_el0", PMEVTYPER10_EL0, {}},
+  {"pmevtyper11_el0", PMEVTYPER11_EL0, {}},
+  {"pmevtyper12_el0", PMEVTYPER12_EL0, {}},
+  {"pmevtyper13_el0", PMEVTYPER13_EL0, {}},
+  {"pmevtyper14_el0", PMEVTYPER14_EL0, {}},
+  {"pmevtyper15_el0", PMEVTYPER15_EL0, {}},
+  {"pmevtyper16_el0", PMEVTYPER16_EL0, {}},
+  {"pmevtyper17_el0", PMEVTYPER17_EL0, {}},
+  {"pmevtyper18_el0", PMEVTYPER18_EL0, {}},
+  {"pmevtyper19_el0", PMEVTYPER19_EL0, {}},
+  {"pmevtyper20_el0", PMEVTYPER20_EL0, {}},
+  {"pmevtyper21_el0", PMEVTYPER21_EL0, {}},
+  {"pmevtyper22_el0", PMEVTYPER22_EL0, {}},
+  {"pmevtyper23_el0", PMEVTYPER23_EL0, {}},
+  {"pmevtyper24_el0", PMEVTYPER24_EL0, {}},
+  {"pmevtyper25_el0", PMEVTYPER25_EL0, {}},
+  {"pmevtyper26_el0", PMEVTYPER26_EL0, {}},
+  {"pmevtyper27_el0", PMEVTYPER27_EL0, {}},
+  {"pmevtyper28_el0", PMEVTYPER28_EL0, {}},
+  {"pmevtyper29_el0", PMEVTYPER29_EL0, {}},
+  {"pmevtyper30_el0", PMEVTYPER30_EL0, {}},
 
   // Trace registers
-  {"trcprgctlr", TRCPRGCTLR, 0},
-  {"trcprocselr", TRCPROCSELR, 0},
-  {"trcconfigr", TRCCONFIGR, 0},
-  {"trcauxctlr", TRCAUXCTLR, 0},
-  {"trceventctl0r", TRCEVENTCTL0R, 0},
-  {"trceventctl1r", TRCEVENTCTL1R, 0},
-  {"trcstallctlr", TRCSTALLCTLR, 0},
-  {"trctsctlr", TRCTSCTLR, 0},
-  {"trcsyncpr", TRCSYNCPR, 0},
-  {"trcccctlr", TRCCCCTLR, 0},
-  {"trcbbctlr", TRCBBCTLR, 0},
-  {"trctraceidr", TRCTRACEIDR, 0},
-  {"trcqctlr", TRCQCTLR, 0},
-  {"trcvictlr", TRCVICTLR, 0},
-  {"trcviiectlr", TRCVIIECTLR, 0},
-  {"trcvissctlr", TRCVISSCTLR, 0},
-  {"trcvipcssctlr", TRCVIPCSSCTLR, 0},
-  {"trcvdctlr", TRCVDCTLR, 0},
-  {"trcvdsacctlr", TRCVDSACCTLR, 0},
-  {"trcvdarcctlr", TRCVDARCCTLR, 0},
-  {"trcseqevr0", TRCSEQEVR0, 0},
-  {"trcseqevr1", TRCSEQEVR1, 0},
-  {"trcseqevr2", TRCSEQEVR2, 0},
-  {"trcseqrstevr", TRCSEQRSTEVR, 0},
-  {"trcseqstr", TRCSEQSTR, 0},
-  {"trcextinselr", TRCEXTINSELR, 0},
-  {"trccntrldvr0", TRCCNTRLDVR0, 0},
-  {"trccntrldvr1", TRCCNTRLDVR1, 0},
-  {"trccntrldvr2", TRCCNTRLDVR2, 0},
-  {"trccntrldvr3", TRCCNTRLDVR3, 0},
-  {"trccntctlr0", TRCCNTCTLR0, 0},
-  {"trccntctlr1", TRCCNTCTLR1, 0},
-  {"trccntctlr2", TRCCNTCTLR2, 0},
-  {"trccntctlr3", TRCCNTCTLR3, 0},
-  {"trccntvr0", TRCCNTVR0, 0},
-  {"trccntvr1", TRCCNTVR1, 0},
-  {"trccntvr2", TRCCNTVR2, 0},
-  {"trccntvr3", TRCCNTVR3, 0},
-  {"trcimspec0", TRCIMSPEC0, 0},
-  {"trcimspec1", TRCIMSPEC1, 0},
-  {"trcimspec2", TRCIMSPEC2, 0},
-  {"trcimspec3", TRCIMSPEC3, 0},
-  {"trcimspec4", TRCIMSPEC4, 0},
-  {"trcimspec5", TRCIMSPEC5, 0},
-  {"trcimspec6", TRCIMSPEC6, 0},
-  {"trcimspec7", TRCIMSPEC7, 0},
-  {"trcrsctlr2", TRCRSCTLR2, 0},
-  {"trcrsctlr3", TRCRSCTLR3, 0},
-  {"trcrsctlr4", TRCRSCTLR4, 0},
-  {"trcrsctlr5", TRCRSCTLR5, 0},
-  {"trcrsctlr6", TRCRSCTLR6, 0},
-  {"trcrsctlr7", TRCRSCTLR7, 0},
-  {"trcrsctlr8", TRCRSCTLR8, 0},
-  {"trcrsctlr9", TRCRSCTLR9, 0},
-  {"trcrsctlr10", TRCRSCTLR10, 0},
-  {"trcrsctlr11", TRCRSCTLR11, 0},
-  {"trcrsctlr12", TRCRSCTLR12, 0},
-  {"trcrsctlr13", TRCRSCTLR13, 0},
-  {"trcrsctlr14", TRCRSCTLR14, 0},
-  {"trcrsctlr15", TRCRSCTLR15, 0},
-  {"trcrsctlr16", TRCRSCTLR16, 0},
-  {"trcrsctlr17", TRCRSCTLR17, 0},
-  {"trcrsctlr18", TRCRSCTLR18, 0},
-  {"trcrsctlr19", TRCRSCTLR19, 0},
-  {"trcrsctlr20", TRCRSCTLR20, 0},
-  {"trcrsctlr21", TRCRSCTLR21, 0},
-  {"trcrsctlr22", TRCRSCTLR22, 0},
-  {"trcrsctlr23", TRCRSCTLR23, 0},
-  {"trcrsctlr24", TRCRSCTLR24, 0},
-  {"trcrsctlr25", TRCRSCTLR25, 0},
-  {"trcrsctlr26", TRCRSCTLR26, 0},
-  {"trcrsctlr27", TRCRSCTLR27, 0},
-  {"trcrsctlr28", TRCRSCTLR28, 0},
-  {"trcrsctlr29", TRCRSCTLR29, 0},
-  {"trcrsctlr30", TRCRSCTLR30, 0},
-  {"trcrsctlr31", TRCRSCTLR31, 0},
-  {"trcssccr0", TRCSSCCR0, 0},
-  {"trcssccr1", TRCSSCCR1, 0},
-  {"trcssccr2", TRCSSCCR2, 0},
-  {"trcssccr3", TRCSSCCR3, 0},
-  {"trcssccr4", TRCSSCCR4, 0},
-  {"trcssccr5", TRCSSCCR5, 0},
-  {"trcssccr6", TRCSSCCR6, 0},
-  {"trcssccr7", TRCSSCCR7, 0},
-  {"trcsscsr0", TRCSSCSR0, 0},
-  {"trcsscsr1", TRCSSCSR1, 0},
-  {"trcsscsr2", TRCSSCSR2, 0},
-  {"trcsscsr3", TRCSSCSR3, 0},
-  {"trcsscsr4", TRCSSCSR4, 0},
-  {"trcsscsr5", TRCSSCSR5, 0},
-  {"trcsscsr6", TRCSSCSR6, 0},
-  {"trcsscsr7", TRCSSCSR7, 0},
-  {"trcsspcicr0", TRCSSPCICR0, 0},
-  {"trcsspcicr1", TRCSSPCICR1, 0},
-  {"trcsspcicr2", TRCSSPCICR2, 0},
-  {"trcsspcicr3", TRCSSPCICR3, 0},
-  {"trcsspcicr4", TRCSSPCICR4, 0},
-  {"trcsspcicr5", TRCSSPCICR5, 0},
-  {"trcsspcicr6", TRCSSPCICR6, 0},
-  {"trcsspcicr7", TRCSSPCICR7, 0},
-  {"trcpdcr", TRCPDCR, 0},
-  {"trcacvr0", TRCACVR0, 0},
-  {"trcacvr1", TRCACVR1, 0},
-  {"trcacvr2", TRCACVR2, 0},
-  {"trcacvr3", TRCACVR3, 0},
-  {"trcacvr4", TRCACVR4, 0},
-  {"trcacvr5", TRCACVR5, 0},
-  {"trcacvr6", TRCACVR6, 0},
-  {"trcacvr7", TRCACVR7, 0},
-  {"trcacvr8", TRCACVR8, 0},
-  {"trcacvr9", TRCACVR9, 0},
-  {"trcacvr10", TRCACVR10, 0},
-  {"trcacvr11", TRCACVR11, 0},
-  {"trcacvr12", TRCACVR12, 0},
-  {"trcacvr13", TRCACVR13, 0},
-  {"trcacvr14", TRCACVR14, 0},
-  {"trcacvr15", TRCACVR15, 0},
-  {"trcacatr0", TRCACATR0, 0},
-  {"trcacatr1", TRCACATR1, 0},
-  {"trcacatr2", TRCACATR2, 0},
-  {"trcacatr3", TRCACATR3, 0},
-  {"trcacatr4", TRCACATR4, 0},
-  {"trcacatr5", TRCACATR5, 0},
-  {"trcacatr6", TRCACATR6, 0},
-  {"trcacatr7", TRCACATR7, 0},
-  {"trcacatr8", TRCACATR8, 0},
-  {"trcacatr9", TRCACATR9, 0},
-  {"trcacatr10", TRCACATR10, 0},
-  {"trcacatr11", TRCACATR11, 0},
-  {"trcacatr12", TRCACATR12, 0},
-  {"trcacatr13", TRCACATR13, 0},
-  {"trcacatr14", TRCACATR14, 0},
-  {"trcacatr15", TRCACATR15, 0},
-  {"trcdvcvr0", TRCDVCVR0, 0},
-  {"trcdvcvr1", TRCDVCVR1, 0},
-  {"trcdvcvr2", TRCDVCVR2, 0},
-  {"trcdvcvr3", TRCDVCVR3, 0},
-  {"trcdvcvr4", TRCDVCVR4, 0},
-  {"trcdvcvr5", TRCDVCVR5, 0},
-  {"trcdvcvr6", TRCDVCVR6, 0},
-  {"trcdvcvr7", TRCDVCVR7, 0},
-  {"trcdvcmr0", TRCDVCMR0, 0},
-  {"trcdvcmr1", TRCDVCMR1, 0},
-  {"trcdvcmr2", TRCDVCMR2, 0},
-  {"trcdvcmr3", TRCDVCMR3, 0},
-  {"trcdvcmr4", TRCDVCMR4, 0},
-  {"trcdvcmr5", TRCDVCMR5, 0},
-  {"trcdvcmr6", TRCDVCMR6, 0},
-  {"trcdvcmr7", TRCDVCMR7, 0},
-  {"trccidcvr0", TRCCIDCVR0, 0},
-  {"trccidcvr1", TRCCIDCVR1, 0},
-  {"trccidcvr2", TRCCIDCVR2, 0},
-  {"trccidcvr3", TRCCIDCVR3, 0},
-  {"trccidcvr4", TRCCIDCVR4, 0},
-  {"trccidcvr5", TRCCIDCVR5, 0},
-  {"trccidcvr6", TRCCIDCVR6, 0},
-  {"trccidcvr7", TRCCIDCVR7, 0},
-  {"trcvmidcvr0", TRCVMIDCVR0, 0},
-  {"trcvmidcvr1", TRCVMIDCVR1, 0},
-  {"trcvmidcvr2", TRCVMIDCVR2, 0},
-  {"trcvmidcvr3", TRCVMIDCVR3, 0},
-  {"trcvmidcvr4", TRCVMIDCVR4, 0},
-  {"trcvmidcvr5", TRCVMIDCVR5, 0},
-  {"trcvmidcvr6", TRCVMIDCVR6, 0},
-  {"trcvmidcvr7", TRCVMIDCVR7, 0},
-  {"trccidcctlr0", TRCCIDCCTLR0, 0},
-  {"trccidcctlr1", TRCCIDCCTLR1, 0},
-  {"trcvmidcctlr0", TRCVMIDCCTLR0, 0},
-  {"trcvmidcctlr1", TRCVMIDCCTLR1, 0},
-  {"trcitctrl", TRCITCTRL, 0},
-  {"trcclaimset", TRCCLAIMSET, 0},
-  {"trcclaimclr", TRCCLAIMCLR, 0},
+  {"trcprgctlr", TRCPRGCTLR, {}},
+  {"trcprocselr", TRCPROCSELR, {}},
+  {"trcconfigr", TRCCONFIGR, {}},
+  {"trcauxctlr", TRCAUXCTLR, {}},
+  {"trceventctl0r", TRCEVENTCTL0R, {}},
+  {"trceventctl1r", TRCEVENTCTL1R, {}},
+  {"trcstallctlr", TRCSTALLCTLR, {}},
+  {"trctsctlr", TRCTSCTLR, {}},
+  {"trcsyncpr", TRCSYNCPR, {}},
+  {"trcccctlr", TRCCCCTLR, {}},
+  {"trcbbctlr", TRCBBCTLR, {}},
+  {"trctraceidr", TRCTRACEIDR, {}},
+  {"trcqctlr", TRCQCTLR, {}},
+  {"trcvictlr", TRCVICTLR, {}},
+  {"trcviiectlr", TRCVIIECTLR, {}},
+  {"trcvissctlr", TRCVISSCTLR, {}},
+  {"trcvipcssctlr", TRCVIPCSSCTLR, {}},
+  {"trcvdctlr", TRCVDCTLR, {}},
+  {"trcvdsacctlr", TRCVDSACCTLR, {}},
+  {"trcvdarcctlr", TRCVDARCCTLR, {}},
+  {"trcseqevr0", TRCSEQEVR0, {}},
+  {"trcseqevr1", TRCSEQEVR1, {}},
+  {"trcseqevr2", TRCSEQEVR2, {}},
+  {"trcseqrstevr", TRCSEQRSTEVR, {}},
+  {"trcseqstr", TRCSEQSTR, {}},
+  {"trcextinselr", TRCEXTINSELR, {}},
+  {"trccntrldvr0", TRCCNTRLDVR0, {}},
+  {"trccntrldvr1", TRCCNTRLDVR1, {}},
+  {"trccntrldvr2", TRCCNTRLDVR2, {}},
+  {"trccntrldvr3", TRCCNTRLDVR3, {}},
+  {"trccntctlr0", TRCCNTCTLR0, {}},
+  {"trccntctlr1", TRCCNTCTLR1, {}},
+  {"trccntctlr2", TRCCNTCTLR2, {}},
+  {"trccntctlr3", TRCCNTCTLR3, {}},
+  {"trccntvr0", TRCCNTVR0, {}},
+  {"trccntvr1", TRCCNTVR1, {}},
+  {"trccntvr2", TRCCNTVR2, {}},
+  {"trccntvr3", TRCCNTVR3, {}},
+  {"trcimspec0", TRCIMSPEC0, {}},
+  {"trcimspec1", TRCIMSPEC1, {}},
+  {"trcimspec2", TRCIMSPEC2, {}},
+  {"trcimspec3", TRCIMSPEC3, {}},
+  {"trcimspec4", TRCIMSPEC4, {}},
+  {"trcimspec5", TRCIMSPEC5, {}},
+  {"trcimspec6", TRCIMSPEC6, {}},
+  {"trcimspec7", TRCIMSPEC7, {}},
+  {"trcrsctlr2", TRCRSCTLR2, {}},
+  {"trcrsctlr3", TRCRSCTLR3, {}},
+  {"trcrsctlr4", TRCRSCTLR4, {}},
+  {"trcrsctlr5", TRCRSCTLR5, {}},
+  {"trcrsctlr6", TRCRSCTLR6, {}},
+  {"trcrsctlr7", TRCRSCTLR7, {}},
+  {"trcrsctlr8", TRCRSCTLR8, {}},
+  {"trcrsctlr9", TRCRSCTLR9, {}},
+  {"trcrsctlr10", TRCRSCTLR10, {}},
+  {"trcrsctlr11", TRCRSCTLR11, {}},
+  {"trcrsctlr12", TRCRSCTLR12, {}},
+  {"trcrsctlr13", TRCRSCTLR13, {}},
+  {"trcrsctlr14", TRCRSCTLR14, {}},
+  {"trcrsctlr15", TRCRSCTLR15, {}},
+  {"trcrsctlr16", TRCRSCTLR16, {}},
+  {"trcrsctlr17", TRCRSCTLR17, {}},
+  {"trcrsctlr18", TRCRSCTLR18, {}},
+  {"trcrsctlr19", TRCRSCTLR19, {}},
+  {"trcrsctlr20", TRCRSCTLR20, {}},
+  {"trcrsctlr21", TRCRSCTLR21, {}},
+  {"trcrsctlr22", TRCRSCTLR22, {}},
+  {"trcrsctlr23", TRCRSCTLR23, {}},
+  {"trcrsctlr24", TRCRSCTLR24, {}},
+  {"trcrsctlr25", TRCRSCTLR25, {}},
+  {"trcrsctlr26", TRCRSCTLR26, {}},
+  {"trcrsctlr27", TRCRSCTLR27, {}},
+  {"trcrsctlr28", TRCRSCTLR28, {}},
+  {"trcrsctlr29", TRCRSCTLR29, {}},
+  {"trcrsctlr30", TRCRSCTLR30, {}},
+  {"trcrsctlr31", TRCRSCTLR31, {}},
+  {"trcssccr0", TRCSSCCR0, {}},
+  {"trcssccr1", TRCSSCCR1, {}},
+  {"trcssccr2", TRCSSCCR2, {}},
+  {"trcssccr3", TRCSSCCR3, {}},
+  {"trcssccr4", TRCSSCCR4, {}},
+  {"trcssccr5", TRCSSCCR5, {}},
+  {"trcssccr6", TRCSSCCR6, {}},
+  {"trcssccr7", TRCSSCCR7, {}},
+  {"trcsscsr0", TRCSSCSR0, {}},
+  {"trcsscsr1", TRCSSCSR1, {}},
+  {"trcsscsr2", TRCSSCSR2, {}},
+  {"trcsscsr3", TRCSSCSR3, {}},
+  {"trcsscsr4", TRCSSCSR4, {}},
+  {"trcsscsr5", TRCSSCSR5, {}},
+  {"trcsscsr6", TRCSSCSR6, {}},
+  {"trcsscsr7", TRCSSCSR7, {}},
+  {"trcsspcicr0", TRCSSPCICR0, {}},
+  {"trcsspcicr1", TRCSSPCICR1, {}},
+  {"trcsspcicr2", TRCSSPCICR2, {}},
+  {"trcsspcicr3", TRCSSPCICR3, {}},
+  {"trcsspcicr4", TRCSSPCICR4, {}},
+  {"trcsspcicr5", TRCSSPCICR5, {}},
+  {"trcsspcicr6", TRCSSPCICR6, {}},
+  {"trcsspcicr7", TRCSSPCICR7, {}},
+  {"trcpdcr", TRCPDCR, {}},
+  {"trcacvr0", TRCACVR0, {}},
+  {"trcacvr1", TRCACVR1, {}},
+  {"trcacvr2", TRCACVR2, {}},
+  {"trcacvr3", TRCACVR3, {}},
+  {"trcacvr4", TRCACVR4, {}},
+  {"trcacvr5", TRCACVR5, {}},
+  {"trcacvr6", TRCACVR6, {}},
+  {"trcacvr7", TRCACVR7, {}},
+  {"trcacvr8", TRCACVR8, {}},
+  {"trcacvr9", TRCACVR9, {}},
+  {"trcacvr10", TRCACVR10, {}},
+  {"trcacvr11", TRCACVR11, {}},
+  {"trcacvr12", TRCACVR12, {}},
+  {"trcacvr13", TRCACVR13, {}},
+  {"trcacvr14", TRCACVR14, {}},
+  {"trcacvr15", TRCACVR15, {}},
+  {"trcacatr0", TRCACATR0, {}},
+  {"trcacatr1", TRCACATR1, {}},
+  {"trcacatr2", TRCACATR2, {}},
+  {"trcacatr3", TRCACATR3, {}},
+  {"trcacatr4", TRCACATR4, {}},
+  {"trcacatr5", TRCACATR5, {}},
+  {"trcacatr6", TRCACATR6, {}},
+  {"trcacatr7", TRCACATR7, {}},
+  {"trcacatr8", TRCACATR8, {}},
+  {"trcacatr9", TRCACATR9, {}},
+  {"trcacatr10", TRCACATR10, {}},
+  {"trcacatr11", TRCACATR11, {}},
+  {"trcacatr12", TRCACATR12, {}},
+  {"trcacatr13", TRCACATR13, {}},
+  {"trcacatr14", TRCACATR14, {}},
+  {"trcacatr15", TRCACATR15, {}},
+  {"trcdvcvr0", TRCDVCVR0, {}},
+  {"trcdvcvr1", TRCDVCVR1, {}},
+  {"trcdvcvr2", TRCDVCVR2, {}},
+  {"trcdvcvr3", TRCDVCVR3, {}},
+  {"trcdvcvr4", TRCDVCVR4, {}},
+  {"trcdvcvr5", TRCDVCVR5, {}},
+  {"trcdvcvr6", TRCDVCVR6, {}},
+  {"trcdvcvr7", TRCDVCVR7, {}},
+  {"trcdvcmr0", TRCDVCMR0, {}},
+  {"trcdvcmr1", TRCDVCMR1, {}},
+  {"trcdvcmr2", TRCDVCMR2, {}},
+  {"trcdvcmr3", TRCDVCMR3, {}},
+  {"trcdvcmr4", TRCDVCMR4, {}},
+  {"trcdvcmr5", TRCDVCMR5, {}},
+  {"trcdvcmr6", TRCDVCMR6, {}},
+  {"trcdvcmr7", TRCDVCMR7, {}},
+  {"trccidcvr0", TRCCIDCVR0, {}},
+  {"trccidcvr1", TRCCIDCVR1, {}},
+  {"trccidcvr2", TRCCIDCVR2, {}},
+  {"trccidcvr3", TRCCIDCVR3, {}},
+  {"trccidcvr4", TRCCIDCVR4, {}},
+  {"trccidcvr5", TRCCIDCVR5, {}},
+  {"trccidcvr6", TRCCIDCVR6, {}},
+  {"trccidcvr7", TRCCIDCVR7, {}},
+  {"trcvmidcvr0", TRCVMIDCVR0, {}},
+  {"trcvmidcvr1", TRCVMIDCVR1, {}},
+  {"trcvmidcvr2", TRCVMIDCVR2, {}},
+  {"trcvmidcvr3", TRCVMIDCVR3, {}},
+  {"trcvmidcvr4", TRCVMIDCVR4, {}},
+  {"trcvmidcvr5", TRCVMIDCVR5, {}},
+  {"trcvmidcvr6", TRCVMIDCVR6, {}},
+  {"trcvmidcvr7", TRCVMIDCVR7, {}},
+  {"trccidcctlr0", TRCCIDCCTLR0, {}},
+  {"trccidcctlr1", TRCCIDCCTLR1, {}},
+  {"trcvmidcctlr0", TRCVMIDCCTLR0, {}},
+  {"trcvmidcctlr1", TRCVMIDCCTLR1, {}},
+  {"trcitctrl", TRCITCTRL, {}},
+  {"trcclaimset", TRCCLAIMSET, {}},
+  {"trcclaimclr", TRCCLAIMCLR, {}},
 
   // GICv3 registers
-  {"icc_bpr1_el1", ICC_BPR1_EL1, 0},
-  {"icc_bpr0_el1", ICC_BPR0_EL1, 0},
-  {"icc_pmr_el1", ICC_PMR_EL1, 0},
-  {"icc_ctlr_el1", ICC_CTLR_EL1, 0},
-  {"icc_ctlr_el3", ICC_CTLR_EL3, 0},
-  {"icc_sre_el1", ICC_SRE_EL1, 0},
-  {"icc_sre_el2", ICC_SRE_EL2, 0},
-  {"icc_sre_el3", ICC_SRE_EL3, 0},
-  {"icc_igrpen0_el1", ICC_IGRPEN0_EL1, 0},
-  {"icc_igrpen1_el1", ICC_IGRPEN1_EL1, 0},
-  {"icc_igrpen1_el3", ICC_IGRPEN1_EL3, 0},
-  {"icc_seien_el1", ICC_SEIEN_EL1, 0},
-  {"icc_ap0r0_el1", ICC_AP0R0_EL1, 0},
-  {"icc_ap0r1_el1", ICC_AP0R1_EL1, 0},
-  {"icc_ap0r2_el1", ICC_AP0R2_EL1, 0},
-  {"icc_ap0r3_el1", ICC_AP0R3_EL1, 0},
-  {"icc_ap1r0_el1", ICC_AP1R0_EL1, 0},
-  {"icc_ap1r1_el1", ICC_AP1R1_EL1, 0},
-  {"icc_ap1r2_el1", ICC_AP1R2_EL1, 0},
-  {"icc_ap1r3_el1", ICC_AP1R3_EL1, 0},
-  {"ich_ap0r0_el2", ICH_AP0R0_EL2, 0},
-  {"ich_ap0r1_el2", ICH_AP0R1_EL2, 0},
-  {"ich_ap0r2_el2", ICH_AP0R2_EL2, 0},
-  {"ich_ap0r3_el2", ICH_AP0R3_EL2, 0},
-  {"ich_ap1r0_el2", ICH_AP1R0_EL2, 0},
-  {"ich_ap1r1_el2", ICH_AP1R1_EL2, 0},
-  {"ich_ap1r2_el2", ICH_AP1R2_EL2, 0},
-  {"ich_ap1r3_el2", ICH_AP1R3_EL2, 0},
-  {"ich_hcr_el2", ICH_HCR_EL2, 0},
-  {"ich_misr_el2", ICH_MISR_EL2, 0},
-  {"ich_vmcr_el2", ICH_VMCR_EL2, 0},
-  {"ich_vseir_el2", ICH_VSEIR_EL2, 0},
-  {"ich_lr0_el2", ICH_LR0_EL2, 0},
-  {"ich_lr1_el2", ICH_LR1_EL2, 0},
-  {"ich_lr2_el2", ICH_LR2_EL2, 0},
-  {"ich_lr3_el2", ICH_LR3_EL2, 0},
-  {"ich_lr4_el2", ICH_LR4_EL2, 0},
-  {"ich_lr5_el2", ICH_LR5_EL2, 0},
-  {"ich_lr6_el2", ICH_LR6_EL2, 0},
-  {"ich_lr7_el2", ICH_LR7_EL2, 0},
-  {"ich_lr8_el2", ICH_LR8_EL2, 0},
-  {"ich_lr9_el2", ICH_LR9_EL2, 0},
-  {"ich_lr10_el2", ICH_LR10_EL2, 0},
-  {"ich_lr11_el2", ICH_LR11_EL2, 0},
-  {"ich_lr12_el2", ICH_LR12_EL2, 0},
-  {"ich_lr13_el2", ICH_LR13_EL2, 0},
-  {"ich_lr14_el2", ICH_LR14_EL2, 0},
-  {"ich_lr15_el2", ICH_LR15_EL2, 0},
+  {"icc_bpr1_el1", ICC_BPR1_EL1, {}},
+  {"icc_bpr0_el1", ICC_BPR0_EL1, {}},
+  {"icc_pmr_el1", ICC_PMR_EL1, {}},
+  {"icc_ctlr_el1", ICC_CTLR_EL1, {}},
+  {"icc_ctlr_el3", ICC_CTLR_EL3, {}},
+  {"icc_sre_el1", ICC_SRE_EL1, {}},
+  {"icc_sre_el2", ICC_SRE_EL2, {}},
+  {"icc_sre_el3", ICC_SRE_EL3, {}},
+  {"icc_igrpen0_el1", ICC_IGRPEN0_EL1, {}},
+  {"icc_igrpen1_el1", ICC_IGRPEN1_EL1, {}},
+  {"icc_igrpen1_el3", ICC_IGRPEN1_EL3, {}},
+  {"icc_seien_el1", ICC_SEIEN_EL1, {}},
+  {"icc_ap0r0_el1", ICC_AP0R0_EL1, {}},
+  {"icc_ap0r1_el1", ICC_AP0R1_EL1, {}},
+  {"icc_ap0r2_el1", ICC_AP0R2_EL1, {}},
+  {"icc_ap0r3_el1", ICC_AP0R3_EL1, {}},
+  {"icc_ap1r0_el1", ICC_AP1R0_EL1, {}},
+  {"icc_ap1r1_el1", ICC_AP1R1_EL1, {}},
+  {"icc_ap1r2_el1", ICC_AP1R2_EL1, {}},
+  {"icc_ap1r3_el1", ICC_AP1R3_EL1, {}},
+  {"ich_ap0r0_el2", ICH_AP0R0_EL2, {}},
+  {"ich_ap0r1_el2", ICH_AP0R1_EL2, {}},
+  {"ich_ap0r2_el2", ICH_AP0R2_EL2, {}},
+  {"ich_ap0r3_el2", ICH_AP0R3_EL2, {}},
+  {"ich_ap1r0_el2", ICH_AP1R0_EL2, {}},
+  {"ich_ap1r1_el2", ICH_AP1R1_EL2, {}},
+  {"ich_ap1r2_el2", ICH_AP1R2_EL2, {}},
+  {"ich_ap1r3_el2", ICH_AP1R3_EL2, {}},
+  {"ich_hcr_el2", ICH_HCR_EL2, {}},
+  {"ich_misr_el2", ICH_MISR_EL2, {}},
+  {"ich_vmcr_el2", ICH_VMCR_EL2, {}},
+  {"ich_vseir_el2", ICH_VSEIR_EL2, {}},
+  {"ich_lr0_el2", ICH_LR0_EL2, {}},
+  {"ich_lr1_el2", ICH_LR1_EL2, {}},
+  {"ich_lr2_el2", ICH_LR2_EL2, {}},
+  {"ich_lr3_el2", ICH_LR3_EL2, {}},
+  {"ich_lr4_el2", ICH_LR4_EL2, {}},
+  {"ich_lr5_el2", ICH_LR5_EL2, {}},
+  {"ich_lr6_el2", ICH_LR6_EL2, {}},
+  {"ich_lr7_el2", ICH_LR7_EL2, {}},
+  {"ich_lr8_el2", ICH_LR8_EL2, {}},
+  {"ich_lr9_el2", ICH_LR9_EL2, {}},
+  {"ich_lr10_el2", ICH_LR10_EL2, {}},
+  {"ich_lr11_el2", ICH_LR11_EL2, {}},
+  {"ich_lr12_el2", ICH_LR12_EL2, {}},
+  {"ich_lr13_el2", ICH_LR13_EL2, {}},
+  {"ich_lr14_el2", ICH_LR14_EL2, {}},
+  {"ich_lr15_el2", ICH_LR15_EL2, {}},
 
   // Cyclone registers
-  {"cpm_ioacc_ctl_el3", CPM_IOACC_CTL_EL3, AArch64::ProcCyclone},
+  {"cpm_ioacc_ctl_el3", CPM_IOACC_CTL_EL3, {AArch64::ProcCyclone}},
 
   // v8.1a "Privileged Access Never" extension-specific system registers
-  {"pan", PAN, AArch64::HasV8_1aOps},
+  {"pan", PAN, {AArch64::HasV8_1aOps}},
 
   // v8.1a "Limited Ordering Regions" extension-specific system registers
-  {"lorsa_el1", LORSA_EL1, AArch64::HasV8_1aOps},
-  {"lorea_el1", LOREA_EL1, AArch64::HasV8_1aOps},
-  {"lorn_el1", LORN_EL1, AArch64::HasV8_1aOps},
-  {"lorc_el1", LORC_EL1, AArch64::HasV8_1aOps},
+  {"lorsa_el1", LORSA_EL1, {AArch64::HasV8_1aOps}},
+  {"lorea_el1", LOREA_EL1, {AArch64::HasV8_1aOps}},
+  {"lorn_el1", LORN_EL1, {AArch64::HasV8_1aOps}},
+  {"lorc_el1", LORC_EL1, {AArch64::HasV8_1aOps}},
 
   // v8.1a "Virtualization host extensions" system registers
-  {"ttbr1_el2", TTBR1_EL2, AArch64::HasV8_1aOps},
-  {"contextidr_el2", CONTEXTIDR_EL2, AArch64::HasV8_1aOps},
-  {"cnthv_tval_el2", CNTHV_TVAL_EL2, AArch64::HasV8_1aOps},
-  {"cnthv_cval_el2", CNTHV_CVAL_EL2, AArch64::HasV8_1aOps},
-  {"cnthv_ctl_el2", CNTHV_CTL_EL2, AArch64::HasV8_1aOps},
-  {"sctlr_el12", SCTLR_EL12, AArch64::HasV8_1aOps},
-  {"cpacr_el12", CPACR_EL12, AArch64::HasV8_1aOps},
-  {"ttbr0_el12", TTBR0_EL12, AArch64::HasV8_1aOps},
-  {"ttbr1_el12", TTBR1_EL12, AArch64::HasV8_1aOps},
-  {"tcr_el12", TCR_EL12, AArch64::HasV8_1aOps},
-  {"afsr0_el12", AFSR0_EL12, AArch64::HasV8_1aOps},
-  {"afsr1_el12", AFSR1_EL12, AArch64::HasV8_1aOps},
-  {"esr_el12", ESR_EL12, AArch64::HasV8_1aOps},
-  {"far_el12", FAR_EL12, AArch64::HasV8_1aOps},
-  {"mair_el12", MAIR_EL12, AArch64::HasV8_1aOps},
-  {"amair_el12", AMAIR_EL12, AArch64::HasV8_1aOps},
-  {"vbar_el12", VBAR_EL12, AArch64::HasV8_1aOps},
-  {"contextidr_el12", CONTEXTIDR_EL12, AArch64::HasV8_1aOps},
-  {"cntkctl_el12", CNTKCTL_EL12, AArch64::HasV8_1aOps},
-  {"cntp_tval_el02", CNTP_TVAL_EL02, AArch64::HasV8_1aOps},
-  {"cntp_ctl_el02", CNTP_CTL_EL02, AArch64::HasV8_1aOps},
-  {"cntp_cval_el02", CNTP_CVAL_EL02, AArch64::HasV8_1aOps},
-  {"cntv_tval_el02", CNTV_TVAL_EL02, AArch64::HasV8_1aOps},
-  {"cntv_ctl_el02", CNTV_CTL_EL02, AArch64::HasV8_1aOps},
-  {"cntv_cval_el02", CNTV_CVAL_EL02, AArch64::HasV8_1aOps},
-  {"spsr_el12", SPSR_EL12, AArch64::HasV8_1aOps},
-  {"elr_el12", ELR_EL12, AArch64::HasV8_1aOps},
+  {"ttbr1_el2", TTBR1_EL2, {AArch64::HasV8_1aOps}},
+  {"contextidr_el2", CONTEXTIDR_EL2, {AArch64::HasV8_1aOps}},
+  {"cnthv_tval_el2", CNTHV_TVAL_EL2, {AArch64::HasV8_1aOps}},
+  {"cnthv_cval_el2", CNTHV_CVAL_EL2, {AArch64::HasV8_1aOps}},
+  {"cnthv_ctl_el2", CNTHV_CTL_EL2, {AArch64::HasV8_1aOps}},
+  {"sctlr_el12", SCTLR_EL12, {AArch64::HasV8_1aOps}},
+  {"cpacr_el12", CPACR_EL12, {AArch64::HasV8_1aOps}},
+  {"ttbr0_el12", TTBR0_EL12, {AArch64::HasV8_1aOps}},
+  {"ttbr1_el12", TTBR1_EL12, {AArch64::HasV8_1aOps}},
+  {"tcr_el12", TCR_EL12, {AArch64::HasV8_1aOps}},
+  {"afsr0_el12", AFSR0_EL12, {AArch64::HasV8_1aOps}},
+  {"afsr1_el12", AFSR1_EL12, {AArch64::HasV8_1aOps}},
+  {"esr_el12", ESR_EL12, {AArch64::HasV8_1aOps}},
+  {"far_el12", FAR_EL12, {AArch64::HasV8_1aOps}},
+  {"mair_el12", MAIR_EL12, {AArch64::HasV8_1aOps}},
+  {"amair_el12", AMAIR_EL12, {AArch64::HasV8_1aOps}},
+  {"vbar_el12", VBAR_EL12, {AArch64::HasV8_1aOps}},
+  {"contextidr_el12", CONTEXTIDR_EL12, {AArch64::HasV8_1aOps}},
+  {"cntkctl_el12", CNTKCTL_EL12, {AArch64::HasV8_1aOps}},
+  {"cntp_tval_el02", CNTP_TVAL_EL02, {AArch64::HasV8_1aOps}},
+  {"cntp_ctl_el02", CNTP_CTL_EL02, {AArch64::HasV8_1aOps}},
+  {"cntp_cval_el02", CNTP_CVAL_EL02, {AArch64::HasV8_1aOps}},
+  {"cntv_tval_el02", CNTV_TVAL_EL02, {AArch64::HasV8_1aOps}},
+  {"cntv_ctl_el02", CNTV_CTL_EL02, {AArch64::HasV8_1aOps}},
+  {"cntv_cval_el02", CNTV_CVAL_EL02, {AArch64::HasV8_1aOps}},
+  {"spsr_el12", SPSR_EL12, {AArch64::HasV8_1aOps}},
+  {"elr_el12", ELR_EL12, {AArch64::HasV8_1aOps}},
 };
 
 uint32_t
-AArch64SysReg::SysRegMapper::fromString(StringRef Name, uint64_t FeatureBits,
-                                        bool &Valid) const {
+AArch64SysReg::SysRegMapper::fromString(StringRef Name, 
+    const FeatureBitset& FeatureBits, bool &Valid) const {
   std::string NameLower = Name.lower();
 
   // First search the registers shared by all
@@ -850,7 +850,8 @@
 }
 
 std::string
-AArch64SysReg::SysRegMapper::toString(uint32_t Bits, uint64_t FeatureBits) const {
+AArch64SysReg::SysRegMapper::toString(uint32_t Bits, 
+                                      const FeatureBitset& FeatureBits) const {
   // First search the registers shared by all
   for (unsigned i = 0; i < array_lengthof(SysRegMappings); ++i) {
     if (SysRegMappings[i].isValueEqual(Bits, FeatureBits)) {
@@ -878,38 +879,38 @@
 }
 
 const AArch64NamedImmMapper::Mapping AArch64TLBI::TLBIMapper::TLBIMappings[] = {
-  {"ipas2e1is", IPAS2E1IS, 0},
-  {"ipas2le1is", IPAS2LE1IS, 0},
-  {"vmalle1is", VMALLE1IS, 0},
-  {"alle2is", ALLE2IS, 0},
-  {"alle3is", ALLE3IS, 0},
-  {"vae1is", VAE1IS, 0},
-  {"vae2is", VAE2IS, 0},
-  {"vae3is", VAE3IS, 0},
-  {"aside1is", ASIDE1IS, 0},
-  {"vaae1is", VAAE1IS, 0},
-  {"alle1is", ALLE1IS, 0},
-  {"vale1is", VALE1IS, 0},
-  {"vale2is", VALE2IS, 0},
-  {"vale3is", VALE3IS, 0},
-  {"vmalls12e1is", VMALLS12E1IS, 0},
-  {"vaale1is", VAALE1IS, 0},
-  {"ipas2e1", IPAS2E1, 0},
-  {"ipas2le1", IPAS2LE1, 0},
-  {"vmalle1", VMALLE1, 0},
-  {"alle2", ALLE2, 0},
-  {"alle3", ALLE3, 0},
-  {"vae1", VAE1, 0},
-  {"vae2", VAE2, 0},
-  {"vae3", VAE3, 0},
-  {"aside1", ASIDE1, 0},
-  {"vaae1", VAAE1, 0},
-  {"alle1", ALLE1, 0},
-  {"vale1", VALE1, 0},
-  {"vale2", VALE2, 0},
-  {"vale3", VALE3, 0},
-  {"vmalls12e1", VMALLS12E1, 0},
-  {"vaale1", VAALE1, 0}
+  {"ipas2e1is", IPAS2E1IS, {}},
+  {"ipas2le1is", IPAS2LE1IS, {}},
+  {"vmalle1is", VMALLE1IS, {}},
+  {"alle2is", ALLE2IS, {}},
+  {"alle3is", ALLE3IS, {}},
+  {"vae1is", VAE1IS, {}},
+  {"vae2is", VAE2IS, {}},
+  {"vae3is", VAE3IS, {}},
+  {"aside1is", ASIDE1IS, {}},
+  {"vaae1is", VAAE1IS, {}},
+  {"alle1is", ALLE1IS, {}},
+  {"vale1is", VALE1IS, {}},
+  {"vale2is", VALE2IS, {}},
+  {"vale3is", VALE3IS, {}},
+  {"vmalls12e1is", VMALLS12E1IS, {}},
+  {"vaale1is", VAALE1IS, {}},
+  {"ipas2e1", IPAS2E1, {}},
+  {"ipas2le1", IPAS2LE1, {}},
+  {"vmalle1", VMALLE1, {}},
+  {"alle2", ALLE2, {}},
+  {"alle3", ALLE3, {}},
+  {"vae1", VAE1, {}},
+  {"vae2", VAE2, {}},
+  {"vae3", VAE3, {}},
+  {"aside1", ASIDE1, {}},
+  {"vaae1", VAAE1, {}},
+  {"alle1", ALLE1, {}},
+  {"vale1", VALE1, {}},
+  {"vale2", VALE2, {}},
+  {"vale3", VALE3, {}},
+  {"vmalls12e1", VMALLS12E1, {}},
+  {"vaale1", VAALE1, {}}
 };
 
 AArch64TLBI::TLBIMapper::TLBIMapper()
diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
index 15350e7..7125f14 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
@@ -22,6 +22,7 @@
 #include "MCTargetDesc/AArch64MCTargetDesc.h" // For AArch64::X0 and friends.
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/MC/SubtargetFeature.h"
 #include "llvm/Support/ErrorHandling.h"
 
 namespace llvm {
@@ -280,16 +281,22 @@
   struct Mapping {
     const char *Name;
     uint32_t Value;
-    uint64_t FeatureBitSet;  // Set of features this mapping is available for
+    // Set of features this mapping is available for
     // Zero value of FeatureBitSet means the mapping is always available
+    FeatureBitset FeatureBitSet;
 
-    bool isNameEqual(std::string Other, uint64_t FeatureBits=~0ULL) const {
-      if (FeatureBitSet && !(FeatureBitSet & FeatureBits))
+    bool isNameEqual(std::string Other, 
+                     const FeatureBitset& FeatureBits) const {
+      if (FeatureBitSet.any() && 
+          (FeatureBitSet & FeatureBits).none())
         return false;
       return Name == Other;
     }
-    bool isValueEqual(uint32_t Other, uint64_t FeatureBits=~0ULL) const {
-      if (FeatureBitSet && !(FeatureBitSet & FeatureBits))
+
+    bool isValueEqual(uint32_t Other, 
+                      const FeatureBitset& FeatureBits) const {
+      if (FeatureBitSet.any() && 
+          (FeatureBitSet & FeatureBits).none())
         return false;
       return Value == Other;
     }
@@ -300,9 +307,11 @@
     : Mappings(&Mappings[0]), NumMappings(N), TooBigImm(TooBigImm) {}
 
   // Maps value to string, depending on availability for FeatureBits given
-  StringRef toString(uint32_t Value, uint64_t FeatureBits, bool &Valid) const;
+  StringRef toString(uint32_t Value, const FeatureBitset& FeatureBits,
+                     bool &Valid) const;
   // Maps string to value, depending on availability for FeatureBits given
-  uint32_t fromString(StringRef Name, uint64_t FeatureBits, bool &Valid) const;
+  uint32_t fromString(StringRef Name, const FeatureBitset& FeatureBits, 
+                     bool &Valid) const;
 
   /// Many of the instructions allow an alternative assembly form consisting of
   /// a simple immediate. Currently the only valid forms are ranges [0, N) where
@@ -1195,8 +1204,9 @@
     size_t NumInstMappings;
 
     SysRegMapper() { }
-    uint32_t fromString(StringRef Name, uint64_t FeatureBits, bool &Valid) const;
-    std::string toString(uint32_t Bits, uint64_t FeatureBits) const;
+    uint32_t fromString(StringRef Name, const FeatureBitset& FeatureBits,
+                        bool &Valid) const;
+    std::string toString(uint32_t Bits, const FeatureBitset& FeatureBits) const;
   };
 
   struct MSRMapper : SysRegMapper {
diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
index 86ef480..04503b8 100644
--- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -415,7 +415,7 @@
 }
 
 static bool isThumb(const MCSubtargetInfo& STI) {
-  return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
+  return STI.getFeatureBits()[ARM::ModeThumb];
 }
 
 void ARMAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
index 8bb4363..c5d6b25 100644
--- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -4538,7 +4538,7 @@
 }
 
 bool ARMBaseInstrInfo::hasNOP() const {
-  return (Subtarget.getFeatureBits() & ARM::HasV6KOps) != 0;
+  return Subtarget.getFeatureBits()[ARM::HasV6KOps];
 }
 
 bool ARMBaseInstrInfo::isSwiftFastImmShift(const MachineInstr *MI) const {
diff --git a/llvm/lib/Target/ARM/ARMSubtarget.cpp b/llvm/lib/Target/ARM/ARMSubtarget.cpp
index 008aeff..f20318d 100644
--- a/llvm/lib/Target/ARM/ARMSubtarget.cpp
+++ b/llvm/lib/Target/ARM/ARMSubtarget.cpp
@@ -265,8 +265,8 @@
   }
 
   // NEON f32 ops are non-IEEE 754 compliant. Darwin is ok with it by default.
-  uint64_t Bits = getFeatureBits();
-  if ((Bits & ARM::ProcA5 || Bits & ARM::ProcA8) && // Where this matters
+  const FeatureBitset &Bits = getFeatureBits();
+  if ((Bits[ARM::ProcA5] || Bits[ARM::ProcA8]) && // Where this matters
       (Options.UnsafeFPMath || isTargetDarwin()))
     UseNEONForSinglePrecisionFP = true;
 }
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 87368b5..863f8b2 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -243,40 +243,40 @@
 
   bool isThumb() const {
     // FIXME: Can tablegen auto-generate this?
-    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
+    return STI.getFeatureBits()[ARM::ModeThumb];
   }
   bool isThumbOne() const {
-    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
+    return isThumb() && !STI.getFeatureBits()[ARM::FeatureThumb2];
   }
   bool isThumbTwo() const {
-    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2);
+    return isThumb() && STI.getFeatureBits()[ARM::FeatureThumb2];
   }
   bool hasThumb() const {
-    return STI.getFeatureBits() & ARM::HasV4TOps;
+    return STI.getFeatureBits()[ARM::HasV4TOps];
   }
   bool hasV6Ops() const {
-    return STI.getFeatureBits() & ARM::HasV6Ops;
+    return STI.getFeatureBits()[ARM::HasV6Ops];
   }
   bool hasV6MOps() const {
-    return STI.getFeatureBits() & ARM::HasV6MOps;
+    return STI.getFeatureBits()[ARM::HasV6MOps];
   }
   bool hasV7Ops() const {
-    return STI.getFeatureBits() & ARM::HasV7Ops;
+    return STI.getFeatureBits()[ARM::HasV7Ops];
   }
   bool hasV8Ops() const {
-    return STI.getFeatureBits() & ARM::HasV8Ops;
+    return STI.getFeatureBits()[ARM::HasV8Ops];
   }
   bool hasARM() const {
-    return !(STI.getFeatureBits() & ARM::FeatureNoARM);
+    return !STI.getFeatureBits()[ARM::FeatureNoARM];
   }
   bool hasThumb2DSP() const {
-    return STI.getFeatureBits() & ARM::FeatureDSPThumb2;
+    return STI.getFeatureBits()[ARM::FeatureDSPThumb2];
   }
   bool hasD16() const {
-    return STI.getFeatureBits() & ARM::FeatureD16;
+    return STI.getFeatureBits()[ARM::FeatureD16];
   }
   bool hasV8_1aOps() const {
-    return STI.getFeatureBits() & ARM::HasV8_1aOps;
+    return STI.getFeatureBits()[ARM::HasV8_1aOps];
   }
 
   void SwitchMode() {
@@ -284,7 +284,7 @@
     setAvailableFeatures(FB);
   }
   bool isMClass() const {
-    return STI.getFeatureBits() & ARM::FeatureMClass;
+    return STI.getFeatureBits()[ARM::FeatureMClass];
   }
 
   /// @name Auto-generated Match Functions
@@ -9187,52 +9187,53 @@
 // tools/clang/lib/Driver/Tools.cpp
 static const struct {
   const unsigned ID;
-  const uint64_t Enabled;
-  const uint64_t Disabled;
+  const FeatureBitset Enabled;
+  const FeatureBitset Disabled;
 } FPUs[] = {
-    {/* ID */ ARM::FK_VFP,
-     /* Enabled */ ARM::FeatureVFP2,
-     /* Disabled */ ARM::FeatureNEON},
-    {/* ID */ ARM::FK_VFPV2,
-     /* Enabled */ ARM::FeatureVFP2,
-     /* Disabled */ ARM::FeatureNEON},
-    {/* ID */ ARM::FK_VFPV3,
-     /* Enabled */ ARM::FeatureVFP2 | ARM::FeatureVFP3,
-     /* Disabled */ ARM::FeatureNEON | ARM::FeatureD16},
-    {/* ID */ ARM::FK_VFPV3_D16,
-     /* Enable */ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureD16,
-     /* Disabled */ ARM::FeatureNEON},
-    {/* ID */ ARM::FK_VFPV4,
-     /* Enabled */ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4,
-     /* Disabled */ ARM::FeatureNEON | ARM::FeatureD16},
-    {/* ID */ ARM::FK_VFPV4_D16,
-     /* Enabled */ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 |
-         ARM::FeatureD16,
-     /* Disabled */ ARM::FeatureNEON},
-    {/* ID */ ARM::FK_FPV5_D16,
-     /* Enabled */ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 |
-         ARM::FeatureFPARMv8 | ARM::FeatureD16,
-     /* Disabled */ ARM::FeatureNEON | ARM::FeatureCrypto},
-    {/* ID */ ARM::FK_FP_ARMV8,
-     /* Enabled */ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 |
-         ARM::FeatureFPARMv8,
-     /* Disabled */ ARM::FeatureNEON | ARM::FeatureCrypto | ARM::FeatureD16},
-    {/* ID */ ARM::FK_NEON,
-     /* Enabled */ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureNEON,
-     /* Disabled */ ARM::FeatureD16},
-    {/* ID */ ARM::FK_NEON_VFPV4,
-     /* Enabled */ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 |
-         ARM::FeatureNEON,
-     /* Disabled */ ARM::FeatureD16},
-    {/* ID */ ARM::FK_NEON_FP_ARMV8,
-     /* Enabled */ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 |
-         ARM::FeatureFPARMv8 | ARM::FeatureNEON,
-     /* Disabled */ ARM::FeatureCrypto | ARM::FeatureD16},
+    {/* ID */ ARM::FK_VFP, 
+     /* Enabled */ {ARM::FeatureVFP2}, 
+     /* Disabled */ {ARM::FeatureNEON}},
+    {/* ID */ ARM::FK_VFPV2, 
+     /* Enabled */ {ARM::FeatureVFP2}, 
+     /* Disabled */ {ARM::FeatureNEON}},
+    {/* ID */ ARM::FK_VFPV3, 
+     /* Enabled */ {ARM::FeatureVFP2, ARM::FeatureVFP3},  
+     /* Disabled */ {ARM::FeatureNEON, ARM::FeatureD16}},
+    {/* ID */ ARM::FK_VFPV3_D16, 
+     /* Enabled */ {ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureD16},
+     /* Disabled */ {ARM::FeatureNEON}},
+    {/* ID */ ARM::FK_VFPV4, 
+     /* Enabled */ {ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureVFP4},
+     /* Disabled */ {ARM::FeatureNEON, ARM::FeatureD16}},
+    {/* ID */ ARM::FK_VFPV4_D16, 
+     /* Enabled */ {ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureVFP4,
+                    ARM::FeatureD16},
+     /* Disabled */ {ARM::FeatureNEON}},
+    {/* ID */ ARM::FK_FPV5_D16, 
+     /* Enabled */ {ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureVFP4,
+                    ARM::FeatureFPARMv8, ARM::FeatureD16},
+     /* Disabled */ {ARM::FeatureNEON, ARM::FeatureCrypto}},
+    {/* ID */ ARM::FK_FP_ARMV8, 
+     /* Enabled */ {ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureVFP4,
+                    ARM::FeatureFPARMv8},
+     /* Disabled */ {ARM::FeatureNEON, ARM::FeatureCrypto, ARM::FeatureD16}},
+    {/* ID */ ARM::FK_NEON, 
+     /* Enabled */ {ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureNEON}, 
+     /* Disabled */ {ARM::FeatureD16}},
+    {/* ID */ ARM::FK_NEON_VFPV4, 
+     /* Enabled */ {ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureVFP4,
+                    ARM::FeatureNEON}, 
+     /* Disabled */ {ARM::FeatureD16}},
+    {/* ID */ ARM::FK_NEON_FP_ARMV8, 
+     /* Enabled */ {ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureVFP4,
+                    ARM::FeatureFPARMv8, ARM::FeatureNEON},
+     /* Disabled */ {ARM::FeatureCrypto, ARM::FeatureD16}},
     {/* ID */ ARM::FK_CRYPTO_NEON_FP_ARMV8,
-     /* Enabled */ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 |
-         ARM::FeatureFPARMv8 | ARM::FeatureNEON | ARM::FeatureCrypto,
-     /* Disabled */ ARM::FeatureD16},
-    {ARM::FK_SOFTVFP, 0, 0},
+     /* Enabled */ {ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureVFP4,
+                    ARM::FeatureFPARMv8, ARM::FeatureNEON, 
+                    ARM::FeatureCrypto},
+     /* Disabled */ {ARM::FeatureD16}},
+    {ARM::FK_SOFTVFP, {}, {}},
 };
 
 /// parseDirectiveFPU
@@ -9254,8 +9255,8 @@
 
     // Need to toggle features that should be on but are off and that
     // should off but are on.
-    uint64_t Toggle = (Entry.Enabled & ~STI.getFeatureBits()) |
-                      (Entry.Disabled & STI.getFeatureBits());
+    FeatureBitset Toggle = (Entry.Enabled & ~STI.getFeatureBits()) |
+                           (Entry.Disabled & STI.getFeatureBits());
     setAvailableFeatures(ComputeAvailableFeatures(STI.ToggleFeature(Toggle)));
     break;
   }
@@ -9984,30 +9985,30 @@
 static const struct {
   const char *Name;
   const unsigned ArchCheck;
-  const uint64_t Features;
+  const FeatureBitset Features;
 } Extensions[] = {
-  { "crc", Feature_HasV8, ARM::FeatureCRC },
+  { "crc", Feature_HasV8, {ARM::FeatureCRC} },
   { "crypto",  Feature_HasV8,
-    ARM::FeatureCrypto | ARM::FeatureNEON | ARM::FeatureFPARMv8 },
-  { "fp", Feature_HasV8, ARM::FeatureFPARMv8 },
+    {ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8} },
+  { "fp", Feature_HasV8, {ARM::FeatureFPARMv8} },
   { "idiv", Feature_HasV7 | Feature_IsNotMClass,
-    ARM::FeatureHWDiv | ARM::FeatureHWDivARM },
+    {ARM::FeatureHWDiv, ARM::FeatureHWDivARM} },
   // FIXME: iWMMXT not supported
-  { "iwmmxt", Feature_None, 0 },
+  { "iwmmxt", Feature_None, {} },
   // FIXME: iWMMXT2 not supported
-  { "iwmmxt2", Feature_None, 0 },
+  { "iwmmxt2", Feature_None, {} },
   // FIXME: Maverick not supported
-  { "maverick", Feature_None, 0 },
-  { "mp", Feature_HasV7 | Feature_IsNotMClass, ARM::FeatureMP },
+  { "maverick", Feature_None, {} },
+  { "mp", Feature_HasV7 | Feature_IsNotMClass, {ARM::FeatureMP} },
   // FIXME: ARMv6-m OS Extensions feature not checked
-  { "os", Feature_None, 0 },
+  { "os", Feature_None, {} },
   // FIXME: Also available in ARMv6-K
-  { "sec", Feature_HasV7, ARM::FeatureTrustZone },
-  { "simd", Feature_HasV8, ARM::FeatureNEON | ARM::FeatureFPARMv8 },
+  { "sec", Feature_HasV7, {ARM::FeatureTrustZone} },
+  { "simd", Feature_HasV8, {ARM::FeatureNEON, ARM::FeatureFPARMv8} },
   // FIXME: Only available in A-class, isel not predicated
-  { "virt", Feature_HasV7, ARM::FeatureVirtualization },
+  { "virt", Feature_HasV7, {ARM::FeatureVirtualization} },
   // FIXME: xscale not supported
-  { "xscale", Feature_None, 0 },
+  { "xscale", Feature_None, {} },
 };
 
 /// parseDirectiveArchExtension
@@ -10035,7 +10036,7 @@
     if (Extension.Name != Name)
       continue;
 
-    if (!Extension.Features)
+    if (Extension.Features.none())
       report_fatal_error("unsupported architectural extension: " + Name);
 
     if ((getAvailableFeatures() & Extension.ArchCheck) != Extension.ArchCheck) {
@@ -10044,9 +10045,10 @@
       return false;
     }
 
-    uint64_t ToggleFeatures = EnableFeature
-                                  ? (~STI.getFeatureBits() & Extension.Features)
-                                  : ( STI.getFeatureBits() & Extension.Features);
+    FeatureBitset ToggleFeatures = EnableFeature
+      ? (~STI.getFeatureBits() & Extension.Features)
+      : ( STI.getFeatureBits() & Extension.Features);
+
     uint64_t Features =
         ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
     setAvailableFeatures(Features);
diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index 609fdb1..097ec04 100644
--- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -435,7 +435,7 @@
                                              raw_ostream &CS) const {
   CommentStream = &CS;
 
-  assert(!(STI.getFeatureBits() & ARM::ModeThumb) &&
+  assert(!STI.getFeatureBits()[ARM::ModeThumb] &&
          "Asked to disassemble an ARM instruction but Subtarget is in Thumb "
          "mode!");
 
@@ -700,7 +700,7 @@
                                                raw_ostream &CS) const {
   CommentStream = &CS;
 
-  assert((STI.getFeatureBits() & ARM::ModeThumb) &&
+  assert(STI.getFeatureBits()[ARM::ModeThumb] &&
          "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!");
 
   // We want to read exactly 2 bytes of data.
@@ -1026,9 +1026,10 @@
 
 static DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
                                    uint64_t Address, const void *Decoder) {
-  uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
-                                                          .getFeatureBits();
-  bool hasD16 = featureBits & ARM::FeatureD16;
+  const FeatureBitset &featureBits =
+    ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
+
+  bool hasD16 = featureBits[ARM::FeatureD16];
 
   if (RegNo > 31 || (hasD16 && RegNo > 15))
     return MCDisassembler::Fail;
@@ -1373,9 +1374,9 @@
       break;
   }
 
-  uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
-                                                          .getFeatureBits();
-  if ((featureBits & ARM::HasV8Ops) && (coproc != 14))
+  const FeatureBitset &featureBits =
+    ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
+  if (featureBits[ARM::HasV8Ops] && (coproc != 14))
     return MCDisassembler::Fail;
 
   Inst.addOperand(MCOperand::createImm(coproc));
@@ -2151,9 +2152,10 @@
   unsigned Imm = fieldFromInstruction(Insn, 9, 1);
 
   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
-  uint64_t FeatureBits = Dis->getSubtargetInfo().getFeatureBits();
-  if ((FeatureBits & ARM::HasV8_1aOps) == 0 || 
-      (FeatureBits & ARM::HasV8Ops) == 0 )
+  const FeatureBitset &FeatureBits = Dis->getSubtargetInfo().getFeatureBits();
+
+  if (!FeatureBits[ARM::HasV8_1aOps] || 
+      !FeatureBits[ARM::HasV8Ops])
     return MCDisassembler::Fail;
 
   // Decoder can be called from DecodeTST, which does not check the full
@@ -3319,10 +3321,11 @@
   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
 
-  uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
-                                                          .getFeatureBits();
-  bool hasMP = featureBits & ARM::FeatureMP;
-  bool hasV7Ops = featureBits & ARM::HasV7Ops;
+  const FeatureBitset &featureBits =
+    ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
+
+  bool hasMP = featureBits[ARM::FeatureMP];
+  bool hasV7Ops = featureBits[ARM::HasV7Ops];
 
   if (Rn == 15) {
     switch (Inst.getOpcode()) {
@@ -3405,10 +3408,11 @@
   imm |= (Rn << 9);
   unsigned add = fieldFromInstruction(Insn, 9, 1);
 
-  uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
-                                                          .getFeatureBits();
-  bool hasMP = featureBits & ARM::FeatureMP;
-  bool hasV7Ops = featureBits & ARM::HasV7Ops;
+  const FeatureBitset &featureBits =
+    ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
+
+  bool hasMP = featureBits[ARM::FeatureMP];
+  bool hasV7Ops = featureBits[ARM::HasV7Ops];
 
   if (Rn == 15) {
     switch (Inst.getOpcode()) {
@@ -3485,10 +3489,11 @@
   unsigned imm = fieldFromInstruction(Insn, 0, 12);
   imm |= (Rn << 13);
 
-  uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
-                                                          .getFeatureBits();
-  bool hasMP = (featureBits & ARM::FeatureMP);
-  bool hasV7Ops = (featureBits & ARM::HasV7Ops);
+  const FeatureBitset &featureBits =
+    ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
+
+  bool hasMP = featureBits[ARM::FeatureMP];
+  bool hasV7Ops = featureBits[ARM::HasV7Ops];
 
   if (Rn == 15) {
     switch (Inst.getOpcode()) {
@@ -3602,9 +3607,10 @@
   unsigned U = fieldFromInstruction(Insn, 23, 1);
   int imm = fieldFromInstruction(Insn, 0, 12);
 
-  uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
-                                                          .getFeatureBits();
-  bool hasV7Ops = (featureBits & ARM::HasV7Ops);
+  const FeatureBitset &featureBits =
+    ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
+
+  bool hasV7Ops = featureBits[ARM::HasV7Ops];
 
   if (Rt == 15) {
     switch (Inst.getOpcode()) {
@@ -3925,9 +3931,10 @@
   if (Val == 0xA || Val == 0xB)
     return MCDisassembler::Fail;
 
-  uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
-                                                          .getFeatureBits();
-  if ((featureBits & ARM::HasV8Ops) && !(Val == 14 || Val == 15))
+  const FeatureBitset &featureBits =
+    ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
+
+  if (featureBits[ARM::HasV8Ops] && !(Val == 14 || Val == 15))
     return MCDisassembler::Fail;
 
   Inst.addOperand(MCOperand::createImm(Val));
@@ -4077,9 +4084,10 @@
 static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val,
                           uint64_t Address, const void *Decoder) {
   DecodeStatus S = MCDisassembler::Success;
-  uint64_t FeatureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
-                                                          .getFeatureBits();
-  if (FeatureBits & ARM::FeatureMClass) {
+  const FeatureBitset &FeatureBits =
+    ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
+
+  if (FeatureBits[ARM::FeatureMClass]) {
     unsigned ValLow = Val & 0xff;
 
     // Validate the SYSm value first.
@@ -4099,7 +4107,7 @@
     case 17: // basepri
     case 18: // basepri_max
     case 19: // faultmask
-      if (!(FeatureBits & ARM::HasV7Ops))
+      if (!(FeatureBits[ARM::HasV7Ops]))
         // Values basepri, basepri_max and faultmask are only valid for v7m.
         return MCDisassembler::Fail;
       break;
@@ -4109,7 +4117,7 @@
 
     if (Inst.getOpcode() == ARM::t2MSR_M) {
       unsigned Mask = fieldFromInstruction(Val, 10, 2);
-      if (!(FeatureBits & ARM::HasV7Ops)) {
+      if (!(FeatureBits[ARM::HasV7Ops])) {
         // The ARMv6-M MSR bits {11-10} can be only 0b10, other values are
         // unpredictable.
         if (Mask != 2)
@@ -4123,7 +4131,7 @@
         // indicates the move for the GE{3:0} bits, the mask{0} bit can be set
         // only if the processor includes the DSP extension.
         if (Mask == 0 || (Mask != 2 && ValLow > 3) ||
-            (!(FeatureBits & ARM::FeatureDSPThumb2) && (Mask & 1)))
+            (!(FeatureBits[ARM::FeatureDSPThumb2]) && (Mask & 1)))
           S = MCDisassembler::SoftFail;
       }
     }
diff --git a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
index d826afd..2d36c30 100644
--- a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
+++ b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
@@ -93,7 +93,7 @@
       O << "\tsev";
       break;
     case 5:
-      if ((STI.getFeatureBits() & ARM::HasV8Ops)) {
+      if (STI.getFeatureBits()[ARM::HasV8Ops]) {
         O << "\tsevl";
         break;
       } // Fallthrough for non-v8
@@ -302,7 +302,7 @@
   case ARM::t2SUBS_PC_LR: {
     if (MI->getNumOperands() == 3 && MI->getOperand(0).isImm() &&
         MI->getOperand(0).getImm() == 0 &&
-        (STI.getFeatureBits() & ARM::FeatureVirtualization)) {
+        STI.getFeatureBits()[ARM::FeatureVirtualization]) {
       O << "\teret";
       printPredicateOperand(MI, 1, STI, O);
       printAnnotation(O, Annot);
@@ -695,7 +695,7 @@
                                      const MCSubtargetInfo &STI,
                                      raw_ostream &O) {
   unsigned val = MI->getOperand(OpNum).getImm();
-  O << ARM_MB::MemBOptToString(val, (STI.getFeatureBits() & ARM::HasV8Ops));
+  O << ARM_MB::MemBOptToString(val, STI.getFeatureBits()[ARM::HasV8Ops]);
 }
 
 void ARMInstPrinter::printInstSyncBOption(const MCInst *MI, unsigned OpNum,
@@ -795,14 +795,14 @@
   const MCOperand &Op = MI->getOperand(OpNum);
   unsigned SpecRegRBit = Op.getImm() >> 4;
   unsigned Mask = Op.getImm() & 0xf;
-  uint64_t FeatureBits = STI.getFeatureBits();
+  const FeatureBitset &FeatureBits = STI.getFeatureBits();
 
-  if (FeatureBits & ARM::FeatureMClass) {
+  if (FeatureBits[ARM::FeatureMClass]) {
     unsigned SYSm = Op.getImm();
     unsigned Opcode = MI->getOpcode();
 
     // For writes, handle extended mask bits if the DSP extension is present.
-    if (Opcode == ARM::t2MSR_M && (FeatureBits & ARM::FeatureDSPThumb2)) {
+    if (Opcode == ARM::t2MSR_M && FeatureBits[ARM::FeatureDSPThumb2]) {
       switch (SYSm) {
       case 0x400:
         O << "apsr_g";
@@ -834,7 +834,7 @@
     // Handle the basic 8-bit mask.
     SYSm &= 0xff;
 
-    if (Opcode == ARM::t2MSR_M && (FeatureBits & ARM::HasV7Ops)) {
+    if (Opcode == ARM::t2MSR_M && FeatureBits [ARM::HasV7Ops]) {
       // ARMv7-M deprecates using MSR APSR without a _<bits> qualifier as an
       // alias for MSR APSR_nzcvq.
       switch (SYSm) {
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index a53bf4e..6c1f789 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -154,7 +154,7 @@
 } // end anonymous namespace
 
 unsigned ARMAsmBackend::getRelaxedOpcode(unsigned Op) const {
-  bool HasThumb2 = STI->getFeatureBits() & ARM::FeatureThumb2;
+  bool HasThumb2 = STI->getFeatureBits()[ARM::FeatureThumb2];
 
   switch (Op) {
   default:
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
index 4fa8c79..4e60372 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
@@ -33,7 +33,7 @@
     return ARM::NumTargetFixupKinds;
   }
 
-  bool hasNOP() const { return (STI->getFeatureBits() & ARM::HasV6T2Ops) != 0; }
+  bool hasNOP() const { return STI->getFeatureBits()[ARM::HasV6T2Ops]; }
 
   const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
 
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
index 53758a0..84bb092 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
@@ -51,10 +51,10 @@
   ~ARMMCCodeEmitter() override {}
 
   bool isThumb(const MCSubtargetInfo &STI) const {
-    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
+    return STI.getFeatureBits()[ARM::ModeThumb];
   }
   bool isThumb2(const MCSubtargetInfo &STI) const {
-    return isThumb(STI) && (STI.getFeatureBits() & ARM::FeatureThumb2) != 0;
+    return isThumb(STI) && STI.getFeatureBits()[ARM::FeatureThumb2];
   }
   bool isTargetMachO(const MCSubtargetInfo &STI) const {
     Triple TT(STI.getTargetTriple());
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
index ebe881a..30deba9 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
@@ -33,7 +33,7 @@
 
 static bool getMCRDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI,
                                   std::string &Info) {
-  if (STI.getFeatureBits() & llvm::ARM::HasV7Ops &&
+  if (STI.getFeatureBits()[llvm::ARM::HasV7Ops] &&
       (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 15) &&
       (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) &&
       // Checks for the deprecated CP15ISB encoding:
@@ -65,7 +65,7 @@
 
 static bool getITDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI,
                                  std::string &Info) {
-  if (STI.getFeatureBits() & llvm::ARM::HasV8Ops && MI.getOperand(1).isImm() &&
+  if (STI.getFeatureBits()[llvm::ARM::HasV8Ops] && MI.getOperand(1).isImm() &&
       MI.getOperand(1).getImm() != 8) {
     Info = "applying IT instruction to more than one subsequent instruction is "
            "deprecated";
@@ -77,7 +77,7 @@
 
 static bool getARMStoreDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI,
                                        std::string &Info) {
-  assert((~STI.getFeatureBits() & llvm::ARM::ModeThumb) &&
+  assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] &&
          "cannot predicate thumb instructions");
 
   assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
@@ -94,7 +94,7 @@
 
 static bool getARMLoadDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI,
                                       std::string &Info) {
-  assert((~STI.getFeatureBits() & llvm::ARM::ModeThumb) &&
+  assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] &&
          "cannot predicate thumb instructions");
 
   assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index fcec18e..d8f2b8b 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -78,15 +78,7 @@
   // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
   // The reason we need this mask is explained in the selectArch function.
   // FIXME: Ideally we would like TableGen to generate this information.
-  static const uint64_t AllArchRelatedMask =
-      Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
-      Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
-      Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
-      Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
-      Mips::FeatureMips32r3 | Mips::FeatureMips32r5 | Mips::FeatureMips32r6 |
-      Mips::FeatureMips64 | Mips::FeatureMips64r2 | Mips::FeatureMips64r3 |
-      Mips::FeatureMips64r5 | Mips::FeatureMips64r6 | Mips::FeatureCnMips |
-      Mips::FeatureFP64Bit | Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
+  static const FeatureBitset AllArchRelatedMask;
 
 private:
   unsigned ATReg;
@@ -96,6 +88,17 @@
 };
 }
 
+const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
+    Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
+    Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
+    Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
+    Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
+    Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
+    Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
+    Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
+    Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
+};
+
 namespace {
 class MipsAsmParser : public MCTargetAsmParser {
   MipsTargetStreamer &getTargetStreamer() {
@@ -317,7 +320,7 @@
   // FeatureMipsGP64 | FeatureMips1)
   // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
   void selectArch(StringRef ArchFeature) {
-    uint64_t FeatureBits = STI.getFeatureBits();
+    FeatureBitset FeatureBits = STI.getFeatureBits();
     FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
     STI.setFeatureBits(FeatureBits);
     setAvailableFeatures(
@@ -326,7 +329,7 @@
   }
 
   void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
-    if (!(STI.getFeatureBits() & Feature)) {
+    if (!(STI.getFeatureBits()[Feature])) {
       setAvailableFeatures(
           ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
     }
@@ -334,7 +337,7 @@
   }
 
   void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
-    if (STI.getFeatureBits() & Feature) {
+    if (STI.getFeatureBits()[Feature]) {
       setAvailableFeatures(
           ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
     }
@@ -381,69 +384,70 @@
   /// True if all of $fcc0 - $fcc7 exist for the current ISA.
   bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
 
-  bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
-  bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
+  bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
+  bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
   const MipsABIInfo &getABI() const { return ABI; }
   bool isABI_N32() const { return ABI.IsN32(); }
   bool isABI_N64() const { return ABI.IsN64(); }
   bool isABI_O32() const { return ABI.IsO32(); }
-  bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
+  bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
 
   bool useOddSPReg() const {
-    return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
+    return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
   }
 
   bool inMicroMipsMode() const {
-    return STI.getFeatureBits() & Mips::FeatureMicroMips;
+    return STI.getFeatureBits()[Mips::FeatureMicroMips];
   }
-  bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
-  bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
-  bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
-  bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
-  bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
+  bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
+  bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
+  bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
+  bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
+  bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
   bool hasMips32() const {
-    return (STI.getFeatureBits() & Mips::FeatureMips32);
+    return STI.getFeatureBits()[Mips::FeatureMips32];
   }
   bool hasMips64() const {
-    return (STI.getFeatureBits() & Mips::FeatureMips64);
+    return STI.getFeatureBits()[Mips::FeatureMips64];
   }
   bool hasMips32r2() const {
-    return (STI.getFeatureBits() & Mips::FeatureMips32r2);
+    return STI.getFeatureBits()[Mips::FeatureMips32r2];
   }
   bool hasMips64r2() const {
-    return (STI.getFeatureBits() & Mips::FeatureMips64r2);
+    return STI.getFeatureBits()[Mips::FeatureMips64r2];
   }
   bool hasMips32r3() const {
-    return (STI.getFeatureBits() & Mips::FeatureMips32r3);
+    return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
   }
   bool hasMips64r3() const {
-    return (STI.getFeatureBits() & Mips::FeatureMips64r3);
+    return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
   }
   bool hasMips32r5() const {
-    return (STI.getFeatureBits() & Mips::FeatureMips32r5);
+    return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
   }
   bool hasMips64r5() const {
-    return (STI.getFeatureBits() & Mips::FeatureMips64r5);
+    return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
   }
   bool hasMips32r6() const {
-    return (STI.getFeatureBits() & Mips::FeatureMips32r6);
+    return STI.getFeatureBits()[Mips::FeatureMips32r6];
   }
   bool hasMips64r6() const {
-    return (STI.getFeatureBits() & Mips::FeatureMips64r6);
+    return STI.getFeatureBits()[Mips::FeatureMips64r6];
   }
+
+  bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
+  bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
+  bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
   bool hasCnMips() const {
-    return (STI.getFeatureBits() & Mips::FeatureCnMips);
+    return (STI.getFeatureBits()[Mips::FeatureCnMips]);
   }
-  bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
-  bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
-  bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
 
   bool inMips16Mode() const {
-    return STI.getFeatureBits() & Mips::FeatureMips16;
+    return STI.getFeatureBits()[Mips::FeatureMips16];
   }
 
   bool useSoftFloat() const {
-    return (STI.getFeatureBits() & Mips::FeatureSoftFloat);
+    return STI.getFeatureBits()[Mips::FeatureSoftFloat];
   }
 
   /// Warn if RegIndex is the same as the current AT.
diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
index 4fc1293..eb97c93 100644
--- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
+++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
@@ -36,16 +36,16 @@
 public:
   MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian)
       : MCDisassembler(STI, Ctx),
-        IsMicroMips(STI.getFeatureBits() & Mips::FeatureMicroMips),
+        IsMicroMips(STI.getFeatureBits()[Mips::FeatureMicroMips]),
         IsBigEndian(IsBigEndian) {}
 
-  bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
-  bool hasMips32() const { return STI.getFeatureBits() & Mips::FeatureMips32; }
+  bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
+  bool hasMips32() const { return STI.getFeatureBits()[Mips::FeatureMips32]; }
   bool hasMips32r6() const {
-    return STI.getFeatureBits() & Mips::FeatureMips32r6;
+    return STI.getFeatureBits()[Mips::FeatureMips32r6];
   }
 
-  bool isGP64() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
+  bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
 
   bool hasCOP3() const {
     // Only present in MIPS-I and MIPS-II
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
index 21cd546..a0d9e15 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
@@ -113,11 +113,11 @@
 }
 
 bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const {
-  return STI.getFeatureBits() & Mips::FeatureMicroMips;
+  return STI.getFeatureBits()[Mips::FeatureMicroMips];
 }
 
 bool MipsMCCodeEmitter::isMips32r6(const MCSubtargetInfo &STI) const {
-  return STI.getFeatureBits() & Mips::FeatureMips32r6;
+  return STI.getFeatureBits()[Mips::FeatureMips32r6];
 }
 
 void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const {
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
index f14160d..a59f353 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
@@ -386,7 +386,7 @@
   MCAssembler &MCA = getStreamer().getAssembler();
   Pic = MCA.getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_;
 
-  uint64_t Features = STI.getFeatureBits();
+  const FeatureBitset &Features = STI.getFeatureBits();
 
   // Set the header flags that we can in the constructor.
   // FIXME: This is a fairly terrible hack. We set the rest
@@ -402,35 +402,35 @@
   unsigned EFlags = MCA.getELFHeaderEFlags();
 
   // Architecture
-  if (Features & Mips::FeatureMips64r6)
+  if (Features[Mips::FeatureMips64r6])
     EFlags |= ELF::EF_MIPS_ARCH_64R6;
-  else if (Features & Mips::FeatureMips64r2 ||
-           Features & Mips::FeatureMips64r3 ||
-           Features & Mips::FeatureMips64r5)
+  else if (Features[Mips::FeatureMips64r2] ||
+           Features[Mips::FeatureMips64r3] ||
+           Features[Mips::FeatureMips64r5])
     EFlags |= ELF::EF_MIPS_ARCH_64R2;
-  else if (Features & Mips::FeatureMips64)
+  else if (Features[Mips::FeatureMips64])
     EFlags |= ELF::EF_MIPS_ARCH_64;
-  else if (Features & Mips::FeatureMips5)
+  else if (Features[Mips::FeatureMips5])
     EFlags |= ELF::EF_MIPS_ARCH_5;
-  else if (Features & Mips::FeatureMips4)
+  else if (Features[Mips::FeatureMips4])
     EFlags |= ELF::EF_MIPS_ARCH_4;
-  else if (Features & Mips::FeatureMips3)
+  else if (Features[Mips::FeatureMips3])
     EFlags |= ELF::EF_MIPS_ARCH_3;
-  else if (Features & Mips::FeatureMips32r6)
+  else if (Features[Mips::FeatureMips32r6])
     EFlags |= ELF::EF_MIPS_ARCH_32R6;
-  else if (Features & Mips::FeatureMips32r2 ||
-           Features & Mips::FeatureMips32r3 ||
-           Features & Mips::FeatureMips32r5)
+  else if (Features[Mips::FeatureMips32r2] ||
+           Features[Mips::FeatureMips32r3] ||
+           Features[Mips::FeatureMips32r5])
     EFlags |= ELF::EF_MIPS_ARCH_32R2;
-  else if (Features & Mips::FeatureMips32)
+  else if (Features[Mips::FeatureMips32])
     EFlags |= ELF::EF_MIPS_ARCH_32;
-  else if (Features & Mips::FeatureMips2)
+  else if (Features[Mips::FeatureMips2])
     EFlags |= ELF::EF_MIPS_ARCH_2;
   else
     EFlags |= ELF::EF_MIPS_ARCH_1;
 
   // Other options.
-  if (Features & Mips::FeatureNaN2008)
+  if (Features[Mips::FeatureNaN2008])
     EFlags |= ELF::EF_MIPS_NAN2008;
 
   // -mabicalls and -mplt are not implemented but we should act as if they were
@@ -470,7 +470,7 @@
   DataSection.setAlignment(std::max(16u, DataSection.getAlignment()));
   BSSSection.setAlignment(std::max(16u, BSSSection.getAlignment()));
 
-  uint64_t Features = STI.getFeatureBits();
+  const FeatureBitset &Features = STI.getFeatureBits();
 
   // Update e_header flags. See the FIXME and comment above in
   // the constructor for a full rundown on this.
@@ -483,10 +483,10 @@
   else if (getABI().IsN32())
     EFlags |= ELF::EF_MIPS_ABI2;
 
-  if (Features & Mips::FeatureGP64Bit) {
+  if (Features[Mips::FeatureGP64Bit]) {
     if (getABI().IsO32())
       EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */
-  } else if (Features & Mips::FeatureMips64r2 || Features & Mips::FeatureMips64)
+  } else if (Features[Mips::FeatureMips64r2] || Features[Mips::FeatureMips64])
     EFlags |= ELF::EF_MIPS_32BITMODE;
 
   // If we've set the cpic eflag and we're n64, go ahead and set the pic
diff --git a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
index 1522504..f8997fd 100644
--- a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
+++ b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
@@ -1682,7 +1682,7 @@
   //  where th can be omitted when it is 0. dcbtst is the same. We take the
   //  server form to be the default, so swap the operands if we're parsing for
   //  an embedded core (they'll be swapped again upon printing).
-  if ((STI.getFeatureBits() & PPC::FeatureBookE) != 0 &&
+  if (STI.getFeatureBits()[PPC::FeatureBookE] &&
       Operands.size() == 4 &&
       (Name == "dcbt" || Name == "dcbtst")) {
     std::swap(Operands[1], Operands[3]);
diff --git a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
index e2320a1..4799ea2 100644
--- a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
+++ b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
@@ -387,7 +387,7 @@
   uint32_t Inst =
       (Bytes[0] << 24) | (Bytes[1] << 16) | (Bytes[2] << 8) | (Bytes[3] << 0);
 
-  if ((STI.getFeatureBits() & PPC::FeatureQPX) != 0) {
+  if (STI.getFeatureBits()[PPC::FeatureQPX]) {
     DecodeStatus result =
       decodeInstruction(DecoderTableQPX32, MI, Inst, Address, this, STI);
     if (result != MCDisassembler::Fail)
diff --git a/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp b/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
index 53223ed..1a130e8 100644
--- a/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
@@ -121,7 +121,7 @@
       O << "t";
     O << " ";
 
-    bool IsBookE = (STI.getFeatureBits() & PPC::FeatureBookE) != 0;
+    bool IsBookE = STI.getFeatureBits()[PPC::FeatureBookE];
     if (IsBookE && TH != 0 && TH != 16)
       O << (unsigned int) TH << ", ";
 
diff --git a/llvm/lib/Target/R600/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/R600/AsmParser/AMDGPUAsmParser.cpp
index 37ecf0f..19bffd5 100644
--- a/llvm/lib/Target/R600/AsmParser/AMDGPUAsmParser.cpp
+++ b/llvm/lib/Target/R600/AsmParser/AMDGPUAsmParser.cpp
@@ -321,7 +321,7 @@
       : MCTargetAsmParser(), STI(STI), MII(MII), Parser(_Parser),
         ForcedEncodingSize(0){
 
-    if (!STI.getFeatureBits()) {
+    if (STI.getFeatureBits().none()) {
       // Set default features.
       STI.ToggleFeature("SOUTHERN_ISLANDS");
     }
diff --git a/llvm/lib/Target/R600/MCTargetDesc/R600MCCodeEmitter.cpp b/llvm/lib/Target/R600/MCTargetDesc/R600MCCodeEmitter.cpp
index daa5859..a809564 100644
--- a/llvm/lib/Target/R600/MCTargetDesc/R600MCCodeEmitter.cpp
+++ b/llvm/lib/Target/R600/MCTargetDesc/R600MCCodeEmitter.cpp
@@ -99,7 +99,7 @@
   } else if (IS_VTX(Desc)) {
     uint64_t InstWord01 = getBinaryCodeForInstr(MI, Fixups, STI);
     uint32_t InstWord2 = MI.getOperand(2).getImm(); // Offset
-    if (!(STI.getFeatureBits() & AMDGPU::FeatureCaymanISA)) {
+    if (!(STI.getFeatureBits()[AMDGPU::FeatureCaymanISA])) {
       InstWord2 |= 1 << 19; // Mega-Fetch bit
     }
 
@@ -132,7 +132,7 @@
       Emit((uint32_t) 0, OS);
   } else {
     uint64_t Inst = getBinaryCodeForInstr(MI, Fixups, STI);
-    if ((STI.getFeatureBits() & AMDGPU::FeatureR600ALUInst) &&
+    if ((STI.getFeatureBits()[AMDGPU::FeatureR600ALUInst]) &&
        ((Desc.TSFlags & R600_InstFlag::OP1) ||
          Desc.TSFlags & R600_InstFlag::OP2)) {
       uint64_t ISAOpCode = Inst & (0x3FFULL << 39);
diff --git a/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp b/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
index b6eebb0..bac2617 100644
--- a/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
+++ b/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
@@ -35,7 +35,7 @@
 #include "SparcGenAsmWriter.inc"
 
 bool SparcInstPrinter::isV9(const MCSubtargetInfo &STI) const {
-  return (STI.getFeatureBits() & Sparc::FeatureV9) != 0;
+  return (STI.getFeatureBits()[Sparc::FeatureV9]) != 0;
 }
 
 void SparcInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp
index 6a206bb..a21f8c7 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp
@@ -261,13 +261,13 @@
                                               MCContext &Ctx, int64_t *Residue);
 
   bool is64BitMode() const {
-    return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
+    return STI.getFeatureBits()[X86::Mode64Bit];
   }
   bool is32BitMode() const {
-    return (STI.getFeatureBits() & X86::Mode32Bit) != 0;
+    return STI.getFeatureBits()[X86::Mode32Bit];
   }
   bool is16BitMode() const {
-    return (STI.getFeatureBits() & X86::Mode16Bit) != 0;
+    return STI.getFeatureBits()[X86::Mode16Bit];
   }
 
   unsigned getPointerWidth() {
@@ -1072,9 +1072,9 @@
   const bool hasCompilerRTSupport = T.isOSLinux();
   if (ClAsanInstrumentAssembly && hasCompilerRTSupport &&
       MCOptions.SanitizeAddress) {
-    if ((STI.getFeatureBits() & X86::Mode32Bit) != 0)
+    if (STI.getFeatureBits()[X86::Mode32Bit] != 0)
       return new X86AddressSanitizer32(STI);
-    if ((STI.getFeatureBits() & X86::Mode64Bit) != 0)
+    if (STI.getFeatureBits()[X86::Mode64Bit] != 0)
       return new X86AddressSanitizer64(STI);
   }
   return new X86AsmInstrumentation(STI);
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 6c384ff..3047fd1 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -729,23 +729,24 @@
 
   bool is64BitMode() const {
     // FIXME: Can tablegen auto-generate this?
-    return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
+    return STI.getFeatureBits()[X86::Mode64Bit];
   }
   bool is32BitMode() const {
     // FIXME: Can tablegen auto-generate this?
-    return (STI.getFeatureBits() & X86::Mode32Bit) != 0;
+    return STI.getFeatureBits()[X86::Mode32Bit];
   }
   bool is16BitMode() const {
     // FIXME: Can tablegen auto-generate this?
-    return (STI.getFeatureBits() & X86::Mode16Bit) != 0;
+    return STI.getFeatureBits()[X86::Mode16Bit];
   }
-  void SwitchMode(uint64_t mode) {
-    uint64_t oldMode = STI.getFeatureBits() &
-        (X86::Mode64Bit | X86::Mode32Bit | X86::Mode16Bit);
-    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(oldMode | mode));
+  void SwitchMode(unsigned mode) {
+    FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit});
+    FeatureBitset OldMode = STI.getFeatureBits() & AllModes;
+    unsigned FB = ComputeAvailableFeatures(
+      STI.ToggleFeature(OldMode.flip(mode)));
     setAvailableFeatures(FB);
-    assert(mode == (STI.getFeatureBits() &
-                    (X86::Mode64Bit | X86::Mode32Bit | X86::Mode16Bit)));
+    
+    assert(FeatureBitset({mode}) == (STI.getFeatureBits() & AllModes));
   }
 
   unsigned getPointerWidth() {
@@ -1696,7 +1697,7 @@
   }
 
   // rounding mode token
-  if (STI.getFeatureBits() & X86::FeatureAVX512 &&
+  if (STI.getFeatureBits()[X86::FeatureAVX512] &&
       getLexer().is(AsmToken::LCurly))
     return ParseRoundingModeOp(Start, End);
 
@@ -1754,7 +1755,7 @@
   }
   case AsmToken::LCurly:{
     SMLoc Start = Parser.getTok().getLoc(), End;
-    if (STI.getFeatureBits() & X86::FeatureAVX512)
+    if (STI.getFeatureBits()[X86::FeatureAVX512])
       return ParseRoundingModeOp(Start, End);
     return ErrorOperand(Start, "unknown token in expression");
   }
@@ -1764,7 +1765,7 @@
 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
                                        const MCParsedAsmOperand &Op) {
   MCAsmParser &Parser = getParser();
-  if(STI.getFeatureBits() & X86::FeatureAVX512) {
+  if(STI.getFeatureBits()[X86::FeatureAVX512]) {
     if (getLexer().is(AsmToken::LCurly)) {
       // Eat "{" and mark the current place.
       const SMLoc consumedToken = consumeToken();
diff --git a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
index 772294c..3469d19 100644
--- a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
+++ b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
@@ -80,20 +80,19 @@
                                          MCContext &Ctx,
                                          std::unique_ptr<const MCInstrInfo> MII)
   : MCDisassembler(STI, Ctx), MII(std::move(MII)) {
-  switch (STI.getFeatureBits() &
-          (X86::Mode16Bit | X86::Mode32Bit | X86::Mode64Bit)) {
-  case X86::Mode16Bit:
+  const FeatureBitset &FB = STI.getFeatureBits();
+  if (FB[X86::Mode16Bit]) {
     fMode = MODE_16BIT;
-    break;
-  case X86::Mode32Bit:
+    return;
+  } else if (FB[X86::Mode32Bit]) {
     fMode = MODE_32BIT;
-    break;
-  case X86::Mode64Bit:
+    return;
+  } else if (FB[X86::Mode64Bit]) {
     fMode = MODE_64BIT;
-    break;
-  default:
-    llvm_unreachable("Invalid CPU mode");
+    return;
   }
+
+  llvm_unreachable("Invalid CPU mode");
 }
 
 struct Region {
diff --git a/llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp b/llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp
index f265f1d..e0b6c50 100644
--- a/llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp
+++ b/llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp
@@ -57,7 +57,7 @@
   // InstrInfo.td as soon as Requires clause is supported properly
   // for InstAlias.
   if (MI->getOpcode() == X86::CALLpcrel32 &&
-      (STI.getFeatureBits() & X86::Mode64Bit) != 0) {
+      (STI.getFeatureBits()[X86::Mode64Bit])) {
     OS << "\tcallq\t";
     printPCRelImm(MI, 0, OS);
   }
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index 3affef0..8aed7a4 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -42,15 +42,15 @@
   ~X86MCCodeEmitter() override {}
 
   bool is64BitMode(const MCSubtargetInfo &STI) const {
-    return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
+    return STI.getFeatureBits()[X86::Mode64Bit];
   }
 
   bool is32BitMode(const MCSubtargetInfo &STI) const {
-    return (STI.getFeatureBits() & X86::Mode32Bit) != 0;
+    return STI.getFeatureBits()[X86::Mode32Bit];
   }
 
   bool is16BitMode(const MCSubtargetInfo &STI) const {
-    return (STI.getFeatureBits() & X86::Mode16Bit) != 0;
+    return STI.getFeatureBits()[X86::Mode16Bit];
   }
 
   /// Is16BitMemOperand - Return true if the specified instruction has