arch: Minimize use of RegClassType constants and the RegId constructor.

These are global values which prevent making register types ISA
specific.

Change-Id: I513adcae5ad316122c24f25a9e01b9974629510f
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49785
Maintainer: Gabe Black <gabe.black@gmail.com>
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
diff --git a/src/arch/arm/aapcs32.hh b/src/arch/arm/aapcs32.hh
index ff52039..a2d5627 100644
--- a/src/arch/arm/aapcs32.hh
+++ b/src/arch/arm/aapcs32.hh
@@ -191,7 +191,7 @@
     get(ThreadContext *tc, Aapcs32::State &state)
     {
         if (state.ncrn <= state.MAX_CRN) {
-            return tc->getReg(RegId(IntRegClass, state.ncrn++));
+            return tc->getReg(ArmISA::intRegClass[state.ncrn++]);
         }
 
         // Max out the ncrn since we effectively exhausted it.
@@ -216,11 +216,13 @@
                 state.ncrn + 1 <= state.MAX_CRN) {
             Integer low, high;
             if (ArmISA::byteOrder(tc) == ByteOrder::little) {
-                low = tc->getReg(RegId(IntRegClass, state.ncrn++)) & mask(32);
-                high = tc->getReg(RegId(IntRegClass, state.ncrn++)) & mask(32);
+                low = tc->getReg(ArmISA::intRegClass[state.ncrn++]) & mask(32);
+                high = tc->getReg(ArmISA::intRegClass[state.ncrn++]) &
+                    mask(32);
             } else {
-                high = tc->getReg(RegId(IntRegClass, state.ncrn++)) & mask(32);
-                low = tc->getReg(RegId(IntRegClass, state.ncrn++)) & mask(32);
+                high = tc->getReg(ArmISA::intRegClass[state.ncrn++]) &
+                    mask(32);
+                low = tc->getReg(ArmISA::intRegClass[state.ncrn++]) & mask(32);
             }
             return low | (high << 32);
         }
@@ -295,7 +297,7 @@
     prepare(ThreadContext *tc, Aapcs32::State &state)
     {
         if (sizeof(Composite) > sizeof(uint32_t))
-            state.retAddr = tc->getReg(RegId(IntRegClass, state.ncrn++));
+            state.retAddr = tc->getReg(ArmISA::intRegClass[state.ncrn++]);
     }
 };
 
@@ -316,7 +318,7 @@
         if (bytes <= chunk_size) {
             if (state.ncrn++ <= state.MAX_CRN) {
                 alignas(alignof(Composite)) uint32_t val =
-                    tc->getReg(RegId(IntRegClass, state.ncrn++));
+                    tc->getReg(ArmISA::intRegClass[state.ncrn++]);
                 val = htog(val, ArmISA::byteOrder(tc));
                 return gtoh(*(Composite *)&val, ArmISA::byteOrder(tc));
             }
@@ -328,7 +330,7 @@
         if (state.ncrn + regs - 1 <= state.MAX_CRN) {
             alignas(alignof(Composite)) uint8_t buf[bytes];
             for (int i = 0; i < regs; i++) {
-                Chunk val = tc->getReg(RegId(IntRegClass, state.ncrn++));
+                Chunk val = tc->getReg(ArmISA::intRegClass[state.ncrn++]);
                 val = htog(val, ArmISA::byteOrder(tc));
                 size_t to_copy = std::min<size_t>(bytes, chunk_size);
                 memcpy(buf + i * chunk_size, &val, to_copy);
@@ -342,7 +344,7 @@
 
             int offset = 0;
             while (state.ncrn <= state.MAX_CRN) {
-                Chunk val = tc->getReg(RegId(IntRegClass, state.ncrn++));
+                Chunk val = tc->getReg(ArmISA::intRegClass[state.ncrn++]);
                 val = htog(val, ArmISA::byteOrder(tc));
                 size_t to_copy = std::min<size_t>(bytes, chunk_size);
                 memcpy(buf + offset, &val, to_copy);
@@ -479,7 +481,7 @@
         auto *vec_elems = static_cast<ArmISA::VecElem *>(&bytes);
         constexpr int chunks = sizeof(Float) / sizeof(ArmISA::VecElem);
         for (int chunk = 0; chunk < chunks; chunk++)
-            tc->setReg(RegId(VecElemClass, chunk), vec_elems[chunk]);
+            tc->setReg(ArmISA::vecElemClass[chunk], vec_elems[chunk]);
     };
 };
 
@@ -503,7 +505,7 @@
 
         constexpr int chunks = sizeof(Float) / sizeof(ArmISA::VecElem);
         for (int chunk = 0; chunk < chunks; chunk++)
-            vec_elems[chunk] = tc->getReg(RegId(VecElemClass, chunk));
+            vec_elems[chunk] = tc->getReg(ArmISA::vecElemClass[chunk]);
 
         return bitsToFloat(result);
     }
@@ -571,7 +573,7 @@
                 const int reg = index / lane_per_reg;
                 const int lane = index % lane_per_reg;
 
-                RegId id(VecRegClass, reg);
+                RegId id = ArmISA::vecRegClass[reg];
                 ArmISA::VecRegContainer val;
                 tc->getReg(id, &val);
                 ha[i] = val.as<Elem>()[lane];
@@ -619,7 +621,7 @@
             const int reg = i / lane_per_reg;
             const int lane = i % lane_per_reg;
 
-            RegId id(VecRegClass, reg);
+            RegId id = ArmISA::vecRegClass[reg];
             ArmISA::VecRegContainer val;
             tc->getReg(id, &val);
             val.as<Elem>()[lane] = ha[i];
diff --git a/src/arch/arm/aapcs64.hh b/src/arch/arm/aapcs64.hh
index fe58fef..f179252 100644
--- a/src/arch/arm/aapcs64.hh
+++ b/src/arch/arm/aapcs64.hh
@@ -201,7 +201,7 @@
     get(ThreadContext *tc, Aapcs64::State &state)
     {
         if (state.nsrn <= state.MAX_SRN) {
-            RegId id(VecRegClass, state.nsrn++);
+            RegId id = ArmISA::vecRegClass[state.nsrn++];
             ArmISA::VecRegContainer vc;
             tc->getReg(id, &vc);
             return vc.as<Float>()[0];
@@ -218,7 +218,7 @@
     static void
     store(ThreadContext *tc, const Float &f)
     {
-        RegId id(VecRegClass, 0);
+        RegId id = ArmISA::vecRegClass[0];
         ArmISA::VecRegContainer reg;
         tc->getReg(id, &reg);
         reg.as<Float>()[0] = f;
@@ -241,7 +241,7 @@
     get(ThreadContext *tc, Aapcs64::State &state)
     {
         if (state.ngrn <= state.MAX_GRN)
-            return tc->getReg(RegId(IntRegClass, state.ngrn++));
+            return tc->getReg(ArmISA::intRegClass[state.ngrn++]);
 
         // Max out ngrn since we've effectively saturated it.
         state.ngrn = state.MAX_GRN + 1;
@@ -262,8 +262,8 @@
             state.ngrn++;
 
         if (sizeof(Integer) == 16 && state.ngrn + 1 <= state.MAX_GRN) {
-            Integer low = tc->getReg(RegId(IntRegClass, state.ngrn++));
-            Integer high = tc->getReg(RegId(IntRegClass, state.ngrn++));
+            Integer low = tc->getReg(ArmISA::intRegClass[state.ngrn++]);
+            Integer high = tc->getReg(ArmISA::intRegClass[state.ngrn++]);
             high = high << 64;
             return high | low;
         }
@@ -382,7 +382,7 @@
         if (state.ngrn + regs - 1 <= state.MAX_GRN) {
             alignas(alignof(Composite)) uint8_t buf[bytes];
             for (int i = 0; i < regs; i++) {
-                Chunk val = tc->getReg(RegId(IntRegClass, state.ngrn++));
+                Chunk val = tc->getReg(ArmISA::intRegClass[state.ngrn++]);
                 val = htog(val, ArmISA::byteOrder(tc));
                 size_t to_copy = std::min<size_t>(bytes, chunk_size);
                 memcpy(buf + i * chunk_size, &val, to_copy);
diff --git a/src/arch/arm/fastmodel/iris/thread_context.cc b/src/arch/arm/fastmodel/iris/thread_context.cc
index eb7ba68..8061d07 100644
--- a/src/arch/arm/fastmodel/iris/thread_context.cc
+++ b/src/arch/arm/fastmodel/iris/thread_context.cc
@@ -46,6 +46,7 @@
 
 #include "arch/arm/fastmodel/iris/cpu.hh"
 #include "arch/arm/fastmodel/iris/memory_spaces.hh"
+#include "arch/arm/regs/vec.hh"
 #include "arch/arm/system.hh"
 #include "arch/arm/utility.hh"
 #include "base/logging.hh"
@@ -878,7 +879,7 @@
 const ArmISA::VecRegContainer &
 ThreadContext::readVecRegFlat(RegIndex idx) const
 {
-    return readVecReg(RegId(VecRegClass, idx));
+    return readVecReg(ArmISA::vecRegClass[idx]);
 }
 
 const ArmISA::VecPredRegContainer &
@@ -913,7 +914,7 @@
 ArmISA::VecPredRegContainer
 ThreadContext::readVecPredRegFlat(RegIndex idx) const
 {
-    return readVecPredReg(RegId(VecPredRegClass, idx));
+    return readVecPredReg(ArmISA::vecPredRegClass[idx]);
 }
 
 } // namespace Iris
diff --git a/src/arch/arm/htm.cc b/src/arch/arm/htm.cc
index 2549fe3..9c249c5 100644
--- a/src/arch/arm/htm.cc
+++ b/src/arch/arm/htm.cc
@@ -77,17 +77,13 @@
     nzcv = tc->readMiscReg(MISCREG_NZCV);
     daif = tc->readMiscReg(MISCREG_DAIF);
     for (auto n = 0; n < int_reg::NumArchRegs; n++) {
-        x[n] = tc->getReg(RegId(IntRegClass, n));
+        x[n] = tc->getReg(intRegClass[n]);
     }
     // TODO first detect if FP is enabled at this EL
-    for (auto n = 0; n < NumVecRegs; n++) {
-        RegId idx = RegId(VecRegClass, n);
-        tc->getReg(idx, &z[n]);
-    }
-    for (auto n = 0; n < NumVecPredRegs; n++) {
-        RegId idx = RegId(VecPredRegClass, n);
-        tc->getReg(idx, &p[n]);
-    }
+    for (auto n = 0; n < NumVecRegs; n++)
+        tc->getReg(vecRegClass[n], &z[n]);
+    for (auto n = 0; n < NumVecPredRegs; n++)
+        tc->getReg(vecPredRegClass[n], &p[n]);
     fpcr = tc->readMiscReg(MISCREG_FPCR);
     fpsr = tc->readMiscReg(MISCREG_FPSR);
     pcstateckpt = tc->pcState().as<PCState>();
@@ -103,18 +99,13 @@
     //tc->setMiscReg(MISCREG_ICC_PMR_EL1, tme_checkpoint->iccPmrEl1);
     tc->setMiscReg(MISCREG_NZCV, nzcv);
     tc->setMiscReg(MISCREG_DAIF, daif);
-    for (auto n = 0; n < int_reg::NumArchRegs; n++) {
-        tc->setReg(RegId(IntRegClass, n), x[n]);
-    }
+    for (auto n = 0; n < int_reg::NumArchRegs; n++)
+        tc->setReg(intRegClass[n], x[n]);
     // TODO first detect if FP is enabled at this EL
-    for (auto n = 0; n < NumVecRegs; n++) {
-        RegId idx = RegId(VecRegClass, n);
-        tc->setReg(idx, &z[n]);
-    }
-    for (auto n = 0; n < NumVecPredRegs; n++) {
-        RegId idx = RegId(VecPredRegClass, n);
-        tc->setReg(idx, &p[n]);
-    }
+    for (auto n = 0; n < NumVecRegs; n++)
+        tc->setReg(vecRegClass[n], &z[n]);
+    for (auto n = 0; n < NumVecPredRegs; n++)
+        tc->setReg(vecPredRegClass[n], &p[n]);
     tc->setMiscReg(MISCREG_FPCR, fpcr);
     tc->setMiscReg(MISCREG_FPSR, fpsr);
 
@@ -158,7 +149,7 @@
         replaceBits(error_code, 15, 1);
     if (interrupt)
         replaceBits(error_code, 23, 1);
-    tc->setReg(RegId(IntRegClass, rt), error_code);
+    tc->setReg(intRegClass[rt], error_code);
 
     // set next PC
     pcstateckpt.uReset();
diff --git a/src/arch/arm/insts/tme64.cc b/src/arch/arm/insts/tme64.cc
index 2b82283..5632dfa 100644
--- a/src/arch/arm/insts/tme64.cc
+++ b/src/arch/arm/insts/tme64.cc
@@ -123,7 +123,7 @@
 
     _numSrcRegs = 0;
     _numDestRegs = 0;
-    setDestRegIdx(_numDestRegs++, RegId(IntRegClass, dest));
+    setDestRegIdx(_numDestRegs++, intRegClass[dest]);
     _numTypedDestRegs[IntRegClass]++;
     flags[IsHtmStart] = true;
     flags[IsInteger] = true;
@@ -152,7 +152,7 @@
 
     _numSrcRegs = 0;
     _numDestRegs = 0;
-    setDestRegIdx(_numDestRegs++, RegId(IntRegClass, dest));
+    setDestRegIdx(_numDestRegs++, intRegClass[dest]);
     _numTypedDestRegs[IntRegClass]++;
     flags[IsInteger] = true;
     flags[IsMicroop] = true;
diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc
index e50b906..69ca4f1 100644
--- a/src/arch/arm/isa.cc
+++ b/src/arch/arm/isa.cc
@@ -550,30 +550,23 @@
 void
 ISA::copyRegsFrom(ThreadContext *src)
 {
-    for (int i = 0; i < int_reg::NumRegs; i++) {
-        RegId reg(IntRegClass, i);
-        tc->setRegFlat(reg, src->getRegFlat(reg));
-    }
+    for (auto &id: intRegClass)
+        tc->setRegFlat(id, src->getRegFlat(id));
 
-    for (int i = 0; i < cc_reg::NumRegs; i++) {
-        RegId reg(CCRegClass, i);
-        tc->setReg(reg, src->getReg(reg));
-    }
+    for (auto &id: ccRegClass)
+        tc->setReg(id, src->getReg(id));
 
     for (int i = 0; i < NUM_MISCREGS; i++)
         tc->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
 
     ArmISA::VecRegContainer vc;
-    for (int i = 0; i < NumVecRegs; i++) {
-        RegId reg(VecRegClass, i);
-        src->getRegFlat(reg, &vc);
-        tc->setRegFlat(reg, &vc);
+    for (auto &id: vecRegClass) {
+        src->getRegFlat(id, &vc);
+        tc->setRegFlat(id, &vc);
     }
 
-    for (int i = 0; i < NumVecRegs * NumVecElemPerVecReg; i++) {
-        RegId reg(VecElemClass, i);
-        tc->setRegFlat(reg, src->getRegFlat(reg));
-    }
+    for (auto &id: vecElemClass)
+        tc->setRegFlat(id, src->getRegFlat(id));
 
     // setMiscReg "with effect" will set the misc register mapping correctly.
     // e.g. updateRegMap(val)
diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh
index 599411f..3aacff7 100644
--- a/src/arch/arm/isa.hh
+++ b/src/arch/arm/isa.hh
@@ -650,20 +650,19 @@
         {
             switch (regId.classValue()) {
               case IntRegClass:
-                return RegId(IntRegClass, flattenIntIndex(regId.index()));
+                return intRegClass[flattenIntIndex(regId.index())];
               case FloatRegClass:
-                return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
+                panic("ARM doesn't use FloatRegClass.");
               case VecRegClass:
-                return RegId(VecRegClass, flattenVecIndex(regId.index()));
+                return vecRegClass[flattenVecIndex(regId.index())];
               case VecElemClass:
-                return RegId(VecElemClass, flattenVecElemIndex(regId.index()));
+                return vecElemClass[flattenVecElemIndex(regId.index())];
               case VecPredRegClass:
-                return RegId(VecPredRegClass,
-                             flattenVecPredIndex(regId.index()));
+                return vecPredRegClass[flattenVecPredIndex(regId.index())];
               case CCRegClass:
-                return RegId(CCRegClass, flattenCCIndex(regId.index()));
+                return ccRegClass[flattenCCIndex(regId.index())];
               case MiscRegClass:
-                return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
+                return miscRegClass[flattenMiscIndex(regId.index())];
               case InvalidRegClass:
                 return RegId();
             }
diff --git a/src/arch/arm/isa/insts/data64.isa b/src/arch/arm/isa/insts/data64.isa
index 922e923..1873e7a 100644
--- a/src/arch/arm/isa/insts/data64.isa
+++ b/src/arch/arm/isa/insts/data64.isa
@@ -324,7 +324,7 @@
     msr_check_code = '''
         auto pre_flat = (MiscRegIndex)snsBankedIndex64(dest, xc->tcBase());
         MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->
-            flattenRegId(RegId(MiscRegClass, pre_flat)).index();
+            flattenRegId(miscRegClass[pre_flat]).index();
         CPSR cpsr = Cpsr;
         ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
         %s
@@ -333,7 +333,7 @@
     mrs_check_code = '''
         auto pre_flat = (MiscRegIndex)snsBankedIndex64(op1, xc->tcBase());
         MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->
-            flattenRegId(RegId(MiscRegClass, pre_flat)).index();
+            flattenRegId(miscRegClass[pre_flat]).index();
         CPSR cpsr = Cpsr;
         ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
         %s
@@ -545,7 +545,7 @@
             auto pre_flat =
                 (MiscRegIndex)snsBankedIndex64(dest, xc->tcBase());
             MiscRegIndex misc_index = (MiscRegIndex) xc->tcBase()->
-                flattenRegId(RegId(MiscRegClass, pre_flat)).index();
+                flattenRegId(miscRegClass[pre_flat]).index();
 
             if (!miscRegInfo[misc_index][MISCREG_IMPLEMENTED]) {
                     return std::make_shared<UndefinedInstruction>(
diff --git a/src/arch/arm/isa/insts/fp.isa b/src/arch/arm/isa/insts/fp.isa
index 00f2b80..43a3214 100644
--- a/src/arch/arm/isa/insts/fp.isa
+++ b/src/arch/arm/isa/insts/fp.isa
@@ -213,7 +213,7 @@
     if (!isSecure(xc->tcBase()) && (cpsr.mode != MODE_HYP)) {
         HCR hcr = Hcr;
         bool hypTrap = false;
-        switch(xc->tcBase()->flattenRegId(RegId(MiscRegClass, op1)).index()) {
+        switch (xc->tcBase()->flattenRegId(miscRegClass[op1]).index()) {
           case MISCREG_FPSID:
             hypTrap = hcr.tid0;
             break;
diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa
index 6083407..e352727 100644
--- a/src/arch/arm/isa/insts/misc.isa
+++ b/src/arch/arm/isa/insts/misc.isa
@@ -890,7 +890,7 @@
 
     mrc14code = '''
     MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenRegId(
-                               RegId(MiscRegClass, op1)).index();
+                               miscRegClass[op1]).index();
     auto [can_read, undefined] = canReadCoprocReg(miscReg, Scr, Cpsr,
                                                   xc->tcBase());
     if (!can_read || undefined) {
@@ -914,7 +914,7 @@
 
     mcr14code = '''
     MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenRegId(
-                               RegId(MiscRegClass, dest)).index();
+                               miscRegClass[dest]).index();
     auto [can_write, undefined] = canWriteCoprocReg(miscReg, Scr, Cpsr,
                                                     xc->tcBase());
     if (undefined || !can_write) {
@@ -938,8 +938,8 @@
     mrc15code = '''
     int preFlatOp1 = snsBankedIndex(op1, xc->tcBase());
     MiscRegIndex miscReg = (MiscRegIndex)
-                           xc->tcBase()->flattenRegId(RegId(MiscRegClass,
-                                                      preFlatOp1)).index();
+                           xc->tcBase()->flattenRegId(miscRegClass[
+                                                      preFlatOp1]).index();
 
     Fault fault = mcrMrc15Trap(miscReg, machInst, xc->tcBase(), imm);
 
@@ -970,8 +970,8 @@
     mcr15CheckCode = '''
     int preFlatDest = snsBankedIndex(dest, xc->tcBase());
     MiscRegIndex miscReg = (MiscRegIndex)
-                       xc->tcBase()->flattenRegId(RegId(MiscRegClass,
-                                                  preFlatDest)).index();
+                       xc->tcBase()->flattenRegId(miscRegClass[
+                                                  preFlatDest]).index();
 
     Fault fault = mcrMrc15Trap(miscReg, machInst, xc->tcBase(), imm);
 
@@ -1016,8 +1016,8 @@
     mrrc15code = '''
     int preFlatOp1 = snsBankedIndex(op1, xc->tcBase());
     MiscRegIndex miscReg = (MiscRegIndex)
-                           xc->tcBase()->flattenRegId(RegId(MiscRegClass,
-                                                      preFlatOp1)).index();
+                           xc->tcBase()->flattenRegId(miscRegClass[
+                                                      preFlatOp1]).index();
 
     Fault fault = mcrrMrrc15Trap(miscReg, machInst, xc->tcBase(), imm);
 
@@ -1048,8 +1048,8 @@
     mcrr15code = '''
     int preFlatDest = snsBankedIndex(dest, xc->tcBase());
     MiscRegIndex miscReg = (MiscRegIndex)
-                           xc->tcBase()->flattenRegId(RegId(MiscRegClass,
-                                                      preFlatDest)).index();
+                           xc->tcBase()->flattenRegId(miscRegClass[
+                                                      preFlatDest]).index();
 
     Fault fault = mcrrMrrc15Trap(miscReg, machInst, xc->tcBase(), imm);
 
diff --git a/src/arch/arm/isa/templates/mem64.isa b/src/arch/arm/isa/templates/mem64.isa
index 5097fb0..fda3560 100644
--- a/src/arch/arm/isa/templates/mem64.isa
+++ b/src/arch/arm/isa/templates/mem64.isa
@@ -923,7 +923,7 @@
         %(set_reg_idx_arr)s;
         %(constructor)s;
         isXZR = false;
-        uint32_t r2 = RegId(IntRegClass, dest).index() ;
+        uint32_t r2 = dest;
         flags[IsStore] = false;
         flags[IsLoad] = false;
         if (r2 == 31) {
diff --git a/src/arch/arm/kvm/arm_cpu.cc b/src/arch/arm/kvm/arm_cpu.cc
index 42aeea6..309ef75 100644
--- a/src/arch/arm/kvm/arm_cpu.cc
+++ b/src/arch/arm/kvm/arm_cpu.cc
@@ -664,7 +664,7 @@
     for (const KvmIntRegInfo *ri(kvmIntRegs);
          ri->idx != init_reg::NumRegs; ++ri) {
 
-        uint64_t value = tc->getRegFlat(RegId(IntRegClass, ri->idx));
+        uint64_t value = tc->getRegFlat(intRegClass[ri->idx]);
         DPRINTF(KvmContext, "kvm(%s) := 0x%x\n", ri->name, value);
         setOneReg(ri->id, value);
     }
@@ -772,9 +772,8 @@
         const unsigned idx_base = idx << 1;
         const unsigned idx_hi = idx_base + 1;
         const unsigned idx_lo = idx_base + 0;
-        uint64_t value =
-            ((uint64_t)tc->getRegFlat(RegId(FloatRegClass, idx_hi)) << 32) |
-            tc->getRegFlat(RegId(FloatRegClass, idx_lo));
+        uint64_t value = (tc->getRegFlat(floatRegClass[idx_hi]) << 32) |
+            tc->getRegFlat(floatRegClass[idx_lo]);
 
         setOneReg(id, value);
     } else if (regIsVfpCtrl(id)) {
@@ -804,7 +803,7 @@
     for (const KvmIntRegInfo *ri(kvmIntRegs);
          ri->idx != int_reg::NumRegs; ++ri) {
 
-        tc->setRegFlat(RegId(IntRegClass, ri->idx), getOneRegU32(ri->id));
+        tc->setRegFlat(intRegClass[ri->idx], getOneRegU32(ri->id));
     }
 
     for (const KvmCoreMiscRegInfo *ri(kvmCoreMiscRegs);
@@ -915,9 +914,8 @@
         const unsigned idx_lo = idx_base + 0;
         uint64_t value = getOneRegU64(id);
 
-        tc->setRegFlat(RegId(FloatRegClass, idx_hi),
-                (value >> 32) & 0xFFFFFFFF);
-        tc->setRegFlat(RegId(FloatRegClass, idx_lo), value & 0xFFFFFFFF);
+        tc->setRegFlat(floatRegClass[idx_hi], (value >> 32) & 0xFFFFFFFF);
+        tc->setRegFlat(floatRegClass[idx_lo], value & 0xFFFFFFFF);
     } else if (regIsVfpCtrl(id)) {
         MiscRegIndex idx = decodeVFPCtrlReg(id);
         if (idx == NUM_MISCREGS) {
diff --git a/src/arch/arm/kvm/armv8_cpu.cc b/src/arch/arm/kvm/armv8_cpu.cc
index a059e14..db626d3 100644
--- a/src/arch/arm/kvm/armv8_cpu.cc
+++ b/src/arch/arm/kvm/armv8_cpu.cc
@@ -39,6 +39,8 @@
 
 #include <linux/kvm.h>
 
+#include "arch/arm/regs/int.hh"
+#include "arch/arm/regs/vec.hh"
 #include "debug/KvmContext.hh"
 #include "params/ArmV8KvmCPU.hh"
 
@@ -249,7 +251,7 @@
     }
 
     for (const auto &ri : intRegMap) {
-        const uint64_t value = tc->getReg(RegId(IntRegClass, ri.idx));
+        const uint64_t value = tc->getReg(intRegClass[ri.idx]);
         DPRINTF(KvmContext, "  %s := 0x%x\n", ri.name, value);
         setOneReg(ri.kvm, value);
     }
@@ -259,7 +261,7 @@
         if (!inAArch64(tc))
             syncVecElemsToRegs(tc);
         ArmISA::VecRegContainer vc;
-        tc->getReg(RegId(VecRegClass, i), &vc);
+        tc->getReg(vecRegClass[i], &vc);
         auto v = vc.as<VecElem>();
         for (int j = 0; j < FP_REGS_PER_VFP_REG; j++)
             reg.s[j].i = v[j];
@@ -327,14 +329,14 @@
     for (const auto &ri : intRegMap) {
         const auto value(getOneRegU64(ri.kvm));
         DPRINTF(KvmContext, "  %s := 0x%x\n", ri.name, value);
-        tc->setReg(RegId(IntRegClass, ri.idx), value);
+        tc->setReg(intRegClass[ri.idx], value);
     }
 
     for (int i = 0; i < NUM_QREGS; ++i) {
         KvmFPReg reg;
         DPRINTF(KvmContext, "  Q%i: %s\n", i, getAndFormatOneReg(kvmFPReg(i)));
         getOneReg(kvmFPReg(i), reg.data);
-        auto v = tc->getWritableVecReg(RegId(VecRegClass, i)).as<VecElem>();
+        auto v = tc->getWritableVecReg(vecRegClass[i]).as<VecElem>();
         for (int j = 0; j < FP_REGS_PER_VFP_REG; j++)
             v[j] = reg.s[j].i;
         if (!inAArch64(tc))
diff --git a/src/arch/arm/nativetrace.cc b/src/arch/arm/nativetrace.cc
index 0303ff6..7e105b7 100644
--- a/src/arch/arm/nativetrace.cc
+++ b/src/arch/arm/nativetrace.cc
@@ -41,7 +41,9 @@
 #include "arch/arm/nativetrace.hh"
 
 #include "arch/arm/regs/cc.hh"
+#include "arch/arm/regs/int.hh"
 #include "arch/arm/regs/misc.hh"
+#include "arch/arm/regs/vec.hh"
 #include "base/compiler.hh"
 #include "cpu/thread_context.hh"
 #include "debug/ExecRegDelta.hh"
@@ -109,7 +111,7 @@
 
     // Regular int regs
     for (int i = 0; i < 15; i++) {
-        newState[i] = tc->getReg(RegId(IntRegClass, i));
+        newState[i] = tc->getReg(intRegClass[i]);
         changed[i] = (oldState[i] != newState[i]);
     }
 
@@ -129,7 +131,7 @@
 
     for (int i = 0; i < NumVecV7ArchRegs; i++) {
         ArmISA::VecRegContainer vec_container;
-        tc->getReg(RegId(VecRegClass, i), &vec_container);
+        tc->getReg(vecRegClass[i], &vec_container);
         auto *vec = vec_container.as<uint64_t>();
         newState[STATE_F0 + 2*i] = vec[0];
         newState[STATE_F0 + 2*i + 1] = vec[1];
diff --git a/src/arch/arm/regs/cc.hh b/src/arch/arm/regs/cc.hh
index 7126e4e..e3792cb 100644
--- a/src/arch/arm/regs/cc.hh
+++ b/src/arch/arm/regs/cc.hh
@@ -61,13 +61,21 @@
     NumRegs
 };
 
+} // namespace cc_reg
+
+inline constexpr RegClass ccRegClass(CCRegClass, cc_reg::NumRegs,
+        debug::CCRegs);
+
+namespace cc_reg
+{
+
 inline constexpr RegId
-    Nz(CCRegClass, _NzIdx),
-    C(CCRegClass, _CIdx),
-    V(CCRegClass, _VIdx),
-    Ge(CCRegClass, _GeIdx),
-    Fp(CCRegClass, _FpIdx),
-    Zero(CCRegClass, _ZeroIdx);
+    Nz = ccRegClass[_NzIdx],
+    C = ccRegClass[_CIdx],
+    V = ccRegClass[_VIdx],
+    Ge = ccRegClass[_GeIdx],
+    Fp = ccRegClass[_FpIdx],
+    Zero = ccRegClass[_ZeroIdx];
 
 const char * const RegName[NumRegs] = {
     "nz",
@@ -80,9 +88,6 @@
 
 } // namespace cc_reg
 
-inline constexpr RegClass ccRegClass(CCRegClass, cc_reg::NumRegs,
-        debug::CCRegs);
-
 enum ConditionCode
 {
     COND_EQ  =   0,
diff --git a/src/arch/arm/regs/int.hh b/src/arch/arm/regs/int.hh
index 8481571..61bdc1d 100644
--- a/src/arch/arm/regs/int.hh
+++ b/src/arch/arm/regs/int.hh
@@ -161,94 +161,102 @@
     _X31Idx
 };
 
+} // namespace int_reg
+
+inline constexpr RegClass intRegClass(IntRegClass, int_reg::NumRegs,
+        debug::IntRegs);
+
+namespace int_reg
+{
+
 inline constexpr RegId
     /* All the unique register indices. */
-    R0(IntRegClass, _R0Idx),
-    R1(IntRegClass, _R1Idx),
-    R2(IntRegClass, _R2Idx),
-    R3(IntRegClass, _R3Idx),
-    R4(IntRegClass, _R4Idx),
-    R5(IntRegClass, _R5Idx),
-    R6(IntRegClass, _R6Idx),
-    R7(IntRegClass, _R7Idx),
-    R8(IntRegClass, _R8Idx),
-    R9(IntRegClass, _R9Idx),
-    R10(IntRegClass, _R10Idx),
-    R11(IntRegClass, _R11Idx),
-    R12(IntRegClass, _R12Idx),
-    R13(IntRegClass, _R13Idx),
-    R14(IntRegClass, _R14Idx),
-    R15(IntRegClass, _R15Idx),
+    R0 = intRegClass[_R0Idx],
+    R1 = intRegClass[_R1Idx],
+    R2 = intRegClass[_R2Idx],
+    R3 = intRegClass[_R3Idx],
+    R4 = intRegClass[_R4Idx],
+    R5 = intRegClass[_R5Idx],
+    R6 = intRegClass[_R6Idx],
+    R7 = intRegClass[_R7Idx],
+    R8 = intRegClass[_R8Idx],
+    R9 = intRegClass[_R9Idx],
+    R10 = intRegClass[_R10Idx],
+    R11 = intRegClass[_R11Idx],
+    R12 = intRegClass[_R12Idx],
+    R13 = intRegClass[_R13Idx],
+    R14 = intRegClass[_R14Idx],
+    R15 = intRegClass[_R15Idx],
 
-    R13Svc(IntRegClass, _R13SvcIdx),
-    R14Svc(IntRegClass, _R14SvcIdx),
+    R13Svc = intRegClass[_R13SvcIdx],
+    R14Svc = intRegClass[_R14SvcIdx],
 
-    R13Mon(IntRegClass, _R13MonIdx),
-    R14Mon(IntRegClass, _R14MonIdx),
+    R13Mon = intRegClass[_R13MonIdx],
+    R14Mon = intRegClass[_R14MonIdx],
 
-    R13Hyp(IntRegClass, _R13HypIdx),
+    R13Hyp = intRegClass[_R13HypIdx],
 
-    R13Abt(IntRegClass, _R13AbtIdx),
-    R14Abt(IntRegClass, _R14AbtIdx),
+    R13Abt = intRegClass[_R13AbtIdx],
+    R14Abt = intRegClass[_R14AbtIdx],
 
-    R13Und(IntRegClass, _R13UndIdx),
-    R14Und(IntRegClass, _R14UndIdx),
+    R13Und = intRegClass[_R13UndIdx],
+    R14Und = intRegClass[_R14UndIdx],
 
-    R13Irq(IntRegClass, _R13IrqIdx),
-    R14Irq(IntRegClass, _R14IrqIdx),
+    R13Irq = intRegClass[_R13IrqIdx],
+    R14Irq = intRegClass[_R14IrqIdx],
 
-    R8Fiq(IntRegClass, _R8FiqIdx),
-    R9Fiq(IntRegClass, _R9FiqIdx),
-    R10Fiq(IntRegClass, _R10FiqIdx),
-    R11Fiq(IntRegClass, _R11FiqIdx),
-    R12Fiq(IntRegClass, _R12FiqIdx),
-    R13Fiq(IntRegClass, _R13FiqIdx),
-    R14Fiq(IntRegClass, _R14FiqIdx),
+    R8Fiq = intRegClass[_R8FiqIdx],
+    R9Fiq = intRegClass[_R9FiqIdx],
+    R10Fiq = intRegClass[_R10FiqIdx],
+    R11Fiq = intRegClass[_R11FiqIdx],
+    R12Fiq = intRegClass[_R12FiqIdx],
+    R13Fiq = intRegClass[_R13FiqIdx],
+    R14Fiq = intRegClass[_R14FiqIdx],
 
-    Zero(IntRegClass, _ZeroIdx),
-    Ureg0(IntRegClass, _Ureg0Idx),
-    Ureg1(IntRegClass, _Ureg1Idx),
-    Ureg2(IntRegClass, _Ureg2Idx),
+    Zero = intRegClass[_ZeroIdx],
+    Ureg0 = intRegClass[_Ureg0Idx],
+    Ureg1 = intRegClass[_Ureg1Idx],
+    Ureg2 = intRegClass[_Ureg2Idx],
 
-    Sp0(IntRegClass, _Sp0Idx),
-    Sp1(IntRegClass, _Sp1Idx),
-    Sp2(IntRegClass, _Sp2Idx),
-    Sp3(IntRegClass, _Sp3Idx),
+    Sp0 = intRegClass[_Sp0Idx],
+    Sp1 = intRegClass[_Sp1Idx],
+    Sp2 = intRegClass[_Sp2Idx],
+    Sp3 = intRegClass[_Sp3Idx],
 
-    Spx(IntRegClass, _SpxIdx),
+    Spx = intRegClass[_SpxIdx],
 
-    X0(IntRegClass, _X0Idx),
-    X1(IntRegClass, _X1Idx),
-    X2(IntRegClass, _X2Idx),
-    X3(IntRegClass, _X3Idx),
-    X4(IntRegClass, _X4Idx),
-    X5(IntRegClass, _X5Idx),
-    X6(IntRegClass, _X6Idx),
-    X7(IntRegClass, _X7Idx),
-    X8(IntRegClass, _X8Idx),
-    X9(IntRegClass, _X9Idx),
-    X10(IntRegClass, _X10Idx),
-    X11(IntRegClass, _X11Idx),
-    X12(IntRegClass, _X12Idx),
-    X13(IntRegClass, _X13Idx),
-    X14(IntRegClass, _X14Idx),
-    X15(IntRegClass, _X15Idx),
-    X16(IntRegClass, _X16Idx),
-    X17(IntRegClass, _X17Idx),
-    X18(IntRegClass, _X18Idx),
-    X19(IntRegClass, _X19Idx),
-    X20(IntRegClass, _X20Idx),
-    X21(IntRegClass, _X21Idx),
-    X22(IntRegClass, _X22Idx),
-    X23(IntRegClass, _X23Idx),
-    X24(IntRegClass, _X24Idx),
-    X25(IntRegClass, _X25Idx),
-    X26(IntRegClass, _X26Idx),
-    X27(IntRegClass, _X27Idx),
-    X28(IntRegClass, _X28Idx),
-    X29(IntRegClass, _X29Idx),
-    X30(IntRegClass, _X30Idx),
-    X31(IntRegClass, _X31Idx);
+    X0 = intRegClass[_X0Idx],
+    X1 = intRegClass[_X1Idx],
+    X2 = intRegClass[_X2Idx],
+    X3 = intRegClass[_X3Idx],
+    X4 = intRegClass[_X4Idx],
+    X5 = intRegClass[_X5Idx],
+    X6 = intRegClass[_X6Idx],
+    X7 = intRegClass[_X7Idx],
+    X8 = intRegClass[_X8Idx],
+    X9 = intRegClass[_X9Idx],
+    X10 = intRegClass[_X10Idx],
+    X11 = intRegClass[_X11Idx],
+    X12 = intRegClass[_X12Idx],
+    X13 = intRegClass[_X13Idx],
+    X14 = intRegClass[_X14Idx],
+    X15 = intRegClass[_X15Idx],
+    X16 = intRegClass[_X16Idx],
+    X17 = intRegClass[_X17Idx],
+    X18 = intRegClass[_X18Idx],
+    X19 = intRegClass[_X19Idx],
+    X20 = intRegClass[_X20Idx],
+    X21 = intRegClass[_X21Idx],
+    X22 = intRegClass[_X22Idx],
+    X23 = intRegClass[_X23Idx],
+    X24 = intRegClass[_X24Idx],
+    X25 = intRegClass[_X25Idx],
+    X26 = intRegClass[_X26Idx],
+    X27 = intRegClass[_X27Idx],
+    X28 = intRegClass[_X28Idx],
+    X29 = intRegClass[_X29Idx],
+    X30 = intRegClass[_X30Idx],
+    X31 = intRegClass[_X31Idx];
 
 inline constexpr auto
     &Sp = R13,
@@ -425,7 +433,7 @@
 x(unsigned index)
 {
     assert(index < NumArchRegs);
-    return RegId(IntRegClass, _X0Idx + index);
+    return intRegClass[_X0Idx + index];
 }
 
 const RegMap RegUsrMap = {
@@ -551,9 +559,6 @@
 
 } // namespace int_reg
 
-inline constexpr RegClass intRegClass(IntRegClass, int_reg::NumRegs,
-        debug::IntRegs);
-
 static inline int
 flattenIntRegModeIndex(int reg)
 {
diff --git a/src/arch/arm/remote_gdb.cc b/src/arch/arm/remote_gdb.cc
index 7b91fab..c357f02 100644
--- a/src/arch/arm/remote_gdb.cc
+++ b/src/arch/arm/remote_gdb.cc
@@ -243,7 +243,7 @@
     size_t base = 0;
     for (int i = 0; i < NumVecV8ArchRegs; i++) {
         ArmISA::VecRegContainer vc;
-        context->getReg(RegId(VecRegClass, i), &vc);
+        context->getReg(vecRegClass[i], &vc);
         auto v = vc.as<VecElem>();
         for (size_t j = 0; j < NumVecElemPerNeonVecReg; j++) {
             r.v[base] = v[j];
@@ -273,7 +273,7 @@
     size_t base = 0;
     for (int i = 0; i < NumVecV8ArchRegs; i++) {
         auto *vc = static_cast<ArmISA::VecRegContainer *>(
-                context->getWritableReg(RegId(VecRegClass, i)));
+                context->getWritableReg(vecRegClass[i]));
         auto v = vc->as<VecElem>();
         for (size_t j = 0; j < NumVecElemPerNeonVecReg; j++) {
             v[j] = r.v[base];
diff --git a/src/arch/arm/tracers/tarmac_parser.cc b/src/arch/arm/tracers/tarmac_parser.cc
index 34d7ca7..6a6742a 100644
--- a/src/arch/arm/tracers/tarmac_parser.cc
+++ b/src/arch/arm/tracers/tarmac_parser.cc
@@ -45,6 +45,8 @@
 
 #include "arch/arm/insts/static_inst.hh"
 #include "arch/arm/mmu.hh"
+#include "arch/arm/regs/int.hh"
+#include "arch/arm/regs/vec.hh"
 #include "cpu/static_inst.hh"
 #include "cpu/thread_context.hh"
 #include "mem/packet.hh"
@@ -755,31 +757,28 @@
         switch (it->type) {
           case REG_R:
           case REG_X:
-            values.push_back(thread->getReg(RegId(IntRegClass, it->index)));
+            values.push_back(thread->getReg(intRegClass[it->index]));
             break;
           case REG_S:
             if (instRecord.isetstate == ISET_A64) {
                 ArmISA::VecRegContainer vc;
-                thread->getReg(RegId(VecRegClass, it->index), &vc);
+                thread->getReg(vecRegClass[it->index], &vc);
                 auto vv = vc.as<uint32_t>();
                 values.push_back(vv[0]);
             } else {
-                const VecElem elem = thread->getReg(
-                    RegId(VecElemClass, it->index));
+                const VecElem elem = thread->getReg(vecElemClass[it->index]);
                 values.push_back(elem);
             }
             break;
           case REG_D:
             if (instRecord.isetstate == ISET_A64) {
                 ArmISA::VecRegContainer vc;
-                thread->getReg(RegId(VecRegClass, it->index), &vc);
+                thread->getReg(vecRegClass[it->index], &vc);
                 auto vv = vc.as<uint64_t>();
                 values.push_back(vv[0]);
             } else {
-                const VecElem w0 = thread->getReg(
-                    RegId(VecElemClass, it->index));
-                const VecElem w1 = thread->getReg(
-                    RegId(VecElemClass, it->index + 1));
+                const VecElem w0 = thread->getReg(vecElemClass[it->index]);
+                const VecElem w1 = thread->getReg(vecElemClass[it->index + 1]);
 
                 values.push_back((uint64_t)(w1) << 32 | w0);
             }
@@ -787,7 +786,7 @@
           case REG_P:
             {
                 ArmISA::VecPredRegContainer pc;
-                thread->getReg(RegId(VecPredRegClass, it->index), &pc);
+                thread->getReg(vecPredRegClass[it->index], &pc);
                 auto pv = pc.as<uint8_t>();
                 uint64_t p = 0;
                 for (int i = maxVectorLength * 8; i > 0; ) {
@@ -799,19 +798,15 @@
           case REG_Q:
             if (instRecord.isetstate == ISET_A64) {
                 ArmISA::VecRegContainer vc;
-                thread->getReg(RegId(VecRegClass, it->index), &vc);
+                thread->getReg(vecRegClass[it->index], &vc);
                 auto vv = vc.as<uint64_t>();
                 values.push_back(vv[0]);
                 values.push_back(vv[1]);
             } else {
-                const VecElem w0 = thread->getReg(
-                    RegId(VecElemClass, it->index));
-                const VecElem w1 = thread->getReg(
-                    RegId(VecElemClass, it->index + 1));
-                const VecElem w2 = thread->getReg(
-                    RegId(VecElemClass, it->index + 2));
-                const VecElem w3 = thread->getReg(
-                    RegId(VecElemClass, it->index + 3));
+                const VecElem w0 = thread->getReg(vecElemClass[it->index]);
+                const VecElem w1 = thread->getReg(vecElemClass[it->index + 1]);
+                const VecElem w2 = thread->getReg(vecElemClass[it->index + 2]);
+                const VecElem w3 = thread->getReg(vecElemClass[it->index + 3]);
 
                 values.push_back((uint64_t)(w1) << 32 | w0);
                 values.push_back((uint64_t)(w3) << 32 | w2);
@@ -821,7 +816,7 @@
             {
                 int8_t i = maxVectorLength;
                 ArmISA::VecRegContainer vc;
-                thread->getReg(RegId(VecRegClass, it->index), &vc);
+                thread->getReg(vecRegClass[it->index], &vc);
                 auto vv = vc.as<uint64_t>();
                 while (i > 0) {
                     values.push_back(vv[--i]);
diff --git a/src/arch/arm/tracers/tarmac_record.cc b/src/arch/arm/tracers/tarmac_record.cc
index 94dbc51..d9b9a88 100644
--- a/src/arch/arm/tracers/tarmac_record.cc
+++ b/src/arch/arm/tracers/tarmac_record.cc
@@ -233,7 +233,7 @@
 
     regValid = true;
     regName = cc_reg::RegName[regRelIdx];
-    values[Lo] = thread->getReg(RegId(CCRegClass, regRelIdx));
+    values[Lo] = thread->getReg(ccRegClass[regRelIdx]);
 }
 
 void
@@ -242,12 +242,9 @@
     RegIndex regRelIdx
 )
 {
-    auto thread = tarmCtx.thread;
-
     regValid = true;
     regName  = "f" + std::to_string(regRelIdx);
-    RegId reg(FloatRegClass, regRelIdx);
-    values[Lo] = bitsToFloat32(thread->getReg(reg));
+    panic("ARM doesn't support float registers.");
 }
 
 void
@@ -287,7 +284,7 @@
         regName  = "r" + std::to_string(regRelIdx);
         break;
     }
-    values[Lo] = thread->getReg(RegId(IntRegClass, regRelIdx));
+    values[Lo] = thread->getReg(intRegClass[regRelIdx]);
 }
 
 void
diff --git a/src/arch/arm/tracers/tarmac_record.hh b/src/arch/arm/tracers/tarmac_record.hh
index 197034f..933e74f 100644
--- a/src/arch/arm/tracers/tarmac_record.hh
+++ b/src/arch/arm/tracers/tarmac_record.hh
@@ -249,7 +249,7 @@
 
             // If CPSR entry not present, generate one
             if (cpsr_it == queue.end()) {
-                RegId reg(MiscRegClass, ArmISA::MISCREG_CPSR);
+                RegId reg = ArmISA::miscRegClass[ArmISA::MISCREG_CPSR];
                 queue.push_back(
                     std::make_unique<RegEntry>(
                         genRegister<RegEntry>(tarmCtx, reg))
diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc
index 1c54c88..34751b8 100644
--- a/src/arch/arm/utility.cc
+++ b/src/arch/arm/utility.cc
@@ -1340,13 +1340,10 @@
 {
     int ei = 0;
     for (int ri = 0; ri < NumVecRegs; ri++) {
-        RegId reg_id(VecRegClass, ri);
         VecRegContainer reg;
-        tc->getReg(reg_id, &reg);
-        for (int j = 0; j < NumVecElemPerVecReg; j++, ei++) {
-            RegId elem_id(VecElemClass, ei);
-            tc->setReg(elem_id, reg.as<VecElem>()[j]);
-        }
+        tc->getReg(vecRegClass[ri], &reg);
+        for (int j = 0; j < NumVecElemPerVecReg; j++, ei++)
+            tc->setReg(vecElemClass[ei], reg.as<VecElem>()[j]);
     }
 }
 
@@ -1360,8 +1357,7 @@
             RegId elem_id(VecElemClass, ei);
             reg.as<VecElem>()[j] = tc->getReg(elem_id);
         }
-        RegId reg_id(VecRegClass, ri);
-        tc->setReg(reg_id, &reg);
+        tc->setReg(vecRegClass[ri], &reg);
     }
 }
 
diff --git a/src/arch/mips/isa.cc b/src/arch/mips/isa.cc
index 1a1098e..7a95e49 100644
--- a/src/arch/mips/isa.cc
+++ b/src/arch/mips/isa.cc
@@ -182,16 +182,12 @@
 ISA::copyRegsFrom(ThreadContext *src)
 {
     // First loop through the integer registers.
-    for (int i = 0; i < int_reg::NumRegs; i++) {
-        RegId reg(IntRegClass, i);
-        tc->setRegFlat(reg, src->getRegFlat(reg));
-    }
+    for (auto &id: intRegClass)
+        tc->setRegFlat(id, src->getRegFlat(id));
 
     // Then loop through the floating point registers.
-    for (int i = 0; i < float_reg::NumRegs; i++) {
-        RegId reg(FloatRegClass, i);
-        tc->setRegFlat(reg, src->getRegFlat(reg));
-    }
+    for (auto &id: floatRegClass)
+        tc->setRegFlat(id, src->getRegFlat(id));
 
     // Copy misc. registers
     for (int i = 0; i < misc_reg::NumRegs; i++)
diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa
index c45ae31..fcb60b3 100644
--- a/src/arch/mips/isa/decoder.isa
+++ b/src/arch/mips/isa/decoder.isa
@@ -382,13 +382,12 @@
                     // Decode MIPS MT MFTR instruction into sub-instructions
                     0x8: decode MT_U {
                         0x0: mftc0({{
-                            data = readRegOtherThread(xc, RegId(MiscRegClass,
-                                                            (RT << 3 | SEL)));
+                            data = readRegOtherThread(xc,
+                                    miscRegClass[RT << 3 | SEL]);
                         }});
                         0x1: decode SEL {
                             0x0: mftgpr({{
-                                data = readRegOtherThread(xc,
-                                                    RegId(IntRegClass, RT));
+                                data = readRegOtherThread(xc, intRegClass[RT]);
                             }});
                             0x1: decode RT {
                                 0x0: mftlo_dsp0({{
@@ -448,11 +447,11 @@
                             0x2: decode MT_H {
                                 0x0: mftc1({{
                                     data = readRegOtherThread(xc,
-                                                     RegId(FloatRegClass, RT));
+                                            floatRegClass[RT]);
                                 }});
                                 0x1: mfthc1({{
                                     data = readRegOtherThread(xc,
-                                                     RegId(FloatRegClass, RT));
+                                            floatRegClass[RT]);
                                 }});
                             }
                             0x3: cftc1({{
@@ -491,11 +490,11 @@
                     // Decode MIPS MT MTTR instruction into sub-instructions
                     0xC: decode MT_U {
                         0x0: mttc0({{ setRegOtherThread(xc,
-                                     RegId(MiscRegClass, (RD << 3 | SEL)), Rt);
+                                     miscRegClass[RD << 3 | SEL], Rt);
                                    }});
                         0x1: decode SEL {
                             0x0: mttgpr({{ setRegOtherThread(xc,
-                                                   RegId(IntRegClass, RD), Rt);
+                                                 intRegClass[RD], Rt);
                             }});
                             0x1: decode RT {
                                 0x0: mttlo_dsp0({{ setRegOtherThread(xc,
@@ -542,11 +541,10 @@
                             }
                             0x2: mttc1({{
                                 uint64_t data = readRegOtherThread(xc,
-                                                     RegId(FloatRegClass, RD));
+                                        floatRegClass[RD]);
                                 data = insertBits(data, MT_H ? 63 : 31,
                                                   MT_H ? 32 : 0, Rt);
-                                setRegOtherThread(xc, RegId(FloatRegClass, RD),
-                                                      data);
+                                setRegOtherThread(xc, floatRegClass[RD], data);
                             }});
                             0x3: cttc1({{
                                 uint32_t data;
diff --git a/src/arch/mips/isa/formats/mt.isa b/src/arch/mips/isa/formats/mt.isa
index dc125b2..f08b1a8 100644
--- a/src/arch/mips/isa/formats/mt.isa
+++ b/src/arch/mips/isa/formats/mt.isa
@@ -93,8 +93,7 @@
             MVPConf0Reg &mvp_conf0)
     {
         vpe_conf0 = xc->readMiscReg(misc_reg::VpeConf0);
-        tc_bind_mt = readRegOtherThread(xc, RegId(MiscRegClass,
-                                                  misc_reg::TcBind));
+        tc_bind_mt = readRegOtherThread(xc, miscRegClass[misc_reg::TcBind]);
         tc_bind = xc->readMiscReg(misc_reg::TcBind);
         vpe_control = xc->readMiscReg(misc_reg::VpeControl);
         mvp_conf0 = xc->readMiscReg(misc_reg::MvpConf0);
diff --git a/src/arch/mips/mt.hh b/src/arch/mips/mt.hh
index c227215..a7b72d5 100644
--- a/src/arch/mips/mt.hh
+++ b/src/arch/mips/mt.hh
@@ -41,6 +41,7 @@
 #include "arch/mips/mt_constants.hh"
 #include "arch/mips/pcstate.hh"
 #include "arch/mips/pra_constants.hh"
+#include "arch/mips/regs/int.hh"
 #include "arch/mips/regs/misc.hh"
 #include "base/bitfield.hh"
 #include "base/logging.hh"
@@ -173,25 +174,23 @@
     int success = 0;
     for (ThreadID tid = 0; tid < num_threads && success == 0; tid++) {
         TCBindReg tidTCBind =
-            readRegOtherThread(tc, RegId(MiscRegClass, misc_reg::TcBind), tid);
+            readRegOtherThread(tc, miscRegClass[misc_reg::TcBind], tid);
         TCBindReg tcBind = tc->readMiscRegNoEffect(misc_reg::TcBind);
 
         if (tidTCBind.curVPE == tcBind.curVPE) {
 
             TCStatusReg tidTCStatus =
-                readRegOtherThread(tc, RegId(MiscRegClass, misc_reg::TcStatus),
-                                       tid);
+                readRegOtherThread(tc, miscRegClass[misc_reg::TcStatus], tid);
 
             TCHaltReg tidTCHalt =
-                readRegOtherThread(tc, RegId(MiscRegClass, misc_reg::TcHalt),
-                                       tid);
+                readRegOtherThread(tc, miscRegClass[misc_reg::TcHalt], tid);
 
             if (tidTCStatus.da == 1 && tidTCHalt.h == 0 &&
                 tidTCStatus.a == 0 && success == 0) {
 
-                setRegOtherThread(tc, RegId(MiscRegClass, misc_reg::TcRestart),
-                                      Rs, tid);
-                setRegOtherThread(tc, RegId(IntRegClass, Rd_bits), Rt, tid);
+                setRegOtherThread(tc, miscRegClass[misc_reg::TcRestart], Rs,
+                                  tid);
+                setRegOtherThread(tc, intRegClass[Rd_bits], Rt, tid);
 
                 StatusReg status = tc->readMiscReg(misc_reg::Status);
                 TCStatusReg tcStatus = tc->readMiscReg(misc_reg::TcStatus);
@@ -210,8 +209,8 @@
                 tidTCStatus.asid = tcStatus.asid;
 
                 // Write Status Register
-                setRegOtherThread(tc, RegId(MiscRegClass, misc_reg::TcStatus),
-                                      tidTCStatus, tid);
+                setRegOtherThread(tc, miscRegClass[misc_reg::TcStatus],
+                                  tidTCStatus, tid);
 
                 // Mark As Successful Fork
                 success = 1;
@@ -246,14 +245,11 @@
 
         for (ThreadID tid = 0; tid < num_threads; tid++) {
             TCStatusReg tidTCStatus =
-                readRegOtherThread(tc, RegId(MiscRegClass, misc_reg::TcStatus),
-                                       tid);
+                readRegOtherThread(tc, miscRegClass[misc_reg::TcStatus], tid);
             TCHaltReg tidTCHalt =
-                readRegOtherThread(tc, RegId(MiscRegClass, misc_reg::TcHalt),
-                                       tid);
+                readRegOtherThread(tc, miscRegClass[misc_reg::TcHalt], tid);
             TCBindReg tidTCBind =
-                readRegOtherThread(tc, RegId(MiscRegClass, misc_reg::TcBind),
-                                       tid);
+                readRegOtherThread(tc, miscRegClass[misc_reg::TcBind], tid);
 
             if (tidTCBind.curVPE == tcBind.curVPE &&
                 tidTCBind.curTC == tcBind.curTC &&
diff --git a/src/arch/mips/regs/float.hh b/src/arch/mips/regs/float.hh
index 7238e20..a61e61b 100644
--- a/src/arch/mips/regs/float.hh
+++ b/src/arch/mips/regs/float.hh
@@ -42,7 +42,7 @@
 namespace float_reg
 {
 
-enum FPControlRegNums
+enum : RegIndex
 {
     _F0Idx,
     _F1Idx,
@@ -87,45 +87,53 @@
     NumRegs,
 };
 
-inline constexpr RegId
-    F0(FloatRegClass, _F0Idx),
-    F1(FloatRegClass, _F1Idx),
-    F2(FloatRegClass, _F2Idx),
-    F3(FloatRegClass, _F3Idx),
-    F4(FloatRegClass, _F4Idx),
-    F5(FloatRegClass, _F5Idx),
-    F6(FloatRegClass, _F6Idx),
-    F7(FloatRegClass, _F7Idx),
-    F8(FloatRegClass, _F8Idx),
-    F9(FloatRegClass, _F9Idx),
-    F10(FloatRegClass, _F10Idx),
-    F11(FloatRegClass, _F11Idx),
-    F12(FloatRegClass, _F12Idx),
-    F13(FloatRegClass, _F13Idx),
-    F14(FloatRegClass, _F14Idx),
-    F15(FloatRegClass, _F15Idx),
-    F16(FloatRegClass, _F16Idx),
-    F17(FloatRegClass, _F17Idx),
-    F18(FloatRegClass, _F18Idx),
-    F19(FloatRegClass, _F19Idx),
-    F20(FloatRegClass, _F20Idx),
-    F21(FloatRegClass, _F21Idx),
-    F22(FloatRegClass, _F22Idx),
-    F23(FloatRegClass, _F23Idx),
-    F24(FloatRegClass, _F24Idx),
-    F25(FloatRegClass, _F25Idx),
-    F26(FloatRegClass, _F26Idx),
-    F27(FloatRegClass, _F27Idx),
-    F28(FloatRegClass, _F28Idx),
-    F29(FloatRegClass, _F29Idx),
-    F30(FloatRegClass, _F30Idx),
-    F31(FloatRegClass, _F31Idx),
+} // namespace float_reg
 
-    Fir(FloatRegClass, _FirIdx),
-    Fccr(FloatRegClass, _FccrIdx),
-    Fexr(FloatRegClass, _FexrIdx),
-    Fenr(FloatRegClass, _FenrIdx),
-    Fcsr(FloatRegClass, _FcsrIdx);
+inline constexpr RegClass floatRegClass(FloatRegClass, float_reg::NumRegs,
+        debug::FloatRegs);
+
+namespace float_reg
+{
+
+inline constexpr RegId
+    F0 = floatRegClass[_F0Idx],
+    F1 = floatRegClass[_F1Idx],
+    F2 = floatRegClass[_F2Idx],
+    F3 = floatRegClass[_F3Idx],
+    F4 = floatRegClass[_F4Idx],
+    F5 = floatRegClass[_F5Idx],
+    F6 = floatRegClass[_F6Idx],
+    F7 = floatRegClass[_F7Idx],
+    F8 = floatRegClass[_F8Idx],
+    F9 = floatRegClass[_F9Idx],
+    F10 = floatRegClass[_F10Idx],
+    F11 = floatRegClass[_F11Idx],
+    F12 = floatRegClass[_F12Idx],
+    F13 = floatRegClass[_F13Idx],
+    F14 = floatRegClass[_F14Idx],
+    F15 = floatRegClass[_F15Idx],
+    F16 = floatRegClass[_F16Idx],
+    F17 = floatRegClass[_F17Idx],
+    F18 = floatRegClass[_F18Idx],
+    F19 = floatRegClass[_F19Idx],
+    F20 = floatRegClass[_F20Idx],
+    F21 = floatRegClass[_F21Idx],
+    F22 = floatRegClass[_F22Idx],
+    F23 = floatRegClass[_F23Idx],
+    F24 = floatRegClass[_F24Idx],
+    F25 = floatRegClass[_F25Idx],
+    F26 = floatRegClass[_F26Idx],
+    F27 = floatRegClass[_F27Idx],
+    F28 = floatRegClass[_F28Idx],
+    F29 = floatRegClass[_F29Idx],
+    F30 = floatRegClass[_F30Idx],
+    F31 = floatRegClass[_F31Idx],
+
+    Fir = floatRegClass[_FirIdx],
+    Fccr = floatRegClass[_FccrIdx],
+    Fexr = floatRegClass[_FexrIdx],
+    Fenr = floatRegClass[_FenrIdx],
+    Fcsr = floatRegClass[_FcsrIdx];
 
 } // namespace float_reg
 
@@ -149,9 +157,6 @@
 const uint32_t MIPS32_QNAN = 0x7fbfffff;
 const uint64_t MIPS64_QNAN = 0x7ff7ffffffffffffULL;
 
-inline constexpr RegClass floatRegClass(FloatRegClass, float_reg::NumRegs,
-        debug::FloatRegs);
-
 } // namespace MipsISA
 } // namespace gem5
 
diff --git a/src/arch/mips/regs/int.hh b/src/arch/mips/regs/int.hh
index 861d8b3..1981d0a 100644
--- a/src/arch/mips/regs/int.hh
+++ b/src/arch/mips/regs/int.hh
@@ -117,78 +117,86 @@
     NumRegs
 };
 
+} // namespace int_reg
+
+inline constexpr RegClass intRegClass(IntRegClass, int_reg::NumRegs,
+        debug::IntRegs);
+
+namespace int_reg
+{
+
 inline constexpr RegId
     // Zero register.
-    Zero(IntRegClass, _ZeroIdx),
+    Zero = intRegClass[_ZeroIdx],
 
     // Assembly temporary.
-    At(IntRegClass, _AtIdx),
+    At = intRegClass[_AtIdx],
 
     // Value returned by subroutine.
-    V0(IntRegClass, _V0Idx),
-    V1(IntRegClass, _V1Idx),
+    V0 = intRegClass[_V0Idx],
+    V1 = intRegClass[_V1Idx],
 
     // Arguments for subroutine.
-    A0(IntRegClass, _A0Idx),
-    A1(IntRegClass, _A1Idx),
-    A2(IntRegClass, _A2Idx),
-    A3(IntRegClass, _A3Idx),
+    A0 = intRegClass[_A0Idx],
+    A1 = intRegClass[_A1Idx],
+    A2 = intRegClass[_A2Idx],
+    A3 = intRegClass[_A3Idx],
 
     // Temporaries.
-    T0(IntRegClass, _T0Idx),
-    T1(IntRegClass, _T1Idx),
-    T2(IntRegClass, _T2Idx),
-    T3(IntRegClass, _T3Idx),
-    T4(IntRegClass, _T4Idx),
-    T5(IntRegClass, _T5Idx),
-    T6(IntRegClass, _T6Idx),
-    T7(IntRegClass, _T7Idx),
-    T8(IntRegClass, _T8Idx),
-    T9(IntRegClass, _T9Idx),
+    T0 = intRegClass[_T0Idx],
+    T1 = intRegClass[_T1Idx],
+    T2 = intRegClass[_T2Idx],
+    T3 = intRegClass[_T3Idx],
+    T4 = intRegClass[_T4Idx],
+    T5 = intRegClass[_T5Idx],
+    T6 = intRegClass[_T6Idx],
+    T7 = intRegClass[_T7Idx],
+    T8 = intRegClass[_T8Idx],
+    T9 = intRegClass[_T9Idx],
 
     // Subroutine registers.
-    S0(IntRegClass, _S0Idx),
-    S1(IntRegClass, _S1Idx),
-    S2(IntRegClass, _S2Idx),
-    S3(IntRegClass, _S3Idx),
-    S4(IntRegClass, _S4Idx),
-    S5(IntRegClass, _S5Idx),
-    S6(IntRegClass, _S6Idx),
-    S7(IntRegClass, _S7Idx),
+    S0 = intRegClass[_S0Idx],
+    S1 = intRegClass[_S1Idx],
+    S2 = intRegClass[_S2Idx],
+    S3 = intRegClass[_S3Idx],
+    S4 = intRegClass[_S4Idx],
+    S5 = intRegClass[_S5Idx],
+    S6 = intRegClass[_S6Idx],
+    S7 = intRegClass[_S7Idx],
 
     // For use in an interrupt/trap handler.
-    K0(IntRegClass, _K0Idx),
-    K1(IntRegClass, _K1Idx),
+    K0 = intRegClass[_K0Idx],
+    K1 = intRegClass[_K1Idx],
 
     // Global pointer.
-    Gp(IntRegClass, _GpIdx),
+    Gp = intRegClass[_GpIdx],
 
     // Stack pointer.
-    Sp(IntRegClass, _SpIdx),
+    Sp = intRegClass[_SpIdx],
 
     // Frame pointer.
-    Fp(IntRegClass, _FpIdx),
+    Fp = intRegClass[_FpIdx],
 
     // Return address.
-    Ra(IntRegClass, _RaIdx),
+    Ra = intRegClass[_RaIdx],
 
-    DspLo0(IntRegClass, _DspLo0Idx),
-    DspHi0(IntRegClass, _DspHi0Idx),
-    DspAcx0(IntRegClass, _DspAcx0Idx),
+    DspLo0 = intRegClass[_DspLo0Idx],
+    DspHi0 = intRegClass[_DspHi0Idx],
+    DspAcx0 = intRegClass[_DspAcx0Idx],
 
-    DspLo1(IntRegClass, _DspLo1Idx),
-    DspHi1(IntRegClass, _DspHi1Idx),
-    DspAcx1(IntRegClass, _DspAcx1Idx),
+    DspLo1 = intRegClass[_DspLo1Idx],
+    DspHi1 = intRegClass[_DspHi1Idx],
+    DspAcx1 = intRegClass[_DspAcx1Idx],
 
-    DspLo2(IntRegClass, _DspLo2Idx),
-    DspHi2(IntRegClass, _DspHi2Idx),
-    DspAcx2(IntRegClass, _DspAcx2Idx),
+    DspLo2 = intRegClass[_DspLo2Idx],
+    DspHi2 = intRegClass[_DspHi2Idx],
+    DspAcx2 = intRegClass[_DspAcx2Idx],
 
-    DspLo3(IntRegClass, _DspLo3Idx),
-    DspHi3(IntRegClass, _DspHi3Idx),
-    DspAcx3(IntRegClass, _DspAcx3Idx),
+    DspLo3 = intRegClass[_DspLo3Idx],
+    DspHi3 = intRegClass[_DspHi3Idx],
+    DspAcx3 = intRegClass[_DspAcx3Idx],
 
-    DspControl(IntRegClass, _DspControlIdx);
+    DspControl = intRegClass[_DspControlIdx];
 
 // Register aliases.
 inline constexpr auto
@@ -200,10 +208,6 @@
     &SyscallSuccess = A3;
 
 } // namespace int_reg
-
-inline constexpr RegClass intRegClass(IntRegClass, int_reg::NumRegs,
-        debug::IntRegs);
-
 } // namespace MipsISA
 } // namespace gem5
 
diff --git a/src/arch/mips/remote_gdb.cc b/src/arch/mips/remote_gdb.cc
index c63e267..fcf31e1 100644
--- a/src/arch/mips/remote_gdb.cc
+++ b/src/arch/mips/remote_gdb.cc
@@ -174,7 +174,7 @@
     DPRINTF(GDBAcc, "getregs in remotegdb \n");
 
     for (int i = 0; i < 32; i++)
-        r.gpr[i] = context->getReg(RegId(IntRegClass, i));
+        r.gpr[i] = context->getReg(intRegClass[i]);
     r.sr = context->readMiscRegNoEffect(misc_reg::Status);
     r.lo = context->getReg(int_reg::Lo);
     r.hi = context->getReg(int_reg::Hi);
@@ -182,7 +182,7 @@
     r.cause = context->readMiscRegNoEffect(misc_reg::Cause);
     r.pc = context->pcState().instAddr();
     for (int i = 0; i < 32; i++)
-        r.fpr[i] = context->getReg(RegId(FloatRegClass, i));
+        r.fpr[i] = context->getReg(floatRegClass[i]);
     r.fsr = context->getReg(float_reg::Fccr);
     r.fir = context->getReg(float_reg::Fir);
 }
@@ -193,7 +193,7 @@
     DPRINTF(GDBAcc, "setregs in remotegdb \n");
 
     for (int i = 1; i < 32; i++)
-        context->setReg(RegId(IntRegClass, i), r.gpr[i]);
+        context->setReg(intRegClass[i], r.gpr[i]);
     context->setMiscRegNoEffect(misc_reg::Status, r.sr);
     context->setReg(int_reg::Lo, r.lo);
     context->setReg(int_reg::Hi, r.hi);
@@ -201,7 +201,7 @@
     context->setMiscRegNoEffect(misc_reg::Cause, r.cause);
     context->pcState(r.pc);
     for (int i = 0; i < 32; i++)
-        context->setReg(RegId(FloatRegClass, i), r.fpr[i]);
+        context->setReg(floatRegClass[i], r.fpr[i]);
     context->setReg(float_reg::Fccr, r.fsr);
     context->setReg(float_reg::Fir, r.fir);
 }
diff --git a/src/arch/power/isa.cc b/src/arch/power/isa.cc
index a5916b5..0646c11 100644
--- a/src/arch/power/isa.cc
+++ b/src/arch/power/isa.cc
@@ -75,16 +75,12 @@
 ISA::copyRegsFrom(ThreadContext *src)
 {
     // First loop through the integer registers.
-    for (int i = 0; i < int_reg::NumRegs; ++i) {
-        RegId reg(IntRegClass, i);
-        tc->setReg(reg, src->getReg(reg));
-    }
+    for (auto &id: intRegClass)
+        tc->setReg(id, src->getReg(id));
 
     // Then loop through the floating point registers.
-    for (int i = 0; i < float_reg::NumRegs; ++i) {
-        RegId reg(FloatRegClass, i);
-        tc->setReg(reg, src->getReg(reg));
-    }
+    for (auto &id: floatRegClass)
+        tc->setReg(id, src->getReg(id));
 
     //TODO Copy misc. registers
 
diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc
index 6b147ef..d31aca2 100644
--- a/src/arch/power/process.cc
+++ b/src/arch/power/process.cc
@@ -341,7 +341,7 @@
 
     //Reset the special-purpose registers
     for (int i = int_reg::NumArchRegs; i < int_reg::NumRegs; i++)
-        tc->setReg(RegId(IntRegClass, i), (RegVal)0);
+        tc->setReg(intRegClass[i], (RegVal)0);
 
     //Set the machine status for a typical userspace
     Msr msr = 0;
diff --git a/src/arch/power/regs/int.hh b/src/arch/power/regs/int.hh
index 7a302fe..cdd2d6e 100644
--- a/src/arch/power/regs/int.hh
+++ b/src/arch/power/regs/int.hh
@@ -93,56 +93,61 @@
     NumRegs
 };
 
-inline constexpr RegId
-    R0(IntRegClass, _R0Idx),
-    R1(IntRegClass, _R1Idx),
-    R2(IntRegClass, _R2Idx),
-    R3(IntRegClass, _R3Idx),
-    R4(IntRegClass, _R4Idx),
-    R5(IntRegClass, _R5Idx),
-    R6(IntRegClass, _R6Idx),
-    R7(IntRegClass, _R7Idx),
-    R8(IntRegClass, _R8Idx),
-    R9(IntRegClass, _R9Idx),
-    R10(IntRegClass, _R10Idx),
-    R11(IntRegClass, _R11Idx),
-    R12(IntRegClass, _R12Idx),
-    R13(IntRegClass, _R13Idx),
-    R14(IntRegClass, _R14Idx),
-    R15(IntRegClass, _R15Idx),
-    R16(IntRegClass, _R16Idx),
-    R17(IntRegClass, _R17Idx),
-    R18(IntRegClass, _R18Idx),
-    R19(IntRegClass, _R19Idx),
-    R20(IntRegClass, _R20Idx),
-    R21(IntRegClass, _R21Idx),
-    R22(IntRegClass, _R22Idx),
-    R23(IntRegClass, _R23Idx),
-    R24(IntRegClass, _R24Idx),
-    R25(IntRegClass, _R25Idx),
-    R26(IntRegClass, _R26Idx),
-    R27(IntRegClass, _R27Idx),
-    R28(IntRegClass, _R28Idx),
-    R29(IntRegClass, _R29Idx),
-    R30(IntRegClass, _R30Idx),
-    R31(IntRegClass, _R31Idx),
-
-    Cr(IntRegClass, _CrIdx),
-    Xer(IntRegClass, _XerIdx),
-    Lr(IntRegClass, _LrIdx),
-    Ctr(IntRegClass, _CtrIdx),
-    Tar(IntRegClass, _TarIdx),
-    Fpscr(IntRegClass, _FpscrIdx),
-    Msr(IntRegClass, _MsrIdx),
-    Rsv(IntRegClass, _RsvIdx),
-    RsvLen(IntRegClass, _RsvLenIdx),
-    RsvAddr(IntRegClass, _RsvAddrIdx);
-
 } // namespace int_reg
 
 inline constexpr RegClass intRegClass(IntRegClass, int_reg::NumRegs,
         debug::IntRegs);
 
+namespace int_reg
+{
+
+inline constexpr RegId
+    R0 = intRegClass[_R0Idx],
+    R1 = intRegClass[_R1Idx],
+    R2 = intRegClass[_R2Idx],
+    R3 = intRegClass[_R3Idx],
+    R4 = intRegClass[_R4Idx],
+    R5 = intRegClass[_R5Idx],
+    R6 = intRegClass[_R6Idx],
+    R7 = intRegClass[_R7Idx],
+    R8 = intRegClass[_R8Idx],
+    R9 = intRegClass[_R9Idx],
+    R10 = intRegClass[_R10Idx],
+    R11 = intRegClass[_R11Idx],
+    R12 = intRegClass[_R12Idx],
+    R13 = intRegClass[_R13Idx],
+    R14 = intRegClass[_R14Idx],
+    R15 = intRegClass[_R15Idx],
+    R16 = intRegClass[_R16Idx],
+    R17 = intRegClass[_R17Idx],
+    R18 = intRegClass[_R18Idx],
+    R19 = intRegClass[_R19Idx],
+    R20 = intRegClass[_R20Idx],
+    R21 = intRegClass[_R21Idx],
+    R22 = intRegClass[_R22Idx],
+    R23 = intRegClass[_R23Idx],
+    R24 = intRegClass[_R24Idx],
+    R25 = intRegClass[_R25Idx],
+    R26 = intRegClass[_R26Idx],
+    R27 = intRegClass[_R27Idx],
+    R28 = intRegClass[_R28Idx],
+    R29 = intRegClass[_R29Idx],
+    R30 = intRegClass[_R30Idx],
+    R31 = intRegClass[_R31Idx],
+
+    Cr = intRegClass[_CrIdx],
+    Xer = intRegClass[_XerIdx],
+    Lr = intRegClass[_LrIdx],
+    Ctr = intRegClass[_CtrIdx],
+    Tar = intRegClass[_TarIdx],
+    Fpscr = intRegClass[_FpscrIdx],
+    Msr = intRegClass[_MsrIdx],
+    Rsv = intRegClass[_RsvIdx],
+    RsvLen = intRegClass[_RsvLenIdx],
+    RsvAddr = intRegClass[_RsvAddrIdx];
+
+} // namespace int_reg
+
 // Semantically meaningful register indices
 inline constexpr auto
     &ReturnValueReg = int_reg::R3,
diff --git a/src/arch/power/remote_gdb.cc b/src/arch/power/remote_gdb.cc
index bd2e087..c69c571 100644
--- a/src/arch/power/remote_gdb.cc
+++ b/src/arch/power/remote_gdb.cc
@@ -188,12 +188,12 @@
     // PC, MSR, CR, LR, CTR, XER, FPSCR (32-bit each)
 
     for (int i = 0; i < int_reg::NumArchRegs; i++) {
-        RegId reg(IntRegClass, i);
+        RegId reg = intRegClass[i];
         r.gpr[i] = htog((uint32_t)context->getReg(reg), order);
     }
 
     for (int i = 0; i < float_reg::NumArchRegs; i++)
-        r.fpr[i] = context->getReg(RegId(FloatRegClass, i));
+        r.fpr[i] = context->getReg(floatRegClass[i]);
 
     r.pc = htog((uint32_t)context->pcState().instAddr(), order);
     r.msr = 0; // MSR is privileged, hence not exposed here
@@ -213,10 +213,10 @@
     ByteOrder order = (msr.le ? ByteOrder::little : ByteOrder::big);
 
     for (int i = 0; i < int_reg::NumArchRegs; i++)
-        context->setReg(RegId(IntRegClass, i), gtoh(r.gpr[i], order));
+        context->setReg(intRegClass[i], gtoh(r.gpr[i], order));
 
     for (int i = 0; i < float_reg::NumArchRegs; i++)
-        context->setReg(RegId(FloatRegClass, i), r.fpr[i]);
+        context->setReg(floatRegClass[i], r.fpr[i]);
 
     auto pc = context->pcState().as<PowerISA::PCState>();
     pc.byteOrder(order);
@@ -244,10 +244,10 @@
     // each and the rest are 64-bit)
 
     for (int i = 0; i < int_reg::NumArchRegs; i++)
-        r.gpr[i] = htog(context->getReg(RegId(IntRegClass, i)), order);
+        r.gpr[i] = htog(context->getReg(intRegClass[i]), order);
 
     for (int i = 0; i < float_reg::NumArchRegs; i++)
-        r.fpr[i] = context->getReg(RegId(FloatRegClass, i));
+        r.fpr[i] = context->getReg(floatRegClass[i]);
 
     r.pc = htog(context->pcState().instAddr(), order);
     r.msr = 0; // MSR is privileged, hence not exposed here
@@ -267,10 +267,10 @@
     ByteOrder order = (msr.le ? ByteOrder::little : ByteOrder::big);
 
     for (int i = 0; i < int_reg::NumArchRegs; i++)
-        context->setReg(RegId(IntRegClass, i), gtoh(r.gpr[i], order));
+        context->setReg(intRegClass[i], gtoh(r.gpr[i], order));
 
     for (int i = 0; i < float_reg::NumArchRegs; i++)
-        context->setReg(RegId(FloatRegClass, i), r.fpr[i]);
+        context->setReg(floatRegClass[i], r.fpr[i]);
 
     auto pc = context->pcState().as<PowerISA::PCState>();
     pc.byteOrder(order);
diff --git a/src/arch/riscv/insts/amo.cc b/src/arch/riscv/insts/amo.cc
index 45a703a..4502fb1 100644
--- a/src/arch/riscv/insts/amo.cc
+++ b/src/arch/riscv/insts/amo.cc
@@ -72,8 +72,8 @@
         ss << "aq";
     if (RL)
         ss << "rl";
-    ss << ' ' << registerName(RegId(IntRegClass, RD)) << ", ("
-            << registerName(RegId(IntRegClass, RS1)) << ')';
+    ss << ' ' << registerName(intRegClass[RD]) << ", ("
+            << registerName(intRegClass[RS1]) << ')';
     return ss.str();
 }
 
@@ -100,9 +100,9 @@
         ss << "aq";
     if (RL)
         ss << "rl";
-    ss << ' ' << registerName(RegId(IntRegClass, RD)) << ", "
-            << registerName(RegId(IntRegClass, RS2)) << ", ("
-            << registerName(RegId(IntRegClass, RS1)) << ')';
+    ss << ' ' << registerName(intRegClass[RD]) << ", "
+            << registerName(intRegClass[RS2]) << ", ("
+            << registerName(intRegClass[RS1]) << ')';
     return ss.str();
 }
 
@@ -130,9 +130,9 @@
         ss << "aq";
     if (RL)
         ss << "rl";
-    ss << ' ' << registerName(RegId(IntRegClass, RD)) << ", "
-            << registerName(RegId(IntRegClass, RS2)) << ", ("
-            << registerName(RegId(IntRegClass, RS1)) << ')';
+    ss << ' ' << registerName(intRegClass[RD]) << ", "
+            << registerName(intRegClass[RS2]) << ", ("
+            << registerName(intRegClass[RS1]) << ')';
     return ss.str();
 }
 
diff --git a/src/arch/riscv/isa.cc b/src/arch/riscv/isa.cc
index e1ff380..f0df13d 100644
--- a/src/arch/riscv/isa.cc
+++ b/src/arch/riscv/isa.cc
@@ -225,16 +225,12 @@
 ISA::copyRegsFrom(ThreadContext *src)
 {
     // First loop through the integer registers.
-    for (int i = 0; i < int_reg::NumRegs; ++i) {
-        RegId reg(IntRegClass, i);
-        tc->setReg(reg, src->getReg(reg));
-    }
+    for (auto &id: intRegClass)
+        tc->setReg(id, src->getReg(id));
 
     // Second loop through the float registers.
-    for (int i = 0; i < float_reg::NumRegs; ++i) {
-        RegId reg(FloatRegClass, i);
-        tc->setReg(reg, src->getReg(reg));
-    }
+    for (auto &id: floatRegClass)
+        tc->setReg(id, src->getReg(id));
 
     // Lastly copy PC/NPC
     tc->pcState(src->pcState());
diff --git a/src/arch/riscv/regs/float.hh b/src/arch/riscv/regs/float.hh
index e7474a1..701e818 100644
--- a/src/arch/riscv/regs/float.hh
+++ b/src/arch/riscv/regs/float.hh
@@ -152,43 +152,51 @@
     NumRegs
 };
 
+} // namespace float_reg
+
+inline constexpr RegClass floatRegClass(FloatRegClass, float_reg::NumRegs,
+        debug::FloatRegs);
+
+namespace float_reg
+{
+
 inline constexpr RegId
-    Ft0(FloatRegClass, _Ft0Idx),
-    Ft1(FloatRegClass, _Ft1Idx),
-    Ft2(FloatRegClass, _Ft2Idx),
-    Ft3(FloatRegClass, _Ft3Idx),
-    Ft4(FloatRegClass, _Ft4Idx),
-    Ft5(FloatRegClass, _Ft5Idx),
-    Ft6(FloatRegClass, _Ft6Idx),
-    Ft7(FloatRegClass, _Ft7Idx),
+    Ft0 = floatRegClass[_Ft0Idx],
+    Ft1 = floatRegClass[_Ft1Idx],
+    Ft2 = floatRegClass[_Ft2Idx],
+    Ft3 = floatRegClass[_Ft3Idx],
+    Ft4 = floatRegClass[_Ft4Idx],
+    Ft5 = floatRegClass[_Ft5Idx],
+    Ft6 = floatRegClass[_Ft6Idx],
+    Ft7 = floatRegClass[_Ft7Idx],
 
-    Fs0(FloatRegClass, _Fs0Idx),
-    Fs1(FloatRegClass, _Fs1Idx),
+    Fs0 = floatRegClass[_Fs0Idx],
+    Fs1 = floatRegClass[_Fs1Idx],
 
-    Fa0(FloatRegClass, _Fa0Idx),
-    Fa1(FloatRegClass, _Fa1Idx),
-    Fa2(FloatRegClass, _Fa2Idx),
-    Fa3(FloatRegClass, _Fa3Idx),
-    Fa4(FloatRegClass, _Fa4Idx),
-    Fa5(FloatRegClass, _Fa5Idx),
-    Fa6(FloatRegClass, _Fa6Idx),
-    Fa7(FloatRegClass, _Fa7Idx),
+    Fa0 = floatRegClass[_Fa0Idx],
+    Fa1 = floatRegClass[_Fa1Idx],
+    Fa2 = floatRegClass[_Fa2Idx],
+    Fa3 = floatRegClass[_Fa3Idx],
+    Fa4 = floatRegClass[_Fa4Idx],
+    Fa5 = floatRegClass[_Fa5Idx],
+    Fa6 = floatRegClass[_Fa6Idx],
+    Fa7 = floatRegClass[_Fa7Idx],
 
-    Fs2(FloatRegClass, _Fs2Idx),
-    Fs3(FloatRegClass, _Fs3Idx),
-    Fs4(FloatRegClass, _Fs4Idx),
-    Fs5(FloatRegClass, _Fs5Idx),
-    Fs6(FloatRegClass, _Fs6Idx),
-    Fs7(FloatRegClass, _Fs7Idx),
-    Fs8(FloatRegClass, _Fs8Idx),
-    Fs9(FloatRegClass, _Fs9Idx),
-    Fs10(FloatRegClass, _Fs10Idx),
-    Fs11(FloatRegClass, _Fs11Idx),
+    Fs2 = floatRegClass[_Fs2Idx],
+    Fs3 = floatRegClass[_Fs3Idx],
+    Fs4 = floatRegClass[_Fs4Idx],
+    Fs5 = floatRegClass[_Fs5Idx],
+    Fs6 = floatRegClass[_Fs6Idx],
+    Fs7 = floatRegClass[_Fs7Idx],
+    Fs8 = floatRegClass[_Fs8Idx],
+    Fs9 = floatRegClass[_Fs9Idx],
+    Fs10 = floatRegClass[_Fs10Idx],
+    Fs11 = floatRegClass[_Fs11Idx],
 
-    Ft8(FloatRegClass, _Ft8Idx),
-    Ft9(FloatRegClass, _Ft9Idx),
-    Ft10(FloatRegClass, _Ft10Idx),
-    Ft11(FloatRegClass, _Ft11Idx);
+    Ft8 = floatRegClass[_Ft8Idx],
+    Ft9 = floatRegClass[_Ft9Idx],
+    Ft10 = floatRegClass[_Ft10Idx],
+    Ft11 = floatRegClass[_Ft11Idx];
 
 const std::vector<std::string> RegNames = {
     "ft0", "ft1", "ft2", "ft3",
@@ -203,9 +211,6 @@
 
 } // namespace float_reg
 
-inline constexpr RegClass floatRegClass(FloatRegClass, float_reg::NumRegs,
-        debug::FloatRegs);
-
 } // namespace RiscvISA
 } // namespace gem5
 
diff --git a/src/arch/riscv/regs/int.hh b/src/arch/riscv/regs/int.hh
index fa5e521..3ca73ac 100644
--- a/src/arch/riscv/regs/int.hh
+++ b/src/arch/riscv/regs/int.hh
@@ -79,40 +79,48 @@
     NumRegs
 };
 
+} // namespace int_reg
+
+inline constexpr RegClass intRegClass(IntRegClass, int_reg::NumRegs,
+        debug::IntRegs);
+
+namespace int_reg
+{
+
 inline constexpr RegId
-    Zero(IntRegClass, _ZeroIdx),
-    Ra(IntRegClass, _RaIdx),
-    Sp(IntRegClass, _SpIdx),
-    Gp(IntRegClass, _GpIdx),
-    Tp(IntRegClass, _TpIdx),
-    T0(IntRegClass, _T0Idx),
-    T1(IntRegClass, _T1Idx),
-    T2(IntRegClass, _T2Idx),
-    S0(IntRegClass, _S0Idx),
-    S1(IntRegClass, _S1Idx),
-    A0(IntRegClass, _A0Idx),
-    A1(IntRegClass, _A1Idx),
-    A2(IntRegClass, _A2Idx),
-    A3(IntRegClass, _A3Idx),
-    A4(IntRegClass, _A4Idx),
-    A5(IntRegClass, _A5Idx),
-    A6(IntRegClass, _A6Idx),
-    A7(IntRegClass, _A7Idx),
-    S2(IntRegClass, _S2Idx),
-    S3(IntRegClass, _S3Idx),
-    S4(IntRegClass, _S4Idx),
-    S5(IntRegClass, _S5Idx),
-    S6(IntRegClass, _S6Idx),
-    S7(IntRegClass, _S7Idx),
-    S8(IntRegClass, _S8Idx),
-    S9(IntRegClass, _S9Idx),
-    S10(IntRegClass, _S10Idx),
-    S11(IntRegClass, _S11Idx),
-    T3(IntRegClass, _T3Idx),
-    T4(IntRegClass, _T4Idx),
-    T5(IntRegClass, _T5Idx),
-    T6(IntRegClass, _T6Idx),
-    Ureg0(IntRegClass, _Ureg0Idx);
+    Zero = intRegClass[_ZeroIdx],
+    Ra = intRegClass[_RaIdx],
+    Sp = intRegClass[_SpIdx],
+    Gp = intRegClass[_GpIdx],
+    Tp = intRegClass[_TpIdx],
+    T0 = intRegClass[_T0Idx],
+    T1 = intRegClass[_T1Idx],
+    T2 = intRegClass[_T2Idx],
+    S0 = intRegClass[_S0Idx],
+    S1 = intRegClass[_S1Idx],
+    A0 = intRegClass[_A0Idx],
+    A1 = intRegClass[_A1Idx],
+    A2 = intRegClass[_A2Idx],
+    A3 = intRegClass[_A3Idx],
+    A4 = intRegClass[_A4Idx],
+    A5 = intRegClass[_A5Idx],
+    A6 = intRegClass[_A6Idx],
+    A7 = intRegClass[_A7Idx],
+    S2 = intRegClass[_S2Idx],
+    S3 = intRegClass[_S3Idx],
+    S4 = intRegClass[_S4Idx],
+    S5 = intRegClass[_S5Idx],
+    S6 = intRegClass[_S6Idx],
+    S7 = intRegClass[_S7Idx],
+    S8 = intRegClass[_S8Idx],
+    S9 = intRegClass[_S9Idx],
+    S10 = intRegClass[_S10Idx],
+    S11 = intRegClass[_S11Idx],
+    T3 = intRegClass[_T3Idx],
+    T4 = intRegClass[_T4Idx],
+    T5 = intRegClass[_T5Idx],
+    T6 = intRegClass[_T6Idx],
+    Ureg0 = intRegClass[_Ureg0Idx];
 
 const std::vector<std::string> RegNames = {
     "zero", "ra", "sp", "gp",
@@ -127,9 +135,6 @@
 
 } // namespace int_reg
 
-inline constexpr RegClass intRegClass(IntRegClass, int_reg::NumRegs,
-        debug::IntRegs);
-
 // Semantically meaningful register indices
 inline constexpr auto
     &ReturnAddrReg = int_reg::Ra,
diff --git a/src/arch/riscv/remote_gdb.cc b/src/arch/riscv/remote_gdb.cc
index 8ac0af6..ed700bb 100644
--- a/src/arch/riscv/remote_gdb.cc
+++ b/src/arch/riscv/remote_gdb.cc
@@ -192,13 +192,13 @@
 
     // General registers
     for (int i = 0; i < int_reg::NumArchRegs; i++) {
-        r.gpr[i] = context->getReg(RegId(IntRegClass, i));
+        r.gpr[i] = context->getReg(intRegClass[i]);
     }
     r.pc = context->pcState().instAddr();
 
     // Floating point registers
     for (int i = 0; i < float_reg::NumRegs; i++)
-        r.fpu[i] = context->getReg(RegId(FloatRegClass, i));
+        r.fpu[i] = context->getReg(floatRegClass[i]);
     r.fflags = context->readMiscRegNoEffect(
         CSRData.at(CSR_FFLAGS).physIndex) & CSRMasks.at(CSR_FFLAGS);
     r.frm = context->readMiscRegNoEffect(
@@ -303,12 +303,12 @@
 
     DPRINTF(GDBAcc, "setregs in remotegdb \n");
     for (int i = 0; i < int_reg::NumArchRegs; i++)
-        context->setReg(RegId(IntRegClass, i), r.gpr[i]);
+        context->setReg(intRegClass[i], r.gpr[i]);
     context->pcState(r.pc);
 
     // Floating point registers
     for (int i = 0; i < float_reg::NumRegs; i++)
-        context->setReg(RegId(FloatRegClass, i), r.fpu[i]);
+        context->setReg(floatRegClass[i], r.fpu[i]);
 
     oldVal = context->readMiscRegNoEffect(
         CSRData.at(CSR_FFLAGS).physIndex);
diff --git a/src/arch/sparc/isa.cc b/src/arch/sparc/isa.cc
index 02c9634..9f2906d 100644
--- a/src/arch/sparc/isa.cc
+++ b/src/arch/sparc/isa.cc
@@ -236,7 +236,7 @@
         tc->setMiscReg(MISCREG_GL, x);
         // Skip %g0 which is always zero.
         for (int y = 1; y < 8; y++) {
-            RegId reg(IntRegClass, y);
+            RegId reg = intRegClass[y];
             tc->setReg(reg, src->getReg(reg));
         }
     }
@@ -245,14 +245,14 @@
          src->setMiscReg(MISCREG_CWP, x);
          tc->setMiscReg(MISCREG_CWP, x);
          for (int y = 16; y < 32; y++) {
-             RegId reg(IntRegClass, y);
+             RegId reg = intRegClass[y];
              tc->setReg(reg, src->getReg(reg));
          }
     }
     // Microcode reg and pseudo int regs (misc regs in the integer regfile).
     for (int y = int_reg::NumArchRegs;
             y < int_reg::NumArchRegs + int_reg::NumMicroRegs; ++y) {
-        RegId reg(IntRegClass, y);
+        RegId reg = intRegClass[y];
         tc->setReg(reg, src->getReg(reg));
     }
 
@@ -263,7 +263,7 @@
 
     // Then loop through the floating point registers.
     for (int i = 0; i < SparcISA::float_reg::NumArchRegs; ++i) {
-        RegId reg(FloatRegClass, i);
+        RegId reg = floatRegClass[i];
         tc->setReg(reg, src->getReg(reg));
     }
 
diff --git a/src/arch/sparc/isa.hh b/src/arch/sparc/isa.hh
index bab4932..14f1b6c 100644
--- a/src/arch/sparc/isa.hh
+++ b/src/arch/sparc/isa.hh
@@ -34,6 +34,7 @@
 
 #include "arch/generic/isa.hh"
 #include "arch/sparc/pcstate.hh"
+#include "arch/sparc/regs/float.hh"
 #include "arch/sparc/regs/int.hh"
 #include "arch/sparc/regs/misc.hh"
 #include "arch/sparc/sparc_traits.hh"
@@ -196,13 +197,11 @@
     {
         switch (regId.classValue()) {
           case IntRegClass:
-            return RegId(IntRegClass, flattenIntIndex(regId.index()));
+            return intRegClass[flattenIntIndex(regId.index())];
           case FloatRegClass:
-            return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
-          case CCRegClass:
-            return RegId(CCRegClass, flattenCCIndex(regId.index()));
+            return floatRegClass[flattenFloatIndex(regId.index())];
           case MiscRegClass:
-            return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
+            return miscRegClass[flattenMiscIndex(regId.index())];
           default:
             break;
         }
diff --git a/src/arch/sparc/linux/linux.hh b/src/arch/sparc/linux/linux.hh
index 91e2419..a5d88ab 100644
--- a/src/arch/sparc/linux/linux.hh
+++ b/src/arch/sparc/linux/linux.hh
@@ -230,7 +230,7 @@
         ctc->setMiscRegNoEffect(SparcISA::MISCREG_TL, (RegVal)0);
         ctc->setMiscReg(SparcISA::MISCREG_ASI, SparcISA::ASI_PRIMARY);
         for (int y = 8; y < 32; y++) {
-            RegId reg(IntRegClass, y);
+            RegId reg = SparcISA::intRegClass[y];
             ctc->setReg(reg, ptc->getReg(reg));
         }
 
diff --git a/src/arch/sparc/linux/se_workload.cc b/src/arch/sparc/linux/se_workload.cc
index c864df3..a2752c2 100644
--- a/src/arch/sparc/linux/se_workload.cc
+++ b/src/arch/sparc/linux/se_workload.cc
@@ -32,6 +32,7 @@
 
 #include "arch/sparc/page_size.hh"
 #include "arch/sparc/process.hh"
+#include "arch/sparc/regs/int.hh"
 #include "base/loader/object_file.hh"
 #include "base/trace.hh"
 #include "cpu/thread_context.hh"
@@ -117,7 +118,7 @@
     // This will move into the base SEWorkload function at some point.
     process->Process::syscall(tc);
 
-    syscall32Descs.get(tc->getReg(RegId(IntRegClass, 1)))->doSyscall(tc);
+    syscall32Descs.get(tc->getReg(int_reg::G1))->doSyscall(tc);
 }
 
 void
@@ -128,7 +129,7 @@
     // This will move into the base SEWorkload function at some point.
     process->Process::syscall(tc);
 
-    syscallDescs.get(tc->getReg(RegId(IntRegClass, 1)))->doSyscall(tc);
+    syscallDescs.get(tc->getReg(int_reg::G1))->doSyscall(tc);
 }
 
 void
diff --git a/src/arch/sparc/nativetrace.cc b/src/arch/sparc/nativetrace.cc
index 4e2377b..ae2e169 100644
--- a/src/arch/sparc/nativetrace.cc
+++ b/src/arch/sparc/nativetrace.cc
@@ -63,7 +63,7 @@
     assert(SparcISA::int_reg::NumArchRegs == 32);
     const char **regName = intRegNames;
     for (int i = 0; i < SparcISA::int_reg::NumArchRegs; i++) {
-        regVal = tc->getReg(RegId(IntRegClass, i));
+        regVal = tc->getReg(SparcISA::intRegClass[i]);
         read(&realRegVal, sizeof(realRegVal));
         realRegVal = betoh(realRegVal);
         checkReg(*(regName++), regVal, realRegVal);
diff --git a/src/arch/sparc/regs/int.hh b/src/arch/sparc/regs/int.hh
index 53d7937..b1bfcae 100644
--- a/src/arch/sparc/regs/int.hh
+++ b/src/arch/sparc/regs/int.hh
@@ -64,81 +64,6 @@
     NumMicroRegs = _GsrIdx - _Ureg0Idx + 1
 };
 
-inline constexpr RegId
-    // Globals
-    G0(IntRegClass, _G0Idx),
-    G1(IntRegClass, _G1Idx),
-    G2(IntRegClass, _G2Idx),
-    G3(IntRegClass, _G3Idx),
-    G4(IntRegClass, _G4Idx),
-    G5(IntRegClass, _G5Idx),
-    G6(IntRegClass, _G6Idx),
-    G7(IntRegClass, _G7Idx),
-
-    // Outputs
-    O0(IntRegClass, _O0Idx),
-    O1(IntRegClass, _O1Idx),
-    O2(IntRegClass, _O2Idx),
-    O3(IntRegClass, _O3Idx),
-    O4(IntRegClass, _O4Idx),
-    O5(IntRegClass, _O5Idx),
-    O6(IntRegClass, _O6Idx),
-    O7(IntRegClass, _O7Idx),
-
-    // Locals
-    L0(IntRegClass, _L0Idx),
-    L1(IntRegClass, _L1Idx),
-    L2(IntRegClass, _L2Idx),
-    L3(IntRegClass, _L3Idx),
-    L4(IntRegClass, _L4Idx),
-    L5(IntRegClass, _L5Idx),
-    L6(IntRegClass, _L6Idx),
-    L7(IntRegClass, _L7Idx),
-
-    // Inputs
-    I0(IntRegClass, _I0Idx),
-    I1(IntRegClass, _I1Idx),
-    I2(IntRegClass, _I2Idx),
-    I3(IntRegClass, _I3Idx),
-    I4(IntRegClass, _I4Idx),
-    I5(IntRegClass, _I5Idx),
-    I6(IntRegClass, _I6Idx),
-    I7(IntRegClass, _I7Idx),
-
-    Ureg0(IntRegClass, _Ureg0Idx),
-    Y(IntRegClass, _YIdx),
-    Ccr(IntRegClass, _CcrIdx),
-    Cansave(IntRegClass, _CansaveIdx),
-    Canrestore(IntRegClass, _CanrestoreIdx),
-    Cleanwin(IntRegClass, _CleanwinIdx),
-    Otherwin(IntRegClass, _OtherwinIdx),
-    Wstate(IntRegClass, _WstateIdx),
-    Gsr(IntRegClass, _GsrIdx);
-
-inline constexpr RegId
-g(int index)
-{
-    return RegId(IntRegClass, G0 + index);
-}
-
-inline constexpr RegId
-o(int index)
-{
-    return RegId(IntRegClass, O0 + index);
-}
-
-inline constexpr RegId
-l(int index)
-{
-    return RegId(IntRegClass, L0 + index);
-}
-
-inline constexpr RegId
-i(int index)
-{
-    return RegId(IntRegClass, I0 + index);
-}
-
 const int NumRegs = (MaxGL + 1) * 8 + NWindows * 16 + NumMicroRegs;
 
 } // namespace int_reg
@@ -146,6 +71,86 @@
 inline constexpr RegClass intRegClass(IntRegClass, int_reg::NumRegs,
         debug::IntRegs);
 
+namespace int_reg
+{
+
+inline constexpr RegId
+    // Globals
+    G0 = intRegClass[_G0Idx],
+    G1 = intRegClass[_G1Idx],
+    G2 = intRegClass[_G2Idx],
+    G3 = intRegClass[_G3Idx],
+    G4 = intRegClass[_G4Idx],
+    G5 = intRegClass[_G5Idx],
+    G6 = intRegClass[_G6Idx],
+    G7 = intRegClass[_G7Idx],
+
+    // Outputs
+    O0 = intRegClass[_O0Idx],
+    O1 = intRegClass[_O1Idx],
+    O2 = intRegClass[_O2Idx],
+    O3 = intRegClass[_O3Idx],
+    O4 = intRegClass[_O4Idx],
+    O5 = intRegClass[_O5Idx],
+    O6 = intRegClass[_O6Idx],
+    O7 = intRegClass[_O7Idx],
+
+    // Locals
+    L0 = intRegClass[_L0Idx],
+    L1 = intRegClass[_L1Idx],
+    L2 = intRegClass[_L2Idx],
+    L3 = intRegClass[_L3Idx],
+    L4 = intRegClass[_L4Idx],
+    L5 = intRegClass[_L5Idx],
+    L6 = intRegClass[_L6Idx],
+    L7 = intRegClass[_L7Idx],
+
+    // Inputs
+    I0 = intRegClass[_I0Idx],
+    I1 = intRegClass[_I1Idx],
+    I2 = intRegClass[_I2Idx],
+    I3 = intRegClass[_I3Idx],
+    I4 = intRegClass[_I4Idx],
+    I5 = intRegClass[_I5Idx],
+    I6 = intRegClass[_I6Idx],
+    I7 = intRegClass[_I7Idx],
+
+    Ureg0 = intRegClass[_Ureg0Idx],
+    Y = intRegClass[_YIdx],
+    Ccr = intRegClass[_CcrIdx],
+    Cansave = intRegClass[_CansaveIdx],
+    Canrestore = intRegClass[_CanrestoreIdx],
+    Cleanwin = intRegClass[_CleanwinIdx],
+    Otherwin = intRegClass[_OtherwinIdx],
+    Wstate = intRegClass[_WstateIdx],
+    Gsr = intRegClass[_GsrIdx];
+
+inline constexpr RegId
+g(int index)
+{
+    return intRegClass[G0 + index];
+}
+
+inline constexpr RegId
+o(int index)
+{
+    return intRegClass[O0 + index];
+}
+
+inline constexpr RegId
+l(int index)
+{
+    return intRegClass[L0 + index];
+}
+
+inline constexpr RegId
+i(int index)
+{
+    return intRegClass[I0 + index];
+}
+
+} // namespace int_reg
+
 // the rest of these depend on the ABI
 inline constexpr auto
     &ReturnAddressReg = int_reg::I7, // post call, precall is 15
diff --git a/src/arch/sparc/remote_gdb.cc b/src/arch/sparc/remote_gdb.cc
index 4597465..481332d 100644
--- a/src/arch/sparc/remote_gdb.cc
+++ b/src/arch/sparc/remote_gdb.cc
@@ -177,7 +177,7 @@
 {
     DPRINTF(GDBAcc, "getRegs in remotegdb \n");
     for (int i = 0; i < 32; i++)
-        r.gpr[i] = htobe((uint32_t)context->getReg(RegId(IntRegClass, i)));
+        r.gpr[i] = htobe((uint32_t)context->getReg(intRegClass[i]));
     auto &pc = context->pcState().as<SparcISA::PCState>();
     r.pc = htobe((uint32_t)pc.pc());
     r.npc = htobe((uint32_t)pc.npc());
@@ -193,7 +193,7 @@
 {
     DPRINTF(GDBAcc, "getRegs in remotegdb \n");
     for (int i = 0; i < 32; i++)
-        r.gpr[i] = htobe(context->getReg(RegId(IntRegClass, i)));
+        r.gpr[i] = htobe(context->getReg(intRegClass[i]));
     for (int i = 0; i < 32; i++)
         r.fpr[i] = 0;
     auto &pc = context->pcState().as<SparcISA::PCState>();
@@ -214,7 +214,7 @@
 RemoteGDB::SPARCGdbRegCache::setRegs(ThreadContext *context) const
 {
     for (int i = 0; i < 32; i++)
-        context->setReg(RegId(IntRegClass, i), r.gpr[i]);
+        context->setReg(intRegClass[i], r.gpr[i]);
     PCState pc;
     pc.pc(r.pc);
     pc.npc(r.npc);
@@ -231,7 +231,7 @@
 RemoteGDB::SPARC64GdbRegCache::setRegs(ThreadContext *context) const
 {
     for (int i = 0; i < 32; i++)
-        context->setReg(RegId(IntRegClass, i), r.gpr[i]);
+        context->setReg(intRegClass[i], r.gpr[i]);
     PCState pc;
     pc.pc(r.pc);
     pc.npc(r.npc);
diff --git a/src/arch/sparc/se_workload.cc b/src/arch/sparc/se_workload.cc
index f435d3b..953c083 100644
--- a/src/arch/sparc/se_workload.cc
+++ b/src/arch/sparc/se_workload.cc
@@ -119,7 +119,7 @@
 
         Addr addr = is_64 ? sp + 2047 : sp;
         for (int index = 16; index < 32; index++) {
-            RegId reg(IntRegClass, index);
+            RegId reg = intRegClass[index];
             if (is_64) {
                 uint64_t regVal = htobe<uint64_t>(tc->getReg(reg));
                 memcpy(bytes, &regVal, reg_bytes);
diff --git a/src/arch/x86/emulenv.cc b/src/arch/x86/emulenv.cc
index 1f9c5f6..6b5b1b1 100644
--- a/src/arch/x86/emulenv.cc
+++ b/src/arch/x86/emulenv.cc
@@ -52,8 +52,8 @@
     //Use the SIB byte for addressing if the modrm byte calls for it.
     if (machInst.modRM.rm == 4 && machInst.addrSize != 2) {
         scale = 1 << machInst.sib.scale;
-        index = RegId(IntRegClass, machInst.sib.index | (machInst.rex.x << 3));
-        base = RegId(IntRegClass, machInst.sib.base | (machInst.rex.b << 3));
+        index = intRegClass[machInst.sib.index | (machInst.rex.x << 3)];
+        base = intRegClass[machInst.sib.base | (machInst.rex.b << 3)];
         //In this special case, we don't use a base. The displacement also
         //changes, but that's managed by the decoder.
         if (machInst.sib.base == (RegIndex)int_reg::Rbp &&
@@ -72,8 +72,7 @@
                 } else {
                     base = int_reg::Rbp;
                 }
-                index = RegId(IntRegClass,
-                        (rm % 2) ? int_reg::Rdi : int_reg::Rsi);
+                index = intRegClass[(rm % 2) ? int_reg::Rdi : int_reg::Rsi];
             } else {
                 scale = 0;
                 switch (rm) {
@@ -95,8 +94,7 @@
             }
         } else {
             scale = 0;
-            base = RegId(IntRegClass,
-                    machInst.modRM.rm | (machInst.rex.b << 3));
+            base = intRegClass[machInst.modRM.rm | (machInst.rex.b << 3)];
             if (machInst.modRM.mod == 0 && machInst.modRM.rm == 5) {
                 //Since we need to use a different encoding of this
                 //instruction anyway, just ignore the base in those cases
diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc
index 3ef886e..fce92b1 100644
--- a/src/arch/x86/faults.cc
+++ b/src/arch/x86/faults.cc
@@ -43,6 +43,7 @@
 #include "arch/x86/generated/decoder.hh"
 #include "arch/x86/insts/static_inst.hh"
 #include "arch/x86/mmu.hh"
+#include "arch/x86/regs/int.hh"
 #include "arch/x86/regs/misc.hh"
 #include "base/loader/symtab.hh"
 #include "base/trace.hh"
@@ -184,7 +185,7 @@
     DPRINTF(Faults, "Init interrupt.\n");
     // The otherwise unmodified integer registers should be set to 0.
     for (int index = 0; index < int_reg::NumArchRegs; index++) {
-        tc->setReg(RegId(IntRegClass, index), (RegVal)0);
+        tc->setReg(intRegClass[index], (RegVal)0);
     }
 
     CR0 cr0 = tc->readMiscReg(misc_reg::Cr0);
diff --git a/src/arch/x86/insts/microop_args.hh b/src/arch/x86/insts/microop_args.hh
index 81ed412..9dd121b 100644
--- a/src/arch/x86/insts/microop_args.hh
+++ b/src/arch/x86/insts/microop_args.hh
@@ -36,7 +36,9 @@
 #include <utility>
 
 #include "arch/x86/insts/static_inst.hh"
+#include "arch/x86/regs/float.hh"
 #include "arch/x86/regs/int.hh"
+#include "arch/x86/regs/misc.hh"
 #include "arch/x86/regs/segment.hh"
 #include "arch/x86/types.hh"
 #include "base/compiler.hh"
@@ -144,8 +146,7 @@
     void
     print(std::ostream &os) const
     {
-        X86StaticInst::printReg(os, RegId(IntRegClass, this->opIndex()),
-                this->size);
+        X86StaticInst::printReg(os, intRegClass[this->opIndex()], this->size);
     }
 };
 
@@ -162,8 +163,7 @@
     void
     print(std::ostream &os) const
     {
-        X86StaticInst::printReg(os, RegId(IntRegClass, this->opIndex()),
-                this->size);
+        X86StaticInst::printReg(os, intRegClass[this->opIndex()], this->size);
     }
 };
 
@@ -224,8 +224,7 @@
     void
     print(std::ostream &os) const
     {
-        X86StaticInst::printReg(os, RegId(MiscRegClass, this->opIndex()),
-                this->size);
+        X86StaticInst::printReg(os, miscRegClass[this->opIndex()], this->size);
     }
 };
 
@@ -247,7 +246,7 @@
     void
     print(std::ostream &os) const
     {
-        X86StaticInst::printReg(os, RegId(FloatRegClass, this->opIndex()),
+        X86StaticInst::printReg(os, floatRegClass[this->opIndex()],
                 this->size);
     }
 };
diff --git a/src/arch/x86/insts/static_inst.cc b/src/arch/x86/insts/static_inst.cc
index 03d844b..1f3df36 100644
--- a/src/arch/x86/insts/static_inst.cc
+++ b/src/arch/x86/insts/static_inst.cc
@@ -269,13 +269,13 @@
         if (scale != 0 && index != int_reg::NumRegs) {
             if (scale != 1)
                 ccprintf(os, "%d*", scale);
-            printReg(os, RegId(IntRegClass, index), addressSize);
+            printReg(os, intRegClass[index], addressSize);
             someAddr = true;
         }
         if (base != int_reg::NumRegs) {
             if (someAddr)
                 os << " + ";
-            printReg(os, RegId(IntRegClass, base), addressSize);
+            printReg(os, intRegClass[base], addressSize);
             someAddr = true;
         }
     }
diff --git a/src/arch/x86/isa.cc b/src/arch/x86/isa.cc
index f75b362..b964a21 100644
--- a/src/arch/x86/isa.cc
+++ b/src/arch/x86/isa.cc
@@ -188,20 +188,14 @@
 ISA::copyRegsFrom(ThreadContext *src)
 {
     //copy int regs
-    for (int i = 0; i < int_reg::NumRegs; ++i) {
-        RegId reg(IntRegClass, i);
-        tc->setRegFlat(reg, src->getRegFlat(reg));
-    }
+    for (auto &id: intRegClass)
+        tc->setRegFlat(id, src->getRegFlat(id));
     //copy float regs
-    for (int i = 0; i < float_reg::NumRegs; ++i) {
-        RegId reg(FloatRegClass, i);
-        tc->setRegFlat(reg, src->getRegFlat(reg));
-    }
+    for (auto &id: floatRegClass)
+        tc->setRegFlat(id, src->getRegFlat(id));
     //copy condition-code regs
-    for (int i = 0; i < cc_reg::NumRegs; ++i) {
-        RegId reg(CCRegClass, i);
-        tc->setRegFlat(reg, src->getRegFlat(reg));
-    }
+    for (auto &id: ccRegClass)
+        tc->setRegFlat(id, src->getRegFlat(id));
     copyMiscRegs(src, tc);
     tc->pcState(src->pcState());
 }
diff --git a/src/arch/x86/isa.hh b/src/arch/x86/isa.hh
index f19ed9f..e15a4be 100644
--- a/src/arch/x86/isa.hh
+++ b/src/arch/x86/isa.hh
@@ -34,6 +34,7 @@
 
 #include "arch/generic/isa.hh"
 #include "arch/x86/pcstate.hh"
+#include "arch/x86/regs/ccr.hh"
 #include "arch/x86/regs/float.hh"
 #include "arch/x86/regs/int.hh"
 #include "arch/x86/regs/misc.hh"
@@ -82,13 +83,13 @@
     {
         switch (regId.classValue()) {
           case IntRegClass:
-            return RegId(IntRegClass, flattenIntIndex(regId.index()));
+            return intRegClass[flattenIntIndex(regId.index())];
           case FloatRegClass:
-            return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
+            return floatRegClass[flattenFloatIndex(regId.index())];
           case CCRegClass:
-            return RegId(CCRegClass, flattenCCIndex(regId.index()));
+            return ccRegClass[flattenCCIndex(regId.index())];
           case MiscRegClass:
-            return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
+            return miscRegClass[flattenMiscIndex(regId.index())];
           default:
             break;
         }
diff --git a/src/arch/x86/isa/specialize.isa b/src/arch/x86/isa/specialize.isa
index d1ce18e..a86d512 100644
--- a/src/arch/x86/isa/specialize.isa
+++ b/src/arch/x86/isa/specialize.isa
@@ -151,7 +151,7 @@
                 else:
                     regString = "env.reg"
                 env.addToDisassembly(
-                    "printReg(out, RegId(IntRegClass, %s), regSize);\n" %
+                    "printReg(out, intRegClass[%s], regSize);\n" %
                     regString)
 
                 Name += "_R"
@@ -170,7 +170,7 @@
                 # This refers to registers whose index is encoded as part of
                 # the opcode.
                 env.addToDisassembly(
-                        "printReg(out, RegId(IntRegClass, %s), regSize);\n" %
+                        "printReg(out, intRegClass[%s], regSize);\n" %
                         InstRegIndex)
 
                 Name += "_R"
@@ -216,7 +216,7 @@
                     Name += "_XMM"
                 else:
                     regFormat = \
-                        "printReg(out, RegId(IntRegClass, %s), regSize);\n"
+                        "printReg(out, intRegClass[%s], regSize);\n"
                     Name += "_R"
                 env.addToDisassembly(regFormat % ModRMRegIndex)
             elif opType.tag in ("E", "Q", "W"):
@@ -238,7 +238,7 @@
                     regSuffix = "_XMM"
                 else:
                     regFormat = \
-                        "printReg(out, RegId(IntRegClass, %s), regSize);\n"
+                        "printReg(out, intRegClass[%s], regSize);\n"
                     regSuffix = "_R"
                 env.addToDisassembly(regFormat % ModRMRegIndex)
                 return doSplitDecode("MODRM_MOD",
@@ -266,7 +266,7 @@
                     Name += "_XMM"
                 else:
                     regFormat = \
-                        "printReg(out, RegId(IntRegClass, %s), regSize);\n"
+                        "printReg(out, intRegClass[%s], regSize);\n"
                     Name += "_R"
                 env.addToDisassembly(regFormat % ModRMRegIndex)
             elif opType.tag in ("X", "Y"):
diff --git a/src/arch/x86/regs/ccr.hh b/src/arch/x86/regs/ccr.hh
index 44cbc49..383f026 100644
--- a/src/arch/x86/regs/ccr.hh
+++ b/src/arch/x86/regs/ccr.hh
@@ -59,18 +59,23 @@
     NumRegs
 };
 
-inline constexpr RegId
-    Zaps(CCRegClass, _ZapsIdx),
-    Cfof(CCRegClass, _CfofIdx),
-    Df(CCRegClass, _DfIdx),
-    Ecf(CCRegClass, _EcfIdx),
-    Ezf(CCRegClass, _EzfIdx);
-
 } // namespace cc_reg
 
 inline constexpr RegClass ccRegClass(CCRegClass, cc_reg::NumRegs,
         debug::CCRegs);
 
+namespace cc_reg
+{
+
+inline constexpr RegId
+    Zaps = ccRegClass[_ZapsIdx],
+    Cfof = ccRegClass[_CfofIdx],
+    Df = ccRegClass[_DfIdx],
+    Ecf = ccRegClass[_EcfIdx],
+    Ezf = ccRegClass[_EzfIdx];
+
+} // namespace cc_reg
+
 } // namespace X86ISA
 } // namespace gem5
 
diff --git a/src/arch/x86/regs/float.hh b/src/arch/x86/regs/float.hh
index f6190f9..e5150a9 100644
--- a/src/arch/x86/regs/float.hh
+++ b/src/arch/x86/regs/float.hh
@@ -119,40 +119,48 @@
     NumRegs = MicrofpBase + NumMicroFpRegs
 };
 
+} // namespace float_reg
+
+inline constexpr RegClass floatRegClass(FloatRegClass, float_reg::NumRegs,
+        debug::FloatRegs);
+
+namespace float_reg
+{
+
 static inline RegId
 mmx(int index)
 {
-    return RegId(FloatRegClass, MmxBase + index);
+    return floatRegClass[MmxBase + index];
 }
 
 static inline RegId
 fpr(int index)
 {
-    return RegId(FloatRegClass, FprBase + index);
+    return floatRegClass[FprBase + index];
 }
 
 static inline RegId
 xmm(int index)
 {
-    return RegId(FloatRegClass, XmmBase + index);
+    return floatRegClass[XmmBase + index];
 }
 
 static inline RegId
 xmmLow(int index)
 {
-    return RegId(FloatRegClass, XmmBase + 2 * index);
+    return floatRegClass[XmmBase + 2 * index];
 }
 
 static inline RegId
 xmmHigh(int index)
 {
-    return RegId(FloatRegClass, XmmBase + 2 * index + 1);
+    return floatRegClass[XmmBase + 2 * index + 1];
 }
 
 static inline RegId
 microfp(int index)
 {
-    return RegId(FloatRegClass, MicrofpBase + index);
+    return floatRegClass[MicrofpBase + index];
 }
 
 static inline RegId
@@ -163,9 +171,6 @@
 
 } // namespace float_reg
 
-inline constexpr RegClass floatRegClass(FloatRegClass, float_reg::NumRegs,
-        debug::FloatRegs);
-
 } // namespace X86ISA
 } // namespace gem5
 
diff --git a/src/arch/x86/regs/int.hh b/src/arch/x86/regs/int.hh
index 4201ffa..9b7b814 100644
--- a/src/arch/x86/regs/int.hh
+++ b/src/arch/x86/regs/int.hh
@@ -100,30 +100,38 @@
     NumRegs
 };
 
+} // namespace int_reg
+
+inline constexpr RegClass intRegClass(IntRegClass, int_reg::NumRegs,
+        debug::IntRegs);
+
+namespace int_reg
+{
+
 inline constexpr RegId
-    Rax(IntRegClass, _RaxIdx),
-    Rcx(IntRegClass, _RcxIdx),
-    Rdx(IntRegClass, _RdxIdx),
-    Rbx(IntRegClass, _RbxIdx),
-    Rsp(IntRegClass, _RspIdx),
-    Rbp(IntRegClass, _RbpIdx),
-    Rsi(IntRegClass, _RsiIdx),
-    Rdi(IntRegClass, _RdiIdx),
-    R8(IntRegClass, _R8Idx),
-    R9(IntRegClass, _R9Idx),
-    R10(IntRegClass, _R10Idx),
-    R11(IntRegClass, _R11Idx),
-    R12(IntRegClass, _R12Idx),
-    R13(IntRegClass, _R13Idx),
-    R14(IntRegClass, _R14Idx),
-    R15(IntRegClass, _R15Idx),
-    T0(IntRegClass, _T0Idx),
-    Prodlow(IntRegClass, _ProdlowIdx),
-    Prodhi(IntRegClass, _ProdhiIdx),
-    Quotient(IntRegClass, _QuotientIdx),
-    Remainder(IntRegClass, _RemainderIdx),
-    Divisor(IntRegClass, _DivisorIdx),
-    Doublebits(IntRegClass, _DoublebitsIdx);
+    Rax = intRegClass[_RaxIdx],
+    Rcx = intRegClass[_RcxIdx],
+    Rdx = intRegClass[_RdxIdx],
+    Rbx = intRegClass[_RbxIdx],
+    Rsp = intRegClass[_RspIdx],
+    Rbp = intRegClass[_RbpIdx],
+    Rsi = intRegClass[_RsiIdx],
+    Rdi = intRegClass[_RdiIdx],
+    R8 = intRegClass[_R8Idx],
+    R9 = intRegClass[_R9Idx],
+    R10 = intRegClass[_R10Idx],
+    R11 = intRegClass[_R11Idx],
+    R12 = intRegClass[_R12Idx],
+    R13 = intRegClass[_R13Idx],
+    R14 = intRegClass[_R14Idx],
+    R15 = intRegClass[_R15Idx],
+    T0 = intRegClass[_T0Idx],
+    Prodlow = intRegClass[_ProdlowIdx],
+    Prodhi = intRegClass[_ProdhiIdx],
+    Quotient = intRegClass[_QuotientIdx],
+    Remainder = intRegClass[_RemainderIdx],
+    Divisor = intRegClass[_DivisorIdx],
+    Doublebits = intRegClass[_DoublebitsIdx];
 
 // Aliases for other register sizes.
 inline constexpr auto
@@ -146,16 +154,13 @@
 
 } // namespace int_reg
 
-inline constexpr RegClass intRegClass(IntRegClass, int_reg::NumRegs,
-        debug::IntRegs);
-
 // This needs to be large enough to miss all the other bits of an index.
 inline constexpr RegIndex IntFoldBit = 1 << 6;
 
 inline static constexpr RegId
 intRegMicro(int index)
 {
-    return RegId(IntRegClass, int_reg::MicroBegin + index);
+    return intRegClass[int_reg::MicroBegin + index];
 }
 
 inline static constexpr RegId
@@ -163,7 +168,7 @@
 {
     if ((index & 0x1C) == 4 && foldBit)
         index = (index - 4) | foldBit;
-    return RegId(IntRegClass, index);
+    return intRegClass[index];
 }
 
 } // namespace X86ISA