/** 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:
/** 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];
/** 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];
}
* 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;
* 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;
}
/*
- * Copyright (c) 2011 ARM Limited
+ * Copyright (c) 2011, 2016 ARM Limited
* Copyright (c) 2013 Advanced Micro Devices, Inc.
* All rights reserved
*
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Kevin Lim
+ * Nathanael Premillieu
*/
#ifndef __CPU_O3_COMM_HH__
// 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>
rob(this, params),
scoreboard(name() + ".scoreboard",
- regFile.totalNumPhysRegs(), TheISA::NumMiscRegs,
- TheISA::ZeroReg, TheISA::ZeroReg),
+ regFile.totalNumPhysRegs()),
isa(numThreads, NULL),
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);
}
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);
}
//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);
}
//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);
}
// 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);
}
// 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);
}
// 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);
}
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>
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
{
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) {
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;
#include <iostream>
#include <queue>
+#include <vector>
#include "base/misc.hh"
#include "base/trace.hh"
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;
}
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(); }
};
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
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));
}
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] "
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;
}
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
// 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);
}
{
// 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);
}
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;
}
}
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
!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(),
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);
: 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);
+ }
}
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]);
}
}
/** 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;
+
+ /**
+ * Number of physical general purpose registers
+ */
+ unsigned numPhysicalIntRegs;
/**
- * 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 numPhysicalFloatRegs;
/**
- * 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 numPhysicalCCRegs;
/** Total number of physical registers. */
unsigned totalNumRegs;
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;
}
};
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;
/**
*/
struct RenameHistory {
RenameHistory(InstSeqNum _instSeqNum, RegId _archReg,
- PhysRegIndex _newPhysReg, PhysRegIndex _prevPhysReg)
+ PhysRegIdPtr _newPhysReg,
+ PhysRegIdPtr _prevPhysReg)
: instSeqNum(_instSeqNum), archReg(_archReg),
newPhysReg(_newPhysReg), prevPhysReg(_prevPhysReg)
{
/** 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
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
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:
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;
// 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,
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++;
}
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.
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);
}
floatMap.init(TheISA::NumFloatRegs, &(freeList->floatList), _floatZeroReg);
ccMap.init(TheISA::NumCCRegs, &(freeList->ccList), (RegIndex)-1);
+
}
}
-PhysRegIndex
+PhysRegIdPtr
UnifiedRenameMap::lookup(RegId arch_reg) const
{
switch (arch_reg.regClass) {
}
void
-UnifiedRenameMap::setEntry(RegId arch_reg, PhysRegIndex phys_reg)
+UnifiedRenameMap::setEntry(RegId arch_reg, PhysRegIdPtr phys_reg)
{
switch (arch_reg.regClass) {
case IntRegClass:
* 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__
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
* 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
* @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];
* @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;
}
/** The floating-point register rename map */
SimpleRenameMap floatMap;
+ /** The condition-code register rename map */
+ SimpleRenameMap ccMap;
+
/**
- * 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.
+ * The register file object is used only to get PhysRegIdPtr
+ * on MiscRegs, as they are stored in it.
*/
PhysRegFile *regFile;
- /** The condition-code register rename map */
- SimpleRenameMap ccMap;
-
public:
typedef SimpleRenameMap::RenameInfo RenameInfo;
*/
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);
}
/**
*/
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);
}
/**
*/
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);
}
/**
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);
}
* @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);
}
/**
* @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);
}
* 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);
}
* 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);
}
#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)
{
}
/**
* 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
{
/** 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() {}
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;
}
};