diff options
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/base_dyn_inst.hh | 18 | ||||
-rw-r--r-- | src/cpu/o3/comm.hh | 54 | ||||
-rw-r--r-- | src/cpu/o3/cpu.cc | 69 | ||||
-rw-r--r-- | src/cpu/o3/cpu.hh | 16 | ||||
-rw-r--r-- | src/cpu/o3/dyn_inst.hh | 2 | ||||
-rw-r--r-- | src/cpu/o3/dyn_inst_impl.hh | 11 | ||||
-rw-r--r-- | src/cpu/o3/free_list.hh | 48 | ||||
-rw-r--r-- | src/cpu/o3/iew_impl.hh | 5 | ||||
-rw-r--r-- | src/cpu/o3/inst_queue_impl.hh | 66 | ||||
-rw-r--r-- | src/cpu/o3/probe/elastic_trace.cc | 20 | ||||
-rw-r--r-- | src/cpu/o3/regfile.cc | 46 | ||||
-rw-r--r-- | src/cpu/o3/regfile.hh | 158 | ||||
-rw-r--r-- | src/cpu/o3/rename.hh | 12 | ||||
-rw-r--r-- | src/cpu/o3/rename_impl.hh | 46 | ||||
-rw-r--r-- | src/cpu/o3/rename_map.cc | 19 | ||||
-rw-r--r-- | src/cpu/o3/rename_map.hh | 87 | ||||
-rw-r--r-- | src/cpu/o3/scoreboard.cc | 7 | ||||
-rw-r--r-- | src/cpu/o3/scoreboard.hh | 75 |
18 files changed, 383 insertions, 376 deletions
diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh index 84a6540af..369d7a02a 100644 --- a/src/cpu/base_dyn_inst.hh +++ b/src/cpu/base_dyn_inst.hh @@ -267,17 +267,17 @@ class BaseDynInst : public ExecContext, public RefCounted /** 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 @@ class BaseDynInst : public ExecContext, public RefCounted /** 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 @@ class BaseDynInst : public ExecContext, public RefCounted /** 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 @@ class BaseDynInst : public ExecContext, public RefCounted * 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 @@ class BaseDynInst : public ExecContext, public RefCounted * 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 4da251104..c5f1c0144 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 a2d8147ea..6e9accdd5 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -180,8 +180,7 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params) rob(this, params), scoreboard(name() + ".scoreboard", - regFile.totalNumPhysRegs(), TheISA::NumMiscRegs, - TheISA::ZeroReg, TheISA::ZeroReg), + regFile.totalNumPhysRegs()), isa(numThreads, NULL), @@ -300,19 +299,19 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params) 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 @@ FullO3CPU<Impl>::insertThread(ThreadID tid) 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 @@ FullO3CPU<Impl>::insertThread(ThreadID tid) //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 @@ FullO3CPU<Impl>::insertThread(ThreadID tid) //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 @@ FullO3CPU<Impl>::removeThread(ThreadID tid) // 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 @@ FullO3CPU<Impl>::removeThread(ThreadID tid) // 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 @@ FullO3CPU<Impl>::removeThread(ThreadID tid) // 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 @@ FullO3CPU<Impl>::setMiscReg(int misc_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> @@ -1301,7 +1300,7 @@ uint64_t 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 @@ float 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 @@ uint64_t 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 @@ CCReg 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 @@ void 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 @@ void 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 @@ void 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 @@ void 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 abe036b09..b5cbc5fe2 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -411,21 +411,21 @@ class FullO3CPU : public BaseO3CPU 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 3096e5946..b200a328a 100644 --- a/src/cpu/o3/dyn_inst.hh +++ b/src/cpu/o3/dyn_inst.hh @@ -207,7 +207,7 @@ class BaseO3DynInst : public BaseDynInst<Impl> { 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 f6a42c398..03437a5ae 100644 --- a/src/cpu/o3/dyn_inst_impl.hh +++ b/src/cpu/o3/dyn_inst_impl.hh @@ -106,17 +106,6 @@ template <class Impl> 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 aa805e26e..3e6740e57 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 @@ class SimpleFreeList 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 @@ class UnifiedFreeList 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 @@ class UnifiedFreeList }; 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 78b83eba6..cdb6b26e2 100644 --- a/src/cpu/o3/iew_impl.hh +++ b/src/cpu/o3/iew_impl.hh @@ -1433,8 +1433,9 @@ DefaultIEW<Impl>::writebackInsts() 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 7352c622b..c46fd6ba7 100644 --- a/src/cpu/o3/inst_queue_impl.hh +++ b/src/cpu/o3/inst_queue_impl.hh @@ -979,24 +979,24 @@ InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst) 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 @@ InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst) 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 @@ InstructionQueue<Impl>::doSquash(ThreadID tid) 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 @@ InstructionQueue<Impl>::doSquash(ThreadID tid) // 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 @@ InstructionQueue<Impl>::addToDependents(DynInstPtr &new_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); } @@ -1345,25 +1347,25 @@ InstructionQueue<Impl>::addToProducers(DynInstPtr &new_inst) 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 05b16805f..76f7e439a 100644 --- a/src/cpu/o3/probe/elastic_trace.cc +++ b/src/cpu/o3/probe/elastic_trace.cc @@ -239,10 +239,11 @@ ElasticTrace::updateRegDep(const DynInstPtr &dyn_inst) 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 @@ ElasticTrace::updateRegDep(const DynInstPtr &dyn_inst) !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 @@ void 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 e1d84c683..ee8d07b3e 100644 --- a/src/cpu/o3/regfile.cc +++ b/src/cpu/o3/regfile.cc @@ -41,18 +41,43 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs, : 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 @@ void 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 8b87725ca..c7935c55c 100644 --- a/src/cpu/o3/regfile.hh +++ b/src/cpu/o3/regfile.hh @@ -64,34 +64,33 @@ class PhysRegFile /** 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; @@ -114,153 +113,112 @@ class PhysRegFile 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 c0483d445..ab7ae5f8b 100644 --- a/src/cpu/o3/rename.hh +++ b/src/cpu/o3/rename.hh @@ -119,7 +119,7 @@ class DefaultRename 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 @@ class DefaultRename */ 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 @@ class DefaultRename /** 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 e675efcd5..a92792639 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -983,9 +983,11 @@ DefaultRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num, ThreadID tid) 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 @@ DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid) 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 @@ DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid) 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 @@ DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid) // 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 @@ DefaultRename<Impl>::dumpHistory() 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 6307b58de..4555946c2 100644 --- a/src/cpu/o3/rename_map.cc +++ b/src/cpu/o3/rename_map.cc @@ -60,11 +60,11 @@ SimpleRenameMap::init(unsigned size, SimpleFreeList *_freeList, 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 @@ SimpleRenameMap::rename(RegIndex arch_reg) 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 @@ UnifiedRenameMap::init(PhysRegFile *_regFile, floatMap.init(TheISA::NumFloatRegs, &(freeList->floatList), _floatZeroReg); ccMap.init(TheISA::NumCCRegs, &(freeList->ccList), (RegIndex)-1); + } @@ -126,7 +129,7 @@ UnifiedRenameMap::rename(RegId arch_reg) } -PhysRegIndex +PhysRegIdPtr UnifiedRenameMap::lookup(RegId arch_reg) const { switch (arch_reg.regClass) { @@ -149,7 +152,7 @@ UnifiedRenameMap::lookup(RegId arch_reg) const } 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 2cce29913..f51cf5922 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 @@ class SimpleRenameMap 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 @@ class SimpleRenameMap * 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 @@ class SimpleRenameMap * @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 @@ class SimpleRenameMap * @param arch_reg The architectural register to remap. * @param phys_reg The physical register to remap it to. */ - void setEntry(RegIndex arch_reg, PhysRegIndex phys_reg) + void setEntry(RegIndex arch_reg, PhysRegIdPtr phys_reg) { map[arch_reg] = phys_reg; } @@ -162,18 +158,15 @@ class UnifiedRenameMap /** 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; @@ -207,9 +200,7 @@ class UnifiedRenameMap */ 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 @@ class UnifiedRenameMap */ 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 @@ class UnifiedRenameMap */ 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 @@ class UnifiedRenameMap 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 @@ class UnifiedRenameMap * @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 @@ class UnifiedRenameMap * @param arch_reg The architectural register to remap. * @param phys_reg The physical register to remap it to. */ - void setEntry(RegId arch_reg, 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 @@ class UnifiedRenameMap * 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 @@ class UnifiedRenameMap * 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 2b2b091af..e15f9c769 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 ec84becdf..44e449944 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 @@ 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() {} @@ -107,54 +78,56 @@ class 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; } }; |