Hello Andreas Sandberg,
I'd like you to do a code review. Please visit
https://gem5-review.googlesource.com/2701
to review the following change.
Change subject: cpu: Physical register structural + flat indexing
......................................................................
cpu: Physical register structural + flat indexing
Mimic the changes done on the architectural register indexes on the
physical register indexes. This is specific to the O3 model. The
structure, called PhysRegId, contains a register class, a register
index and a flat register index. The flat register index is kept
because it is useful in some cases where the type of register is not
important (dependency graph and scoreboard for example). Instead
of directly using the structure, most of the code is working with
a const PhysRegId* (typedef to PhysRegIdPtr). The actual PhysRegId
objects are stored in the regFile.
Change-Id: Ic879a3cc608aa2f34e2168280faac1846de77667
Reviewed-by: Andreas Sandberg <[email protected]>
---
M src/cpu/base_dyn_inst.hh
M src/cpu/o3/comm.hh
M src/cpu/o3/cpu.cc
M src/cpu/o3/cpu.hh
M src/cpu/o3/dyn_inst.hh
M src/cpu/o3/dyn_inst_impl.hh
M src/cpu/o3/free_list.hh
M src/cpu/o3/iew_impl.hh
M src/cpu/o3/inst_queue_impl.hh
M src/cpu/o3/probe/elastic_trace.cc
M src/cpu/o3/regfile.cc
M src/cpu/o3/regfile.hh
M src/cpu/o3/rename.hh
M src/cpu/o3/rename_impl.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
18 files changed, 384 insertions(+), 377 deletions(-)
diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh
index 84a6540..369d7a0 100644
--- a/src/cpu/base_dyn_inst.hh
+++ b/src/cpu/base_dyn_inst.hh
@@ -267,17 +267,17 @@
/** Physical register index of the destination registers of this
* instruction.
*/
- std::array<PhysRegIndex, TheISA::MaxInstDestRegs> _destRegIdx;
+ std::array<PhysRegIdPtr, TheISA::MaxInstDestRegs> _destRegIdx;
/** Physical register index of the source registers of this
* instruction.
*/
- std::array<PhysRegIndex, TheISA::MaxInstSrcRegs> _srcRegIdx;
+ std::array<PhysRegIdPtr, TheISA::MaxInstSrcRegs> _srcRegIdx;
/** Physical register index of the previous producers of the
* architected destinations.
*/
- std::array<PhysRegIndex, TheISA::MaxInstDestRegs> _prevDestRegIdx;
+ std::array<PhysRegIdPtr, TheISA::MaxInstDestRegs> _prevDestRegIdx;
public:
@@ -368,13 +368,13 @@
/** Returns the physical register index of the i'th destination
* register.
*/
- PhysRegIndex renamedDestRegIdx(int idx) const
+ PhysRegIdPtr renamedDestRegIdx(int idx) const
{
return _destRegIdx[idx];
}
/** Returns the physical register index of the i'th source register. */
- PhysRegIndex renamedSrcRegIdx(int idx) const
+ PhysRegIdPtr renamedSrcRegIdx(int idx) const
{
assert(TheISA::MaxInstSrcRegs > idx);
return _srcRegIdx[idx];
@@ -391,7 +391,7 @@
/** Returns the physical register index of the previous physical
register
* that remapped to the same logical register index.
*/
- PhysRegIndex prevDestRegIdx(int idx) const
+ PhysRegIdPtr prevDestRegIdx(int idx) const
{
return _prevDestRegIdx[idx];
}
@@ -400,8 +400,8 @@
* the previous physical register that the logical register mapped to.
*/
void renameDestReg(int idx,
- PhysRegIndex renamed_dest,
- PhysRegIndex previous_rename)
+ PhysRegIdPtr renamed_dest,
+ PhysRegIdPtr previous_rename)
{
_destRegIdx[idx] = renamed_dest;
_prevDestRegIdx[idx] = previous_rename;
@@ -411,7 +411,7 @@
* has/will produce that logical register's result.
* @todo: add in whether or not the source register is ready.
*/
- void renameSrcReg(int idx, PhysRegIndex renamed_src)
+ void renameSrcReg(int idx, PhysRegIdPtr renamed_src)
{
_srcRegIdx[idx] = renamed_src;
}
diff --git a/src/cpu/o3/comm.hh b/src/cpu/o3/comm.hh
index 4da2511..c5f1c01 100644
--- a/src/cpu/o3/comm.hh
+++ b/src/cpu/o3/comm.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 ARM Limited
+ * Copyright (c) 2011, 2016 ARM Limited
* Copyright (c) 2013 Advanced Micro Devices, Inc.
* All rights reserved
*
@@ -39,6 +39,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Kevin Lim
+ * Nathanael Premillieu
*/
#ifndef __CPU_O3_COMM_HH__
@@ -55,6 +56,57 @@
// 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;
+ PhysRegIndex flatIdx;
+ PhysRegId(RegClass _regClass, PhysRegIndex _regIdx,
+ PhysRegIndex _flatIdx)
+ : regClass(_regClass), regIdx(_regIdx), flatIdx(_flatIdx)
+ {}
+
+ bool operator==(const PhysRegId& that) const {
+ return regClass == that.regClass && regIdx == that.regIdx;
+ }
+
+ bool operator!=(const PhysRegId& that) const {
+ return !(*this==that);
+ }
+
+ bool isZeroReg() const
+ {
+ return (regIdx == TheISA::ZeroReg &&
+ (regClass == IntRegClass ||
+ (THE_ISA == ALPHA_ISA && regClass == FloatRegClass)));
+ }
+
+ /** @return true if it is an integer physical register. */
+ bool isIntPhysReg() const { return regClass == IntRegClass; }
+
+ /** @return true if it is a floating-point physical register. */
+ bool isFloatPhysReg() const { return regClass == FloatRegClass; }
+
+ /** @Return true if it is a condition-code physical register. */
+ bool isCCPhysReg() const { return regClass == CCRegClass; }
+
+ /**
+ * Returns true if this register is always associated to the same
+ * architectural register.
+ */
+ bool isFixedMapping() const
+ {
+ return regClass == MiscRegClass;
+ }
+};
+
+// PhysRegIds only need to be created once and then we can use the
following
+// to work with them
+typedef const PhysRegId* PhysRegIdPtr;
/** Struct that defines the information passed from fetch to decode. */
template<class Impl>
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index a2d8147..6e9accd 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -180,8 +180,7 @@
rob(this, params),
scoreboard(name() + ".scoreboard",
- regFile.totalNumPhysRegs(), TheISA::NumMiscRegs,
- TheISA::ZeroReg, TheISA::ZeroReg),
+ regFile.totalNumPhysRegs()),
isa(numThreads, NULL),
@@ -300,19 +299,19 @@
for (RegIndex ridx = 0; ridx < TheISA::NumIntRegs; ++ridx) {
// Note that we can't use the rename() method because we don't
// want special treatment for the zero register at this point
- PhysRegIndex phys_reg = freeList.getIntReg();
+ PhysRegIdPtr phys_reg = freeList.getIntReg();
renameMap[tid].setIntEntry(ridx, phys_reg);
commitRenameMap[tid].setIntEntry(ridx, phys_reg);
}
for (RegIndex ridx = 0; ridx < TheISA::NumFloatRegs; ++ridx) {
- PhysRegIndex phys_reg = freeList.getFloatReg();
+ PhysRegIdPtr phys_reg = freeList.getFloatReg();
renameMap[tid].setFloatEntry(ridx, phys_reg);
commitRenameMap[tid].setFloatEntry(ridx, phys_reg);
}
for (RegIndex ridx = 0; ridx < TheISA::NumCCRegs; ++ridx) {
- PhysRegIndex phys_reg = freeList.getCCReg();
+ PhysRegIdPtr phys_reg = freeList.getCCReg();
renameMap[tid].setCCEntry(ridx, phys_reg);
commitRenameMap[tid].setCCEntry(ridx, phys_reg);
}
@@ -791,7 +790,7 @@
for (RegId reg_id(IntRegClass, 0); reg_id.regIdx < TheISA::NumIntRegs;
reg_id.regIdx++) {
- PhysRegIndex phys_reg = freeList.getIntReg();
+ PhysRegIdPtr phys_reg = freeList.getIntReg();
renameMap[tid].setEntry(reg_id, phys_reg);
scoreboard.setReg(phys_reg);
}
@@ -799,7 +798,7 @@
//Bind Float Regs to Rename Map
for (RegId reg_id(FloatRegClass, 0); reg_id.regIdx <
TheISA::NumFloatRegs;
reg_id.regIdx++) {
- PhysRegIndex phys_reg = freeList.getFloatReg();
+ PhysRegIdPtr phys_reg = freeList.getFloatReg();
renameMap[tid].setEntry(reg_id, phys_reg);
scoreboard.setReg(phys_reg);
}
@@ -807,7 +806,7 @@
//Bind condition-code Regs to Rename Map
for (RegId reg_id(CCRegClass, 0); reg_id.regIdx < TheISA::NumCCRegs;
reg_id.regIdx++) {
- PhysRegIndex phys_reg = freeList.getCCReg();
+ PhysRegIdPtr phys_reg = freeList.getCCReg();
renameMap[tid].setEntry(reg_id, phys_reg);
scoreboard.setReg(phys_reg);
}
@@ -845,7 +844,7 @@
// Unbind Int Regs from Rename Map
for (RegId reg_id(IntRegClass, 0); reg_id.regIdx < TheISA::NumIntRegs;
reg_id.regIdx++) {
- PhysRegIndex phys_reg = renameMap[tid].lookup(reg_id);
+ PhysRegIdPtr phys_reg = renameMap[tid].lookup(reg_id);
scoreboard.unsetReg(phys_reg);
freeList.addReg(phys_reg);
}
@@ -853,7 +852,7 @@
// Unbind Float Regs from Rename Map
for (RegId reg_id(FloatRegClass, 0); reg_id.regIdx <
TheISA::NumFloatRegs;
reg_id.regIdx++) {
- PhysRegIndex phys_reg = renameMap[tid].lookup(reg_id);
+ PhysRegIdPtr phys_reg = renameMap[tid].lookup(reg_id);
scoreboard.unsetReg(phys_reg);
freeList.addReg(phys_reg);
}
@@ -861,7 +860,7 @@
// Unbind condition-code Regs from Rename Map
for (RegId reg_id(CCRegClass, 0); reg_id.regIdx < TheISA::NumCCRegs;
reg_id.regIdx++) {
- PhysRegIndex phys_reg = renameMap[tid].lookup(reg_id);
+ PhysRegIdPtr phys_reg = renameMap[tid].lookup(reg_id);
scoreboard.unsetReg(phys_reg);
freeList.addReg(phys_reg);
}
@@ -1234,66 +1233,66 @@
template <class Impl>
uint64_t
-FullO3CPU<Impl>::readIntReg(int reg_idx)
+FullO3CPU<Impl>::readIntReg(PhysRegIdPtr phys_reg)
{
intRegfileReads++;
- return regFile.readIntReg(reg_idx);
+ return regFile.readIntReg(phys_reg);
}
template <class Impl>
FloatReg
-FullO3CPU<Impl>::readFloatReg(int reg_idx)
+FullO3CPU<Impl>::readFloatReg(PhysRegIdPtr phys_reg)
{
fpRegfileReads++;
- return regFile.readFloatReg(reg_idx);
+ return regFile.readFloatReg(phys_reg);
}
template <class Impl>
FloatRegBits
-FullO3CPU<Impl>::readFloatRegBits(int reg_idx)
+FullO3CPU<Impl>::readFloatRegBits(PhysRegIdPtr phys_reg)
{
fpRegfileReads++;
- return regFile.readFloatRegBits(reg_idx);
+ return regFile.readFloatRegBits(phys_reg);
}
template <class Impl>
CCReg
-FullO3CPU<Impl>::readCCReg(int reg_idx)
+FullO3CPU<Impl>::readCCReg(PhysRegIdPtr phys_reg)
{
ccRegfileReads++;
- return regFile.readCCReg(reg_idx);
+ return regFile.readCCReg(phys_reg);
}
template <class Impl>
void
-FullO3CPU<Impl>::setIntReg(int reg_idx, uint64_t val)
+FullO3CPU<Impl>::setIntReg(PhysRegIdPtr phys_reg, uint64_t val)
{
intRegfileWrites++;
- regFile.setIntReg(reg_idx, val);
+ regFile.setIntReg(phys_reg, val);
}
template <class Impl>
void
-FullO3CPU<Impl>::setFloatReg(int reg_idx, FloatReg val)
+FullO3CPU<Impl>::setFloatReg(PhysRegIdPtr phys_reg, FloatReg val)
{
fpRegfileWrites++;
- regFile.setFloatReg(reg_idx, val);
+ regFile.setFloatReg(phys_reg, val);
}
template <class Impl>
void
-FullO3CPU<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val)
+FullO3CPU<Impl>::setFloatRegBits(PhysRegIdPtr phys_reg, FloatRegBits val)
{
fpRegfileWrites++;
- regFile.setFloatRegBits(reg_idx, val);
+ regFile.setFloatRegBits(phys_reg, val);
}
template <class Impl>
void
-FullO3CPU<Impl>::setCCReg(int reg_idx, CCReg val)
+FullO3CPU<Impl>::setCCReg(PhysRegIdPtr phys_reg, CCReg val)
{
ccRegfileWrites++;
- regFile.setCCReg(reg_idx, val);
+ regFile.setCCReg(phys_reg, val);
}
template <class Impl>
@@ -1301,7 +1300,7 @@
FullO3CPU<Impl>::readArchIntReg(int reg_idx, ThreadID tid)
{
intRegfileReads++;
- PhysRegIndex phys_reg = commitRenameMap[tid].lookupInt(reg_idx);
+ PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupInt(reg_idx);
return regFile.readIntReg(phys_reg);
}
@@ -1311,7 +1310,7 @@
FullO3CPU<Impl>::readArchFloatReg(int reg_idx, ThreadID tid)
{
fpRegfileReads++;
- PhysRegIndex phys_reg = commitRenameMap[tid].lookupFloat(reg_idx);
+ PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupFloat(reg_idx);
return regFile.readFloatReg(phys_reg);
}
@@ -1321,7 +1320,7 @@
FullO3CPU<Impl>::readArchFloatRegInt(int reg_idx, ThreadID tid)
{
fpRegfileReads++;
- PhysRegIndex phys_reg = commitRenameMap[tid].lookupFloat(reg_idx);
+ PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupFloat(reg_idx);
return regFile.readFloatRegBits(phys_reg);
}
@@ -1331,7 +1330,7 @@
FullO3CPU<Impl>::readArchCCReg(int reg_idx, ThreadID tid)
{
ccRegfileReads++;
- PhysRegIndex phys_reg = commitRenameMap[tid].lookupCC(reg_idx);
+ PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupCC(reg_idx);
return regFile.readCCReg(phys_reg);
}
@@ -1341,7 +1340,7 @@
FullO3CPU<Impl>::setArchIntReg(int reg_idx, uint64_t val, ThreadID tid)
{
intRegfileWrites++;
- PhysRegIndex phys_reg = commitRenameMap[tid].lookupInt(reg_idx);
+ PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupInt(reg_idx);
regFile.setIntReg(phys_reg, val);
}
@@ -1351,7 +1350,7 @@
FullO3CPU<Impl>::setArchFloatReg(int reg_idx, float val, ThreadID tid)
{
fpRegfileWrites++;
- PhysRegIndex phys_reg = commitRenameMap[tid].lookupFloat(reg_idx);
+ PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupFloat(reg_idx);
regFile.setFloatReg(phys_reg, val);
}
@@ -1361,7 +1360,7 @@
FullO3CPU<Impl>::setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID
tid)
{
fpRegfileWrites++;
- PhysRegIndex phys_reg = commitRenameMap[tid].lookupFloat(reg_idx);
+ PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupFloat(reg_idx);
regFile.setFloatRegBits(phys_reg, val);
}
@@ -1371,7 +1370,7 @@
FullO3CPU<Impl>::setArchCCReg(int reg_idx, CCReg val, ThreadID tid)
{
ccRegfileWrites++;
- PhysRegIndex phys_reg = commitRenameMap[tid].lookupCC(reg_idx);
+ PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupCC(reg_idx);
regFile.setCCReg(phys_reg, val);
}
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index abe036b..b5cbc5f 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -411,21 +411,21 @@
void setMiscReg(int misc_reg, const TheISA::MiscReg &val,
ThreadID tid);
- uint64_t readIntReg(int reg_idx);
+ uint64_t readIntReg(PhysRegIdPtr phys_reg);
- TheISA::FloatReg readFloatReg(int reg_idx);
+ TheISA::FloatReg readFloatReg(PhysRegIdPtr phys_reg);
- TheISA::FloatRegBits readFloatRegBits(int reg_idx);
+ TheISA::FloatRegBits readFloatRegBits(PhysRegIdPtr phys_reg);
- TheISA::CCReg readCCReg(int reg_idx);
+ TheISA::CCReg readCCReg(PhysRegIdPtr phys_reg);
- void setIntReg(int reg_idx, uint64_t val);
+ void setIntReg(PhysRegIdPtr phys_reg, uint64_t val);
- void setFloatReg(int reg_idx, TheISA::FloatReg val);
+ void setFloatReg(PhysRegIdPtr phys_reg, TheISA::FloatReg val);
- void setFloatRegBits(int reg_idx, TheISA::FloatRegBits val);
+ void setFloatRegBits(PhysRegIdPtr phys_reg, TheISA::FloatRegBits val);
- void setCCReg(int reg_idx, TheISA::CCReg val);
+ void setCCReg(PhysRegIdPtr phys_reg, TheISA::CCReg val);
uint64_t readArchIntReg(int reg_idx, ThreadID tid);
diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh
index 3096e59..b200a32 100644
--- a/src/cpu/o3/dyn_inst.hh
+++ b/src/cpu/o3/dyn_inst.hh
@@ -207,7 +207,7 @@
{
for (int idx = 0; idx < this->numDestRegs(); idx++) {
- PhysRegIndex prev_phys_reg = this->prevDestRegIdx(idx);
+ PhysRegIdPtr prev_phys_reg = this->prevDestRegIdx(idx);
RegId original_dest_reg =
this->staticInst->destRegIdx(idx);
switch (original_dest_reg.regClass) {
diff --git a/src/cpu/o3/dyn_inst_impl.hh b/src/cpu/o3/dyn_inst_impl.hh
index f6a42c3..03437a5 100644
--- a/src/cpu/o3/dyn_inst_impl.hh
+++ b/src/cpu/o3/dyn_inst_impl.hh
@@ -106,17 +106,6 @@
void
BaseO3DynInst<Impl>::initVars()
{
- // Make sure to have the renamed register entries set to the same
- // as the normal register entries. It will allow the IQ to work
- // without any modifications.
- for (int i = 0; i < this->staticInst->numDestRegs(); i++) {
- this->_destRegIdx[i] = this->staticInst->destRegIdx(i).regIdx;
- }
-
- for (int i = 0; i < this->staticInst->numSrcRegs(); i++) {
- this->_srcRegIdx[i] = this->staticInst->srcRegIdx(i).regIdx;
- }
-
this->_readySrcRegIdx.reset();
_numDestMiscRegs = 0;
diff --git a/src/cpu/o3/free_list.hh b/src/cpu/o3/free_list.hh
index aa805e2..3e6740e 100644
--- a/src/cpu/o3/free_list.hh
+++ b/src/cpu/o3/free_list.hh
@@ -34,6 +34,7 @@
#include <iostream>
#include <queue>
+#include <vector>
#include "base/misc.hh"
#include "base/trace.hh"
@@ -53,20 +54,20 @@
private:
/** The actual free list */
- std::queue<PhysRegIndex> freeRegs;
+ std::queue<PhysRegIdPtr> freeRegs;
public:
SimpleFreeList() {};
/** Add a physical register to the free list */
- void addReg(PhysRegIndex reg) { freeRegs.push(reg); }
+ void addReg(PhysRegIdPtr reg) { freeRegs.push(reg); }
/** Get the next available register from the free list */
- PhysRegIndex getReg()
+ PhysRegIdPtr getReg()
{
assert(!freeRegs.empty());
- PhysRegIndex free_reg = freeRegs.front();
+ PhysRegIdPtr free_reg = freeRegs.front();
freeRegs.pop();
return free_reg;
}
@@ -140,25 +141,25 @@
SimpleFreeList *getCCList() { return &ccList; }
/** Gets a free integer register. */
- PhysRegIndex getIntReg() { return intList.getReg(); }
+ PhysRegIdPtr getIntReg() { return intList.getReg(); }
/** Gets a free fp register. */
- PhysRegIndex getFloatReg() { return floatList.getReg(); }
+ PhysRegIdPtr getFloatReg() { return floatList.getReg(); }
/** Gets a free cc register. */
- PhysRegIndex getCCReg() { return ccList.getReg(); }
+ PhysRegIdPtr getCCReg() { return ccList.getReg(); }
/** Adds a register back to the free list. */
- void addReg(PhysRegIndex freed_reg);
+ void addReg(PhysRegIdPtr freed_reg);
/** Adds an integer register back to the free list. */
- void addIntReg(PhysRegIndex freed_reg) { intList.addReg(freed_reg); }
+ void addIntReg(PhysRegIdPtr freed_reg) { intList.addReg(freed_reg); }
/** Adds a fp register back to the free list. */
- void addFloatReg(PhysRegIndex freed_reg) {
floatList.addReg(freed_reg); }
+ void addFloatReg(PhysRegIdPtr freed_reg) {
floatList.addReg(freed_reg); }
/** Adds a cc register back to the free list. */
- void addCCReg(PhysRegIndex freed_reg) { ccList.addReg(freed_reg); }
+ void addCCReg(PhysRegIdPtr freed_reg) { ccList.addReg(freed_reg); }
/** Checks if there are any free integer registers. */
bool hasFreeIntRegs() const { return intList.hasFreeRegs(); }
@@ -180,18 +181,25 @@
};
inline void
-UnifiedFreeList::addReg(PhysRegIndex freed_reg)
+UnifiedFreeList::addReg(PhysRegIdPtr freed_reg)
{
- DPRINTF(FreeList,"Freeing register %i.\n", freed_reg);
+ DPRINTF(FreeList,"Freeing register %i (%s).\n", freed_reg->regIdx,
+ RegClassStrings[freed_reg->regClass]);
//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.
- if (regFile->isIntPhysReg(freed_reg)) {
- intList.addReg(freed_reg);
- } else if (regFile->isFloatPhysReg(freed_reg)) {
- floatList.addReg(freed_reg);
- } else {
- assert(regFile->isCCPhysReg(freed_reg));
- ccList.addReg(freed_reg);
+ switch (freed_reg->regClass) {
+ case IntRegClass:
+ intList.addReg(freed_reg);
+ break;
+ case FloatRegClass:
+ floatList.addReg(freed_reg);
+ break;
+ case CCRegClass:
+ ccList.addReg(freed_reg);
+ break;
+ default:
+ panic("Unexpected RegClass (%s)",
+ RegClassStrings[freed_reg->regClass]);
}
// These assert conditions ensure that the number of free
diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh
index 78b83eb..cdb6b26 100644
--- a/src/cpu/o3/iew_impl.hh
+++ b/src/cpu/o3/iew_impl.hh
@@ -1433,8 +1433,9 @@
for (int i = 0; i < inst->numDestRegs(); i++) {
//mark as Ready
- DPRINTF(IEW,"Setting Destination Register %i\n",
- inst->renamedDestRegIdx(i));
+ DPRINTF(IEW,"Setting Destination Register %i (%s)\n",
+ inst->renamedDestRegIdx(i)->regIdx,
+
RegClassStrings[inst->renamedDestRegIdx(i)->regClass]);
scoreboard->setReg(inst->renamedDestRegIdx(i));
}
diff --git a/src/cpu/o3/inst_queue_impl.hh b/src/cpu/o3/inst_queue_impl.hh
index 7352c62..c46fd6b 100644
--- a/src/cpu/o3/inst_queue_impl.hh
+++ b/src/cpu/o3/inst_queue_impl.hh
@@ -979,24 +979,24 @@
dest_reg_idx < completed_inst->numDestRegs();
dest_reg_idx++)
{
- PhysRegIndex dest_reg =
+ PhysRegIdPtr dest_reg =
completed_inst->renamedDestRegIdx(dest_reg_idx);
// Special case of uniq or control registers. They are not
// handled by the IQ and thus have no dependency graph entry.
- // @todo Figure out a cleaner way to handle this.
- if (dest_reg >= numPhysRegs) {
- DPRINTF(IQ, "dest_reg :%d, numPhysRegs: %d\n", dest_reg,
- numPhysRegs);
+ if (dest_reg->isFixedMapping()) {
+ DPRINTF(IQ, "Reg %d [%s] is part of a fix mapping, skipping\n",
+ dest_reg->regIdx, RegClassStrings[dest_reg->regClass]);
continue;
}
- DPRINTF(IQ, "Waking any dependents on register %i.\n",
- (int) dest_reg);
+ DPRINTF(IQ, "Waking any dependents on register %i (%s).\n",
+ dest_reg->regIdx,
+ RegClassStrings[dest_reg->regClass]);
//Go through the dependency chain, marking the registers as
//ready within the waiting instructions.
- DynInstPtr dep_inst = dependGraph.pop(dest_reg);
+ DynInstPtr dep_inst = dependGraph.pop(dest_reg->flatIdx);
while (dep_inst) {
DPRINTF(IQ, "Waking up a dependent instruction, [sn:%lli] "
@@ -1010,18 +1010,18 @@
addIfReady(dep_inst);
- dep_inst = dependGraph.pop(dest_reg);
+ dep_inst = dependGraph.pop(dest_reg->flatIdx);
++dependents;
}
// Reset the head node now that all of its dependents have
// been woken up.
- assert(dependGraph.empty(dest_reg));
- dependGraph.clearInst(dest_reg);
+ assert(dependGraph.empty(dest_reg->flatIdx));
+ dependGraph.clearInst(dest_reg->flatIdx);
// Mark the scoreboard as having that register ready.
- regScoreboard[dest_reg] = true;
+ regScoreboard[dest_reg->flatIdx] = true;
}
return dependents;
}
@@ -1219,7 +1219,7 @@
src_reg_idx < squashed_inst->numSrcRegs();
src_reg_idx++)
{
- PhysRegIndex src_reg =
+ PhysRegIdPtr src_reg =
squashed_inst->renamedSrcRegIdx(src_reg_idx);
// Only remove it from the dependency graph if it
@@ -1232,8 +1232,8 @@
// leaves more room for error.
if (!squashed_inst->isReadySrcRegIdx(src_reg_idx) &&
- src_reg < numPhysRegs) {
- dependGraph.remove(src_reg, squashed_inst);
+ !src_reg->isFixedMapping()) {
+ dependGraph.remove(src_reg->flatIdx,
squashed_inst);
}
@@ -1300,28 +1300,30 @@
{
// Only add it to the dependency graph if it's not ready.
if (!new_inst->isReadySrcRegIdx(src_reg_idx)) {
- PhysRegIndex src_reg = new_inst->renamedSrcRegIdx(src_reg_idx);
+ PhysRegIdPtr src_reg = new_inst->renamedSrcRegIdx(src_reg_idx);
// Check the IQ's scoreboard to make sure the register
// hasn't become ready while the instruction was in flight
// between stages. Only if it really isn't ready should
// it be added to the dependency graph.
- if (src_reg >= numPhysRegs) {
+ if (src_reg->isFixedMapping()) {
continue;
- } else if (!regScoreboard[src_reg]) {
- DPRINTF(IQ, "Instruction PC %s has src reg %i that "
+ } else if (!regScoreboard[src_reg->flatIdx]) {
+ DPRINTF(IQ, "Instruction PC %s has src reg %i (%s) that "
"is being added to the dependency chain.\n",
- new_inst->pcState(), src_reg);
+ new_inst->pcState(), src_reg->regIdx,
+ RegClassStrings[src_reg->regClass]);
- dependGraph.insert(src_reg, new_inst);
+ dependGraph.insert(src_reg->flatIdx, new_inst);
// Change the return value to indicate that something
// was added to the dependency graph.
return_val = true;
} else {
- DPRINTF(IQ, "Instruction PC %s has src reg %i that "
+ DPRINTF(IQ, "Instruction PC %s has src reg %i (%s) that "
"became ready before it reached the IQ.\n",
- new_inst->pcState(), src_reg);
+ new_inst->pcState(), src_reg->regIdx,
+ RegClassStrings[src_reg->regClass]);
// Mark a register ready within the instruction.
new_inst->markSrcRegReady(src_reg_idx);
}
@@ -1345,25 +1347,25 @@
dest_reg_idx < total_dest_regs;
dest_reg_idx++)
{
- PhysRegIndex dest_reg = new_inst->renamedDestRegIdx(dest_reg_idx);
+ PhysRegIdPtr dest_reg = new_inst->renamedDestRegIdx(dest_reg_idx);
- // Instructions that use the misc regs will have a reg number
- // higher than the normal physical registers. In this case these
- // registers are not renamed, and there is no need to track
+ // Some registers have fixed mapping, and there is no need to track
// dependencies as these instructions must be executed at commit.
- if (dest_reg >= numPhysRegs) {
+ if (dest_reg->isFixedMapping()) {
continue;
}
- if (!dependGraph.empty(dest_reg)) {
+ if (!dependGraph.empty(dest_reg->flatIdx)) {
dependGraph.dump();
- panic("Dependency graph %i not empty!", dest_reg);
+ panic("Dependency graph %i (%s) (flat: %i) not empty!",
+ dest_reg->regIdx, RegClassStrings[dest_reg->regClass],
+ dest_reg->flatIdx);
}
- dependGraph.setInst(dest_reg, new_inst);
+ dependGraph.setInst(dest_reg->flatIdx, new_inst);
// Mark the scoreboard to say it's not yet ready.
- regScoreboard[dest_reg] = false;
+ regScoreboard[dest_reg->flatIdx] = false;
}
}
diff --git a/src/cpu/o3/probe/elastic_trace.cc
b/src/cpu/o3/probe/elastic_trace.cc
index e0466b5..7a425ea 100644
--- a/src/cpu/o3/probe/elastic_trace.cc
+++ b/src/cpu/o3/probe/elastic_trace.cc
@@ -239,10 +239,11 @@
int8_t max_regs = dyn_inst->numSrcRegs();
for (int src_idx = 0; src_idx < max_regs; src_idx++) {
// Get the physical register index of the i'th source register.
- PhysRegIndex src_reg = dyn_inst->renamedSrcRegIdx(src_idx);
- DPRINTFR(ElasticTrace, "[sn:%lli] Check map for src reg %i\n",
seq_num,
- src_reg);
- auto itr_last_writer = physRegDepMap.find(src_reg);
+ 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);
if (itr_last_writer != physRegDepMap.end()) {
InstSeqNum last_writer = itr_last_writer->second;
// Additionally the dependency distance is kept less than the
window
@@ -267,10 +268,11 @@
!dest_reg.isZeroReg()) {
// Get the physical register index of the i'th destination
// register.
- PhysRegIndex phys_dest_reg =
dyn_inst->renamedDestRegIdx(dest_idx);
- DPRINTFR(ElasticTrace, "[sn:%lli] Update map for dest
reg %i\n",
- seq_num, dest_reg.regIdx);
- physRegDepMap[phys_dest_reg] = seq_num;
+ 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;
}
}
maxPhysRegDepMapSize = std::max(physRegDepMap.size(),
@@ -281,7 +283,7 @@
ElasticTrace::removeRegDepMapEntry(const SeqNumRegPair &inst_reg_pair)
{
DPRINTFR(ElasticTrace, "Remove Map entry for Reg %i\n",
- inst_reg_pair.second);
+ inst_reg_pair.second);
auto itr_regdep_map = physRegDepMap.find(inst_reg_pair.second);
if (itr_regdep_map != physRegDepMap.end())
physRegDepMap.erase(itr_regdep_map);
diff --git a/src/cpu/o3/regfile.cc b/src/cpu/o3/regfile.cc
index e1d84c6..ee8d07b 100644
--- a/src/cpu/o3/regfile.cc
+++ b/src/cpu/o3/regfile.cc
@@ -41,17 +41,42 @@
: intRegFile(_numPhysicalIntRegs),
floatRegFile(_numPhysicalFloatRegs),
ccRegFile(_numPhysicalCCRegs),
- baseFloatRegIndex(_numPhysicalIntRegs),
- baseCCRegIndex(_numPhysicalIntRegs + _numPhysicalFloatRegs),
+ numPhysicalIntRegs(_numPhysicalIntRegs),
+ numPhysicalFloatRegs(_numPhysicalFloatRegs),
+ numPhysicalCCRegs(_numPhysicalCCRegs),
totalNumRegs(_numPhysicalIntRegs
+ _numPhysicalFloatRegs
+ _numPhysicalCCRegs)
{
+ PhysRegIndex phys_reg;
+ PhysRegIndex flat_reg_idx = 0;
+
if (TheISA::NumCCRegs == 0 && _numPhysicalCCRegs != 0) {
// Just make this a warning and go ahead and allocate them
// anyway, to keep from having to add checks everywhere
warn("Non-zero number of physical CC regs specified, even though\n"
" ISA does not use them.\n");
+ }
+ // The initial batch of registers are the integer ones
+ for (phys_reg = 0; phys_reg < numPhysicalIntRegs; phys_reg++) {
+ intRegIds.emplace_back(IntRegClass, phys_reg, flat_reg_idx++);
+ }
+
+ // 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++) {
+ floatRegIds.emplace_back(FloatRegClass, phys_reg, flat_reg_idx++);
+ }
+
+ // The rest of the registers are the condition-code physical
+ // registers; put them onto the condition-code free list.
+ for (phys_reg = 0; phys_reg < numPhysicalCCRegs; phys_reg++) {
+ ccRegIds.emplace_back(CCRegClass, phys_reg, flat_reg_idx++);
+ }
+
+ // Misc regs have a fixed mapping but still need PhysRegIds.
+ for (phys_reg = 0; phys_reg < TheISA::NumMiscRegs; phys_reg++) {
+ miscRegIds.emplace_back(MiscRegClass, phys_reg, 0);
}
}
@@ -60,22 +85,25 @@
PhysRegFile::initFreeList(UnifiedFreeList *freeList)
{
// Initialize the free lists.
- PhysRegIndex reg_idx = 0;
+ int reg_idx = 0;
// The initial batch of registers are the integer ones
- while (reg_idx < baseFloatRegIndex) {
- freeList->addIntReg(reg_idx++);
+ for (reg_idx = 0; reg_idx < numPhysicalIntRegs; reg_idx++) {
+ assert(intRegIds[reg_idx].regIdx == 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.
- while (reg_idx < baseCCRegIndex) {
- freeList->addFloatReg(reg_idx++);
+ for (reg_idx = 0; reg_idx < numPhysicalFloatRegs; reg_idx++) {
+ assert(floatRegIds[reg_idx].regIdx == 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.
- while (reg_idx < totalNumRegs) {
- freeList->addCCReg(reg_idx++);
+ for (reg_idx = 0; reg_idx < numPhysicalCCRegs; reg_idx++) {
+ assert(ccRegIds[reg_idx].regIdx == reg_idx);
+ freeList->addCCReg(&ccRegIds[reg_idx]);
}
}
diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh
index 8b87725..c7935c5 100644
--- a/src/cpu/o3/regfile.hh
+++ b/src/cpu/o3/regfile.hh
@@ -64,34 +64,33 @@
/** Integer register file. */
std::vector<IntReg> intRegFile;
+ std::vector<PhysRegId> intRegIds;
/** Floating point register file. */
std::vector<PhysFloatReg> floatRegFile;
+ std::vector<PhysRegId> floatRegIds;
/** Condition-code register file. */
std::vector<CCReg> ccRegFile;
+ std::vector<PhysRegId> ccRegIds;
+
+ /** Misc Reg Ids */
+ std::vector<PhysRegId> miscRegIds;
/**
- * The first floating-point physical register index. The physical
- * register file has a single continuous index space, with the
- * initial indices mapping to the integer registers, followed
- * immediately by the floating-point registers. Thus the first
- * floating-point index is equal to the number of integer
- * registers.
- *
- * Note that this internal organizational detail on how physical
- * register file indices are ordered should *NOT* be exposed
- * outside of this class. Other classes can use the is*PhysReg()
- * methods to map from a physical register index to a class
- * without knowing the internal structure of the index map.
+ * Number of physical general purpose registers
*/
- unsigned baseFloatRegIndex;
+ unsigned numPhysicalIntRegs;
/**
- * The first condition-code physical register index. The
- * condition-code registers follow the floating-point registers.
+ * Number of physical general purpose registers
*/
- unsigned baseCCRegIndex;
+ unsigned numPhysicalFloatRegs;
+
+ /**
+ * Number of physical general purpose registers
+ */
+ unsigned numPhysicalCCRegs;
/** Total number of physical registers. */
unsigned totalNumRegs;
@@ -114,153 +113,112 @@
void initFreeList(UnifiedFreeList *freeList);
/** @return the number of integer physical registers. */
- unsigned numIntPhysRegs() const { return baseFloatRegIndex; }
+ unsigned numIntPhysRegs() const { return numPhysicalIntRegs; }
/** @return the number of floating-point physical registers. */
- unsigned numFloatPhysRegs() const
- { return baseCCRegIndex - baseFloatRegIndex; }
+ unsigned numFloatPhysRegs() const { return numPhysicalFloatRegs; }
/** @return the number of condition-code physical registers. */
- unsigned numCCPhysRegs() const
- { return totalNumRegs - baseCCRegIndex; }
+ unsigned numCCPhysRegs() const { return numPhysicalCCRegs; }
/** @return the total number of physical registers. */
unsigned totalNumPhysRegs() const { return totalNumRegs; }
- /**
- * @return true if the specified physical register index
- * corresponds to an integer physical register.
- */
- bool isIntPhysReg(PhysRegIndex reg_idx) const
- {
- return 0 <= reg_idx && reg_idx < baseFloatRegIndex;
- }
-
- /**
- * @return true if the specified physical register index
- * corresponds to a floating-point physical register.
- */
- bool isFloatPhysReg(PhysRegIndex reg_idx) const
- {
- return (baseFloatRegIndex <= reg_idx && reg_idx < baseCCRegIndex);
- }
-
- /**
- * Return true if the specified physical register index
- * corresponds to a condition-code physical register.
- */
- bool isCCPhysReg(PhysRegIndex reg_idx)
- {
- return (baseCCRegIndex <= reg_idx && reg_idx < totalNumRegs);
+ /** Gets a misc register PhysRegIdPtr. */
+ PhysRegIdPtr getMiscRegId(RegIndex reg_idx) {
+ return &miscRegIds[reg_idx];
}
/** Reads an integer register. */
- uint64_t readIntReg(PhysRegIndex reg_idx) const
+ uint64_t readIntReg(PhysRegIdPtr phys_reg) const
{
- assert(isIntPhysReg(reg_idx));
+ assert(phys_reg->isIntPhysReg());
DPRINTF(IEW, "RegFile: Access to int register %i, has data "
- "%#x\n", int(reg_idx), intRegFile[reg_idx]);
- return intRegFile[reg_idx];
+ "%#x\n", phys_reg->regIdx, intRegFile[phys_reg->regIdx]);
+ return intRegFile[phys_reg->regIdx];
}
/** Reads a floating point register (double precision). */
- FloatReg readFloatReg(PhysRegIndex reg_idx) const
+ FloatReg readFloatReg(PhysRegIdPtr phys_reg) const
{
- assert(isFloatPhysReg(reg_idx));
-
- // Remove the base Float reg dependency.
- PhysRegIndex reg_offset = reg_idx - baseFloatRegIndex;
+ assert(phys_reg->isFloatPhysReg());
DPRINTF(IEW, "RegFile: Access to float register %i, has "
- "data %#x\n", int(reg_idx), floatRegFile[reg_offset].q);
+ "data %#x\n", phys_reg->regIdx,
+ floatRegFile[phys_reg->regIdx].q);
- return floatRegFile[reg_offset].d;
+ return floatRegFile[phys_reg->regIdx].d;
}
- FloatRegBits readFloatRegBits(PhysRegIndex reg_idx) const
+ FloatRegBits readFloatRegBits(PhysRegIdPtr phys_reg) const
{
- assert(isFloatPhysReg(reg_idx));
+ assert(phys_reg->isFloatPhysReg());
- // Remove the base Float reg dependency.
- PhysRegIndex reg_offset = reg_idx - baseFloatRegIndex;
-
- FloatRegBits floatRegBits = floatRegFile[reg_offset].q;
+ FloatRegBits floatRegBits = floatRegFile[phys_reg->regIdx].q;
DPRINTF(IEW, "RegFile: Access to float register %i as int, "
- "has data %#x\n", int(reg_idx), (uint64_t)floatRegBits);
+ "has data %#x\n", phys_reg->regIdx,
+ (uint64_t)floatRegBits);
return floatRegBits;
}
/** Reads a condition-code register. */
- CCReg readCCReg(PhysRegIndex reg_idx)
+ CCReg readCCReg(PhysRegIdPtr phys_reg)
{
- assert(isCCPhysReg(reg_idx));
-
- // Remove the base CC reg dependency.
- PhysRegIndex reg_offset = reg_idx - baseCCRegIndex;
+ assert(phys_reg->isCCPhysReg());
DPRINTF(IEW, "RegFile: Access to cc register %i, has "
- "data %#x\n", int(reg_idx), ccRegFile[reg_offset]);
+ "data %#x\n", phys_reg->regIdx,
+ ccRegFile[phys_reg->regIdx]);
- return ccRegFile[reg_offset];
+ return ccRegFile[phys_reg->regIdx];
}
/** Sets an integer register to the given value. */
- void setIntReg(PhysRegIndex reg_idx, uint64_t val)
+ void setIntReg(PhysRegIdPtr phys_reg, uint64_t val)
{
- assert(isIntPhysReg(reg_idx));
+ assert(phys_reg->isIntPhysReg());
DPRINTF(IEW, "RegFile: Setting int register %i to %#x\n",
- int(reg_idx), val);
+ phys_reg->regIdx, val);
- if (reg_idx != TheISA::ZeroReg)
- intRegFile[reg_idx] = val;
+ if (!phys_reg->isZeroReg())
+ intRegFile[phys_reg->regIdx] = val;
}
/** Sets a double precision floating point register to the given
value. */
- void setFloatReg(PhysRegIndex reg_idx, FloatReg val)
+ void setFloatReg(PhysRegIdPtr phys_reg, FloatReg val)
{
- assert(isFloatPhysReg(reg_idx));
-
- // Remove the base Float reg dependency.
- PhysRegIndex reg_offset = reg_idx - baseFloatRegIndex;
+ assert(phys_reg->isFloatPhysReg());
DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
- int(reg_idx), (uint64_t)val);
+ phys_reg->regIdx, (uint64_t)val);
-#if THE_ISA == ALPHA_ISA
- if (reg_offset != TheISA::ZeroReg)
-#endif
- floatRegFile[reg_offset].d = val;
+ if (!phys_reg->isZeroReg())
+ floatRegFile[phys_reg->regIdx].d = val;
}
- void setFloatRegBits(PhysRegIndex reg_idx, FloatRegBits val)
+ void setFloatRegBits(PhysRegIdPtr phys_reg, FloatRegBits val)
{
- assert(isFloatPhysReg(reg_idx));
-
- // Remove the base Float reg dependency.
- PhysRegIndex reg_offset = reg_idx - baseFloatRegIndex;
+ assert(phys_reg->isFloatPhysReg());
DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
- int(reg_idx), (uint64_t)val);
+ phys_reg->regIdx, (uint64_t)val);
- floatRegFile[reg_offset].q = val;
+ floatRegFile[phys_reg->regIdx].q = val;
}
/** Sets a condition-code register to the given value. */
- void setCCReg(PhysRegIndex reg_idx, CCReg val)
+ void setCCReg(PhysRegIdPtr phys_reg, CCReg val)
{
- assert(isCCPhysReg(reg_idx));
-
- // Remove the base CC reg dependency.
- PhysRegIndex reg_offset = reg_idx - baseCCRegIndex;
+ assert(phys_reg->isCCPhysReg());
DPRINTF(IEW, "RegFile: Setting cc register %i to %#x\n",
- int(reg_idx), (uint64_t)val);
+ phys_reg->regIdx, (uint64_t)val);
- ccRegFile[reg_offset] = val;
+ ccRegFile[phys_reg->regIdx] = val;
}
};
diff --git a/src/cpu/o3/rename.hh b/src/cpu/o3/rename.hh
index c0483d4..ab7ae5f 100644
--- a/src/cpu/o3/rename.hh
+++ b/src/cpu/o3/rename.hh
@@ -119,7 +119,7 @@
ThreadStatus renameStatus[Impl::MaxThreads];
/** Probe points. */
- typedef typename std::pair<InstSeqNum, short int> SeqNumRegPair;
+ typedef typename std::pair<InstSeqNum, PhysRegIdPtr> SeqNumRegPair;
/** To probe when register renaming for an instruction is complete */
ProbePointArg<DynInstPtr> *ppRename;
/**
@@ -299,7 +299,8 @@
*/
struct RenameHistory {
RenameHistory(InstSeqNum _instSeqNum, RegId _archReg,
- PhysRegIndex _newPhysReg, PhysRegIndex _prevPhysReg)
+ PhysRegIdPtr _newPhysReg,
+ PhysRegIdPtr _prevPhysReg)
: instSeqNum(_instSeqNum), archReg(_archReg),
newPhysReg(_newPhysReg), prevPhysReg(_prevPhysReg)
{
@@ -310,9 +311,10 @@
/** The architectural register index that was renamed. */
RegId archReg;
/** The new physical register that the arch. register is renamed
to. */
- PhysRegIndex newPhysReg;
- /** The old physical register that the arch. register was renamed
to. */
- PhysRegIndex prevPhysReg;
+ PhysRegIdPtr newPhysReg;
+ /** The old physical register that the arch. register was renamed
to.
+ */
+ PhysRegIdPtr prevPhysReg;
};
/** A per-thread list of all destination register renames, used to
either
diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh
index e675efc..a927926 100644
--- a/src/cpu/o3/rename_impl.hh
+++ b/src/cpu/o3/rename_impl.hh
@@ -983,9 +983,11 @@
hb_it != historyBuffer[tid].end() &&
hb_it->instSeqNum <= inst_seq_num) {
- DPRINTF(Rename, "[tid:%u]: Freeing up older rename of reg %i, "
+ DPRINTF(Rename, "[tid:%u]: Freeing up older rename of reg %i
(%s), "
"[sn:%lli].\n",
- tid, hb_it->prevPhysReg, hb_it->instSeqNum);
+ tid, hb_it->prevPhysReg->regIdx,
+ RegClassStrings[hb_it->prevPhysReg->regClass],
+ hb_it->instSeqNum);
// Don't free special phys regs like misc and zero regs, which
// can be recognized because the new mapping is the same as
@@ -1013,7 +1015,7 @@
for (int src_idx = 0; src_idx < num_src_regs; src_idx++) {
RegId src_reg = inst->srcRegIdx(src_idx);
RegIndex flat_src_reg;
- PhysRegIndex renamed_reg;
+ PhysRegIdPtr renamed_reg;
switch (src_reg.regClass) {
case IntRegClass:
@@ -1043,21 +1045,27 @@
panic("Invalid register class: %d.", src_reg.regClass);
}
- DPRINTF(Rename, "[tid:%u]: Looking up %s arch reg %i
(flattened %i), "
- "got phys reg %i\n", tid,
RegClassStrings[src_reg.regClass],
- (int)src_reg.regIdx, (int)flat_src_reg, (int)renamed_reg);
+ 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]);
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 is ready.\n",
- tid, 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]);
inst->markSrcRegReady(src_idx);
} else {
- DPRINTF(Rename, "[tid:%u]: Register %d is not ready.\n",
- tid, renamed_reg);
+ DPRINTF(Rename, "[tid:%u]: Register %d (flat: %d) (%s)"
+ " is not ready.\n", tid, renamed_reg->regIdx,
+ renamed_reg->flatIdx,
+ RegClassStrings[renamed_reg->regClass]);
}
++renameRenameLookups;
@@ -1111,9 +1119,11 @@
// Mark Scoreboard entry as not ready
scoreboard->unsetReg(rename_result.first);
- DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i to physical "
- "reg %i.\n", tid, (int)flat_dest_reg,
- (int)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);
// Record the rename information so that a history can be kept.
RenameHistory hb_entry(inst->seqNum, flat_uni_dest_reg,
@@ -1426,11 +1436,15 @@
buf_it = historyBuffer[tid].begin();
while (buf_it != historyBuffer[tid].end()) {
- cprintf("Seq num: %i\nArch reg[%s]: %i New phys reg: %i Old
phys "
- "reg: %i\n", (*buf_it).instSeqNum,
+ 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,
- (int)(*buf_it).newPhysReg, (int)(*buf_it).prevPhysReg);
+ (*buf_it).newPhysReg->regIdx,
+ RegClassStrings[(*buf_it).newPhysReg->regClass],
+ (*buf_it).prevPhysReg->regIdx,
+ RegClassStrings[(*buf_it).prevPhysReg->regClass]);
buf_it++;
}
diff --git a/src/cpu/o3/rename_map.cc b/src/cpu/o3/rename_map.cc
index 6307b58..4555946 100644
--- a/src/cpu/o3/rename_map.cc
+++ b/src/cpu/o3/rename_map.cc
@@ -60,11 +60,11 @@
SimpleRenameMap::RenameInfo
SimpleRenameMap::rename(RegIndex arch_reg)
{
- PhysRegIndex renamed_reg;
+ PhysRegIdPtr renamed_reg;
// Record the current physical register that is renamed to the
// requested architected register.
- PhysRegIndex prev_reg = map[arch_reg];
+ PhysRegIdPtr prev_reg = map[arch_reg];
// If it's not referencing the zero register, then rename the
// register.
@@ -74,12 +74,14 @@
map[arch_reg] = renamed_reg;
} else {
// Otherwise return the zero register so nothing bad happens.
- assert(prev_reg == zeroReg);
- renamed_reg = zeroReg;
+ assert(prev_reg->isZeroReg());
+ renamed_reg = prev_reg;
}
- DPRINTF(Rename, "Renamed reg %d to physical reg %d old mapping
was %d\n",
- arch_reg, renamed_reg, prev_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);
return RenameInfo(renamed_reg, prev_reg);
}
@@ -100,6 +102,7 @@
floatMap.init(TheISA::NumFloatRegs, &(freeList->floatList),
_floatZeroReg);
ccMap.init(TheISA::NumCCRegs, &(freeList->ccList), (RegIndex)-1);
+
}
@@ -126,7 +129,7 @@
}
-PhysRegIndex
+PhysRegIdPtr
UnifiedRenameMap::lookup(RegId arch_reg) const
{
switch (arch_reg.regClass) {
@@ -149,7 +152,7 @@
}
void
-UnifiedRenameMap::setEntry(RegId arch_reg, PhysRegIndex phys_reg)
+UnifiedRenameMap::setEntry(RegId arch_reg, PhysRegIdPtr phys_reg)
{
switch (arch_reg.regClass) {
case IntRegClass:
diff --git a/src/cpu/o3/rename_map.hh b/src/cpu/o3/rename_map.hh
index 2cce299..f51cf59 100644
--- a/src/cpu/o3/rename_map.hh
+++ b/src/cpu/o3/rename_map.hh
@@ -42,10 +42,6 @@
* Steve Reinhardt
*/
-// Todo: Create destructor.
-// Have it so that there's a more meaningful name given to the variable
-// that marks the beginning of the FP registers.
-
#ifndef __CPU_O3_RENAME_MAP_HH__
#define __CPU_O3_RENAME_MAP_HH__
@@ -71,7 +67,7 @@
private:
/** The acutal arch-to-phys register map */
- std::vector<PhysRegIndex> map;
+ std::vector<PhysRegIdPtr> map;
/**
* Pointer to the free list from which new physical registers
@@ -107,7 +103,7 @@
* renamed to, and the previous physical register that the same
* logical register was previously mapped to.
*/
- typedef std::pair<PhysRegIndex, PhysRegIndex> RenameInfo;
+ typedef std::pair<PhysRegIdPtr, PhysRegIdPtr> RenameInfo;
/**
* Tell rename map to get a new free physical register to remap
@@ -123,7 +119,7 @@
* @param arch_reg The architectural register to look up.
* @return The physical register it is currently mapped to.
*/
- PhysRegIndex lookup(RegIndex arch_reg) const
+ PhysRegIdPtr lookup(RegIndex arch_reg) const
{
assert(arch_reg < map.size());
return map[arch_reg];
@@ -135,7 +131,7 @@
* @param arch_reg The architectural register to remap.
* @param phys_reg The physical register to remap it to.
*/
- void setEntry(RegIndex arch_reg, PhysRegIndex phys_reg)
+ void setEntry(RegIndex arch_reg, PhysRegIdPtr phys_reg)
{
map[arch_reg] = phys_reg;
}
@@ -162,17 +158,14 @@
/** The floating-point register rename map */
SimpleRenameMap floatMap;
- /**
- * The register file object is used only to distinguish integer
- * from floating-point physical register indices, which in turn is
- * used only for assert statements that make sure the physical
- * register indices that get passed in and handed out are of the
- * proper class.
- */
- PhysRegFile *regFile;
-
/** The condition-code register rename map */
SimpleRenameMap ccMap;
+
+ /**
+ * The register file object is used only to get PhysRegIdPtr
+ * on MiscRegs, as they are stored in it.
+ */
+ PhysRegFile *regFile;
public:
@@ -207,9 +200,7 @@
*/
RenameInfo renameInt(RegIndex rel_arch_reg)
{
- RenameInfo info = intMap.rename(rel_arch_reg);
- assert(regFile->isIntPhysReg(info.first));
- return info;
+ return intMap.rename(rel_arch_reg);
}
/**
@@ -218,9 +209,7 @@
*/
RenameInfo renameFloat(RegIndex rel_arch_reg)
{
- RenameInfo info = floatMap.rename(rel_arch_reg);
- assert(regFile->isFloatPhysReg(info.first));
- return info;
+ return floatMap.rename(rel_arch_reg);
}
/**
@@ -229,9 +218,7 @@
*/
RenameInfo renameCC(RegIndex rel_arch_reg)
{
- RenameInfo info = ccMap.rename(rel_arch_reg);
- assert(regFile->isCCPhysReg(info.first));
- return info;
+ return ccMap.rename(rel_arch_reg);
}
/**
@@ -241,10 +228,9 @@
RenameInfo renameMisc(RegIndex rel_arch_reg)
{
// misc regs aren't really renamed, just remapped
- PhysRegIndex phys_reg = lookupMisc(rel_arch_reg);
- // Set the previous register to the same register; mainly it must
be
- // known that the prev reg was outside the range of normal
registers
- // so the free list can avoid adding it.
+ 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);
}
@@ -256,51 +242,44 @@
* @param arch_reg The architectural register to look up.
* @return The physical register it is currently mapped to.
*/
- PhysRegIndex lookup(RegId arch_reg) const;
+ PhysRegIdPtr lookup(RegId arch_reg) const;
/**
* Perform lookup() on an integer register, given a
* integer register index.
*/
- PhysRegIndex lookupInt(RegIndex rel_arch_reg) const
+ PhysRegIdPtr lookupInt(RegIndex rel_arch_reg) const
{
- PhysRegIndex phys_reg = intMap.lookup(rel_arch_reg);
- assert(regFile->isIntPhysReg(phys_reg));
- return phys_reg;
+ return intMap.lookup(rel_arch_reg);
}
/**
* Perform lookup() on a floating-point register, given a
* floating-point register index.
*/
- PhysRegIndex lookupFloat(RegIndex rel_arch_reg) const
+ PhysRegIdPtr lookupFloat(RegIndex rel_arch_reg) const
{
- PhysRegIndex phys_reg = floatMap.lookup(rel_arch_reg);
- assert(regFile->isFloatPhysReg(phys_reg));
- return phys_reg;
+ return floatMap.lookup(rel_arch_reg);
}
/**
* Perform lookup() on a condition-code register, given a
* condition-code register index.
*/
- PhysRegIndex lookupCC(RegIndex rel_arch_reg) const
+ PhysRegIdPtr lookupCC(RegIndex rel_arch_reg) const
{
- PhysRegIndex phys_reg = ccMap.lookup(rel_arch_reg);
- assert(regFile->isCCPhysReg(phys_reg));
- return phys_reg;
+ return ccMap.lookup(rel_arch_reg);
}
/**
* Perform lookup() on a misc register, given a relative
* misc register index.
*/
- PhysRegIndex lookupMisc(RegIndex rel_arch_reg) const
+ PhysRegIdPtr lookupMisc(RegIndex rel_arch_reg) const
{
- // misc regs aren't really renamed, just given an index
- // beyond the range of actual physical registers
- PhysRegIndex phys_reg = rel_arch_reg + regFile->totalNumPhysRegs();
- return phys_reg;
+ // misc regs aren't really renamed, they keep the same
+ // mapping throughout the execution.
+ return regFile->getMiscRegId(rel_arch_reg);
}
/**
@@ -311,15 +290,15 @@
* @param arch_reg The architectural register to remap.
* @param phys_reg The physical register to remap it to.
*/
- void setEntry(RegId arch_reg, PhysRegIndex phys_reg);
+ void setEntry(RegId arch_reg, PhysRegIdPtr phys_reg);
/**
* Perform setEntry() on an integer register, given a
* integer register index.
*/
- void setIntEntry(RegIndex arch_reg, PhysRegIndex phys_reg)
+ void setIntEntry(RegIndex arch_reg, PhysRegIdPtr phys_reg)
{
- assert(regFile->isIntPhysReg(phys_reg));
+ assert(phys_reg->isIntPhysReg());
intMap.setEntry(arch_reg, phys_reg);
}
@@ -327,9 +306,9 @@
* Perform setEntry() on a floating-point register, given a
* floating-point register index.
*/
- void setFloatEntry(RegIndex arch_reg, PhysRegIndex phys_reg)
+ void setFloatEntry(RegIndex arch_reg, PhysRegIdPtr phys_reg)
{
- assert(regFile->isFloatPhysReg(phys_reg));
+ assert(phys_reg->isFloatPhysReg());
floatMap.setEntry(arch_reg, phys_reg);
}
@@ -337,9 +316,9 @@
* Perform setEntry() on a condition-code register, given a
* condition-code register index.
*/
- void setCCEntry(RegIndex arch_reg, PhysRegIndex phys_reg)
+ void setCCEntry(RegIndex arch_reg, PhysRegIdPtr phys_reg)
{
- assert(regFile->isCCPhysReg(phys_reg));
+ assert(phys_reg->isCCPhysReg());
ccMap.setEntry(arch_reg, phys_reg);
}
diff --git a/src/cpu/o3/scoreboard.cc b/src/cpu/o3/scoreboard.cc
index 2b2b091..e15f9c7 100644
--- a/src/cpu/o3/scoreboard.cc
+++ b/src/cpu/o3/scoreboard.cc
@@ -36,12 +36,9 @@
#include "debug/Scoreboard.hh"
Scoreboard::Scoreboard(const std::string &_my_name,
- unsigned _numPhysicalRegs, unsigned _numMiscRegs,
- PhysRegIndex _zeroRegIdx, PhysRegIndex
_fpZeroRegIdx)
+ unsigned _numPhysicalRegs)
: _name(_my_name),
regScoreBoard(_numPhysicalRegs, true),
- numPhysRegs(_numPhysicalRegs),
- numTotalRegs(_numPhysicalRegs + _numMiscRegs),
- zeroRegIdx(_zeroRegIdx), fpZeroRegIdx(_fpZeroRegIdx)
+ numPhysRegs(_numPhysicalRegs)
{
}
diff --git a/src/cpu/o3/scoreboard.hh b/src/cpu/o3/scoreboard.hh
index ec84bec..44e4499 100644
--- a/src/cpu/o3/scoreboard.hh
+++ b/src/cpu/o3/scoreboard.hh
@@ -46,12 +46,8 @@
/**
* Implements a simple scoreboard to track which registers are
* ready. This class operates on the unified physical register space,
- * so integer and floating-point registers are not distinguished. For
- * convenience, it also accepts operations on the physical-space
- * mapping of misc registers, which are numbered starting after the
- * end of the actual physical register file. However, there is no
- * actual scoreboard for misc registers, and they are always
- * considered ready.
+ * because the different classes of registers do not need to be
distinguished.
+ * Registers being part of a fixed mapping are always considered ready.
*/
class Scoreboard
{
@@ -67,38 +63,13 @@
/** The number of actual physical registers */
unsigned numPhysRegs;
- /**
- * The total number of registers which can be indexed, including
- * the misc registers that come after the physical registers and
- * which are hardwired to be always considered ready.
- */
- unsigned M5_CLASS_VAR_USED numTotalRegs;
-
- /** The index of the zero register. */
- PhysRegIndex zeroRegIdx;
-
- /** The index of the FP zero register. */
- PhysRegIndex fpZeroRegIdx;
-
- bool isZeroReg(PhysRegIndex idx) const
- {
- return (idx == zeroRegIdx ||
- (THE_ISA == ALPHA_ISA && idx == fpZeroRegIdx));
- }
-
public:
/** Constructs a scoreboard.
* @param _numPhysicalRegs Number of physical registers.
* @param _numMiscRegs Number of miscellaneous registers.
- * @param _zeroRegIdx Index of the zero register.
- * @param _fpZeroRegIdx Index of the FP zero register (if any,
currently
- * used only for Alpha).
*/
Scoreboard(const std::string &_my_name,
- unsigned _numPhysicalRegs,
- unsigned _numMiscRegs,
- PhysRegIndex _zeroRegIdx,
- PhysRegIndex _fpZeroRegIdx);
+ unsigned _numPhysicalRegs);
/** Destructor. */
~Scoreboard() {}
@@ -107,54 +78,56 @@
std::string name() const { return _name; };
/** Checks if the register is ready. */
- bool getReg(PhysRegIndex reg_idx) const
+ bool getReg(PhysRegIdPtr phys_reg) const
{
- assert(reg_idx < numTotalRegs);
+ assert(phys_reg->flatIdx < numPhysRegs);
- if (reg_idx >= numPhysRegs) {
- // misc regs are always ready
+ if (phys_reg->isFixedMapping()) {
+ // Fixed mapping regs are always ready
return true;
}
- bool ready = regScoreBoard[reg_idx];
+ bool ready = regScoreBoard[phys_reg->flatIdx];
- if (isZeroReg(reg_idx))
+ if (phys_reg->isZeroReg())
assert(ready);
return ready;
}
/** Sets the register as ready. */
- void setReg(PhysRegIndex reg_idx)
+ void setReg(PhysRegIdPtr phys_reg)
{
- assert(reg_idx < numTotalRegs);
+ assert(phys_reg->flatIdx < numPhysRegs);
- if (reg_idx >= numPhysRegs) {
- // misc regs are always ready, ignore attempts to change that
+ if (phys_reg->isFixedMapping()) {
+ // Fixed mapping regs are always ready, ignore attempts to
change
+ // that
return;
}
- DPRINTF(Scoreboard, "Setting reg %i as ready\n", reg_idx);
+ DPRINTF(Scoreboard, "Setting reg %i (%s) as ready\n",
phys_reg->regIdx,
+ RegClassStrings[phys_reg->regClass]);
- assert(reg_idx < numTotalRegs);
- regScoreBoard[reg_idx] = true;
+ regScoreBoard[phys_reg->flatIdx] = true;
}
/** Sets the register as not ready. */
- void unsetReg(PhysRegIndex reg_idx)
+ void unsetReg(PhysRegIdPtr phys_reg)
{
- assert(reg_idx < numTotalRegs);
+ assert(phys_reg->flatIdx < numPhysRegs);
- if (reg_idx >= numPhysRegs) {
- // misc regs are always ready, ignore attempts to change that
+ if (phys_reg->isFixedMapping()) {
+ // Fixed mapping regs are always ready, ignore attempts to
+ // change that
return;
}
// zero reg should never be marked unready
- if (isZeroReg(reg_idx))
+ if (phys_reg->isZeroReg())
return;
- regScoreBoard[reg_idx] = false;
+ regScoreBoard[phys_reg->flatIdx] = false;
}
};
--
To view, visit https://gem5-review.googlesource.com/2701
To unsubscribe, visit https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic879a3cc608aa2f34e2168280faac1846de77667
Gerrit-Change-Number: 2701
Gerrit-PatchSet: 1
Gerrit-Owner: Curtis Dunham <[email protected]>
Gerrit-Reviewer: Andreas Sandberg <[email protected]>
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev