cpu: Simplify the rename interface and use RegId
authorRekai Gonzalez-Alberquilla <Rekai.GonzalezAlberquilla@arm.com>
Wed, 5 Apr 2017 18:14:34 +0000 (13:14 -0500)
committerAndreas Sandberg <andreas.sandberg@arm.com>
Wed, 5 Jul 2017 14:43:49 +0000 (14:43 +0000)
With the hierarchical RegId there are a lot of functions that are
redundant now.

The idea behind the simplification is that instead of having the regId,
telling which kind of register read/write/rename/lookup/etc. and then
the function panic_if'ing if the regId is not of the appropriate type,
we provide an interface that decides what kind of register to read
depending on the register type of the given regId.

Change-Id: I7d52e9e21fc01205ae365d86921a4ceb67a57178
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
[ Fix RISCV build issues ]
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/2702

64 files changed:
src/arch/alpha/isa.hh
src/arch/alpha/isa/branch.isa
src/arch/alpha/isa/fp.isa
src/arch/alpha/isa/main.isa
src/arch/arm/insts/misc.cc
src/arch/arm/isa.hh
src/arch/arm/isa/insts/data64.isa
src/arch/arm/isa/insts/fp.isa
src/arch/arm/isa/insts/misc.isa
src/arch/mips/isa.hh
src/arch/mips/isa/base.isa
src/arch/mips/isa/formats/int.isa
src/arch/power/insts/branch.cc
src/arch/power/insts/static_inst.cc
src/arch/power/isa.hh
src/arch/riscv/isa.hh
src/arch/riscv/isa/base.isa
src/arch/riscv/isa/formats/type.isa
src/arch/sparc/isa.hh
src/arch/sparc/isa/base.isa
src/arch/sparc/isa/formats/integerop.isa
src/arch/sparc/isa/formats/mem/util.isa
src/arch/sparc/isa/formats/priv.isa
src/arch/x86/insts/microfpop.hh
src/arch/x86/insts/microldstop.hh
src/arch/x86/insts/micromediaop.hh
src/arch/x86/insts/microregop.hh
src/arch/x86/insts/static_inst.cc
src/arch/x86/insts/static_inst.hh
src/arch/x86/isa.hh
src/arch/x86/isa/microops/limmop.isa
src/cpu/base_dyn_inst.hh
src/cpu/checker/cpu.hh
src/cpu/checker/cpu_impl.hh
src/cpu/checker/thread_context.hh
src/cpu/exec_context.hh
src/cpu/minor/dyn_inst.cc
src/cpu/minor/exec_context.hh
src/cpu/minor/scoreboard.cc
src/cpu/minor/scoreboard.hh
src/cpu/o3/comm.hh
src/cpu/o3/cpu.cc
src/cpu/o3/dyn_inst.hh
src/cpu/o3/free_list.hh
src/cpu/o3/iew_impl.hh
src/cpu/o3/inst_queue_impl.hh
src/cpu/o3/probe/elastic_trace.cc
src/cpu/o3/regfile.cc
src/cpu/o3/regfile.hh
src/cpu/o3/rename.hh
src/cpu/o3/rename_impl.hh
src/cpu/o3/rename_map.cc
src/cpu/o3/rename_map.hh
src/cpu/o3/scoreboard.hh
src/cpu/o3/thread_context.hh
src/cpu/o3/thread_context_impl.hh
src/cpu/reg_class.cc
src/cpu/reg_class.hh
src/cpu/reg_class_impl.hh [new file with mode: 0644]
src/cpu/simple/exec_context.hh
src/cpu/simple_thread.hh
src/cpu/static_inst.hh
src/cpu/thread_context.hh
src/cpu/timing_expr.cc

index 6c06fc39760ec71c7d83bf1a0597bf340845d960..80d8ab149ab3f871cace66457ffeea06b12047c4 100644 (file)
@@ -38,6 +38,7 @@
 #include "arch/alpha/registers.hh"
 #include "arch/alpha/types.hh"
 #include "base/types.hh"
+#include "cpu/reg_class.hh"
 #include "sim/sim_object.hh"
 #include "sim/system.hh"
 
@@ -95,6 +96,8 @@ namespace AlphaISA
         void serialize(CheckpointOut &cp) const override;
         void unserialize(CheckpointIn &cp) override;
 
+        RegId flattenRegId(const RegId& regId) const { return regId; }
+
         int
         flattenIntIndex(int reg) const
         {
index d4b6db043dce1a4c2028916f22e317ec2a66e6e9..a43efff9c94110db8433d553d89cb61a0e320342 100644 (file)
@@ -130,7 +130,7 @@ output decoder {{
     Jump::branchTarget(ThreadContext *tc) const
     {
         PCState pc = tc->pcState();
-        uint64_t Rb = tc->readIntReg(_srcRegIdx[0].regIdx);
+        uint64_t Rb = tc->readIntReg(_srcRegIdx[0].index());
         pc.set((Rb & ~3) | (pc.pc() & 1));
         return pc;
     }
index afece988f56a8acb92c38acd03f9b695399f0fcf..6213c8e08b8304aefee8a1f982418c13a87519f4 100644 (file)
@@ -149,7 +149,7 @@ output decoder {{
 
 #ifndef SS_COMPATIBLE_DISASSEMBLY
         std::string suffix("");
-        suffix += ((_destRegIdx[0].regClass == FloatRegClass)
+        suffix += ((_destRegIdx[0].isFloatReg())
                    ? fpTrappingModeSuffix[trappingMode]
                    : intTrappingModeSuffix[trappingMode]);
         suffix += roundingModeSuffix[roundingMode];
index e75cec52453ee6253a354353aa3782d7488123d0..34e2cb5ad1e6ed9b204af1c86415606e84ba23f7 100644 (file)
@@ -246,11 +246,11 @@ output decoder {{
     void
     AlphaStaticInst::printReg(std::ostream &os, RegId reg) const
     {
-        if (reg.regClass == IntRegClass) {
-            ccprintf(os, "r%d", reg.regIdx);
+        if (reg.isIntReg()) {
+            ccprintf(os, "r%d", reg.index());
         }
         else {
-            ccprintf(os, "f%d", reg.regIdx);
+            ccprintf(os, "f%d", reg.index());
         }
     }
 
index 0114a4aba61dfe25d06034b59c6b76adb90a4790..059f86f63a5a92bb89ffe7aea40abb826821f668 100644 (file)
@@ -51,16 +51,16 @@ MrsOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
     ss << ", ";
     bool foundPsr = false;
     for (unsigned i = 0; i < numSrcRegs(); i++) {
-        RegId reg = srcRegIdx(i);
-        if (reg.regClass != MiscRegClass) {
+        const RegId& reg = srcRegIdx(i);
+        if (!reg.isMiscReg()) {
             continue;
         }
-        if (reg.regIdx == MISCREG_CPSR) {
+        if (reg.index() == MISCREG_CPSR) {
             ss << "cpsr";
             foundPsr = true;
             break;
         }
-        if (reg.regIdx == MISCREG_SPSR) {
+        if (reg.index() == MISCREG_SPSR) {
             ss << "spsr";
             foundPsr = true;
             break;
@@ -79,16 +79,16 @@ MsrBase::printMsrBase(std::ostream &os) const
     bool apsr = false;
     bool foundPsr = false;
     for (unsigned i = 0; i < numDestRegs(); i++) {
-        RegId reg = destRegIdx(i);
-        if (reg.regClass != MiscRegClass) {
+        const RegId& reg = destRegIdx(i);
+        if (!reg.isMiscReg()) {
             continue;
         }
-        if (reg.regIdx == MISCREG_CPSR) {
+        if (reg.index() == MISCREG_CPSR) {
             os << "cpsr_";
             foundPsr = true;
             break;
         }
-        if (reg.regIdx == MISCREG_SPSR) {
+        if (reg.index() == MISCREG_SPSR) {
             if (bits(byteMask, 1, 0)) {
                 os << "spsr_";
             } else {
index e05f0e18ad3f8f9b4cf3c5aa1929b7fb7e51c29e..8de90dc9329449dfba8fe240a71d678e01fec76f 100644 (file)
@@ -177,6 +177,22 @@ namespace ArmISA
         void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
         void setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc);
 
+        RegId
+        flattenRegId(const RegId& regId) const
+        {
+            switch (regId.classValue()) {
+              case IntRegClass:
+                return RegId(IntRegClass, flattenIntIndex(regId.index()));
+              case FloatRegClass:
+                return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
+              case CCRegClass:
+                return RegId(CCRegClass, flattenCCIndex(regId.index()));
+              case MiscRegClass:
+                return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
+            }
+            return RegId();
+        }
+
         int
         flattenIntIndex(int reg) const
         {
index d60dc60f1a783b35240f4b7bdfc4bce47f2d6604..48fc87ccb16ede8350f520af6f6fc12f02a1f517 100644 (file)
@@ -328,7 +328,7 @@ let {{
 
     buildDataXImmInst("mrs", '''
         MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->
-            flattenMiscIndex(op1);
+            flattenRegId(RegId(MiscRegClass, op1)).index();
         CPSR cpsr = Cpsr;
         ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
         %s
@@ -346,7 +346,7 @@ let {{
 
     buildDataXImmInst("msr", '''
         MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->
-            flattenMiscIndex(dest);
+            flattenRegId(RegId(MiscRegClass, dest)).index();
         CPSR cpsr = Cpsr;
         ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
         %s
@@ -362,7 +362,8 @@ let {{
     ''')
 
     msrdczva_ea_code = '''
-        MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->flattenMiscIndex(dest);
+        MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->flattenRegId(
+                                   RegId(MiscRegClass, dest)).index();
         CPSR cpsr = Cpsr;
         ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
     '''
@@ -391,7 +392,8 @@ let {{
 
     buildDataXImmInst("msrSP", '''
         if (!canWriteAArch64SysReg(
-                (MiscRegIndex) xc->tcBase()->flattenMiscIndex(dest),
+                (MiscRegIndex) xc->tcBase()->flattenRegId(
+                   RegId(MiscRegClass, dest)).index(),
                 Scr64, Cpsr, xc->tcBase())) {
             return std::make_shared<UndefinedInstruction>(machInst, false,
                                                           mnemonic);
@@ -401,7 +403,8 @@ let {{
 
     buildDataXImmInst("msrDAIFSet", '''
         if (!canWriteAArch64SysReg(
-                (MiscRegIndex) xc->tcBase()->flattenMiscIndex(dest),
+                (MiscRegIndex) xc->tcBase()->flattenRegId(
+                   RegId(MiscRegClass, dest)).index(),
                 Scr64, Cpsr, xc->tcBase())) {
             return std::make_shared<UndefinedInstruction>(
                             machInst, 0, EC_TRAPPED_MSR_MRS_64,
@@ -414,7 +417,8 @@ let {{
 
     buildDataXImmInst("msrDAIFClr", '''
         if (!canWriteAArch64SysReg(
-                (MiscRegIndex) xc->tcBase()->flattenMiscIndex(dest),
+                (MiscRegIndex) xc->tcBase()->flattenRegId(
+                   RegId(MiscRegClass, dest)).index(),
                 Scr64, Cpsr, xc->tcBase())) {
             return std::make_shared<UndefinedInstruction>(
                                 machInst, 0, EC_TRAPPED_MSR_MRS_64,
index dc2f3070109c47fc1e96ebaf34bcb14409fee82c..dff906755084c92011f6452922ca8bd916ef6e59 100644 (file)
@@ -224,7 +224,7 @@ let {{
     if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
         HCR hcr = Hcr;
         bool hypTrap = false;
-        switch(xc->tcBase()->flattenMiscIndex(op1)) {
+        switch(xc->tcBase()->flattenRegId(RegId(MiscRegClass, op1)).index()) {
           case MISCREG_FPSID:
             hypTrap = hcr.tid0;
             break;
index 6d6e56b8fb6c113e3c619b1389f92641835c0505..5eda615b5506c383e56c83cc2c8078f897b485d0 100644 (file)
@@ -813,7 +813,8 @@ let {{
     exec_output += PredOpExecute.subst(bfiIop)
 
     mrc14code = '''
-    MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenMiscIndex(op1);
+    MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenRegId(
+                               RegId(MiscRegClass, op1)).index();
     bool can_read, undefined;
     std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr);
     if (!can_read || undefined) {
@@ -837,7 +838,8 @@ let {{
 
 
     mcr14code = '''
-    MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenMiscIndex(dest);
+    MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenRegId(
+                               RegId(MiscRegClass, dest)).index();
     bool can_write, undefined;
     std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr);
     if (undefined || !can_write) {
@@ -862,7 +864,8 @@ let {{
     mrc15code = '''
     int preFlatOp1 = flattenMiscRegNsBanked(op1, xc->tcBase());
     MiscRegIndex miscReg = (MiscRegIndex)
-                           xc->tcBase()->flattenMiscIndex(preFlatOp1);
+                           xc->tcBase()->flattenRegId(RegId(MiscRegClass,
+                                                      preFlatOp1)).index();
     bool hypTrap = mcrMrc15TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, Hstr,
                                      Hcptr, imm);
     bool can_read, undefined;
@@ -893,7 +896,8 @@ let {{
     mcr15code = '''
     int preFlatDest = flattenMiscRegNsBanked(dest, xc->tcBase());
     MiscRegIndex miscReg = (MiscRegIndex)
-                       xc->tcBase()->flattenMiscIndex(preFlatDest);
+                       xc->tcBase()->flattenRegId(RegId(MiscRegClass,
+                                                  preFlatDest)).index();
     bool hypTrap  = mcrMrc15TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, Hstr,
                                       Hcptr, imm);
     bool can_write, undefined;
@@ -925,7 +929,8 @@ let {{
     mrrc15code = '''
     int preFlatOp1 = flattenMiscRegNsBanked(op1, xc->tcBase());
     MiscRegIndex miscReg = (MiscRegIndex)
-                           xc->tcBase()->flattenMiscIndex(preFlatOp1);
+                           xc->tcBase()->flattenRegId(RegId(MiscRegClass,
+                                                      preFlatOp1)).index();
     bool hypTrap = mcrrMrrc15TrapToHyp(miscReg, Cpsr, Scr, Hstr, Hcr, imm);
     bool can_read, undefined;
     std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr);
@@ -955,7 +960,8 @@ let {{
     mcrr15code = '''
     int preFlatDest = flattenMiscRegNsBanked(dest, xc->tcBase());
     MiscRegIndex miscReg = (MiscRegIndex)
-                           xc->tcBase()->flattenMiscIndex(preFlatDest);
+                           xc->tcBase()->flattenRegId(RegId(MiscRegClass,
+                                                      preFlatDest)).index();
     bool hypTrap  = mcrrMrrc15TrapToHyp(miscReg, Cpsr, Scr, Hstr, Hcr, imm);
     bool can_write, undefined;
     std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr);
index feb55e473996dfeac988c62617ab7b884a805f78..c751cb16825a889a58c89f3b4b58e5edd2bcc3b7 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "arch/mips/registers.hh"
 #include "arch/mips/types.hh"
+#include "cpu/reg_class.hh"
 #include "sim/eventq.hh"
 #include "sim/sim_object.hh"
 
@@ -165,6 +166,8 @@ namespace MipsISA
 
         ISA(Params *p);
 
+        RegId flattenRegId(const RegId& regId) const { return regId; }
+
         int
         flattenIntIndex(int reg) const
         {
index c0f25966655093d39d840350e1ecce23dfa002fd..946dce6dfd53fcc05b90f4a6f19d14dd577c4702 100644 (file)
@@ -72,11 +72,11 @@ output decoder {{
 
     void MipsStaticInst::printReg(std::ostream &os, RegId reg) const
     {
-        if (reg.regClass == IntRegClass) {
-            ccprintf(os, "r%d", reg.regIdx);
+        if (reg.isIntReg()) {
+            ccprintf(os, "r%d", reg.index());
         }
         else {
-            ccprintf(os, "f%d", reg.regIdx);
+            ccprintf(os, "f%d", reg.index());
         }
     }
 
index 641608e89568b4e7b99e5fcac2ad590a3e3b7d7b..c21c1255b61479e47b645c7a449c17b424681209 100644 (file)
@@ -257,9 +257,9 @@ output decoder {{
 
             ccprintf(ss, "%-10s ", mnemonic);
 
-            if (_numDestRegs > 0 && _destRegIdx[0].regIdx < 32) {
+            if (_numDestRegs > 0 && _destRegIdx[0].index() < 32) {
                 printReg(ss, _destRegIdx[0]);
-            } else if (_numSrcRegs > 0 && _srcRegIdx[0].regIdx < 32) {
+            } else if (_numSrcRegs > 0 && _srcRegIdx[0].index() < 32) {
                 printReg(ss, _srcRegIdx[0]);
             }
 
@@ -272,9 +272,9 @@ output decoder {{
 
             ccprintf(ss, "%-10s ", mnemonic);
 
-            if (_numDestRegs > 0 && _destRegIdx[0].regIdx < 32) {
+            if (_numDestRegs > 0 && _destRegIdx[0].index() < 32) {
                 printReg(ss, _destRegIdx[0]);
-            } else if (_numSrcRegs > 0 && _srcRegIdx[0].regIdx < 32) {
+            } else if (_numSrcRegs > 0 && _srcRegIdx[0].index() < 32) {
                 printReg(ss, _srcRegIdx[0]);
             }
 
@@ -287,9 +287,9 @@ output decoder {{
 
             ccprintf(ss, "%-10s ", mnemonic);
 
-            if (_numDestRegs > 0 && _destRegIdx[0].regIdx < 32) {
+            if (_numDestRegs > 0 && _destRegIdx[0].index() < 32) {
                 printReg(ss, _destRegIdx[0]);
-            } else if (_numSrcRegs > 0 && _srcRegIdx[0].regIdx < 32) {
+            } else if (_numSrcRegs > 0 && _srcRegIdx[0].index() < 32) {
                 printReg(ss, _srcRegIdx[0]);
             }
 
index f10e8453a9418f599e7b435a6bba4f978f422700..d13a0a7d3a4a687ad3df90c6e503a7a8beda6c9c 100644 (file)
@@ -153,7 +153,7 @@ BranchNonPCRelCond::generateDisassembly(Addr pc,
 PowerISA::PCState
 BranchRegCond::branchTarget(ThreadContext *tc) const
 {
-    uint32_t regVal = tc->readIntReg(_srcRegIdx[_numSrcRegs - 1].regIdx);
+    uint32_t regVal = tc->readIntReg(_srcRegIdx[_numSrcRegs - 1].index());
     return regVal & 0xfffffffc;
 }
 
index 210205db2e081cdb8e0ce894a78c5b1bf5e3c526..85f9cf6281b5e227e0eedf01e2f1173bd112cbda 100644 (file)
@@ -38,15 +38,12 @@ using namespace PowerISA;
 void
 PowerStaticInst::printReg(std::ostream &os, RegId reg) const
 {
-    switch (reg.regClass) {
-      case IntRegClass:
-        ccprintf(os, "r%d", reg.regIdx);
-        break;
-      case FloatRegClass:
-        ccprintf(os, "f%d", reg.regIdx);
-        break;
-      case MiscRegClass:
-        switch (reg.regIdx) {
+    if (reg.isIntReg())
+        ccprintf(os, "r%d", reg.index());
+    else if (reg.isFloatReg())
+        ccprintf(os, "f%d", reg.index());
+    else if (reg.isMiscReg())
+        switch (reg.index()) {
           case 0: ccprintf(os, "cr"); break;
           case 1: ccprintf(os, "xer"); break;
           case 2: ccprintf(os, "lr"); break;
@@ -54,9 +51,8 @@ PowerStaticInst::printReg(std::ostream &os, RegId reg) const
           default: ccprintf(os, "unknown_reg");
             break;
         }
-      case CCRegClass:
+    else if (reg.isCCReg())
         panic("printReg: POWER does not implement CCRegClass\n");
-    }
 }
 
 std::string
index aaf5bd92a3be06ff65fd59b5727a76e932108357..475b4d2f828c62e891fdee4a85a67a5695e49aee 100644 (file)
@@ -36,6 +36,7 @@
 #include "arch/power/registers.hh"
 #include "arch/power/types.hh"
 #include "base/misc.hh"
+#include "cpu/reg_class.hh"
 #include "sim/sim_object.hh"
 
 struct PowerISAParams;
@@ -86,6 +87,8 @@ class ISA : public SimObject
         fatal("Power does not currently have any misc regs defined\n");
     }
 
+    RegId flattenRegId(const RegId& regId) const { return regId; }
+
     int
     flattenIntIndex(int reg) const
     {
index d2f38b158395ef24b59ad0d1e472b587111e48f4..3f241230356e1580579a078d70a0c51117d1b6ba 100644 (file)
@@ -44,6 +44,7 @@
 #include "arch/riscv/registers.hh"
 #include "arch/riscv/types.hh"
 #include "base/misc.hh"
+#include "cpu/reg_class.hh"
 #include "sim/sim_object.hh"
 
 struct RiscvISAParams;
@@ -78,6 +79,12 @@ class ISA : public SimObject
     void
     setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc);
 
+    RegId
+    flattenRegId(const RegId &regId) const
+    {
+        return regId;
+    }
+
     int
     flattenIntIndex(int reg) const
     {
index dafccc98123d0e2c6b4014047bb647ad3c1a3e52..a7e2fc954689b0b17e571a45cb136286634e53c5 100644 (file)
@@ -70,13 +70,12 @@ output decoder {{
     std::string
     RiscvStaticInst::regName(RegId reg) const
     {
-        switch (reg.regClass) {
-          case IntRegClass:
-            return std::string(RegisterNames[reg.regIdx]);
-          case FloatRegClass:
-            return std::string("f") + std::to_string(reg.regIdx);
-          default:
-            return csprintf("unknown[%i/%i]", reg.regClass, reg.regIdx);
+        if (reg.isIntReg()) {
+            return std::string(RegisterNames[reg.index()]);
+        } else if (reg.isFloatReg()) {
+            return std::string("f") + std::to_string(reg.index());
+        } else {
+            return csprintf("%s{%i}", reg.className(), reg.index());
         }
     }
 }};
index 0f2ffe9c40c5ef6015c6497e7e7f8668b41e77db..f6a5636995a561d68bde1d7dee00d4b088f5126d 100644 (file)
@@ -210,7 +210,7 @@ output decoder {{
     Jump::branchTarget(ThreadContext *tc) const
     {
         PCState pc = tc->pcState();
-        IntReg Rs1 = tc->readIntReg(_srcRegIdx[0].regIdx);
+        IntReg Rs1 = tc->readIntReg(_srcRegIdx[0].index());
         pc.set((Rs1 + imm)&~0x1);
         return pc;
     }
index 18ac30857daedd5f462d48e1f0c932eeb1fe557b..ded5b34ffdbe94462c04617b193b95aa03f296b4 100644 (file)
@@ -37,6 +37,7 @@
 #include "arch/sparc/registers.hh"
 #include "arch/sparc/types.hh"
 #include "cpu/cpuevent.hh"
+#include "cpu/reg_class.hh"
 #include "sim/sim_object.hh"
 
 class Checkpoint;
@@ -189,6 +190,22 @@ class ISA : public SimObject
     void setMiscReg(int miscReg, const MiscReg val,
             ThreadContext *tc);
 
+    RegId
+    flattenRegId(const RegId& regId) const
+    {
+        switch (regId.classValue()) {
+          case IntRegClass:
+            return RegId(IntRegClass, flattenIntIndex(regId.index()));
+          case FloatRegClass:
+            return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
+          case CCRegClass:
+            return RegId(CCRegClass, flattenCCIndex(regId.index()));
+          case MiscRegClass:
+            return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
+        }
+        return regId;
+    }
+
     int
     flattenIntIndex(int reg) const
     {
index 4a4293e50a8e68ac6fb7db68813d4377dea7cae6..b517d462cad8adda571e2bee780bd9aebdfa6b3f 100644 (file)
@@ -290,8 +290,8 @@ output decoder {{
             const int MaxLocal = 24;
             const int MaxInput = 32;
             const int MaxMicroReg = 40;
-            RegIndex reg_idx = reg.regIdx;
-            if (reg.regClass == IntRegClass) {
+            RegIndex reg_idx = reg.index();
+            if (reg.isIntReg()) {
                 // If we used a register from the next or previous window,
                 // take out the offset.
                 while (reg_idx >= MaxMicroReg)
@@ -336,7 +336,7 @@ output decoder {{
                         break;
                     }
                 }
-            } else if (reg.regClass == FloatRegClass) {
+            } else if (reg.isFloatReg()) {
                 ccprintf(os, "%%f%d", reg_idx);
             } else {
                 switch (reg_idx) {
index 585dfccedabfe5e86bba99614286bacc8498234a..e60c93cd26abfb39e13bac81da3f5ef801edb320 100644 (file)
@@ -155,7 +155,7 @@ output decoder {{
         IntOp::printPseudoOps(std::ostream &os, Addr pc,
                 const SymbolTable *symbab) const
         {
-            if (!std::strcmp(mnemonic, "or") && _srcRegIdx[0].regIdx == 0) {
+            if (!std::strcmp(mnemonic, "or") && _srcRegIdx[0].index() == 0) {
                 printMnemonic(os, "mov");
                 printSrcReg(os, 1);
                 ccprintf(os, ", ");
@@ -170,7 +170,7 @@ output decoder {{
                 const SymbolTable *symbab) const
         {
             if (!std::strcmp(mnemonic, "or")) {
-                if (_numSrcRegs > 0 && _srcRegIdx[0].regIdx == 0) {
+                if (_numSrcRegs > 0 && _srcRegIdx[0].index() == 0) {
                     if (imm == 0) {
                         printMnemonic(os, "clr");
                     } else {
index 9b3132e4000510ec6315a30ebe64eaddd9066597..00e09ce5460672b80a3fb953653dcb2f3be33545 100644 (file)
@@ -84,7 +84,7 @@ output decoder {{
                 ccprintf(response, ", ");
             }
             ccprintf(response, "[");
-            if (_srcRegIdx[!store ? 0 : 1].regIdx != 0) {
+            if (_srcRegIdx[!store ? 0 : 1].index() != 0) {
                 printSrcReg(response, !store ? 0 : 1);
                 ccprintf(response, " + ");
             }
@@ -111,7 +111,7 @@ output decoder {{
                 ccprintf(response, ", ");
             }
             ccprintf(response, "[");
-            if (_srcRegIdx[!save ? 0 : 1].regIdx != 0) {
+            if (_srcRegIdx[!save ? 0 : 1].index() != 0) {
                 printReg(response, _srcRegIdx[!save ? 0 : 1]);
                 ccprintf(response, " + ");
             }
index f5e1a082611b71f7479ac41a33c3ea4b87d4a2c7..3f6d35330a348b957dd271bc330c994f0e7610b7 100644 (file)
@@ -155,7 +155,7 @@ output decoder {{
             ccprintf(response, " ");
             // If the first reg is %g0, don't print it.
             // This improves readability
-            if (_srcRegIdx[0].regIdx != 0) {
+            if (_srcRegIdx[0].index() != 0) {
                 printSrcReg(response, 0);
                 ccprintf(response, ", ");
             }
@@ -175,7 +175,7 @@ output decoder {{
             ccprintf(response, " ");
             // If the first reg is %g0, don't print it.
             // This improves readability
-            if (_srcRegIdx[0].regIdx != 0) {
+            if (_srcRegIdx[0].index() != 0) {
                 printSrcReg(response, 0);
                 ccprintf(response, ", ");
             }
index 04ec285d450c2d8e514c93a2a7f080c96db9f545..d326b5dfcfd255113c89a62a38a6719dc86897a0 100644 (file)
@@ -66,7 +66,7 @@ namespace X86ISA
                 OpClass __opClass) :
             X86MicroopBase(_machInst, mnem, _instMnem, setFlags,
                     __opClass),
-            src1(_src1.regIdx), src2(_src2.regIdx), dest(_dest.regIdx),
+            src1(_src1.index()), src2(_src2.index()), dest(_dest.index()),
             dataSize(_dataSize), spm(_spm)
         {}
 /*
index e12a51c4c6ac3037fd980f225381cfd5a436b9fe..1d328d1a1a27692f2f9bc8c790aa6308aeb66c90 100644 (file)
@@ -75,12 +75,12 @@ namespace X86ISA
                 Request::FlagsType _memFlags,
                 OpClass __opClass) :
         X86MicroopBase(_machInst, mnem, _instMnem, setFlags, __opClass),
-                scale(_scale), index(_index.regIdx), base(_base.regIdx),
-                disp(_disp), segment(_segment.regIdx),
+                scale(_scale), index(_index.index()), base(_base.index()),
+                disp(_disp), segment(_segment.index()),
                 dataSize(_dataSize), addressSize(_addressSize),
-                memFlags(_memFlags | _segment.regIdx)
+                memFlags(_memFlags | _segment.index())
         {
-            assert(_segment.regIdx < NUM_SEGMENTREGS);
+            assert(_segment.index() < NUM_SEGMENTREGS);
             foldOBit =
                 (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
             foldABit =
@@ -110,7 +110,7 @@ namespace X86ISA
                 _scale, _index, _base, _disp, _segment,
                 _dataSize, _addressSize, _memFlags,
                 __opClass),
-                data(_data.regIdx)
+                data(_data.index())
         {
         }
 
@@ -143,8 +143,8 @@ namespace X86ISA
                 _scale, _index, _base, _disp, _segment,
                 _dataSize, _addressSize, _memFlags,
                 __opClass),
-                dataLow(_dataLow.regIdx),
-                dataHi(_dataHi.regIdx)
+                dataLow(_dataLow.index()),
+                dataHi(_dataHi.index())
         {
         }
 
index 547780108e554d5d1a7d38336ca85822c59ff315..5cb0bdbb0e61d25c3660215d073046e75cb1b19b 100644 (file)
@@ -59,7 +59,7 @@ namespace X86ISA
                 OpClass __opClass) :
             X86MicroopBase(_machInst, mnem, _instMnem, setFlags,
                     __opClass),
-            src1(_src1.regIdx), dest(_dest.regIdx),
+            src1(_src1.index()), dest(_dest.index()),
             srcSize(_srcSize), destSize(_destSize), ext(_ext)
         {}
 
@@ -102,7 +102,7 @@ namespace X86ISA
             MediaOpBase(_machInst, mnem, _instMnem, setFlags,
                     _src1, _dest, _srcSize, _destSize, _ext,
                     __opClass),
-            src2(_src2.regIdx)
+            src2(_src2.index())
         {}
 
         std::string generateDisassembly(Addr pc,
index 1accc35553244a16bc3d37aa7fbb2be84d9fe7f9..9838b7cc16dd52975f18abb6335f247637fd86d0 100644 (file)
@@ -64,7 +64,7 @@ namespace X86ISA
                 OpClass __opClass) :
             X86MicroopBase(_machInst, mnem, _instMnem, setFlags,
                     __opClass),
-            src1(_src1.regIdx), dest(_dest.regIdx),
+            src1(_src1.index()), dest(_dest.index()),
             dataSize(_dataSize), ext(_ext)
         {
             foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
@@ -90,7 +90,7 @@ namespace X86ISA
             RegOpBase(_machInst, mnem, _instMnem, setFlags,
                     _src1, _dest, _dataSize, _ext,
                     __opClass),
-            src2(_src2.regIdx)
+            src2(_src2.index())
         {
         }
 
index b9c5486ed97a3681f8b33507742c11bd26e8999e..28c268d4ef599fdfbebc37970ff5a1e9b47c2b7c 100644 (file)
@@ -132,10 +132,9 @@ namespace X86ISA
         static const char * microFormats[9] =
             {"", "t%db", "t%dw", "", "t%dd", "", "", "", "t%d"};
 
-        RegIndex reg_idx = reg.regIdx;
+        RegIndex reg_idx = reg.index();
 
-        switch (reg.regClass) {
-          case IntRegClass: {
+        if (reg.isIntReg()) {
             const char * suffix = "";
             bool fold = reg_idx & IntFoldBit;
             reg_idx &= ~IntFoldBit;
@@ -198,10 +197,8 @@ namespace X86ISA
                 ccprintf(os, microFormats[size], reg_idx - NUM_INTREGS);
             }
             ccprintf(os, suffix);
-            break;
-          }
 
-          case FloatRegClass: {
+        } else if (reg.isFloatReg()) {
             if (reg_idx < NumMMXRegs) {
                 ccprintf(os, "%%mmx%d", reg_idx);
                 return;
@@ -219,19 +216,15 @@ namespace X86ISA
             }
             reg_idx -= NumMicroFpRegs;
             ccprintf(os, "%%st(%d)", reg_idx);
-            break;
-          }
 
-          case CCRegClass:
+        } else if (reg.isCCReg()) {
             ccprintf(os, "%%cc%d", reg_idx);
-            break;
 
-          case MiscRegClass:
+        } else if (reg.isMiscReg()) {
             switch (reg_idx) {
               default:
                 ccprintf(os, "%%ctrl%d", reg_idx);
             }
-            break;
         }
     }
 
index 0cea0e132c89624d6237fb81b9925801ff95023a..8dac3ec0f506d31937b6d8ef69177eaac01b406d 100644 (file)
@@ -107,7 +107,7 @@ namespace X86ISA
         inline uint64_t merge(uint64_t into, uint64_t val, int size) const
         {
             X86IntReg reg = into;
-            if (_destRegIdx[0].regIdx & IntFoldBit)
+            if (_destRegIdx[0].index() & IntFoldBit)
             {
                 reg.H = val;
                 return reg;
@@ -138,7 +138,7 @@ namespace X86ISA
         {
             X86IntReg reg = from;
             DPRINTF(X86, "Picking with size %d\n", size);
-            if (_srcRegIdx[idx].regIdx & IntFoldBit)
+            if (_srcRegIdx[idx].index() & IntFoldBit)
                 return reg.H;
             switch(size)
             {
@@ -159,7 +159,7 @@ namespace X86ISA
         {
             X86IntReg reg = from;
             DPRINTF(X86, "Picking with size %d\n", size);
-            if (_srcRegIdx[idx].regIdx & IntFoldBit)
+            if (_srcRegIdx[idx].index() & IntFoldBit)
                 return reg.SH;
             switch(size)
             {
index 90ab619cce5b9eedae1b454dc3ab0ede8b1f7cd2..099d27c7c5202b6681b7ff3530efab979062a80f 100644 (file)
@@ -38,6 +38,7 @@
 #include "arch/x86/regs/misc.hh"
 #include "arch/x86/registers.hh"
 #include "base/types.hh"
+#include "cpu/reg_class.hh"
 #include "sim/sim_object.hh"
 
 class Checkpoint;
@@ -69,6 +70,22 @@ namespace X86ISA
         void setMiscRegNoEffect(int miscReg, MiscReg val);
         void setMiscReg(int miscReg, MiscReg val, ThreadContext *tc);
 
+        RegId
+        flattenRegId(const RegId& regId) const
+        {
+            switch (regId.classValue()) {
+              case IntRegClass:
+                return RegId(IntRegClass, flattenIntIndex(regId.index()));
+              case FloatRegClass:
+                return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
+              case CCRegClass:
+                return RegId(CCRegClass, flattenCCIndex(regId.index()));
+              case MiscRegClass:
+                return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
+            }
+            return regId;
+        }
+
         int
         flattenIntIndex(int reg) const
         {
index 8a832f5d577bef73f1046f1d16587dac292966e4..c002a16849744435e280e47754493794d7f64502 100644 (file)
@@ -95,7 +95,7 @@ def template MicroLimmOpConstructor {{
             InstRegIndex _dest, uint64_t _imm, uint8_t _dataSize) :
         %(base_class)s(machInst, "%(mnemonic)s", instMnem,
                 setFlags, %(op_class)s),
-                dest(_dest.regIdx), imm(_imm), dataSize(_dataSize)
+                dest(_dest.index()), imm(_imm), dataSize(_dataSize)
     {
         foldOBit = (dataSize == 1 && !machInst.rex.present) ? 1 << 6 : 0;
         %(constructor)s;
index 369d7a02aa3e0d8fb0922360366233a525af3723..9c69523109e0482f7eb21c08bdfe8785aec6e822 100644 (file)
@@ -383,7 +383,7 @@ class BaseDynInst : public ExecContext, public RefCounted
     /** Returns the flattened register index of the i'th destination
      *  register.
      */
-    RegId flattenedDestRegIdx(int idx) const
+    const RegId& flattenedDestRegIdx(int idx) const
     {
         return _flatDestRegIdx[idx];
     }
@@ -419,7 +419,7 @@ class BaseDynInst : public ExecContext, public RefCounted
     /** Flattens a destination architectural register index into a logical
      * index.
      */
-    void flattenDestReg(int idx, RegId flattened_dest)
+    void flattenDestReg(int idx, const RegId& flattened_dest)
     {
         _flatDestRegIdx[idx] = flattened_dest;
     }
@@ -601,10 +601,10 @@ class BaseDynInst : public ExecContext, public RefCounted
     int8_t numCCDestRegs() const { return staticInst->numCCDestRegs(); }
 
     /** Returns the logical register index of the i'th destination register. */
-    RegId destRegIdx(int i) const { return staticInst->destRegIdx(i); }
+    const RegId& destRegIdx(int i) const { return staticInst->destRegIdx(i); }
 
     /** Returns the logical register index of the i'th source register. */
-    RegId srcRegIdx(int i) const { return staticInst->srcRegIdx(i); }
+    const RegId& srcRegIdx(int i) const { return staticInst->srcRegIdx(i); }
 
     /** Pops a result off the instResult queue */
     template <class T>
index 3afbc31fb1e4e1b72defc127554a97a051fc197c..304caaa85b55dad762f2502d18b2e525ddead361 100644 (file)
@@ -213,31 +213,31 @@ class CheckerCPU : public BaseCPU, public ExecContext
 
     IntReg readIntRegOperand(const StaticInst *si, int idx) override
     {
-        RegId reg = si->srcRegIdx(idx);
-        assert(reg.regClass == IntRegClass);
-        return thread->readIntReg(reg.regIdx);
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isIntReg());
+        return thread->readIntReg(reg.index());
     }
 
     FloatReg readFloatRegOperand(const StaticInst *si, int idx) override
     {
-        RegId reg = si->srcRegIdx(idx);
-        assert(reg.regClass == FloatRegClass);
-        return thread->readFloatReg(reg.regIdx);
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isFloatReg());
+        return thread->readFloatReg(reg.index());
     }
 
     FloatRegBits readFloatRegOperandBits(const StaticInst *si,
                                          int idx) override
     {
-        RegId reg = si->srcRegIdx(idx);
-        assert(reg.regClass == FloatRegClass);
-        return thread->readFloatRegBits(reg.regIdx);
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isFloatReg());
+        return thread->readFloatRegBits(reg.index());
     }
 
     CCReg readCCRegOperand(const StaticInst *si, int idx) override
     {
-        RegId reg = si->srcRegIdx(idx);
-        assert(reg.regClass == CCRegClass);
-        return thread->readCCReg(reg.regIdx);
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isCCReg());
+        return thread->readCCReg(reg.index());
     }
 
     template <class T>
@@ -251,35 +251,35 @@ class CheckerCPU : public BaseCPU, public ExecContext
     void setIntRegOperand(const StaticInst *si, int idx,
                           IntReg val) override
     {
-        RegId reg = si->destRegIdx(idx);
-        assert(reg.regClass == IntRegClass);
-        thread->setIntReg(reg.regIdx, val);
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isIntReg());
+        thread->setIntReg(reg.index(), val);
         setResult<uint64_t>(val);
     }
 
     void setFloatRegOperand(const StaticInst *si, int idx,
                             FloatReg val) override
     {
-        RegId reg = si->destRegIdx(idx);
-        assert(reg.regClass == FloatRegClass);
-        thread->setFloatReg(reg.regIdx, val);
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isFloatReg());
+        thread->setFloatReg(reg.index(), val);
         setResult<double>(val);
     }
 
     void setFloatRegOperandBits(const StaticInst *si, int idx,
                                 FloatRegBits val) override
     {
-        RegId reg = si->destRegIdx(idx);
-        assert(reg.regClass == FloatRegClass);
-        thread->setFloatRegBits(reg.regIdx, val);
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isFloatReg());
+        thread->setFloatRegBits(reg.index(), val);
         setResult<uint64_t>(val);
     }
 
     void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
     {
-        RegId reg = si->destRegIdx(idx);
-        assert(reg.regClass == CCRegClass);
-        thread->setCCReg(reg.regIdx, val);
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isCCReg());
+        thread->setCCReg(reg.index(), val);
         setResult<uint64_t>(val);
     }
 
@@ -327,27 +327,28 @@ class CheckerCPU : public BaseCPU, public ExecContext
 
     MiscReg readMiscRegOperand(const StaticInst *si, int idx) override
     {
-        RegId reg = si->srcRegIdx(idx);
-        assert(reg.regClass == MiscRegClass);
-        return thread->readMiscReg(reg.regIdx);
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isMiscReg());
+        return thread->readMiscReg(reg.index());
     }
 
     void setMiscRegOperand(const StaticInst *si, int idx,
                            const MiscReg &val) override
     {
-        RegId reg = si->destRegIdx(idx);
-        assert(reg.regClass == MiscRegClass);
-        return this->setMiscReg(reg.regIdx, val);
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isMiscReg());
+        return this->setMiscReg(reg.index(), val);
     }
 
 #if THE_ISA == MIPS_ISA
-    MiscReg readRegOtherThread(RegId misc_reg, ThreadID tid) override
+    MiscReg readRegOtherThread(const RegId& misc_reg, ThreadID tid) override
     {
         panic("MIPS MT not defined for CheckerCPU.\n");
         return 0;
     }
 
-    void setRegOtherThread(RegId misc_reg, MiscReg val, ThreadID tid) override
+    void setRegOtherThread(const RegId& misc_reg, MiscReg val,
+                               ThreadID tid) override
     {
         panic("MIPS MT not defined for CheckerCPU.\n");
     }
index 47a088aa6ccd6e6ba769c9a0049085fa3ed8eef3..0c90590c750015dacf27b5157ae96de266cf8a59 100644 (file)
@@ -595,40 +595,40 @@ Checker<Impl>::copyResult(DynInstPtr &inst, uint64_t mismatch_val,
     // We've already popped one dest off the queue,
     // so do the fix-up then start with the next dest reg;
     if (start_idx >= 0) {
-        RegId idx = inst->destRegIdx(start_idx);
-        switch (idx.regClass) {
+        const RegId& idx = inst->destRegIdx(start_idx);
+        switch (idx.classValue()) {
           case IntRegClass:
-            thread->setIntReg(idx.regIdx, mismatch_val);
+            thread->setIntReg(idx.index(), mismatch_val);
             break;
           case FloatRegClass:
-            thread->setFloatRegBits(idx.regIdx, mismatch_val);
+            thread->setFloatRegBits(idx.index(), mismatch_val);
             break;
           case CCRegClass:
-            thread->setCCReg(idx.regIdx, mismatch_val);
+            thread->setCCReg(idx.index(), mismatch_val);
             break;
           case MiscRegClass:
-            thread->setMiscReg(idx.regIdx, mismatch_val);
+            thread->setMiscReg(idx.index(), mismatch_val);
             break;
         }
     }
     start_idx++;
     uint64_t res = 0;
     for (int i = start_idx; i < inst->numDestRegs(); i++) {
-        RegId idx = inst->destRegIdx(i);
+        const RegId& idx = inst->destRegIdx(i);
         inst->template popResult<uint64_t>(res);
-        switch (idx.regClass) {
+        switch (idx.classValue()) {
           case IntRegClass:
-            thread->setIntReg(idx.regIdx, res);
+            thread->setIntReg(idx.index(), res);
             break;
           case FloatRegClass:
-            thread->setFloatRegBits(idx.regIdx, res);
+            thread->setFloatRegBits(idx.index(), res);
             break;
           case CCRegClass:
-            thread->setCCReg(idx.regIdx, res);
+            thread->setCCReg(idx.index(), res);
             break;
           case MiscRegClass:
             // Try to get the proper misc register index for ARM here...
-            thread->setMiscReg(idx.regIdx, res);
+            thread->setMiscReg(idx.index(), res);
             break;
             // else Register is out of range...
         }
index 7b09dde9005b94c15c6d673dcc1057504435ce2e..e48f5936b8fb70d096fabffe81f2f11371cacf7c 100644 (file)
@@ -301,10 +301,9 @@ class CheckerThreadContext : public ThreadContext
         actualTC->setMiscReg(misc_reg, val);
     }
 
-    int flattenIntIndex(int reg) { return actualTC->flattenIntIndex(reg); }
-    int flattenFloatIndex(int reg) { return actualTC->flattenFloatIndex(reg); }
-    int flattenCCIndex(int reg) { return actualTC->flattenCCIndex(reg); }
-    int flattenMiscIndex(int reg) { return actualTC->flattenMiscIndex(reg); }
+    RegId flattenRegId(const RegId& regId) const {
+        return actualTC->flattenRegId(regId);
+    }
 
     unsigned readStCondFailures()
     { return actualTC->readStCondFailures(); }
index 1b6084e27803cb0c0aac6323772365af6dc3888d..d331472407c4f7f7d254f90f5126fb9f618101f3 100644 (file)
@@ -287,9 +287,9 @@ class ExecContext {
      */
 
 #if THE_ISA == MIPS_ISA
-    virtual MiscReg readRegOtherThread(RegId reg,
+    virtual MiscReg readRegOtherThread(const RegId& reg,
                                        ThreadID tid = InvalidThreadID) = 0;
-    virtual void setRegOtherThread(RegId reg, MiscReg val,
+    virtual void setRegOtherThread(const RegId& reg, MiscReg val,
                                    ThreadID tid = InvalidThreadID) = 0;
 #endif
 
index 42c370a709f7e9643ad72d5fa3d34e7a94dcd7bf..1ed5988333c01f4843c2b09ed04f815ee64c6fff 100644 (file)
@@ -133,15 +133,13 @@ operator <<(std::ostream &os, const MinorDynInst &inst)
 /** Print a register in the form r<n>, f<n>, m<n>(<name>), z for integer,
  *  float, misc and zero registers given an 'architectural register number' */
 static void
-printRegName(std::ostream &os, RegId reg)
+printRegName(std::ostream &os, const RegId& reg)
 {
-    RegClass reg_class = reg.regClass;
-
-    switch (reg_class)
+    switch (reg.classValue())
     {
       case MiscRegClass:
         {
-            RegIndex misc_reg = reg.regIdx;
+            RegIndex misc_reg = reg.index();
 
         /* This is an ugly test because not all archs. have miscRegName */
 #if THE_ISA == ARM_ISA
@@ -153,17 +151,17 @@ printRegName(std::ostream &os, RegId reg)
         }
         break;
       case FloatRegClass:
-        os << 'f' << static_cast<unsigned int>(reg.regIdx);
+        os << 'f' << static_cast<unsigned int>(reg.index());
         break;
       case IntRegClass:
         if (reg.isZeroReg()) {
             os << 'z';
         } else {
-            os << 'r' << static_cast<unsigned int>(reg.regIdx);
+            os << 'r' << static_cast<unsigned int>(reg.index());
         }
         break;
       case CCRegClass:
-        os << 'c' << static_cast<unsigned int>(reg.regIdx);
+        os << 'c' << static_cast<unsigned int>(reg.index());
     }
 }
 
index d517d5abb1b855e00b7a1dc89038c4f745c77312..e91b7a6dde912560daca554caf24e1e08527aa43 100644 (file)
@@ -124,51 +124,51 @@ class ExecContext : public ::ExecContext
     IntReg
     readIntRegOperand(const StaticInst *si, int idx) override
     {
-        RegId reg = si->srcRegIdx(idx);
-        assert(reg.regClass == IntRegClass);
-        return thread.readIntReg(reg.regIdx);
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isIntReg());
+        return thread.readIntReg(reg.index());
     }
 
     TheISA::FloatReg
     readFloatRegOperand(const StaticInst *si, int idx) override
     {
-        RegId reg = si->srcRegIdx(idx);
-        assert(reg.regClass == FloatRegClass);
-        return thread.readFloatReg(reg.regIdx);
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isFloatReg());
+        return thread.readFloatReg(reg.index());
     }
 
     TheISA::FloatRegBits
     readFloatRegOperandBits(const StaticInst *si, int idx) override
     {
-        RegId reg = si->srcRegIdx(idx);
-        assert(reg.regClass == FloatRegClass);
-        return thread.readFloatRegBits(reg.regIdx);
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isFloatReg());
+        return thread.readFloatRegBits(reg.index());
     }
 
     void
     setIntRegOperand(const StaticInst *si, int idx, IntReg val) override
     {
-        RegId reg = si->destRegIdx(idx);
-        assert(reg.regClass == IntRegClass);
-        thread.setIntReg(reg.regIdx, val);
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isIntReg());
+        thread.setIntReg(reg.index(), val);
     }
 
     void
     setFloatRegOperand(const StaticInst *si, int idx,
         TheISA::FloatReg val) override
     {
-        RegId reg = si->destRegIdx(idx);
-        assert(reg.regClass == FloatRegClass);
-        thread.setFloatReg(reg.regIdx, val);
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isFloatReg());
+        thread.setFloatReg(reg.index(), val);
     }
 
     void
     setFloatRegOperandBits(const StaticInst *si, int idx,
         TheISA::FloatRegBits val) override
     {
-        RegId reg = si->destRegIdx(idx);
-        assert(reg.regClass == FloatRegClass);
-        thread.setFloatRegBits(reg.regIdx, val);
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isFloatReg());
+        thread.setFloatRegBits(reg.index(), val);
     }
 
     bool
@@ -216,18 +216,18 @@ class ExecContext : public ::ExecContext
     TheISA::MiscReg
     readMiscRegOperand(const StaticInst *si, int idx) override
     {
-        RegId reg = si->srcRegIdx(idx);
-        assert(reg.regClass == MiscRegClass);
-        return thread.readMiscReg(reg.regIdx);
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isMiscReg());
+        return thread.readMiscReg(reg.index());
     }
 
     void
     setMiscRegOperand(const StaticInst *si, int idx,
         const TheISA::MiscReg &val) override
     {
-        RegId reg = si->destRegIdx(idx);
-        assert(reg.regClass == MiscRegClass);
-        return thread.setMiscReg(reg.regIdx, val);
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isMiscReg());
+        return thread.setMiscReg(reg.index(), val);
     }
 
     Fault
@@ -279,17 +279,17 @@ class ExecContext : public ::ExecContext
     TheISA::CCReg
     readCCRegOperand(const StaticInst *si, int idx) override
     {
-        RegId reg = si->srcRegIdx(idx);
-        assert(reg.regClass == CCRegClass);
-        return thread.readCCReg(reg.regIdx);
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isCCReg());
+        return thread.readCCReg(reg.index());
     }
 
     void
     setCCRegOperand(const StaticInst *si, int idx, TheISA::CCReg val) override
     {
-        RegId reg = si->destRegIdx(idx);
-        assert(reg.regClass == CCRegClass);
-        thread.setCCReg(reg.regIdx, val);
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isCCReg());
+        thread.setCCReg(reg.index(), val);
     }
 
     void
@@ -320,46 +320,46 @@ class ExecContext : public ::ExecContext
 
     /* MIPS: other thread register reading/writing */
     uint64_t
-    readRegOtherThread(RegId reg, ThreadID tid = InvalidThreadID)
+    readRegOtherThread(const RegId& reg, ThreadID tid = InvalidThreadID)
     {
         SimpleThread *other_thread = (tid == InvalidThreadID
             ? &thread : cpu.threads[tid]);
 
-        switch(reg.regClass) {
+        switch (reg.classValue()) {
             case IntRegClass:
-                return other_thread->readIntReg(reg.regIdx);
+                return other_thread->readIntReg(reg.index());
                 break;
             case FloatRegClass:
-                return other_thread->readFloatRegBits(reg.regIdx);
+                return other_thread->readFloatRegBits(reg.index());
                 break;
             case MiscRegClass:
-                return other_thread->readMiscReg(reg.regIdx);
+                return other_thread->readMiscReg(reg.index());
             default:
                 panic("Unexpected reg class! (%s)",
-                      RegClassStrings[reg.regClass]);
+                      reg.className());
                 return 0;
         }
     }
 
     void
-    setRegOtherThread(RegId reg, const TheISA::MiscReg &val,
+    setRegOtherThread(const RegId& reg, const TheISA::MiscReg &val,
         ThreadID tid = InvalidThreadID)
     {
         SimpleThread *other_thread = (tid == InvalidThreadID
             ? &thread : cpu.threads[tid]);
 
-         switch(reg.regClass) {
+        switch (reg.classValue()) {
             case IntRegClass:
-                return other_thread->setIntReg(reg.regIdx, val);
+                return other_thread->setIntReg(reg.index(), val);
                 break;
             case FloatRegClass:
-                return other_thread->setFloatRegBits(reg.regIdx, val);
+                return other_thread->setFloatRegBits(reg.index(), val);
                 break;
             case MiscRegClass:
-                return other_thread->setMiscReg(reg.regIdx, val);
+                return other_thread->setMiscReg(reg.index(), val);
             default:
                 panic("Unexpected reg class! (%s)",
-                      RegClassStrings[reg.regClass]);
+                      reg.className());
         }
     }
 
index 31657b310006ab114f9b23dd7481da036c3bd8f0..e3497a5cfe05270ac089eed2ae3ed5f4828d303f 100644 (file)
@@ -48,7 +48,7 @@ namespace Minor
 {
 
 bool
-Scoreboard::findIndex(RegId reg, Index &scoreboard_index)
+Scoreboard::findIndex(const RegId& reg, Index &scoreboard_index)
 {
     bool ret = false;
 
@@ -56,19 +56,19 @@ Scoreboard::findIndex(RegId reg, Index &scoreboard_index)
         /* Don't bother with the zero register */
         ret = false;
     } else {
-        switch (reg.regClass)
+        switch (reg.classValue())
         {
           case IntRegClass:
-            scoreboard_index = reg.regIdx;
+            scoreboard_index = reg.index();
             ret = true;
             break;
           case FloatRegClass:
             scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
-                reg.regIdx;
+                reg.index();
             ret = true;
             break;
           case CCRegClass:
-            scoreboard_index = TheISA::NumIntRegs + reg.regIdx;
+            scoreboard_index = TheISA::NumIntRegs + reg.index();
             ret = true;
             break;
           case MiscRegClass:
@@ -83,26 +83,9 @@ Scoreboard::findIndex(RegId reg, Index &scoreboard_index)
 
 /** Flatten a RegId, irrespective of what reg type it's pointing to */
 static RegId
-flattenRegIndex(RegId reg, ThreadContext *thread_context)
+flattenRegIndex(const RegId& reg, ThreadContext *thread_context)
 {
-    switch (reg.regClass)
-    {
-      case IntRegClass:
-        reg.regIdx = thread_context->flattenIntIndex(reg.regIdx);
-        break;
-      case FloatRegClass:
-        reg.regIdx = thread_context->flattenFloatIndex(reg.regIdx);
-        break;
-      case CCRegClass:
-        reg.regIdx = thread_context->flattenCCIndex(reg.regIdx);
-        break;
-      case MiscRegClass:
-        /* Don't bother to flatten misc regs as we don't need them here */
-        /* return thread_context->flattenMiscIndex(reg); */
-        break;
-    }
-
-    return reg;
+    return thread_context->flattenRegId(reg);
 }
 
 void
@@ -143,7 +126,8 @@ Scoreboard::markupInstDests(MinorDynInstPtr inst, Cycles retire_time,
                 *inst, index, numResults[index], returnCycle[index]);
         } else {
             /* Use ZeroReg to mark invalid/untracked dests */
-            inst->flatDestRegIdx[dest_index] = RegId::zeroReg;
+            inst->flatDestRegIdx[dest_index] = RegId(IntRegClass,
+                                                     TheISA::ZeroReg);
         }
     }
 }
@@ -190,7 +174,7 @@ Scoreboard::clearInstDests(MinorDynInstPtr inst, bool clear_unpredictable)
     for (unsigned int dest_index = 0; dest_index < num_dests;
         dest_index++)
     {
-        RegId reg = inst->flatDestRegIdx[dest_index];
+        const RegId& reg = inst->flatDestRegIdx[dest_index];
         Index index;
 
         if (findIndex(reg, index)) {
index 815d8140803fc45c25122dae072b256a81e96e4d..7fe5002f9e4e2cd37fbe2470dc37a2fa94f1cea6 100644 (file)
@@ -106,7 +106,7 @@ class Scoreboard : public Named
     /** Sets scoreboard_index to the index into numResults of the
      *  given register index.  Returns true if the given register
      *  is in the scoreboard and false if it isn't */
-    bool findIndex(RegId reg, Index &scoreboard_index);
+    bool findIndex(const RegId& reg, Index &scoreboard_index);
 
     /** Mark up an instruction's effects by incrementing
      *  numResults counts.  If mark_unpredictable is true, the inst's
index c5f1c014412e83df03fcc2148eb66a5a3423d453..49e153a52568d4bb9c391c4554ef82318e4ad85f 100644 (file)
 #include "cpu/inst_seq.hh"
 #include "sim/faults.hh"
 
-// Typedef for physical register index type. Although the Impl would be the
-// most likely location for this, there are a few classes that need this
-// typedef yet are not templated on the Impl. For now it will be defined here.
-typedef short int PhysRegIndex;
-// Physical register ID
-// Associate a physical register index to a register class and
-// so it is easy to track which type of register are used.
-// A flat index is also provided for when it is useful to have a unified
-// indexing (for the dependency graph and the scoreboard for example)
-struct PhysRegId {
-    RegClass regClass;
-    PhysRegIndex regIdx;
+/** Physical register index type.
+ * Although the Impl might be a better for this, but there are a few classes
+ * that need this typedef yet are not templated on the Impl.
+ */
+using PhysRegIndex = short int;
+
+/** Physical register ID.
+ * Like a register ID but physical. The inheritance is private because the
+ * only relationship between this types is functional, and it is done to
+ * prevent code replication. */
+class PhysRegId : private RegId {
+  private:
     PhysRegIndex flatIdx;
-    PhysRegId(RegClass _regClass, PhysRegIndex _regIdx,
+
+  public:
+    explicit PhysRegId() : RegId(IntRegClass, -1), flatIdx(-1) {}
+
+    /** Scalar PhysRegId constructor. */
+    explicit PhysRegId(RegClass _regClass, PhysRegIndex _regIdx,
               PhysRegIndex _flatIdx)
-        : regClass(_regClass), regIdx(_regIdx), flatIdx(_flatIdx)
+        : RegId(_regClass, _regIdx), flatIdx(_flatIdx)
     {}
 
-    bool operator==(const PhysRegId& that) const {
-        return regClass == that.regClass && regIdx == that.regIdx;
+    /** Visible RegId methods */
+    /** @{ */
+    using RegId::index;
+    using RegId::classValue;
+    using RegId::isZeroReg;
+    using RegId::className;
+     /** @} */
+    /**
+     * Explicit forward methods, to prevent comparisons of PhysRegId with
+     * RegIds.
+     */
+    /** @{ */
+    bool operator<(const PhysRegId& that) const {
+        return RegId::operator<(that);
     }
 
-    bool operator!=(const PhysRegId& that) const {
-        return !(*this==that);
+    bool operator==(const PhysRegId& that) const {
+        return RegId::operator==(that);
     }
 
-    bool isZeroReg() const
-    {
-        return (regIdx == TheISA::ZeroReg &&
-                (regClass == IntRegClass ||
-                 (THE_ISA == ALPHA_ISA && regClass == FloatRegClass)));
+    bool operator!=(const PhysRegId& that) const {
+        return RegId::operator!=(that);
     }
+    /** @} */
 
     /** @return true if it is an integer physical register. */
-    bool isIntPhysReg() const { return regClass == IntRegClass; }
+    bool isIntPhysReg() const { return isIntReg(); }
 
     /** @return true if it is a floating-point physical register. */
-    bool isFloatPhysReg() const { return regClass == FloatRegClass; }
+    bool isFloatPhysReg() const { return isFloatReg(); }
 
     /** @Return true if it is a  condition-code physical register. */
-    bool isCCPhysReg() const { return regClass == CCRegClass; }
+    bool isCCPhysReg() const { return isCCReg(); }
+
+    /** @Return true if it is a  condition-code physical register. */
+    bool isMiscPhysReg() const { return isMiscReg(); }
 
     /**
      * Returns true if this register is always associated to the same
@@ -100,8 +118,11 @@ struct PhysRegId {
      */
     bool isFixedMapping() const
     {
-        return regClass == MiscRegClass;
+        return !isRenameable();
     }
+
+    /** Flat index accessor */
+    const PhysRegIndex& flatIndex() const { return flatIdx; }
 };
 
 // PhysRegIds only need to be created once and then we can use the following
index 6e9accdd5718edc9ae04299cf5dc175c840035b5..a7a39b72a5219344b90f1a0d1b737c2eb45fc57d 100644 (file)
@@ -300,20 +300,21 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
             // Note that we can't use the rename() method because we don't
             // want special treatment for the zero register at this point
             PhysRegIdPtr phys_reg = freeList.getIntReg();
-            renameMap[tid].setIntEntry(ridx, phys_reg);
-            commitRenameMap[tid].setIntEntry(ridx, phys_reg);
+            renameMap[tid].setEntry(RegId(IntRegClass, ridx), phys_reg);
+            commitRenameMap[tid].setEntry(RegId(IntRegClass, ridx), phys_reg);
         }
 
         for (RegIndex ridx = 0; ridx < TheISA::NumFloatRegs; ++ridx) {
             PhysRegIdPtr phys_reg = freeList.getFloatReg();
-            renameMap[tid].setFloatEntry(ridx, phys_reg);
-            commitRenameMap[tid].setFloatEntry(ridx, phys_reg);
+            renameMap[tid].setEntry(RegId(FloatRegClass, ridx), phys_reg);
+            commitRenameMap[tid].setEntry(
+                    RegId(FloatRegClass, ridx), phys_reg);
         }
 
         for (RegIndex ridx = 0; ridx < TheISA::NumCCRegs; ++ridx) {
             PhysRegIdPtr phys_reg = freeList.getCCReg();
-            renameMap[tid].setCCEntry(ridx, phys_reg);
-            commitRenameMap[tid].setCCEntry(ridx, phys_reg);
+            renameMap[tid].setEntry(RegId(CCRegClass, ridx), phys_reg);
+            commitRenameMap[tid].setEntry(RegId(CCRegClass, ridx), phys_reg);
         }
     }
 
@@ -788,24 +789,24 @@ FullO3CPU<Impl>::insertThread(ThreadID tid)
 
     //Bind Int Regs to Rename Map
 
-    for (RegId reg_id(IntRegClass, 0); reg_id.regIdx < TheISA::NumIntRegs;
-         reg_id.regIdx++) {
+    for (RegId reg_id(IntRegClass, 0); reg_id.index() < TheISA::NumIntRegs;
+         reg_id.index()++) {
         PhysRegIdPtr phys_reg = freeList.getIntReg();
         renameMap[tid].setEntry(reg_id, phys_reg);
         scoreboard.setReg(phys_reg);
     }
 
     //Bind Float Regs to Rename Map
-    for (RegId reg_id(FloatRegClass, 0); reg_id.regIdx < TheISA::NumFloatRegs;
-         reg_id.regIdx++) {
+    for (RegId reg_id(FloatRegClass, 0); reg_id.index() < TheISA::NumFloatRegs;
+         reg_id.index()++) {
         PhysRegIdPtr phys_reg = freeList.getFloatReg();
         renameMap[tid].setEntry(reg_id, phys_reg);
         scoreboard.setReg(phys_reg);
     }
 
     //Bind condition-code Regs to Rename Map
-    for (RegId reg_id(CCRegClass, 0); reg_id.regIdx < TheISA::NumCCRegs;
-         reg_id.regIdx++) {
+    for (RegId reg_id(CCRegClass, 0); reg_id.index() < TheISA::NumCCRegs;
+         reg_id.index()++) {
         PhysRegIdPtr phys_reg = freeList.getCCReg();
         renameMap[tid].setEntry(reg_id, phys_reg);
         scoreboard.setReg(phys_reg);
@@ -842,24 +843,24 @@ FullO3CPU<Impl>::removeThread(ThreadID tid)
     // in SMT workloads.
 
     // Unbind Int Regs from Rename Map
-    for (RegId reg_id(IntRegClass, 0); reg_id.regIdx < TheISA::NumIntRegs;
-         reg_id.regIdx++) {
+    for (RegId reg_id(IntRegClass, 0); reg_id.index() < TheISA::NumIntRegs;
+         reg_id.index()++) {
         PhysRegIdPtr phys_reg = renameMap[tid].lookup(reg_id);
         scoreboard.unsetReg(phys_reg);
         freeList.addReg(phys_reg);
     }
 
     // Unbind Float Regs from Rename Map
-    for (RegId reg_id(FloatRegClass, 0); reg_id.regIdx < TheISA::NumFloatRegs;
-         reg_id.regIdx++) {
+    for (RegId reg_id(FloatRegClass, 0); reg_id.index() < TheISA::NumFloatRegs;
+         reg_id.index()++) {
         PhysRegIdPtr phys_reg = renameMap[tid].lookup(reg_id);
         scoreboard.unsetReg(phys_reg);
         freeList.addReg(phys_reg);
     }
 
     // Unbind condition-code Regs from Rename Map
-    for (RegId reg_id(CCRegClass, 0); reg_id.regIdx < TheISA::NumCCRegs;
-         reg_id.regIdx++) {
+    for (RegId reg_id(CCRegClass, 0); reg_id.index() < TheISA::NumCCRegs;
+         reg_id.index()++) {
         PhysRegIdPtr phys_reg = renameMap[tid].lookup(reg_id);
         scoreboard.unsetReg(phys_reg);
         freeList.addReg(phys_reg);
@@ -1300,7 +1301,8 @@ uint64_t
 FullO3CPU<Impl>::readArchIntReg(int reg_idx, ThreadID tid)
 {
     intRegfileReads++;
-    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupInt(reg_idx);
+    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
+            RegId(IntRegClass, reg_idx));
 
     return regFile.readIntReg(phys_reg);
 }
@@ -1310,7 +1312,8 @@ float
 FullO3CPU<Impl>::readArchFloatReg(int reg_idx, ThreadID tid)
 {
     fpRegfileReads++;
-    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupFloat(reg_idx);
+    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
+        RegId(FloatRegClass, reg_idx));
 
     return regFile.readFloatReg(phys_reg);
 }
@@ -1320,7 +1323,8 @@ uint64_t
 FullO3CPU<Impl>::readArchFloatRegInt(int reg_idx, ThreadID tid)
 {
     fpRegfileReads++;
-    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupFloat(reg_idx);
+    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
+        RegId(FloatRegClass, reg_idx));
 
     return regFile.readFloatRegBits(phys_reg);
 }
@@ -1330,7 +1334,8 @@ CCReg
 FullO3CPU<Impl>::readArchCCReg(int reg_idx, ThreadID tid)
 {
     ccRegfileReads++;
-    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupCC(reg_idx);
+    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
+        RegId(CCRegClass, reg_idx));
 
     return regFile.readCCReg(phys_reg);
 }
@@ -1340,7 +1345,8 @@ void
 FullO3CPU<Impl>::setArchIntReg(int reg_idx, uint64_t val, ThreadID tid)
 {
     intRegfileWrites++;
-    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupInt(reg_idx);
+    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
+            RegId(IntRegClass, reg_idx));
 
     regFile.setIntReg(phys_reg, val);
 }
@@ -1350,7 +1356,8 @@ void
 FullO3CPU<Impl>::setArchFloatReg(int reg_idx, float val, ThreadID tid)
 {
     fpRegfileWrites++;
-    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupFloat(reg_idx);
+    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
+            RegId(FloatRegClass, reg_idx));
 
     regFile.setFloatReg(phys_reg, val);
 }
@@ -1360,7 +1367,8 @@ void
 FullO3CPU<Impl>::setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid)
 {
     fpRegfileWrites++;
-    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupFloat(reg_idx);
+    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
+            RegId(FloatRegClass, reg_idx));
 
     regFile.setFloatRegBits(phys_reg, val);
 }
@@ -1370,7 +1378,8 @@ void
 FullO3CPU<Impl>::setArchCCReg(int reg_idx, CCReg val, ThreadID tid)
 {
     ccRegfileWrites++;
-    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupCC(reg_idx);
+    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
+            RegId(CCRegClass, reg_idx));
 
     regFile.setCCReg(phys_reg, val);
 }
index b200a328a89eb894f95a8110d3330b33c31286b0..a6adb4c2080b60c89856a09fbb734f62195dc1d6 100644 (file)
@@ -123,7 +123,7 @@ class BaseO3DynInst : public BaseDynInst<Impl>
   public:
 #if TRACING_ON
     /** Tick records used for the pipeline activity viewer. */
-    Tick fetchTick;         // instruction fetch is completed.
+    Tick fetchTick;      // instruction fetch is completed.
     int32_t decodeTick;  // instruction enters decode phase
     int32_t renameTick;  // instruction enters rename phase
     int32_t dispatchTick;
@@ -170,9 +170,9 @@ class BaseO3DynInst : public BaseDynInst<Impl>
      */
     TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
     {
-        RegId reg = si->srcRegIdx(idx);
-        assert(reg.regClass == MiscRegClass);
-        return this->cpu->readMiscReg(reg.regIdx, this->threadNumber);
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isMiscReg());
+        return this->cpu->readMiscReg(reg.index(), this->threadNumber);
     }
 
     /** Sets a misc. register, including any side-effects the write
@@ -181,9 +181,9 @@ class BaseO3DynInst : public BaseDynInst<Impl>
     void setMiscRegOperand(const StaticInst *si, int idx,
                                      const MiscReg &val)
     {
-        RegId reg =  si->destRegIdx(idx);
-        assert(reg.regClass == MiscRegClass);
-        setMiscReg(reg.regIdx, val);
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isMiscReg());
+        setMiscReg(reg.index(), val);
     }
 
     /** Called at the commit stage to update the misc. registers. */
@@ -208,9 +208,9 @@ class BaseO3DynInst : public BaseDynInst<Impl>
 
         for (int idx = 0; idx < this->numDestRegs(); idx++) {
             PhysRegIdPtr prev_phys_reg = this->prevDestRegIdx(idx);
-            RegId original_dest_reg =
+            const RegId& original_dest_reg =
                 this->staticInst->destRegIdx(idx);
-            switch (original_dest_reg.regClass) {
+            switch (original_dest_reg.classValue()) {
               case IntRegClass:
                 this->setIntRegOperand(this->staticInst.get(), idx,
                                        this->cpu->readIntReg(prev_phys_reg));
@@ -300,13 +300,13 @@ class BaseO3DynInst : public BaseDynInst<Impl>
     }
 
 #if THE_ISA == MIPS_ISA
-    MiscReg readRegOtherThread(RegId misc_reg, ThreadID tid)
+    MiscReg readRegOtherThread(const RegId& misc_reg, ThreadID tid)
     {
         panic("MIPS MT not defined for O3 CPU.\n");
         return 0;
     }
 
-    void setRegOtherThread(RegId misc_reg, MiscReg val, ThreadID tid)
+    void setRegOtherThread(const RegId& misc_reg, MiscReg val, ThreadID tid)
     {
         panic("MIPS MT not defined for O3 CPU.\n");
     }
index 3e6740e57800e26189a7a0b5016ecb991ee0f552..6fc6cc909a748e69a95e8e62b45d01c4515cc324 100644 (file)
@@ -183,11 +183,11 @@ class UnifiedFreeList
 inline void
 UnifiedFreeList::addReg(PhysRegIdPtr freed_reg)
 {
-    DPRINTF(FreeList,"Freeing register %i (%s).\n", freed_reg->regIdx,
-            RegClassStrings[freed_reg->regClass]);
+    DPRINTF(FreeList,"Freeing register %i (%s).\n", freed_reg->index(),
+            freed_reg->className());
     //Might want to add in a check for whether or not this register is
     //already in there.  A bit vector or something similar would be useful.
-    switch (freed_reg->regClass) {
+    switch (freed_reg->classValue()) {
         case IntRegClass:
             intList.addReg(freed_reg);
             break;
@@ -199,7 +199,7 @@ UnifiedFreeList::addReg(PhysRegIdPtr freed_reg)
             break;
         default:
             panic("Unexpected RegClass (%s)",
-                                   RegClassStrings[freed_reg->regClass]);
+                                   freed_reg->className());
     }
 
     // These assert conditions ensure that the number of free
index cdb6b26e255f0eca61cd154d0e5d07f592f8a7ff..80d7adc5416b35bd270b5c6a554fc22456766385 100644 (file)
@@ -1434,8 +1434,8 @@ DefaultIEW<Impl>::writebackInsts()
             for (int i = 0; i < inst->numDestRegs(); i++) {
                 //mark as Ready
                 DPRINTF(IEW,"Setting Destination Register %i (%s)\n",
-                        inst->renamedDestRegIdx(i)->regIdx,
-                        RegClassStrings[inst->renamedDestRegIdx(i)->regClass]);
+                        inst->renamedDestRegIdx(i)->index(),
+                        inst->renamedDestRegIdx(i)->className());
                 scoreboard->setReg(inst->renamedDestRegIdx(i));
             }
 
index c46fd6ba7b68b05d784d30973adbf6b9e5d19094..f52cf2d6c2163d3b04afb24e064f60353e47f689 100644 (file)
@@ -986,17 +986,17 @@ InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst)
         // handled by the IQ and thus have no dependency graph entry.
         if (dest_reg->isFixedMapping()) {
             DPRINTF(IQ, "Reg %d [%s] is part of a fix mapping, skipping\n",
-                    dest_reg->regIdx, RegClassStrings[dest_reg->regClass]);
+                    dest_reg->index(), dest_reg->className());
             continue;
         }
 
         DPRINTF(IQ, "Waking any dependents on register %i (%s).\n",
-                dest_reg->regIdx,
-                RegClassStrings[dest_reg->regClass]);
+                dest_reg->index(),
+                dest_reg->className());
 
         //Go through the dependency chain, marking the registers as
         //ready within the waiting instructions.
-        DynInstPtr dep_inst = dependGraph.pop(dest_reg->flatIdx);
+        DynInstPtr dep_inst = dependGraph.pop(dest_reg->flatIndex());
 
         while (dep_inst) {
             DPRINTF(IQ, "Waking up a dependent instruction, [sn:%lli] "
@@ -1010,18 +1010,18 @@ InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst)
 
             addIfReady(dep_inst);
 
-            dep_inst = dependGraph.pop(dest_reg->flatIdx);
+            dep_inst = dependGraph.pop(dest_reg->flatIndex());
 
             ++dependents;
         }
 
         // Reset the head node now that all of its dependents have
         // been woken up.
-        assert(dependGraph.empty(dest_reg->flatIdx));
-        dependGraph.clearInst(dest_reg->flatIdx);
+        assert(dependGraph.empty(dest_reg->flatIndex()));
+        dependGraph.clearInst(dest_reg->flatIndex());
 
         // Mark the scoreboard as having that register ready.
-        regScoreboard[dest_reg->flatIdx] = true;
+        regScoreboard[dest_reg->flatIndex()] = true;
     }
     return dependents;
 }
@@ -1233,7 +1233,8 @@ InstructionQueue<Impl>::doSquash(ThreadID tid)
 
                     if (!squashed_inst->isReadySrcRegIdx(src_reg_idx) &&
                         !src_reg->isFixedMapping()) {
-                        dependGraph.remove(src_reg->flatIdx, squashed_inst);
+                        dependGraph.remove(src_reg->flatIndex(),
+                                           squashed_inst);
                     }
 
 
@@ -1308,13 +1309,13 @@ InstructionQueue<Impl>::addToDependents(DynInstPtr &new_inst)
             // it be added to the dependency graph.
             if (src_reg->isFixedMapping()) {
                 continue;
-            } else if (!regScoreboard[src_reg->flatIdx]) {
+            } else if (!regScoreboard[src_reg->flatIndex()]) {
                 DPRINTF(IQ, "Instruction PC %s has src reg %i (%s) that "
                         "is being added to the dependency chain.\n",
-                        new_inst->pcState(), src_reg->regIdx,
-                        RegClassStrings[src_reg->regClass]);
+                        new_inst->pcState(), src_reg->index(),
+                        src_reg->className());
 
-                dependGraph.insert(src_reg->flatIdx, new_inst);
+                dependGraph.insert(src_reg->flatIndex(), new_inst);
 
                 // Change the return value to indicate that something
                 // was added to the dependency graph.
@@ -1322,8 +1323,8 @@ InstructionQueue<Impl>::addToDependents(DynInstPtr &new_inst)
             } else {
                 DPRINTF(IQ, "Instruction PC %s has src reg %i (%s) that "
                         "became ready before it reached the IQ.\n",
-                        new_inst->pcState(), src_reg->regIdx,
-                        RegClassStrings[src_reg->regClass]);
+                        new_inst->pcState(), src_reg->index(),
+                        src_reg->className());
                 // Mark a register ready within the instruction.
                 new_inst->markSrcRegReady(src_reg_idx);
             }
@@ -1355,17 +1356,17 @@ InstructionQueue<Impl>::addToProducers(DynInstPtr &new_inst)
             continue;
         }
 
-        if (!dependGraph.empty(dest_reg->flatIdx)) {
+        if (!dependGraph.empty(dest_reg->flatIndex())) {
             dependGraph.dump();
             panic("Dependency graph %i (%s) (flat: %i) not empty!",
-                  dest_reg->regIdx, RegClassStrings[dest_reg->regClass],
-                  dest_reg->flatIdx);
+                  dest_reg->index(), dest_reg->className(),
+                  dest_reg->flatIndex());
         }
 
-        dependGraph.setInst(dest_reg->flatIdx, new_inst);
+        dependGraph.setInst(dest_reg->flatIndex(), new_inst);
 
         // Mark the scoreboard to say it's not yet ready.
-        regScoreboard[dest_reg->flatIdx] = false;
+        regScoreboard[dest_reg->flatIndex()] = false;
     }
 }
 
index 76f7e439adaf795a8d33b92765187738b4c51462..08ef6654d71ca63eac6533f54aaa47f20b368e2d 100644 (file)
@@ -242,8 +242,8 @@ ElasticTrace::updateRegDep(const DynInstPtr &dyn_inst)
         PhysRegIdPtr src_reg = dyn_inst->renamedSrcRegIdx(src_idx);
         DPRINTFR(ElasticTrace, "[sn:%lli] Check map for src reg"
                  " %i (%s)\n", seq_num,
-                 src_reg->regIdx, RegClassStrings[src_reg->regClass]);
-        auto itr_last_writer = physRegDepMap.find(src_reg->flatIdx);
+                 src_reg->index(), src_reg->className());
+        auto itr_last_writer = physRegDepMap.find(src_reg->flatIndex());
         if (itr_last_writer != physRegDepMap.end()) {
             InstSeqNum last_writer = itr_last_writer->second;
             // Additionally the dependency distance is kept less than the window
@@ -263,16 +263,16 @@ ElasticTrace::updateRegDep(const DynInstPtr &dyn_inst)
     for (int dest_idx = 0; dest_idx < max_regs; dest_idx++) {
         // For data dependency tracking the register must be an int, float or
         // CC register and not a Misc register.
-        RegId dest_reg = dyn_inst->destRegIdx(dest_idx);
-        if (dest_reg.isRenameable() &&
+        const RegId& dest_reg = dyn_inst->destRegIdx(dest_idx);
+        if (!dest_reg.isMiscReg() &&
             !dest_reg.isZeroReg()) {
             // Get the physical register index of the i'th destination
             // register.
             PhysRegIdPtr phys_dest_reg = dyn_inst->renamedDestRegIdx(dest_idx);
             DPRINTFR(ElasticTrace, "[sn:%lli] Update map for dest reg"
-                     " %i (%s)\n", seq_num, dest_reg.regIdx,
-                     RegClassStrings[dest_reg.regClass]);
-            physRegDepMap[phys_dest_reg->flatIdx] = seq_num;
+                     " %i (%s)\n", seq_num, dest_reg.index(),
+                     dest_reg.className());
+            physRegDepMap[phys_dest_reg->flatIndex()] = seq_num;
         }
     }
     maxPhysRegDepMapSize = std::max(physRegDepMap.size(),
index ee8d07b3e3b080133948d2842d960c1a89373ecb..ea4370f48b6eb0f30b5aa8c774b0c92a1e67e20f 100644 (file)
@@ -89,21 +89,21 @@ PhysRegFile::initFreeList(UnifiedFreeList *freeList)
 
     // The initial batch of registers are the integer ones
     for (reg_idx = 0; reg_idx < numPhysicalIntRegs; reg_idx++) {
-        assert(intRegIds[reg_idx].regIdx == reg_idx);
+        assert(intRegIds[reg_idx].index() == reg_idx);
         freeList->addIntReg(&intRegIds[reg_idx]);
     }
 
     // The next batch of the registers are the floating-point physical
     // registers; put them onto the floating-point free list.
     for (reg_idx = 0; reg_idx < numPhysicalFloatRegs; reg_idx++) {
-        assert(floatRegIds[reg_idx].regIdx == reg_idx);
+        assert(floatRegIds[reg_idx].index() == reg_idx);
         freeList->addFloatReg(&floatRegIds[reg_idx]);
     }
 
     // The rest of the registers are the condition-code physical
     // registers; put them onto the condition-code free list.
     for (reg_idx = 0; reg_idx < numPhysicalCCRegs; reg_idx++) {
-        assert(ccRegIds[reg_idx].regIdx == reg_idx);
+        assert(ccRegIds[reg_idx].index() == reg_idx);
         freeList->addCCReg(&ccRegIds[reg_idx]);
     }
 }
index c7935c55c6c989062c2855bfca13c0e65251e04d..c353b2746f48e0a12285cfeac441815f962509b7 100644 (file)
@@ -135,8 +135,8 @@ class PhysRegFile
         assert(phys_reg->isIntPhysReg());
 
         DPRINTF(IEW, "RegFile: Access to int register %i, has data "
-                "%#x\n", phys_reg->regIdx, intRegFile[phys_reg->regIdx]);
-        return intRegFile[phys_reg->regIdx];
+                "%#x\n", phys_reg->index(), intRegFile[phys_reg->index()]);
+        return intRegFile[phys_reg->index()];
     }
 
     /** Reads a floating point register (double precision). */
@@ -145,20 +145,20 @@ class PhysRegFile
         assert(phys_reg->isFloatPhysReg());
 
         DPRINTF(IEW, "RegFile: Access to float register %i, has "
-                "data %#x\n", phys_reg->regIdx,
-                floatRegFile[phys_reg->regIdx].q);
+                "data %#x\n", phys_reg->index(),
+                floatRegFile[phys_reg->index()].q);
 
-        return floatRegFile[phys_reg->regIdx].d;
+        return floatRegFile[phys_reg->index()].d;
     }
 
     FloatRegBits readFloatRegBits(PhysRegIdPtr phys_reg) const
     {
         assert(phys_reg->isFloatPhysReg());
 
-        FloatRegBits floatRegBits = floatRegFile[phys_reg->regIdx].q;
+        FloatRegBits floatRegBits = floatRegFile[phys_reg->index()].q;
 
         DPRINTF(IEW, "RegFile: Access to float register %i as int, "
-                "has data %#x\n", phys_reg->regIdx,
+                "has data %#x\n", phys_reg->index(),
                 (uint64_t)floatRegBits);
 
         return floatRegBits;
@@ -170,10 +170,10 @@ class PhysRegFile
         assert(phys_reg->isCCPhysReg());
 
         DPRINTF(IEW, "RegFile: Access to cc register %i, has "
-                "data %#x\n", phys_reg->regIdx,
-                ccRegFile[phys_reg->regIdx]);
+                "data %#x\n", phys_reg->index(),
+                ccRegFile[phys_reg->index()]);
 
-        return ccRegFile[phys_reg->regIdx];
+        return ccRegFile[phys_reg->index()];
     }
 
     /** Sets an integer register to the given value. */
@@ -182,10 +182,10 @@ class PhysRegFile
         assert(phys_reg->isIntPhysReg());
 
         DPRINTF(IEW, "RegFile: Setting int register %i to %#x\n",
-                phys_reg->regIdx, val);
+                phys_reg->index(), val);
 
         if (!phys_reg->isZeroReg())
-            intRegFile[phys_reg->regIdx] = val;
+            intRegFile[phys_reg->index()] = val;
     }
 
     /** Sets a double precision floating point register to the given value. */
@@ -194,10 +194,10 @@ class PhysRegFile
         assert(phys_reg->isFloatPhysReg());
 
         DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
-                phys_reg->regIdx, (uint64_t)val);
+                phys_reg->index(), (uint64_t)val);
 
         if (!phys_reg->isZeroReg())
-            floatRegFile[phys_reg->regIdx].d = val;
+            floatRegFile[phys_reg->index()].d = val;
     }
 
     void setFloatRegBits(PhysRegIdPtr phys_reg, FloatRegBits val)
@@ -205,9 +205,9 @@ class PhysRegFile
         assert(phys_reg->isFloatPhysReg());
 
         DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
-                phys_reg->regIdx, (uint64_t)val);
+                phys_reg->index(), (uint64_t)val);
 
-        floatRegFile[phys_reg->regIdx].q = val;
+        floatRegFile[phys_reg->index()].q = val;
     }
 
     /** Sets a condition-code register to the given value. */
@@ -216,9 +216,9 @@ class PhysRegFile
         assert(phys_reg->isCCPhysReg());
 
         DPRINTF(IEW, "RegFile: Setting cc register %i to %#x\n",
-                phys_reg->regIdx, (uint64_t)val);
+                phys_reg->index(), (uint64_t)val);
 
-        ccRegFile[phys_reg->regIdx] = val;
+        ccRegFile[phys_reg->index()] = val;
     }
 };
 
index ab7ae5f8b2768ca9427417f2297e4ae910322d72..6d3861ba69c04006532f95d22fdd1425a1bcdbe1 100644 (file)
@@ -298,7 +298,7 @@ class DefaultRename
      * register for that arch. register, and the new physical register.
      */
     struct RenameHistory {
-        RenameHistory(InstSeqNum _instSeqNum, RegId _archReg,
+        RenameHistory(InstSeqNum _instSeqNum, const RegId& _archReg,
                       PhysRegIdPtr _newPhysReg,
                       PhysRegIdPtr _prevPhysReg)
             : instSeqNum(_instSeqNum), archReg(_archReg),
index a9279263986963cc12bb7e759e91e9ae2f57405e..9c9b030f57b8963a8be7ff7c5fa0ea821e93b97e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012, 2014-2015 ARM Limited
+ * Copyright (c) 2010-2012, 2014-2016 ARM Limited
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved.
  *
@@ -985,8 +985,8 @@ DefaultRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num, ThreadID tid)
 
         DPRINTF(Rename, "[tid:%u]: Freeing up older rename of reg %i (%s), "
                 "[sn:%lli].\n",
-                tid, hb_it->prevPhysReg->regIdx,
-                RegClassStrings[hb_it->prevPhysReg->regClass],
+                tid, hb_it->prevPhysReg->index(),
+                hb_it->prevPhysReg->className(),
                 hb_it->instSeqNum);
 
         // Don't free special phys regs like misc and zero regs, which
@@ -1013,59 +1013,46 @@ DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid)
     // Get the architectual register numbers from the source and
     // operands, and redirect them to the right physical register.
     for (int src_idx = 0; src_idx < num_src_regs; src_idx++) {
-        RegId src_reg = inst->srcRegIdx(src_idx);
-        RegIndex flat_src_reg;
+        const RegId& src_reg = inst->srcRegIdx(src_idx);
         PhysRegIdPtr renamed_reg;
 
-        switch (src_reg.regClass) {
+        renamed_reg = map->lookup(tc->flattenRegId(src_reg));
+        switch (src_reg.classValue()) {
           case IntRegClass:
-            flat_src_reg = tc->flattenIntIndex(src_reg.regIdx);
-            renamed_reg = map->lookupInt(flat_src_reg);
             intRenameLookups++;
             break;
-
           case FloatRegClass:
-            flat_src_reg = tc->flattenFloatIndex(src_reg.regIdx);
-            renamed_reg = map->lookupFloat(flat_src_reg);
             fpRenameLookups++;
             break;
-
           case CCRegClass:
-            flat_src_reg = tc->flattenCCIndex(src_reg.regIdx);
-            renamed_reg = map->lookupCC(flat_src_reg);
-            break;
-
           case MiscRegClass:
-            // misc regs don't get flattened
-            flat_src_reg = src_reg.regIdx;
-            renamed_reg = map->lookupMisc(flat_src_reg);
             break;
 
           default:
-            panic("Invalid register class: %d.", src_reg.regClass);
+            panic("Invalid register class: %d.", src_reg.classValue());
         }
 
         DPRINTF(Rename, "[tid:%u]: Looking up %s arch reg %i"
-                " (flattened %i), got phys reg %i (%s)\n", tid,
-                RegClassStrings[src_reg.regClass], src_reg.regIdx,
-                flat_src_reg, renamed_reg->regIdx,
-                RegClassStrings[renamed_reg->regClass]);
+                ", got phys reg %i (%s)\n", tid,
+                src_reg.className(), src_reg.index(),
+                renamed_reg->index(),
+                renamed_reg->className());
 
         inst->renameSrcReg(src_idx, renamed_reg);
 
         // See if the register is ready or not.
         if (scoreboard->getReg(renamed_reg)) {
             DPRINTF(Rename, "[tid:%u]: Register %d (flat: %d) (%s)"
-                    " is ready.\n", tid, renamed_reg->regIdx,
-                    renamed_reg->flatIdx,
-                    RegClassStrings[renamed_reg->regClass]);
+                    " is ready.\n", tid, renamed_reg->index(),
+                    renamed_reg->flatIndex(),
+                    renamed_reg->className());
 
             inst->markSrcRegReady(src_idx);
         } else {
             DPRINTF(Rename, "[tid:%u]: Register %d (flat: %d) (%s)"
-                    " is not ready.\n", tid, renamed_reg->regIdx,
-                    renamed_reg->flatIdx,
-                    RegClassStrings[renamed_reg->regClass]);
+                    " is not ready.\n", tid, renamed_reg->index(),
+                    renamed_reg->flatIndex(),
+                    renamed_reg->className());
         }
 
         ++renameRenameLookups;
@@ -1082,51 +1069,26 @@ DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid)
 
     // Rename the destination registers.
     for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) {
-        RegId dest_reg = inst->destRegIdx(dest_idx);
-        RegIndex flat_dest_reg;
+        const RegId& dest_reg = inst->destRegIdx(dest_idx);
         typename RenameMap::RenameInfo rename_result;
 
-        switch (dest_reg.regClass) {
-          case IntRegClass:
-            flat_dest_reg = tc->flattenIntIndex(dest_reg.regIdx);
-            rename_result = map->renameInt(flat_dest_reg);
-            break;
-
-          case FloatRegClass:
-            flat_dest_reg = tc->flattenFloatIndex(dest_reg.regIdx);
-            rename_result = map->renameFloat(flat_dest_reg);
-            break;
-
-          case CCRegClass:
-            flat_dest_reg = tc->flattenCCIndex(dest_reg.regIdx);
-            rename_result = map->renameCC(flat_dest_reg);
-            break;
-
-          case MiscRegClass:
-            // misc regs don't get flattened
-            flat_dest_reg = dest_reg.regIdx;
-            rename_result = map->renameMisc(dest_reg.regIdx);
-            break;
-
-          default:
-            panic("Invalid register class: %d.", dest_reg.regClass);
-        }
+        RegId flat_dest_regid = tc->flattenRegId(dest_reg);
 
-        RegId flat_uni_dest_reg(dest_reg.regClass, flat_dest_reg);
+        rename_result = map->rename(flat_dest_regid);
 
-        inst->flattenDestReg(dest_idx, flat_uni_dest_reg);
+        inst->flattenDestReg(dest_idx, flat_dest_regid);
 
         // Mark Scoreboard entry as not ready
         scoreboard->unsetReg(rename_result.first);
 
         DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i (%s) to physical "
-                "reg %i (%i).\n", tid, dest_reg.regIdx,
-                RegClassStrings[dest_reg.regClass],
-                rename_result.first->regIdx,
-                rename_result.first->flatIdx);
+                "reg %i (%i).\n", tid, dest_reg.index(),
+                dest_reg.className(),
+                rename_result.first->index(),
+                rename_result.first->flatIndex());
 
         // Record the rename information so that a history can be kept.
-        RenameHistory hb_entry(inst->seqNum, flat_uni_dest_reg,
+        RenameHistory hb_entry(inst->seqNum, flat_dest_regid,
                                rename_result.first,
                                rename_result.second);
 
@@ -1439,12 +1401,12 @@ DefaultRename<Impl>::dumpHistory()
             cprintf("Seq num: %i\nArch reg[%s]: %i New phys reg:"
                     " %i[%s] Old phys reg: %i[%s]\n",
                     (*buf_it).instSeqNum,
-                    RegClassStrings[(*buf_it).archReg.regClass],
-                    (*buf_it).archReg.regIdx,
-                    (*buf_it).newPhysReg->regIdx,
-                    RegClassStrings[(*buf_it).newPhysReg->regClass],
-                    (*buf_it).prevPhysReg->regIdx,
-                    RegClassStrings[(*buf_it).prevPhysReg->regClass]);
+                    (*buf_it).archReg.className(),
+                    (*buf_it).archReg.index(),
+                    (*buf_it).newPhysReg->index(),
+                    (*buf_it).newPhysReg->className(),
+                    (*buf_it).prevPhysReg->index(),
+                    (*buf_it).prevPhysReg->className());
 
             buf_it++;
         }
index 4555946c2d68dbd6b8aeae268b9c8972ef336d85..38ccc7ec9ca2117dd5e45ca7605d9de382d6c148 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <vector>
 
+#include "cpu/reg_class_impl.hh"
 #include "debug/Rename.hh"
 
 using namespace std;
@@ -40,7 +41,7 @@ using namespace std;
 /**** SimpleRenameMap methods ****/
 
 SimpleRenameMap::SimpleRenameMap()
-    : freeList(NULL), zeroReg(0)
+    : freeList(NULL), zeroReg(IntRegClass,0)
 {
 }
 
@@ -54,24 +55,23 @@ SimpleRenameMap::init(unsigned size, SimpleFreeList *_freeList,
 
     map.resize(size);
     freeList = _freeList;
-    zeroReg = _zeroReg;
+    zeroReg = RegId(IntRegClass, _zeroReg);
 }
 
 SimpleRenameMap::RenameInfo
-SimpleRenameMap::rename(RegIndex arch_reg)
+SimpleRenameMap::rename(const RegId& arch_reg)
 {
     PhysRegIdPtr renamed_reg;
-
     // Record the current physical register that is renamed to the
     // requested architected register.
-    PhysRegIdPtr prev_reg = map[arch_reg];
+    PhysRegIdPtr prev_reg = map[arch_reg.index()];
 
     // If it's not referencing the zero register, then rename the
     // register.
     if (arch_reg != zeroReg) {
         renamed_reg = freeList->getReg();
 
-        map[arch_reg] = renamed_reg;
+        map[arch_reg.index()] = renamed_reg;
     } else {
         // Otherwise return the zero register so nothing bad happens.
         assert(prev_reg->isZeroReg());
@@ -80,8 +80,8 @@ SimpleRenameMap::rename(RegIndex arch_reg)
 
     DPRINTF(Rename, "Renamed reg %d to physical reg %d (%d) old mapping was"
             " %d (%d)\n",
-            arch_reg, renamed_reg->regIdx, renamed_reg->flatIdx,
-            prev_reg->regIdx, prev_reg->flatIdx);
+            arch_reg, renamed_reg->index(), renamed_reg->flatIndex(),
+            prev_reg->index(), prev_reg->flatIndex());
 
     return RenameInfo(renamed_reg, prev_reg);
 }
@@ -105,75 +105,3 @@ UnifiedRenameMap::init(PhysRegFile *_regFile,
 
 }
 
-
-UnifiedRenameMap::RenameInfo
-UnifiedRenameMap::rename(RegId arch_reg)
-{
-    switch (arch_reg.regClass) {
-      case IntRegClass:
-        return renameInt(arch_reg.regIdx);
-
-      case FloatRegClass:
-        return renameFloat(arch_reg.regIdx);
-
-      case CCRegClass:
-        return renameCC(arch_reg.regIdx);
-
-      case MiscRegClass:
-        return renameMisc(arch_reg.regIdx);
-
-      default:
-        panic("rename rename(): unknown reg class %s\n",
-              RegClassStrings[arch_reg.regClass]);
-    }
-}
-
-
-PhysRegIdPtr
-UnifiedRenameMap::lookup(RegId arch_reg) const
-{
-    switch (arch_reg.regClass) {
-      case IntRegClass:
-        return lookupInt(arch_reg.regIdx);
-
-      case FloatRegClass:
-        return lookupFloat(arch_reg.regIdx);
-
-      case CCRegClass:
-        return lookupCC(arch_reg.regIdx);
-
-      case MiscRegClass:
-        return lookupMisc(arch_reg.regIdx);
-
-      default:
-        panic("rename lookup(): unknown reg class %s\n",
-              RegClassStrings[arch_reg.regClass]);
-    }
-}
-
-void
-UnifiedRenameMap::setEntry(RegId arch_reg, PhysRegIdPtr phys_reg)
-{
-    switch (arch_reg.regClass) {
-      case IntRegClass:
-        return setIntEntry(arch_reg.regIdx, phys_reg);
-
-      case FloatRegClass:
-        return setFloatEntry(arch_reg.regIdx, phys_reg);
-
-      case CCRegClass:
-        return setCCEntry(arch_reg.regIdx, phys_reg);
-
-      case MiscRegClass:
-        // Misc registers do not actually rename, so don't change
-        // their mappings.  We end up here when a commit or squash
-        // tries to update or undo a hardwired misc reg nmapping,
-        // which should always be setting it to what it already is.
-        assert(phys_reg == lookupMisc(arch_reg.regIdx));
-        return;
-
-      default:
-        panic("rename setEntry(): unknown reg class %s\n",
-              RegClassStrings[arch_reg.regClass]);
-    }
-}
index f51cf59223acb3f67de86092e454244fed5aa8bc..028c32e3abe873423571fb99c40ee6b1643ed1c2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 ARM Limited
+ * Copyright (c) 2015-2016 ARM Limited
  * All rights reserved.
  *
  * The license below extends only to copyright in the software and shall
@@ -65,9 +65,9 @@
 class SimpleRenameMap
 {
   private:
-
+    using Arch2PhysMap = std::vector<PhysRegIdPtr>;
     /** The acutal arch-to-phys register map */
-    std::vector<PhysRegIdPtr> map;
+    Arch2PhysMap map;
 
     /**
      * Pointer to the free list from which new physical registers
@@ -82,7 +82,7 @@ class SimpleRenameMap
      * table, it should be set to an invalid index so that it never
      * matches.
      */
-    RegIndex zeroReg;
+    RegId zeroReg;
 
   public:
 
@@ -112,17 +112,17 @@ class SimpleRenameMap
      * @return A RenameInfo pair indicating both the new and previous
      * physical registers.
      */
-    RenameInfo rename(RegIndex arch_reg);
+    RenameInfo rename(const RegId& arch_reg);
 
     /**
      * Look up the physical register mapped to an architectural register.
      * @param arch_reg The architectural register to look up.
      * @return The physical register it is currently mapped to.
      */
-    PhysRegIdPtr lookup(RegIndex arch_reg) const
+    PhysRegIdPtr lookup(const RegId& arch_reg) const
     {
-        assert(arch_reg < map.size());
-        return map[arch_reg];
+        assert(arch_reg.flatIndex() <= map.size());
+        return map[arch_reg.flatIndex()];
     }
 
     /**
@@ -131,9 +131,10 @@ class SimpleRenameMap
      * @param arch_reg The architectural register to remap.
      * @param phys_reg The physical register to remap it to.
      */
-    void setEntry(RegIndex arch_reg, PhysRegIdPtr phys_reg)
+    void setEntry(const RegId& arch_reg, PhysRegIdPtr phys_reg)
     {
-        map[arch_reg] = phys_reg;
+        assert(arch_reg.flatIndex() <= map.size());
+        map[arch_reg.flatIndex()] = phys_reg;
     }
 
     /** Return the number of free entries on the associated free list. */
@@ -186,55 +187,35 @@ class UnifiedRenameMap
     /**
      * Tell rename map to get a new free physical register to remap
      * the specified architectural register. This version takes a
-     * flattened architectural register id and calls the
-     * appropriate class-specific rename table.
-     * @param arch_reg The architectural register index to remap.
+     * RegId and reads the  appropriate class-specific rename table.
+     * @param arch_reg The architectural register id to remap.
      * @return A RenameInfo pair indicating both the new and previous
      * physical registers.
      */
-    RenameInfo rename(RegId arch_reg);
-
-    /**
-     * Perform rename() on an integer register, given a
-     * integer register index.
-     */
-    RenameInfo renameInt(RegIndex rel_arch_reg)
-    {
-        return intMap.rename(rel_arch_reg);
-    }
-
-    /**
-     * Perform rename() on a floating-point register, given a
-     * floating-point register index.
-     */
-    RenameInfo renameFloat(RegIndex rel_arch_reg)
-    {
-        return floatMap.rename(rel_arch_reg);
-    }
-
-    /**
-     * Perform rename() on a condition-code register, given a
-     * condition-code register index.
-     */
-    RenameInfo renameCC(RegIndex rel_arch_reg)
+    RenameInfo rename(const RegId& arch_reg)
     {
-        return ccMap.rename(rel_arch_reg);
+        switch (arch_reg.classValue()) {
+          case IntRegClass:
+            return intMap.rename(arch_reg);
+          case FloatRegClass:
+            return floatMap.rename(arch_reg);
+          case CCRegClass:
+            return ccMap.rename(arch_reg);
+          case MiscRegClass:
+            {
+            // misc regs aren't really renamed, just remapped
+            PhysRegIdPtr phys_reg = lookup(arch_reg);
+            // Set the new register to the previous one to keep the same
+            // mapping throughout the execution.
+            return RenameInfo(phys_reg, phys_reg);
+            }
+
+          default:
+            panic("rename rename(): unknown reg class %s\n",
+                  arch_reg.className());
+        }
     }
 
-    /**
-     * Perform rename() on a misc register, given a
-     * misc register index.
-     */
-    RenameInfo renameMisc(RegIndex rel_arch_reg)
-    {
-        // misc regs aren't really renamed, just remapped
-        PhysRegIdPtr phys_reg = lookupMisc(rel_arch_reg);
-        // Set the new register to the previous one to keep the same
-        // mapping throughout the execution.
-        return RenameInfo(phys_reg, phys_reg);
-    }
-
-
     /**
      * Look up the physical register mapped to an architectural register.
      * This version takes a flattened architectural register id
@@ -242,44 +223,27 @@ class UnifiedRenameMap
      * @param arch_reg The architectural register to look up.
      * @return The physical register it is currently mapped to.
      */
-    PhysRegIdPtr lookup(RegId arch_reg) const;
-
-    /**
-     * Perform lookup() on an integer register, given a
-     * integer register index.
-     */
-    PhysRegIdPtr lookupInt(RegIndex rel_arch_reg) const
+    PhysRegIdPtr lookup(const RegId& arch_reg) const
     {
-        return intMap.lookup(rel_arch_reg);
-    }
+        switch (arch_reg.classValue()) {
+          case IntRegClass:
+            return intMap.lookup(arch_reg);
 
-    /**
-     * Perform lookup() on a floating-point register, given a
-     * floating-point register index.
-     */
-    PhysRegIdPtr lookupFloat(RegIndex rel_arch_reg) const
-    {
-        return  floatMap.lookup(rel_arch_reg);
-    }
+          case FloatRegClass:
+            return  floatMap.lookup(arch_reg);
 
-    /**
-     * Perform lookup() on a condition-code register, given a
-     * condition-code register index.
-     */
-    PhysRegIdPtr lookupCC(RegIndex rel_arch_reg) const
-    {
-        return ccMap.lookup(rel_arch_reg);
-    }
+          case CCRegClass:
+            return ccMap.lookup(arch_reg);
 
-    /**
-     * Perform lookup() on a misc register, given a relative
-     * misc register index.
-     */
-    PhysRegIdPtr lookupMisc(RegIndex rel_arch_reg) const
-    {
-        // misc regs aren't really renamed, they keep the same
-        // mapping throughout the execution.
-        return regFile->getMiscRegId(rel_arch_reg);
+          case MiscRegClass:
+            // misc regs aren't really renamed, they keep the same
+            // mapping throughout the execution.
+            return regFile->getMiscRegId(arch_reg.flatIndex());
+
+          default:
+            panic("rename lookup(): unknown reg class %s\n",
+                  arch_reg.className());
+        }
     }
 
     /**
@@ -290,36 +254,33 @@ class UnifiedRenameMap
      * @param arch_reg The architectural register to remap.
      * @param phys_reg The physical register to remap it to.
      */
-    void setEntry(RegId arch_reg, PhysRegIdPtr phys_reg);
-
-    /**
-     * Perform setEntry() on an integer register, given a
-     * integer register index.
-     */
-    void setIntEntry(RegIndex arch_reg, PhysRegIdPtr phys_reg)
-    {
-        assert(phys_reg->isIntPhysReg());
-        intMap.setEntry(arch_reg, phys_reg);
-    }
-
-    /**
-     * Perform setEntry() on a floating-point register, given a
-     * floating-point register index.
-     */
-    void setFloatEntry(RegIndex arch_reg, PhysRegIdPtr phys_reg)
-    {
-        assert(phys_reg->isFloatPhysReg());
-        floatMap.setEntry(arch_reg, phys_reg);
-    }
-
-    /**
-     * Perform setEntry() on a condition-code register, given a
-     * condition-code register index.
-     */
-    void setCCEntry(RegIndex arch_reg, PhysRegIdPtr phys_reg)
+    void setEntry(const RegId& arch_reg, PhysRegIdPtr phys_reg)
     {
-        assert(phys_reg->isCCPhysReg());
-        ccMap.setEntry(arch_reg, phys_reg);
+        switch (arch_reg.classValue()) {
+          case IntRegClass:
+            assert(phys_reg->isIntPhysReg());
+            return intMap.setEntry(arch_reg, phys_reg);
+
+          case FloatRegClass:
+            assert(phys_reg->isFloatPhysReg());
+            return floatMap.setEntry(arch_reg, phys_reg);
+
+          case CCRegClass:
+            assert(phys_reg->isCCPhysReg());
+            return ccMap.setEntry(arch_reg, phys_reg);
+
+          case MiscRegClass:
+            // Misc registers do not actually rename, so don't change
+            // their mappings.  We end up here when a commit or squash
+            // tries to update or undo a hardwired misc reg nmapping,
+            // which should always be setting it to what it already is.
+            assert(phys_reg == lookup(arch_reg));
+            return;
+
+          default:
+            panic("rename setEntry(): unknown reg class %s\n",
+                  arch_reg.className());
+        }
     }
 
     /**
index 44e449944568c42451f4a46649c53bb985e07baf..1012bae5958f54550c7fa82b3d0253117e5a340f 100644 (file)
@@ -80,14 +80,14 @@ class Scoreboard
     /** Checks if the register is ready. */
     bool getReg(PhysRegIdPtr phys_reg) const
     {
-        assert(phys_reg->flatIdx < numPhysRegs);
+        assert(phys_reg->flatIndex() < numPhysRegs);
 
         if (phys_reg->isFixedMapping()) {
             // Fixed mapping regs are always ready
             return true;
         }
 
-        bool ready = regScoreBoard[phys_reg->flatIdx];
+        bool ready = regScoreBoard[phys_reg->flatIndex()];
 
         if (phys_reg->isZeroReg())
             assert(ready);
@@ -98,7 +98,7 @@ class Scoreboard
     /** Sets the register as ready. */
     void setReg(PhysRegIdPtr phys_reg)
     {
-        assert(phys_reg->flatIdx < numPhysRegs);
+        assert(phys_reg->flatIndex() < numPhysRegs);
 
         if (phys_reg->isFixedMapping()) {
             // Fixed mapping regs are always ready, ignore attempts to change
@@ -106,16 +106,16 @@ class Scoreboard
             return;
         }
 
-        DPRINTF(Scoreboard, "Setting reg %i (%s) as ready\n", phys_reg->regIdx,
-                RegClassStrings[phys_reg->regClass]);
+        DPRINTF(Scoreboard, "Setting reg %i (%s) as ready\n",
+                phys_reg->index(), phys_reg->className());
 
-        regScoreBoard[phys_reg->flatIdx] = true;
+        regScoreBoard[phys_reg->flatIndex()] = true;
     }
 
     /** Sets the register as not ready. */
     void unsetReg(PhysRegIdPtr phys_reg)
     {
-        assert(phys_reg->flatIdx < numPhysRegs);
+        assert(phys_reg->flatIndex() < numPhysRegs);
 
         if (phys_reg->isFixedMapping()) {
             // Fixed mapping regs are always ready, ignore attempts to
@@ -127,7 +127,7 @@ class Scoreboard
         if (phys_reg->isZeroReg())
             return;
 
-        regScoreBoard[phys_reg->flatIdx] = false;
+        regScoreBoard[phys_reg->flatIndex()] = false;
     }
 
 };
index 78b88ac2a1d320668431f1f5c7c24bff220adab4..161d70b2849595fa8c2e8fd478096f854e1c57e6 100755 (executable)
@@ -175,37 +175,47 @@ class O3ThreadContext : public ThreadContext
     virtual void clearArchRegs();
 
     /** Reads an integer register. */
+    virtual uint64_t readReg(int reg_idx) {
+        return readIntRegFlat(flattenRegId(RegId(IntRegClass,
+                                                 reg_idx)).index());
+    }
     virtual uint64_t readIntReg(int reg_idx) {
-        return readIntRegFlat(flattenIntIndex(reg_idx));
+        return readIntRegFlat(flattenRegId(RegId(IntRegClass,
+                                                 reg_idx)).index());
     }
 
     virtual FloatReg readFloatReg(int reg_idx) {
-        return readFloatRegFlat(flattenFloatIndex(reg_idx));
+        return readFloatRegFlat(flattenRegId(RegId(FloatRegClass,
+                                                 reg_idx)).index());
     }
 
     virtual FloatRegBits readFloatRegBits(int reg_idx) {
-        return readFloatRegBitsFlat(flattenFloatIndex(reg_idx));
+        return readFloatRegBitsFlat(flattenRegId(RegId(FloatRegClass,
+                                                 reg_idx)).index());
     }
 
     virtual CCReg readCCReg(int reg_idx) {
-        return readCCRegFlat(flattenCCIndex(reg_idx));
+        return readCCRegFlat(flattenRegId(RegId(CCRegClass,
+                                                 reg_idx)).index());
     }
 
     /** Sets an integer register to a value. */
     virtual void setIntReg(int reg_idx, uint64_t val) {
-        setIntRegFlat(flattenIntIndex(reg_idx), val);
+        setIntRegFlat(flattenRegId(RegId(IntRegClass, reg_idx)).index(), val);
     }
 
     virtual void setFloatReg(int reg_idx, FloatReg val) {
-        setFloatRegFlat(flattenFloatIndex(reg_idx), val);
+        setFloatRegFlat(flattenRegId(RegId(FloatRegClass,
+                                           reg_idx)).index(), val);
     }
 
     virtual void setFloatRegBits(int reg_idx, FloatRegBits val) {
-        setFloatRegBitsFlat(flattenFloatIndex(reg_idx), val);
+        setFloatRegBitsFlat(flattenRegId(RegId(FloatRegClass,
+                                               reg_idx)).index(), val);
     }
 
     virtual void setCCReg(int reg_idx, CCReg val) {
-        setCCRegFlat(flattenCCIndex(reg_idx), val);
+        setCCRegFlat(flattenRegId(RegId(CCRegClass, reg_idx)).index(), val);
     }
 
     /** Reads this thread's PC state. */
@@ -245,10 +255,7 @@ class O3ThreadContext : public ThreadContext
      * write might have as defined by the architecture. */
     virtual void setMiscReg(int misc_reg, const MiscReg &val);
 
-    virtual int flattenIntIndex(int reg);
-    virtual int flattenFloatIndex(int reg);
-    virtual int flattenCCIndex(int reg);
-    virtual int flattenMiscIndex(int reg);
+    virtual RegId flattenRegId(const RegId& regId) const;
 
     /** Returns the number of consecutive store conditional failures. */
     // @todo: Figure out where these store cond failures should go.
index e6a3d50831bd2cb3eec54672bbccdf848482c634..c3f894275b7c73da1ce371c73d24702e425acf63 100755 (executable)
@@ -270,31 +270,10 @@ O3ThreadContext<Impl>::pcStateNoRecord(const TheISA::PCState &val)
 }
 
 template <class Impl>
-int
-O3ThreadContext<Impl>::flattenIntIndex(int reg)
+RegId
+O3ThreadContext<Impl>::flattenRegId(const RegId& regId) const
 {
-    return cpu->isa[thread->threadId()]->flattenIntIndex(reg);
-}
-
-template <class Impl>
-int
-O3ThreadContext<Impl>::flattenFloatIndex(int reg)
-{
-    return cpu->isa[thread->threadId()]->flattenFloatIndex(reg);
-}
-
-template <class Impl>
-int
-O3ThreadContext<Impl>::flattenCCIndex(int reg)
-{
-    return cpu->isa[thread->threadId()]->flattenCCIndex(reg);
-}
-
-template <class Impl>
-int
-O3ThreadContext<Impl>::flattenMiscIndex(int reg)
-{
-    return cpu->isa[thread->threadId()]->flattenMiscIndex(reg);
+    return cpu->isa[thread->threadId()]->flattenRegId(regId);
 }
 
 template <class Impl>
index 75be4679ddee21ceeb439f994fcf17ac4eb938cf..53a50ce8e3e266f86548874e61458d51ebf3640a 100644 (file)
 
 #include "cpu/reg_class.hh"
 
-const char *RegClassStrings[] = {
+const char *RegId::regClassStrings[] = {
     "IntRegClass",
     "FloatRegClass",
     "CCRegClass",
     "MiscRegClass"
 };
 
-const RegId RegId::zeroReg = RegId(IntRegClass, TheISA::ZeroReg);
index 25c882c5841cdf2f68e97fb2a9530e2945cb19eb..05869e8fbed702e3a40fc1fee30bc26394a4dca9 100644 (file)
@@ -51,7 +51,7 @@
 #include "arch/registers.hh"
 #include "config/the_isa.hh"
 
-/// Enumerate the classes of registers.
+/** Enumerate the classes of registers. */
 enum RegClass {
     IntRegClass,        ///< Integer register
     FloatRegClass,      ///< Floating-point register
@@ -59,54 +59,91 @@ enum RegClass {
     MiscRegClass        ///< Control (misc) register
 };
 
-/// Number of register classes.  This value is not part of the enum,
-/// because putting it there makes the compiler complain about
-/// unhandled cases in some switch statements.
+/** Number of register classes.
+ * This value is not part of the enum, because putting it there makes the
+ * compiler complain about unhandled cases in some switch statements.
+ */
 const int NumRegClasses = MiscRegClass + 1;
 
-/// Register ID: describe an architectural register with its class and index.
-/// This structure is used instead of just the register index to disambiguate
-/// between different classes of registers.
-/// For example, a integer register with index 3 is represented by
-/// Regid(IntRegClass, 3).
-struct RegId {
+/** Register ID: describe an architectural register with its class and index.
+ * This structure is used instead of just the register index to disambiguate
+ * between different classes of registers. For example, a integer register with
+ * index 3 is represented by Regid(IntRegClass, 3).
+ */
+class RegId {
+  private:
+    static const char* regClassStrings[];
     RegClass regClass;
     RegIndex regIdx;
+  public:
     RegId() {};
     RegId(RegClass reg_class, RegIndex reg_idx)
         : regClass(reg_class), regIdx(reg_idx)
     {}
 
     bool operator==(const RegId& that) const {
-        return regClass == that.regClass && regIdx == that.regIdx;
+        return regClass == that.classValue() && regIdx == that.index();
     }
 
     bool operator!=(const RegId& that) const {
         return !(*this==that);
     }
 
-    /**
-     * Returns true if this register is a zero register (needs to have a
-     * constant zero value throughout the execution)
+    /** Order operator.
+     * The order is required to implement maps with key type RegId
      */
-    bool isZeroReg() const
-    {
-        return (regIdx == TheISA::ZeroReg &&
-                (regClass == IntRegClass ||
-                 (THE_ISA == ALPHA_ISA && regClass == FloatRegClass)));
+    bool operator<(const RegId& that) const {
+        return regClass < that.classValue() ||
+                (regClass == that.classValue() && regIdx < that.index());
     }
 
     /**
      * Return true if this register can be renamed
      */
-    bool isRenameable()
+    bool isRenameable() const
     {
         return regClass != MiscRegClass;
     }
 
-    static const RegId zeroReg;
-};
+    /**
+     * Check if this is the zero register.
+     * Returns true if this register is a zero register (needs to have a
+     * constant zero value throughout the execution).
+     */
+
+    inline bool isZeroReg() const;
 
-/// Map enum values to strings for debugging
-extern const char *RegClassStrings[];
+    /** @return true if it is an integer physical register. */
+    bool isIntReg() const { return regClass == IntRegClass; }
+
+    /** @return true if it is a floating-point physical register. */
+    bool isFloatReg() const { return regClass == FloatRegClass; }
+
+    /** @Return true if it is a  condition-code physical register. */
+    bool isCCReg() const { return regClass == CCRegClass; }
+
+    /** @Return true if it is a  condition-code physical register. */
+    bool isMiscReg() const { return regClass == MiscRegClass; }
+
+    /** Index accessors */
+    /** @{ */
+    const RegIndex& index() const { return regIdx; }
+    RegIndex& index() { return regIdx; }
+
+    /** Index flattening.
+     * Required to be able to use a vector for the register mapping.
+     */
+    inline RegIndex flatIndex() const;
+    /** @} */
+
+    /** Class accessor */
+    const RegClass& classValue() const { return regClass; }
+    /** Return a const char* with the register class name. */
+    const char* className() const { return regClassStrings[regClass]; }
+
+    friend std::ostream&
+    operator<<(std::ostream& os, const RegId& rid) {
+        return os << rid.className() << "{" << rid.index() << "}";
+    }
+};
 #endif // __CPU__REG_CLASS_HH__
diff --git a/src/cpu/reg_class_impl.hh b/src/cpu/reg_class_impl.hh
new file mode 100644 (file)
index 0000000..a47328b
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Rekai Gonzalez
+ */
+
+#ifndef __CPU__REG_CLASS_IMPL_HH__
+#define __CPU__REG_CLASS_IMPL_HH__
+
+#include <cassert>
+#include <cstddef>
+#include <iostream>
+
+#include "arch/registers.hh"
+#include "config/the_isa.hh"
+#include "cpu/reg_class.hh"
+
+bool RegId::isZeroReg() const
+{
+    return ((regClass == IntRegClass && regIdx == TheISA::ZeroReg) ||
+            (THE_ISA == ALPHA_ISA && regClass == FloatRegClass &&
+             regIdx == TheISA::ZeroReg));
+}
+
+RegIndex RegId::flatIndex() const {
+    switch (regClass) {
+    case IntRegClass:
+    case FloatRegClass:
+    case CCRegClass:
+    case MiscRegClass:
+        return regIdx;
+    }
+    panic("Trying to flatten a register without class!");
+    return -1;
+}
+
+#endif // __CPU__REG_CLASS_IMPL_HH__
index 9689796f316bb8118fe523d8140fa513f99047e9..f221d6c93852e0a47a9e7abd5008345b4ca37a3a 100644 (file)
@@ -165,27 +165,27 @@ class SimpleExecContext : public ExecContext {
     IntReg readIntRegOperand(const StaticInst *si, int idx) override
     {
         numIntRegReads++;
-        RegId reg = si->srcRegIdx(idx);
-        assert(reg.regClass == IntRegClass);
-        return thread->readIntReg(reg.regIdx);
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isIntReg());
+        return thread->readIntReg(reg.index());
     }
 
     /** Sets an integer register to a value. */
     void setIntRegOperand(const StaticInst *si, int idx, IntReg val) override
     {
         numIntRegWrites++;
-        RegId reg = si->destRegIdx(idx);
-        assert(reg.regClass == IntRegClass);
-        thread->setIntReg(reg.regIdx, val);
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isIntReg());
+        thread->setIntReg(reg.index(), val);
     }
 
     /** Reads a floating point register of single register width. */
     FloatReg readFloatRegOperand(const StaticInst *si, int idx) override
     {
         numFpRegReads++;
-        RegId reg = si->srcRegIdx(idx);
-        assert(reg.regClass == FloatRegClass);
-        return thread->readFloatReg(reg.regIdx);
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isFloatReg());
+        return thread->readFloatReg(reg.index());
     }
 
     /** Reads a floating point register in its binary format, instead
@@ -193,9 +193,9 @@ class SimpleExecContext : public ExecContext {
     FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) override
     {
         numFpRegReads++;
-        RegId reg = si->srcRegIdx(idx);
-        assert(reg.regClass == FloatRegClass);
-        return thread->readFloatRegBits(reg.regIdx);
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isFloatReg());
+        return thread->readFloatRegBits(reg.index());
     }
 
     /** Sets a floating point register of single width to a value. */
@@ -203,9 +203,9 @@ class SimpleExecContext : public ExecContext {
                             FloatReg val) override
     {
         numFpRegWrites++;
-        RegId reg = si->destRegIdx(idx);
-        assert(reg.regClass == FloatRegClass);
-        thread->setFloatReg(reg.regIdx, val);
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isFloatReg());
+        thread->setFloatReg(reg.index(), val);
     }
 
     /** Sets the bits of a floating point register of single width
@@ -214,42 +214,42 @@ class SimpleExecContext : public ExecContext {
                                 FloatRegBits val) override
     {
         numFpRegWrites++;
-        RegId reg = si->destRegIdx(idx);
-        assert(reg.regClass == FloatRegClass);
-        thread->setFloatRegBits(reg.regIdx, val);
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isFloatReg());
+        thread->setFloatRegBits(reg.index(), val);
     }
 
     CCReg readCCRegOperand(const StaticInst *si, int idx) override
     {
         numCCRegReads++;
-        RegId reg = si->srcRegIdx(idx);
-        assert(reg.regClass == CCRegClass);
-        return thread->readCCReg(reg.regIdx);
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isCCReg());
+        return thread->readCCReg(reg.index());
     }
 
     void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
     {
         numCCRegWrites++;
-        RegId reg = si->destRegIdx(idx);
-        assert(reg.regClass == CCRegClass);
-        thread->setCCReg(reg.regIdx, val);
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isCCReg());
+        thread->setCCReg(reg.index(), val);
     }
 
     MiscReg readMiscRegOperand(const StaticInst *si, int idx) override
     {
         numIntRegReads++;
-        RegId reg = si->srcRegIdx(idx);
-        assert(reg.regClass == MiscRegClass);
-        return thread->readMiscReg(reg.regIdx);
+        const RegId& reg = si->srcRegIdx(idx);
+        assert(reg.isMiscReg());
+        return thread->readMiscReg(reg.index());
     }
 
     void setMiscRegOperand(const StaticInst *si, int idx,
                            const MiscReg &val) override
     {
         numIntRegWrites++;
-        RegId reg = si->destRegIdx(idx);
-        assert(reg.regClass == MiscRegClass);
-        thread->setMiscReg(reg.regIdx, val);
+        const RegId& reg = si->destRegIdx(idx);
+        assert(reg.isMiscReg());
+        thread->setMiscReg(reg.index(), val);
     }
 
     /**
@@ -411,14 +411,15 @@ class SimpleExecContext : public ExecContext {
     }
 
 #if THE_ISA == MIPS_ISA
-    MiscReg readRegOtherThread(RegId reg, ThreadID tid = InvalidThreadID)
+    MiscReg readRegOtherThread(const RegId& reg,
+                               ThreadID tid = InvalidThreadID)
         override
     {
         panic("Simple CPU models do not support multithreaded "
               "register access.");
     }
 
-    void setRegOtherThread(RegId reg, MiscReg val,
+    void setRegOtherThread(const RegId& reg, MiscReg val,
                            ThreadID tid = InvalidThreadID) override
     {
         panic("Simple CPU models do not support multithreaded "
index bdf93b0e402839863773c24c669befe1b4242869..286d917668ed7e3238b4313113cad1a6cc30b4c9 100644 (file)
@@ -401,28 +401,10 @@ class SimpleThread : public ThreadState
         return isa->setMiscReg(misc_reg, val, tc);
     }
 
-    int
-    flattenIntIndex(int reg)
+    RegId
+    flattenRegId(const RegId& regId) const
     {
-        return isa->flattenIntIndex(reg);
-    }
-
-    int
-    flattenFloatIndex(int reg)
-    {
-        return isa->flattenFloatIndex(reg);
-    }
-
-    int
-    flattenCCIndex(int reg)
-    {
-        return isa->flattenCCIndex(reg);
-    }
-
-    int
-    flattenMiscIndex(int reg)
-    {
-        return isa->flattenMiscIndex(reg);
+        return isa->flattenRegId(regId);
     }
 
     unsigned readStCondFailures() { return storeCondFailures; }
index 7513010955d97aae28b4f507ac2a37d4bdde8033..d60afc019231f542544aaed9118e1a7d4eaa6758 100644 (file)
@@ -43,6 +43,7 @@
 #include "config/the_isa.hh"
 #include "cpu/op_class.hh"
 #include "cpu/reg_class.hh"
+#include "cpu/reg_class_impl.hh"
 #include "cpu/static_inst_fwd.hh"
 #include "cpu/thread_context.hh"
 #include "enums/StaticInstFlags.hh"
@@ -184,11 +185,11 @@ class StaticInst : public RefCounted, public StaticInstFlags
 
     /// Return logical index (architectural reg num) of i'th destination reg.
     /// Only the entries from 0 through numDestRegs()-1 are valid.
-    RegId destRegIdx(int i) const { return _destRegIdx[i]; }
+    const RegId& destRegIdx(int i) const { return _destRegIdx[i]; }
 
     /// Return logical index (architectural reg num) of i'th source reg.
     /// Only the entries from 0 through numSrcRegs()-1 are valid.
-    RegId srcRegIdx(int i)  const { return _srcRegIdx[i]; }
+    const RegId& srcRegIdx(int i)  const { return _srcRegIdx[i]; }
 
     /// Pointer to a statically allocated "null" instruction object.
     /// Used to give eaCompInst() and memAccInst() something to return
index efa0b21623d8ab5c5d02f1d03a4c3238d9bd5bc8..43c40481e8792042e16894aa2fcdfa7a573c6ec7 100644 (file)
@@ -250,19 +250,16 @@ class ThreadContext
 
     virtual void setMiscReg(int misc_reg, const MiscReg &val) = 0;
 
-    virtual int flattenIntIndex(int reg) = 0;
-    virtual int flattenFloatIndex(int reg) = 0;
-    virtual int flattenCCIndex(int reg) = 0;
-    virtual int flattenMiscIndex(int reg) = 0;
+    virtual RegId flattenRegId(const RegId& regId) const = 0;
 
     virtual uint64_t
-    readRegOtherThread(RegId misc_reg, ThreadID tid)
+    readRegOtherThread(const RegId& misc_reg, ThreadID tid)
     {
         return 0;
     }
 
     virtual void
-    setRegOtherThread(RegId misc_reg, const MiscReg &val, ThreadID tid)
+    setRegOtherThread(const RegId& misc_reg, const MiscReg &val, ThreadID tid)
     {
     }
 
@@ -291,7 +288,7 @@ class ThreadContext
      *
      * Some architectures have different registers visible in
      * different modes. Such architectures "flatten" a register (see
-     * flattenIntIndex() and flattenFloatIndex()) to map it into the
+     * flattenRegId()) to map it into the
      * gem5 register file. This interface provides a flat interface to
      * the underlying register file, which allows for example
      * serialization code to access all registers.
@@ -466,17 +463,8 @@ class ProxyThreadContext : public ThreadContext
     void setMiscReg(int misc_reg, const MiscReg &val)
     { return actualTC->setMiscReg(misc_reg, val); }
 
-    int flattenIntIndex(int reg)
-    { return actualTC->flattenIntIndex(reg); }
-
-    int flattenFloatIndex(int reg)
-    { return actualTC->flattenFloatIndex(reg); }
-
-    int flattenCCIndex(int reg)
-    { return actualTC->flattenCCIndex(reg); }
-
-    int flattenMiscIndex(int reg)
-    { return actualTC->flattenMiscIndex(reg); }
+    RegId flattenRegId(const RegId& regId) const
+    { return actualTC->flattenRegId(regId); }
 
     unsigned readStCondFailures()
     { return actualTC->readStCondFailures(); }
index 99b4eb6aa3aed767361ae45ee917f0e350a7e364..da5c6489edab64207581fda450b77c1877d96801 100644 (file)
@@ -58,7 +58,7 @@ TimingExprEvalContext::TimingExprEvalContext(const StaticInstPtr &inst_,
 
 uint64_t TimingExprSrcReg::eval(TimingExprEvalContext &context)
 {
-    return context.inst->srcRegIdx(index).regIdx;
+    return context.inst->srcRegIdx(index).index();
 }
 
 uint64_t TimingExprReadIntReg::eval(TimingExprEvalContext &context)