Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/42685 )

Change subject: cpu,arch: Move the zero register index into RegClassInfo.
......................................................................

cpu,arch: Move the zero register index into RegClassInfo.

There is a design which has been put forward which eliminates the idea
of a zero register entirely, but in the mean time, to get rid of one
more ISA specific constant, this change moves the ZeroReg constant into
the RegClassInfo class, specifically the IntRegClass instance which is
published by each ISA.

When the idea of zero registers has been eliminated entirely from
non ISA specific code, this and the existing machinery can be
eliminated.

Change-Id: I4302a53220dd5ff6b9b47ecc765bddc6698310ca
---
M src/arch/arm/isa.cc
M src/arch/arm/registers.hh
M src/arch/mips/isa.cc
M src/arch/mips/registers.hh
M src/arch/null/registers.hh
M src/arch/power/isa.cc
M src/arch/power/registers.hh
M src/arch/riscv/isa.cc
M src/arch/riscv/registers.hh
M src/arch/sparc/isa.cc
M src/arch/sparc/registers.hh
M src/arch/x86/isa.cc
M src/arch/x86/registers.hh
M src/cpu/checker/cpu.cc
M src/cpu/checker/cpu.hh
M src/cpu/checker/cpu_impl.hh
M src/cpu/minor/dyn_inst.cc
M src/cpu/minor/exec_context.hh
M src/cpu/minor/execute.cc
M src/cpu/minor/execute.hh
M src/cpu/minor/lsq.cc
M src/cpu/minor/lsq.hh
M src/cpu/minor/scoreboard.cc
M src/cpu/minor/scoreboard.hh
M src/cpu/o3/cpu.cc
M src/cpu/o3/probe/elastic_trace.cc
M src/cpu/o3/probe/elastic_trace.hh
M src/cpu/o3/regfile.cc
M src/cpu/o3/regfile.hh
M src/cpu/o3/rename_map.cc
M src/cpu/o3/rename_map.hh
M src/cpu/o3/scoreboard.cc
M src/cpu/o3/scoreboard.hh
M src/cpu/reg_class.hh
M src/cpu/simple/base.cc
M src/cpu/simple/base.hh
36 files changed, 117 insertions(+), 131 deletions(-)



diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc
index 039224f..93c14a3 100644
--- a/src/arch/arm/isa.cc
+++ b/src/arch/arm/isa.cc
@@ -67,7 +67,7 @@
     afterStartup(false)
 {
     _regClasses.insert(_regClasses.end(), {
-            { NUM_INTREGS },
+            { NUM_INTREGS, INTREG_ZERO },
             { 0 },
             { NumVecRegs },
             { NumVecRegs * TheISA::NumVecElemPerVecReg },
diff --git a/src/arch/arm/registers.hh b/src/arch/arm/registers.hh
index 8d5cfdf..55ba141 100644
--- a/src/arch/arm/registers.hh
+++ b/src/arch/arm/registers.hh
@@ -41,14 +41,6 @@
 #ifndef __ARCH_ARM_REGISTERS_HH__
 #define __ARCH_ARM_REGISTERS_HH__

-#include "arch/arm/regs/int.hh"
 #include "arch/arm/regs/vec.hh"

-namespace ArmISA
-{
-
-const int ZeroReg = INTREG_ZERO;
-
-} // namespace ArmISA
-
 #endif
diff --git a/src/arch/mips/isa.cc b/src/arch/mips/isa.cc
index 3e4bb1e..bc98e2b 100644
--- a/src/arch/mips/isa.cc
+++ b/src/arch/mips/isa.cc
@@ -95,7 +95,7 @@
     numVpes(p.num_vpes)
 {
     _regClasses.insert(_regClasses.end(), {
-            { NumIntRegs },
+            { NumIntRegs, 0 },
             { NumFloatRegs },
             { 1 }, // Not applicable to MIPS.
             { 2 }, // Not applicable to MIPS.
diff --git a/src/arch/mips/registers.hh b/src/arch/mips/registers.hh
index 1f49262..95801e5 100644
--- a/src/arch/mips/registers.hh
+++ b/src/arch/mips/registers.hh
@@ -36,8 +36,6 @@
 namespace MipsISA
 {

-const int ZeroReg = 0;
-
 // Not applicable to MIPS
 using VecElem = ::DummyVecElem;
 using VecReg = ::DummyVecReg;
diff --git a/src/arch/null/registers.hh b/src/arch/null/registers.hh
index 3e96472..8aacc56 100644
--- a/src/arch/null/registers.hh
+++ b/src/arch/null/registers.hh
@@ -40,12 +40,9 @@

 #include "arch/generic/vec_pred_reg.hh"
 #include "arch/generic/vec_reg.hh"
-#include "arch/null/types.hh"
-#include "base/types.hh"

-namespace NullISA {
-
-const RegIndex ZeroReg = 0;
+namespace NullISA
+{

 // Not applicable to null
 using VecElem = ::DummyVecElem;
diff --git a/src/arch/power/isa.cc b/src/arch/power/isa.cc
index 8908645..cccbda4 100644
--- a/src/arch/power/isa.cc
+++ b/src/arch/power/isa.cc
@@ -48,7 +48,7 @@
 ISA::ISA(const Params &p) : BaseISA(p)
 {
     _regClasses.insert(_regClasses.end(), {
-            { NumIntRegs },
+            { NumIntRegs, NumIntRegs - 1 },
             { NumFloatRegs },
             { 1 },
             { 2 },
diff --git a/src/arch/power/registers.hh b/src/arch/power/registers.hh
index 5bdc058..d06cae5 100644
--- a/src/arch/power/registers.hh
+++ b/src/arch/power/registers.hh
@@ -33,7 +33,6 @@

 #include "arch/generic/vec_pred_reg.hh"
 #include "arch/generic/vec_reg.hh"
-#include "arch/power/regs/int.hh"

 namespace PowerISA
 {
@@ -53,9 +52,6 @@
 constexpr size_t VecPredRegSizeBits = ::DummyVecPredRegSizeBits;
 constexpr bool VecPredRegHasPackedRepr = ::DummyVecPredRegHasPackedRepr;

-// There isn't one in Power, but we need to define one somewhere
-const int ZeroReg = NumIntRegs - 1;
-
 } // namespace PowerISA

 #endif // __ARCH_POWER_REGISTERS_HH__
diff --git a/src/arch/riscv/isa.cc b/src/arch/riscv/isa.cc
index 18a76a8..40d8bc9 100644
--- a/src/arch/riscv/isa.cc
+++ b/src/arch/riscv/isa.cc
@@ -181,7 +181,7 @@
 ISA::ISA(const Params &p) : BaseISA(p)
 {
     _regClasses.insert(_regClasses.begin(), {
-            { NumIntRegs },
+            { NumIntRegs, 0 },
             { NumFloatRegs },
             { 1 }, // Not applicable to RISCV
             { 2 }, // Not applicable to RISCV
diff --git a/src/arch/riscv/registers.hh b/src/arch/riscv/registers.hh
index 90dbd23..685e23c 100644
--- a/src/arch/riscv/registers.hh
+++ b/src/arch/riscv/registers.hh
@@ -54,8 +54,6 @@
 namespace RiscvISA
 {

-const int ZeroReg = 0;
-
 // Not applicable to RISC-V
 using VecElem = ::DummyVecElem;
 using VecReg = ::DummyVecReg;
diff --git a/src/arch/sparc/isa.cc b/src/arch/sparc/isa.cc
index 6fe79be..7fa88f2 100644
--- a/src/arch/sparc/isa.cc
+++ b/src/arch/sparc/isa.cc
@@ -66,7 +66,7 @@
 ISA::ISA(const Params &p) : BaseISA(p)
 {
     _regClasses.insert(_regClasses.end(), {
-            { NumIntRegs },
+            { NumIntRegs, 0 },
             { NumFloatRegs },
             { 1 }, // Not applicable for SPARC
             { 2 }, // Not applicable for SPARC
diff --git a/src/arch/sparc/registers.hh b/src/arch/sparc/registers.hh
index 62fd3f5..077daf9 100644
--- a/src/arch/sparc/registers.hh
+++ b/src/arch/sparc/registers.hh
@@ -50,8 +50,6 @@
 constexpr size_t VecPredRegSizeBits = ::DummyVecPredRegSizeBits;
 constexpr bool VecPredRegHasPackedRepr = ::DummyVecPredRegHasPackedRepr;

-const int ZeroReg = 0;
-
 } // namespace SparcISA

 #endif
diff --git a/src/arch/x86/isa.cc b/src/arch/x86/isa.cc
index 640422d..c2fb59d 100644
--- a/src/arch/x86/isa.cc
+++ b/src/arch/x86/isa.cc
@@ -140,7 +140,7 @@
              "CPUID vendor string must be 12 characters\n");

     _regClasses.insert(_regClasses.end(), {
-            { NumIntRegs },
+            { NumIntRegs, NUM_INTREGS },
             { NumFloatRegs },
             { 1 }, // Not applicable to X86
             { 2 }, // Not applicable to X86
diff --git a/src/arch/x86/registers.hh b/src/arch/x86/registers.hh
index e7c1d9f..2ac9c27 100644
--- a/src/arch/x86/registers.hh
+++ b/src/arch/x86/registers.hh
@@ -60,9 +60,6 @@
     Max_Reg_Index = Misc_Reg_Base + NUM_MISCREGS
 };

-// There is no such register in X86.
-const int ZeroReg = NUM_INTREGS;
-
 // Not applicable to x86
 using VecElem = ::DummyVecElem;
 using VecReg = ::DummyVecReg;
diff --git a/src/cpu/checker/cpu.cc b/src/cpu/checker/cpu.cc
index 52daea9..2bc89e7 100644
--- a/src/cpu/checker/cpu.cc
+++ b/src/cpu/checker/cpu.cc
@@ -59,7 +59,9 @@
 }

 CheckerCPU::CheckerCPU(const Params &p)
- : BaseCPU(p, true), systemPtr(NULL), icachePort(NULL), dcachePort(NULL),
+    : BaseCPU(p, true),
+      zeroReg(params().isa[0]->regClasses().at(IntRegClass).zeroReg()),
+      systemPtr(NULL), icachePort(NULL), dcachePort(NULL),
       tc(NULL), thread(NULL),
       unverifiedReq(nullptr),
       unverifiedMemData(nullptr)
diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh
index 0900125..0e175f7 100644
--- a/src/cpu/checker/cpu.hh
+++ b/src/cpu/checker/cpu.hh
@@ -88,6 +88,8 @@
     /** id attached to all issued requests */
     RequestorID requestorId;

+    RegIndex zeroReg;
+
   public:
     void init() override;

diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh
index 7dc62e0..1bc9389 100644
--- a/src/cpu/checker/cpu_impl.hh
+++ b/src/cpu/checker/cpu_impl.hh
@@ -198,7 +198,7 @@
         Fault fault = NoFault;

         // maintain $r0 semantics
-        thread->setIntReg(TheISA::ZeroReg, 0);
+        thread->setIntReg(zeroReg, 0);

         // Check if any recent PC changes match up with anything we
         // expect to happen.  This is mostly to check if traps or
diff --git a/src/cpu/minor/dyn_inst.cc b/src/cpu/minor/dyn_inst.cc
index 510ec10..2cfef31 100644
--- a/src/cpu/minor/dyn_inst.cc
+++ b/src/cpu/minor/dyn_inst.cc
@@ -132,8 +132,8 @@
     return os;
 }

-/** 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' */
+/** Print a register in the form r<n>, f<n>, m<n>(<name>) for integer,
+ *  float, and misc given an 'architectural register number' */
 static void
 printRegName(std::ostream &os, const RegId& reg)
 {
@@ -153,24 +153,19 @@
         }
         break;
       case FloatRegClass:
-        os << 'f' << static_cast<unsigned int>(reg.index());
+        os << 'f' << reg.index();
         break;
       case VecRegClass:
-        os << 'v' << static_cast<unsigned int>(reg.index());
+        os << 'v' << reg.index();
         break;
       case VecElemClass:
-        os << 'v' << static_cast<unsigned int>(reg.index()) << '[' <<
-              static_cast<unsigned int>(reg.elemIndex()) << ']';
+        os << 'v' << reg.index() << '[' << reg.elemIndex() << ']';
         break;
       case IntRegClass:
-        if (reg.index() == TheISA::ZeroReg) {
-            os << 'z';
-        } else {
-            os << 'r' << static_cast<unsigned int>(reg.index());
-        }
+        os << 'r' << reg.index();
         break;
       case CCRegClass:
-        os << 'c' << static_cast<unsigned int>(reg.index());
+        os << 'c' << reg.index();
         break;
       default:
         panic("Unknown register class: %d", (int)reg.classValue());
diff --git a/src/cpu/minor/exec_context.hh b/src/cpu/minor/exec_context.hh
index 58f4b4b..5630b4b 100644
--- a/src/cpu/minor/exec_context.hh
+++ b/src/cpu/minor/exec_context.hh
@@ -83,7 +83,7 @@
     ExecContext (
         MinorCPU &cpu_,
         SimpleThread &thread_, Execute &execute_,
-        MinorDynInstPtr inst_) :
+        MinorDynInstPtr inst_, RegIndex zeroReg) :
         cpu(cpu_),
         thread(thread_),
         execute(execute_),
@@ -93,7 +93,7 @@
         pcState(inst->pc);
         setPredicate(inst->readPredicate());
         setMemAccPredicate(inst->readMemAccPredicate());
-        thread.setIntReg(TheISA::ZeroReg, 0);
+        thread.setIntReg(zeroReg, 0);
     }

     ~ExecContext()
diff --git a/src/cpu/minor/execute.cc b/src/cpu/minor/execute.cc
index 7575cf9..3036ae5 100644
--- a/src/cpu/minor/execute.cc
+++ b/src/cpu/minor/execute.cc
@@ -67,6 +67,8 @@
     inp(inp_),
     out(out_),
     cpu(cpu_),
+    zeroReg(cpu.threads[0]->getIsaPtr()->regClasses().
+        at(IntRegClass).zeroReg()),
     issueLimit(params.executeIssueLimit),
     memoryIssueLimit(params.executeMemoryIssueLimit),
     commitLimit(params.executeCommitLimit),
@@ -85,8 +87,10 @@
         params.executeLSQRequestsQueueSize,
         params.executeLSQTransfersQueueSize,
         params.executeLSQStoreBufferSize,
-        params.executeLSQMaxStoreBufferStoresPerCycle),
- executeInfo(params.numThreads, ExecuteThreadInfo(params.executeCommitLimit)),
+        params.executeLSQMaxStoreBufferStoresPerCycle,
+        zeroReg),
+    executeInfo(params.numThreads,
+            ExecuteThreadInfo(params.executeCommitLimit)),
     interruptPriority(0),
     issuePriority(0),
     commitPriority(0)
@@ -176,6 +180,7 @@
                 params.executeInputBufferSize));

const auto &regClasses = cpu.threads[tid]->getIsaPtr()->regClasses();
+        zeroReg = regClasses.at(IntRegClass).zeroReg();

         /* Scoreboards */
scoreboard.emplace_back(name_ + ".scoreboard" + tid_str, regClasses);
@@ -324,7 +329,7 @@
     ThreadID thread_id = inst->id.threadId;
     ThreadContext *thread = cpu.getContext(thread_id);

-    ExecContext context(cpu, *cpu.threads[thread_id], *this, inst);
+ ExecContext context(cpu, *cpu.threads[thread_id], *this, inst, zeroReg);

     PacketPtr packet = response->packet;

@@ -460,7 +465,7 @@
         TheISA::PCState old_pc = thread->pcState();

         ExecContext context(cpu, *cpu.threads[inst->id.threadId],
-            *this, inst);
+            *this, inst, zeroReg);

         DPRINTF(MinorExecute, "Initiating memRef inst: %s\n", *inst);

@@ -904,7 +909,8 @@
         panic("We should never hit the case where we try to commit from a "
               "suspended thread as the streamSeqNum should not match");
     } else if (inst->isFault()) {
-        ExecContext context(cpu, *cpu.threads[thread_id], *this, inst);
+        ExecContext context(cpu, *cpu.threads[thread_id], *this,
+                inst, zeroReg);

         DPRINTF(MinorExecute, "Fault inst reached Execute: %s\n",
             inst->fault->name());
@@ -965,7 +971,8 @@
          * backwards, so no other branches may evaluate this cycle*/
         completed_inst = false;
     } else {
-        ExecContext context(cpu, *cpu.threads[thread_id], *this, inst);
+        ExecContext context(cpu, *cpu.threads[thread_id], *this,
+                inst, zeroReg);

         DPRINTF(MinorExecute, "Committing inst: %s\n", *inst);

diff --git a/src/cpu/minor/execute.hh b/src/cpu/minor/execute.hh
index 4d36a5d..7805d87 100644
--- a/src/cpu/minor/execute.hh
+++ b/src/cpu/minor/execute.hh
@@ -63,6 +63,7 @@
 class Execute : public Named
 {
   protected:
+
     /** Input port carrying instructions from Decode */
     Latch<ForwardInstData>::Output inp;

@@ -72,6 +73,8 @@
     /** Pointer back to the containing CPU */
     MinorCPU &cpu;

+    RegIndex zeroReg;
+
     /** Number of instructions that can be issued per cycle */
     unsigned int issueLimit;

diff --git a/src/cpu/minor/lsq.cc b/src/cpu/minor/lsq.cc
index 7e156ea..0b62709 100644
--- a/src/cpu/minor/lsq.cc
+++ b/src/cpu/minor/lsq.cc
@@ -54,9 +54,10 @@
 {

LSQ::LSQRequest::LSQRequest(LSQ &port_, MinorDynInstPtr inst_, bool isLoad_,
-    PacketDataPtr data_, uint64_t *res_) :
+        RegIndex zero_reg, PacketDataPtr data_, uint64_t *res_) :
     SenderState(),
     port(port_),
+    zeroReg(zero_reg),
     inst(inst_),
     isLoad(isLoad_),
     data(data_),
@@ -76,7 +77,7 @@
 {
     SimpleThread &thread = *port.cpu.threads[inst->id.threadId];
     TheISA::PCState old_pc = thread.pcState();
-    ExecContext context(port.cpu, thread, port.execute, inst);
+    ExecContext context(port.cpu, thread, port.execute, inst, zeroReg);
     M5_VAR_USED Fault fault = inst->translationFault;

     // Give the instruction a chance to suppress a translation fault
@@ -99,7 +100,7 @@
     SimpleThread &thread = *port.cpu.threads[inst->id.threadId];
     TheISA::PCState old_pc = thread.pcState();

-    ExecContext context(port.cpu, thread, port.execute, inst);
+    ExecContext context(port.cpu, thread, port.execute, inst, zeroReg);

     context.setMemAccPredicate(false);
     inst->staticInst->completeAcc(nullptr, &context, inst->traceData);
@@ -388,7 +389,7 @@

 LSQ::SplitDataRequest::SplitDataRequest(LSQ &port_, MinorDynInstPtr inst_,
     bool isLoad_, PacketDataPtr data_, uint64_t *res_) :
-    LSQRequest(port_, inst_, isLoad_, data_, res_),
+    LSQRequest(port_, inst_, isLoad_, port_.zeroReg, data_, res_),
     translationEvent([this]{ sendNextFragmentToTranslation(); },
                      "translationEvent"),
     numFragments(0),
@@ -1127,7 +1128,7 @@
         SimpleThread &thread = *cpu.threads[request->inst->id.threadId];

         TheISA::PCState old_pc = thread.pcState();
-        ExecContext context(cpu, thread, execute, request->inst);
+        ExecContext context(cpu, thread, execute, request->inst, zeroReg);

         /* Handle LLSC requests and tests */
         if (is_load) {
@@ -1401,10 +1402,12 @@
     unsigned int in_memory_system_limit, unsigned int line_width,
     unsigned int requests_queue_size, unsigned int transfers_queue_size,
     unsigned int store_buffer_size,
-    unsigned int store_buffer_cycle_store_limit) :
+    unsigned int store_buffer_cycle_store_limit,
+    RegIndex zero_reg) :
     Named(name_),
     cpu(cpu_),
     execute(execute_),
+    zeroReg(zero_reg),
     dcachePort(dcache_port_name_, *this, cpu_),
     lastMemBarrier(cpu.numThreads, 0),
     state(MemoryRunning),
diff --git a/src/cpu/minor/lsq.hh b/src/cpu/minor/lsq.hh
index 1174883..233400c 100644
--- a/src/cpu/minor/lsq.hh
+++ b/src/cpu/minor/lsq.hh
@@ -67,6 +67,8 @@
     MinorCPU &cpu;
     Execute &execute;

+    RegIndex zeroReg;
+
   protected:
     /** State of memory access for head access. */
     enum MemoryState
@@ -127,6 +129,8 @@
         /** Owning port */
         LSQ &port;

+        RegIndex zeroReg;
+
         /** Instruction which made this request */
         MinorDynInstPtr inst;

@@ -199,7 +203,8 @@

       public:
         LSQRequest(LSQ &port_, MinorDynInstPtr inst_, bool isLoad_,
-            PacketDataPtr data_ = NULL, uint64_t *res_ = NULL);
+                RegIndex zero_reg, PacketDataPtr data_ = NULL,
+                uint64_t *res_ = NULL);

         virtual ~LSQRequest();

@@ -309,7 +314,7 @@
       public:
         SpecialDataRequest(LSQ &port_, MinorDynInstPtr inst_) :
             /* Say this is a load, not actually relevant */
-            LSQRequest(port_, inst_, true, NULL, 0)
+            LSQRequest(port_, inst_, true, port_.zeroReg, NULL, 0)
         { }
     };

@@ -376,7 +381,7 @@
       public:
         SingleDataRequest(LSQ &port_, MinorDynInstPtr inst_,
bool isLoad_, PacketDataPtr data_ = NULL, uint64_t *res_ = NULL) :
-            LSQRequest(port_, inst_, isLoad_, data_, res_),
+            LSQRequest(port_, inst_, isLoad_, port_.zeroReg, data_, res_),
             packetInFlight(false),
             packetSent(false)
         { }
@@ -646,7 +651,8 @@
unsigned int max_accesses_in_memory_system, unsigned int line_width, unsigned int requests_queue_size, unsigned int transfers_queue_size,
         unsigned int store_buffer_size,
-        unsigned int store_buffer_cycle_store_limit);
+        unsigned int store_buffer_cycle_store_limit,
+        RegIndex zeroReg);

     virtual ~LSQ();

diff --git a/src/cpu/minor/scoreboard.cc b/src/cpu/minor/scoreboard.cc
index 5f8df87..33b6b40 100644
--- a/src/cpu/minor/scoreboard.cc
+++ b/src/cpu/minor/scoreboard.cc
@@ -52,7 +52,7 @@

     switch (reg.classValue()) {
       case IntRegClass:
-        if (reg.index() == TheISA::ZeroReg) {
+        if (reg.index() == zeroReg) {
             /* Don't bother with the zero register */
             ret = false;
         } else {
@@ -132,9 +132,8 @@
                 " regIndex: %d final numResults: %d returnCycle: %d\n",
                 *inst, index, numResults[index], returnCycle[index]);
         } else {
-            /* Use ZeroReg to mark invalid/untracked dests */
-            inst->flatDestRegIdx[dest_index] = RegId(IntRegClass,
-                                                     TheISA::ZeroReg);
+            /* Use zeroReg to mark invalid/untracked dests */
+            inst->flatDestRegIdx[dest_index] = RegId(IntRegClass, zeroReg);
         }
     }
 }
diff --git a/src/cpu/minor/scoreboard.hh b/src/cpu/minor/scoreboard.hh
index 1e4b1f1..22c8bf0 100644
--- a/src/cpu/minor/scoreboard.hh
+++ b/src/cpu/minor/scoreboard.hh
@@ -77,6 +77,8 @@
      *  [NumIntRegs+NumCCRegs, NumFloatRegs+NumIntRegs+NumCCRegs-1] */
     const unsigned numRegs;

+    const RegIndex zeroReg;
+
     /** Type to use when indexing numResults */
     typedef unsigned short int Index;

@@ -111,6 +113,7 @@
         vecRegOffset(ccRegOffset + reg_classes.at(CCRegClass).size()),
vecPredRegOffset(vecRegOffset + reg_classes.at(VecElemClass).size()),
         numRegs(vecPredRegOffset + reg_classes.at(VecPredRegClass).size()),
+        zeroReg(reg_classes.at(IntRegClass).zeroReg()),
         numResults(numRegs, 0),
         numUnpredictableResults(numRegs, 0),
         fuIndices(numRegs, 0),
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index ace3b73..d733eb2 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -95,15 +95,15 @@
               params.numPhysVecRegs,
               params.numPhysVecPredRegs,
               params.numPhysCCRegs,
-              params.isa[0]->regClasses().at(MiscRegClass).size(),
+              params.isa[0]->regClasses(),
               vecMode),

       freeList(name() + ".freelist", &regFile),

       rob(this, params),

-      scoreboard(name() + ".scoreboard",
-                 regFile.totalNumPhysRegs()),
+      scoreboard(name() + ".scoreboard", regFile.totalNumPhysRegs(),
+              params.isa[0]->regClasses().at(IntRegClass).zeroReg()),

       isa(numThreads, NULL),

@@ -225,16 +225,8 @@
         assert(isa[tid]);
         assert(RenameMode<TheISA::ISA>::equalsInit(isa[tid], isa[0]));

-        // Only Alpha has an FP zero register, so for other ISAs we
-        // use an invalid FP register index to avoid special treatment
-        // of any valid FP reg.
-        RegIndex invalidFPReg = regClasses.at(FloatRegClass).size() + 1;
-
-        commitRenameMap[tid].init(regClasses, &regFile, TheISA::ZeroReg,
-                invalidFPReg, &freeList, vecMode);
-
-        renameMap[tid].init(regClasses, &regFile, TheISA::ZeroReg,
-                invalidFPReg, &freeList, vecMode);
+ commitRenameMap[tid].init(regClasses, &regFile, &freeList, vecMode);
+        renameMap[tid].init(regClasses, &regFile, &freeList, vecMode);
     }

     // Initialize rename map to assign physical registers to the
diff --git a/src/cpu/o3/probe/elastic_trace.cc b/src/cpu/o3/probe/elastic_trace.cc
index b48504a..d7b07fe 100644
--- a/src/cpu/o3/probe/elastic_trace.cc
+++ b/src/cpu/o3/probe/elastic_trace.cc
@@ -58,6 +58,10 @@
        stats(this)
 {
     cpu = dynamic_cast<FullO3CPU<O3CPUImpl>*>(params.manager);
+    const BaseISA::RegClasses &regClasses =
+        cpu->getContext(0)->getIsaPtr()->regClasses();
+    zeroReg = regClasses.at(IntRegClass).zeroReg();
+
     fatal_if(!cpu, "Manager of %s is not of type O3CPU and thus does not "\
                 "support dependency tracing.\n", name());

@@ -241,7 +245,7 @@

         const RegId& src_reg = dyn_inst->srcRegIdx(src_idx);
         if (!src_reg.isMiscReg() &&
- !(src_reg.isIntReg() && src_reg.index() == TheISA::ZeroReg)) {
+                !(src_reg.isIntReg() && src_reg.index() == zeroReg)) {
             // Get the physical register index of the i'th source register.
PhysRegIdPtr phys_src_reg = dyn_inst->regs.renamedSrcIdx(src_idx);
             DPRINTFR(ElasticTrace, "[sn:%lli] Check map for src reg"
@@ -273,8 +277,7 @@
         // CC register and not a Misc register.
         const RegId& dest_reg = dyn_inst->destRegIdx(dest_idx);
         if (!dest_reg.isMiscReg() &&
-                !(dest_reg.isIntReg() &&
-                    dest_reg.index() == TheISA::ZeroReg)) {
+                !(dest_reg.isIntReg() && dest_reg.index() == zeroReg)) {
             // Get the physical register index of the i'th destination
             // register.
             PhysRegIdPtr phys_dest_reg =
diff --git a/src/cpu/o3/probe/elastic_trace.hh b/src/cpu/o3/probe/elastic_trace.hh
index 1c44873..2673482 100644
--- a/src/cpu/o3/probe/elastic_trace.hh
+++ b/src/cpu/o3/probe/elastic_trace.hh
@@ -186,6 +186,8 @@
      */
     bool firstWin;

+    RegIndex zeroReg;
+
     /**
      * @defgroup InstExecInfo Struct for storing information before an
      * instruction reaches the commit stage, e.g. execute timestamp.
diff --git a/src/cpu/o3/regfile.cc b/src/cpu/o3/regfile.cc
index fa08191..bfdb621 100644
--- a/src/cpu/o3/regfile.cc
+++ b/src/cpu/o3/regfile.cc
@@ -50,7 +50,7 @@
                          unsigned _numPhysicalVecRegs,
                          unsigned _numPhysicalVecPredRegs,
                          unsigned _numPhysicalCCRegs,
-                         unsigned _numPhysicalMiscRegs,
+                         const BaseISA::RegClasses &regClasses,
                          VecMode vmode)
     : intRegFile(_numPhysicalIntRegs),
       floatRegFile(_numPhysicalFloatRegs),
@@ -80,6 +80,8 @@
         intRegIds.emplace_back(IntRegClass, phys_reg, flat_reg_idx++);
     }

+    zeroReg = RegId(IntRegClass, regClasses.at(IntRegClass).zeroReg());
+
     // The next batch of the registers are the floating-point physical
     // registers; put them onto the floating-point free list.
     for (phys_reg = 0; phys_reg < numPhysicalFloatRegs; phys_reg++) {
@@ -116,7 +118,8 @@
     }

     // Misc regs have a fixed mapping but still need PhysRegIds.
-    for (phys_reg = 0; phys_reg < _numPhysicalMiscRegs; phys_reg++) {
+    for (phys_reg = 0; phys_reg < regClasses.at(MiscRegClass).size();
+            phys_reg++) {
         miscRegIds.emplace_back(MiscRegClass, phys_reg, 0);
     }
 }
diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh
index adfa326..a95f93b 100644
--- a/src/cpu/o3/regfile.hh
+++ b/src/cpu/o3/regfile.hh
@@ -69,6 +69,7 @@
     /** Integer register file. */
     std::vector<RegVal> intRegFile;
     std::vector<PhysRegId> intRegIds;
+    RegId zeroReg;

     /** Floating point register file. */
     std::vector<RegVal> floatRegFile;
@@ -136,7 +137,7 @@
                 unsigned _numPhysicalVecRegs,
                 unsigned _numPhysicalVecPredRegs,
                 unsigned _numPhysicalCCRegs,
-                unsigned _numPhysicalMiscRegs,
+                const BaseISA::RegClasses &regClasses,
                 VecMode vmode
                 );

@@ -274,7 +275,7 @@
         DPRINTF(IEW, "RegFile: Setting int register %i to %#x\n",
                 phys_reg->index(), val);

-        if (phys_reg->index() != TheISA::ZeroReg)
+        if (phys_reg->index() != zeroReg.index())
             intRegFile[phys_reg->index()] = val;
     }

diff --git a/src/cpu/o3/rename_map.cc b/src/cpu/o3/rename_map.cc
index e26ef9b..d42bdee 100644
--- a/src/cpu/o3/rename_map.cc
+++ b/src/cpu/o3/rename_map.cc
@@ -57,14 +57,14 @@

 void
 SimpleRenameMap::init(const RegClassInfo &reg_class_info,
-        SimpleFreeList *_freeList, RegIndex _zeroReg)
+        SimpleFreeList *_freeList)
 {
     assert(freeList == NULL);
     assert(map.empty());

     map.resize(reg_class_info.size());
     freeList = _freeList;
-    zeroReg = RegId(IntRegClass, _zeroReg);
+    zeroReg = RegId(IntRegClass, reg_class_info.zeroReg());
 }

 SimpleRenameMap::RenameInfo
@@ -76,7 +76,7 @@
     PhysRegIdPtr prev_reg = map[arch_reg.flatIndex()];

     if (arch_reg == zeroReg) {
-        assert(prev_reg->index() == TheISA::ZeroReg);
+        assert(prev_reg->index() == zeroReg.index());
         renamed_reg = prev_reg;
     } else if (prev_reg->getNumPinnedWrites() > 0) {
         // Do not rename if the register is pinned
@@ -107,30 +107,17 @@

 void
 UnifiedRenameMap::init(const BaseISA::RegClasses &regClasses,
-                       PhysRegFile *_regFile,
-                       RegIndex _intZeroReg,
-                       RegIndex _floatZeroReg,
-                       UnifiedFreeList *freeList,
-                       VecMode _mode)
+        PhysRegFile *_regFile, UnifiedFreeList *freeList, VecMode _mode)
 {
     regFile = _regFile;
     vecMode = _mode;

- intMap.init(regClasses.at(IntRegClass), &(freeList->intList), _intZeroReg);
-
-    floatMap.init(regClasses.at(FloatRegClass), &(freeList->floatList),
-            _floatZeroReg);
-
-    vecMap.init(regClasses.at(VecRegClass), &(freeList->vecList),
-            (RegIndex)-1);
-
-    vecElemMap.init(regClasses.at(VecElemClass), &(freeList->vecElemList),
-            (RegIndex)-1);
-
-    predMap.init(regClasses.at(VecPredRegClass), &(freeList->predList),
-            (RegIndex)-1);
-
- ccMap.init(regClasses.at(CCRegClass), &(freeList->ccList), (RegIndex)-1);
+    intMap.init(regClasses.at(IntRegClass), &(freeList->intList));
+    floatMap.init(regClasses.at(FloatRegClass), &(freeList->floatList));
+    vecMap.init(regClasses.at(VecRegClass), &(freeList->vecList));
+    vecElemMap.init(regClasses.at(VecElemClass), &(freeList->vecElemList));
+    predMap.init(regClasses.at(VecPredRegClass), &(freeList->predList));
+    ccMap.init(regClasses.at(CCRegClass), &(freeList->ccList));

 }

diff --git a/src/cpu/o3/rename_map.hh b/src/cpu/o3/rename_map.hh
index 5f779bd..861f496 100644
--- a/src/cpu/o3/rename_map.hh
+++ b/src/cpu/o3/rename_map.hh
@@ -95,8 +95,7 @@
      * it's awkward to initialize this object via the constructor.
      * Instead, this method is used for initialization.
      */
- void init(const RegClassInfo &reg_class_info, SimpleFreeList *_freeList,
-            RegIndex _zeroReg);
+ void init(const RegClassInfo &reg_class_info, SimpleFreeList *_freeList);

     /**
      * Pair of a physical register and a physical register.  Used to
@@ -209,11 +208,7 @@

     /** Initializes rename map with given parameters. */
     void init(const BaseISA::RegClasses &regClasses,
-              PhysRegFile *_regFile,
-              RegIndex _intZeroReg,
-              RegIndex _floatZeroReg,
-              UnifiedFreeList *freeList,
-              VecMode _mode);
+ PhysRegFile *_regFile, UnifiedFreeList *freeList, VecMode _mode);

     /**
      * Tell rename map to get a new free physical register to remap
diff --git a/src/cpu/o3/scoreboard.cc b/src/cpu/o3/scoreboard.cc
index 2712035..269bf88 100644
--- a/src/cpu/o3/scoreboard.cc
+++ b/src/cpu/o3/scoreboard.cc
@@ -29,10 +29,8 @@

 #include "cpu/o3/scoreboard.hh"

-Scoreboard::Scoreboard(const std::string &_my_name,
-                       unsigned _numPhysicalRegs)
-    : _name(_my_name),
-      regScoreBoard(_numPhysicalRegs, true),
-      numPhysRegs(_numPhysicalRegs)
-{
-}
+Scoreboard::Scoreboard(const std::string &_my_name, unsigned _numPhysicalRegs,
+        RegIndex zero_reg) :
+ _name(_my_name), zeroReg(zero_reg), regScoreBoard(_numPhysicalRegs, true),
+    numPhysRegs(_numPhysicalRegs)
+{}
diff --git a/src/cpu/o3/scoreboard.hh b/src/cpu/o3/scoreboard.hh
index 1873116..cf32d3e 100644
--- a/src/cpu/o3/scoreboard.hh
+++ b/src/cpu/o3/scoreboard.hh
@@ -50,6 +50,8 @@
      *  explicitly because Scoreboard is not a SimObject. */
     const std::string _name;

+    RegIndex zeroReg;
+
/** Scoreboard of physical integer registers, saying whether or not they
      *  are ready. */
     std::vector<bool> regScoreBoard;
@@ -62,8 +64,8 @@
      *  @param _numPhysicalRegs Number of physical registers.
      *  @param _numMiscRegs Number of miscellaneous registers.
      */
-    Scoreboard(const std::string &_my_name,
-               unsigned _numPhysicalRegs);
+    Scoreboard(const std::string &_my_name, unsigned _numPhysicalRegs,
+               RegIndex _zero_reg);

     /** Destructor. */
     ~Scoreboard() {}
@@ -84,7 +86,7 @@

         bool ready = regScoreBoard[phys_reg->flatIndex()];

- if (phys_reg->isIntPhysReg() && phys_reg->index() == TheISA::ZeroReg)
+        if (phys_reg->isIntPhysReg() && phys_reg->index() == zeroReg)
             assert(ready);

         return ready;
@@ -121,7 +123,7 @@
         }

         // zero reg should never be marked unready
- if (phys_reg->isIntPhysReg() && phys_reg->index() == TheISA::ZeroReg)
+        if (phys_reg->isIntPhysReg() && phys_reg->index() == zeroReg)
             return;

         regScoreBoard[phys_reg->flatIndex()] = false;
diff --git a/src/cpu/reg_class.hh b/src/cpu/reg_class.hh
index 292131e..740f9ee 100644
--- a/src/cpu/reg_class.hh
+++ b/src/cpu/reg_class.hh
@@ -65,11 +65,15 @@
 {
   private:
     size_t _size;
+    RegIndex _zeroReg;

   public:
-    RegClassInfo(size_t new_size) : _size(new_size) {}
+    RegClassInfo(size_t new_size, RegIndex new_zero = -1) :
+        _size(new_size), _zeroReg(new_zero)
+    {}

     size_t size() const { return _size; }
+    RegIndex zeroReg() const { return _zeroReg; }
 };

 /** Number of register classes.
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index 0941388..19ed909 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -81,6 +81,7 @@
     : BaseCPU(p),
       curThread(0),
       branchPred(p.branchPred),
+      zeroReg(p.isa[0]->regClasses().at(IntRegClass).zeroReg()),
       traceData(NULL),
       inst(),
       _status(Idle)
@@ -308,7 +309,7 @@
     SimpleThread* thread = t_info.thread;

     // maintain $r0 semantics
-    thread->setIntReg(TheISA::ZeroReg, 0);
+    thread->setIntReg(zeroReg, 0);

     // resets predicates
     t_info.setPredicate(true);
diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh
index 4305e0e..d6601b6 100644
--- a/src/cpu/simple/base.hh
+++ b/src/cpu/simple/base.hh
@@ -83,6 +83,8 @@
     ThreadID curThread;
     BPredUnit *branchPred;

+    RegIndex zeroReg;
+
     void checkPcEventQueue();
     void swapActiveThread();


--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/42685
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I4302a53220dd5ff6b9b47ecc765bddc6698310ca
Gerrit-Change-Number: 42685
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to