diff options
author | Rekai Gonzalez-Alberquilla <Rekai.GonzalezAlberquilla@arm.com> | 2017-04-05 13:14:34 -0500 |
---|---|---|
committer | Andreas Sandberg <andreas.sandberg@arm.com> | 2017-07-05 14:43:49 +0000 |
commit | a473b5a6eb269cc303ecfb5e5643d891a5d255d9 (patch) | |
tree | 4fde47e5c62c566f81d13f6e90ad98cca781ff6e /src/cpu/o3 | |
parent | 43d833246fcfe092a0c08dde1fdf7e3d409d1af9 (diff) | |
download | gem5-a473b5a6eb269cc303ecfb5e5643d891a5d255d9.tar.xz |
cpu: Simplify the rename interface and use RegId
With the hierarchical RegId there are a lot of functions that are
redundant now.
The idea behind the simplification is that instead of having the regId,
telling which kind of register read/write/rename/lookup/etc. and then
the function panic_if'ing if the regId is not of the appropriate type,
we provide an interface that decides what kind of register to read
depending on the register type of the given regId.
Change-Id: I7d52e9e21fc01205ae365d86921a4ceb67a57178
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
[ Fix RISCV build issues ]
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/2702
Diffstat (limited to 'src/cpu/o3')
-rw-r--r-- | src/cpu/o3/comm.hh | 75 | ||||
-rw-r--r-- | src/cpu/o3/cpu.cc | 61 | ||||
-rw-r--r-- | src/cpu/o3/dyn_inst.hh | 22 | ||||
-rw-r--r-- | src/cpu/o3/free_list.hh | 8 | ||||
-rw-r--r-- | src/cpu/o3/iew_impl.hh | 4 | ||||
-rw-r--r-- | src/cpu/o3/inst_queue_impl.hh | 41 | ||||
-rw-r--r-- | src/cpu/o3/probe/elastic_trace.cc | 14 | ||||
-rw-r--r-- | src/cpu/o3/regfile.cc | 6 | ||||
-rw-r--r-- | src/cpu/o3/regfile.hh | 36 | ||||
-rw-r--r-- | src/cpu/o3/rename.hh | 2 | ||||
-rw-r--r-- | src/cpu/o3/rename_impl.hh | 102 | ||||
-rw-r--r-- | src/cpu/o3/rename_map.cc | 88 | ||||
-rw-r--r-- | src/cpu/o3/rename_map.hh | 193 | ||||
-rw-r--r-- | src/cpu/o3/scoreboard.hh | 16 | ||||
-rwxr-xr-x | src/cpu/o3/thread_context.hh | 31 | ||||
-rwxr-xr-x | src/cpu/o3/thread_context_impl.hh | 27 |
16 files changed, 297 insertions, 429 deletions
diff --git a/src/cpu/o3/comm.hh b/src/cpu/o3/comm.hh index c5f1c0144..49e153a52 100644 --- a/src/cpu/o3/comm.hh +++ b/src/cpu/o3/comm.hh @@ -52,47 +52,65 @@ #include "cpu/inst_seq.hh" #include "sim/faults.hh" -// Typedef for physical register index type. Although the Impl would be the -// most likely location for this, there are a few classes that need this -// typedef yet are not templated on the Impl. For now it will be defined here. -typedef short int PhysRegIndex; -// Physical register ID -// Associate a physical register index to a register class and -// so it is easy to track which type of register are used. -// A flat index is also provided for when it is useful to have a unified -// indexing (for the dependency graph and the scoreboard for example) -struct PhysRegId { - RegClass regClass; - PhysRegIndex regIdx; +/** Physical register index type. + * Although the Impl might be a better for this, but there are a few classes + * that need this typedef yet are not templated on the Impl. + */ +using PhysRegIndex = short int; + +/** Physical register ID. + * Like a register ID but physical. The inheritance is private because the + * only relationship between this types is functional, and it is done to + * prevent code replication. */ +class PhysRegId : private RegId { + private: PhysRegIndex flatIdx; - PhysRegId(RegClass _regClass, PhysRegIndex _regIdx, + + public: + explicit PhysRegId() : RegId(IntRegClass, -1), flatIdx(-1) {} + + /** Scalar PhysRegId constructor. */ + explicit PhysRegId(RegClass _regClass, PhysRegIndex _regIdx, PhysRegIndex _flatIdx) - : regClass(_regClass), regIdx(_regIdx), flatIdx(_flatIdx) + : RegId(_regClass, _regIdx), flatIdx(_flatIdx) {} - bool operator==(const PhysRegId& that) const { - return regClass == that.regClass && regIdx == that.regIdx; + /** Visible RegId methods */ + /** @{ */ + using RegId::index; + using RegId::classValue; + using RegId::isZeroReg; + using RegId::className; + /** @} */ + /** + * Explicit forward methods, to prevent comparisons of PhysRegId with + * RegIds. + */ + /** @{ */ + bool operator<(const PhysRegId& that) const { + return RegId::operator<(that); } - bool operator!=(const PhysRegId& that) const { - return !(*this==that); + bool operator==(const PhysRegId& that) const { + return RegId::operator==(that); } - bool isZeroReg() const - { - return (regIdx == TheISA::ZeroReg && - (regClass == IntRegClass || - (THE_ISA == ALPHA_ISA && regClass == FloatRegClass))); + bool operator!=(const PhysRegId& that) const { + return RegId::operator!=(that); } + /** @} */ /** @return true if it is an integer physical register. */ - bool isIntPhysReg() const { return regClass == IntRegClass; } + bool isIntPhysReg() const { return isIntReg(); } /** @return true if it is a floating-point physical register. */ - bool isFloatPhysReg() const { return regClass == FloatRegClass; } + bool isFloatPhysReg() const { return isFloatReg(); } /** @Return true if it is a condition-code physical register. */ - bool isCCPhysReg() const { return regClass == CCRegClass; } + bool isCCPhysReg() const { return isCCReg(); } + + /** @Return true if it is a condition-code physical register. */ + bool isMiscPhysReg() const { return isMiscReg(); } /** * Returns true if this register is always associated to the same @@ -100,8 +118,11 @@ struct PhysRegId { */ bool isFixedMapping() const { - return regClass == MiscRegClass; + return !isRenameable(); } + + /** Flat index accessor */ + const PhysRegIndex& flatIndex() const { return flatIdx; } }; // PhysRegIds only need to be created once and then we can use the following diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 6e9accdd5..a7a39b72a 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -300,20 +300,21 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params) // Note that we can't use the rename() method because we don't // want special treatment for the zero register at this point PhysRegIdPtr phys_reg = freeList.getIntReg(); - renameMap[tid].setIntEntry(ridx, phys_reg); - commitRenameMap[tid].setIntEntry(ridx, phys_reg); + renameMap[tid].setEntry(RegId(IntRegClass, ridx), phys_reg); + commitRenameMap[tid].setEntry(RegId(IntRegClass, ridx), phys_reg); } for (RegIndex ridx = 0; ridx < TheISA::NumFloatRegs; ++ridx) { PhysRegIdPtr phys_reg = freeList.getFloatReg(); - renameMap[tid].setFloatEntry(ridx, phys_reg); - commitRenameMap[tid].setFloatEntry(ridx, phys_reg); + renameMap[tid].setEntry(RegId(FloatRegClass, ridx), phys_reg); + commitRenameMap[tid].setEntry( + RegId(FloatRegClass, ridx), phys_reg); } for (RegIndex ridx = 0; ridx < TheISA::NumCCRegs; ++ridx) { PhysRegIdPtr phys_reg = freeList.getCCReg(); - renameMap[tid].setCCEntry(ridx, phys_reg); - commitRenameMap[tid].setCCEntry(ridx, phys_reg); + renameMap[tid].setEntry(RegId(CCRegClass, ridx), phys_reg); + commitRenameMap[tid].setEntry(RegId(CCRegClass, ridx), phys_reg); } } @@ -788,24 +789,24 @@ FullO3CPU<Impl>::insertThread(ThreadID tid) //Bind Int Regs to Rename Map - for (RegId reg_id(IntRegClass, 0); reg_id.regIdx < TheISA::NumIntRegs; - reg_id.regIdx++) { + for (RegId reg_id(IntRegClass, 0); reg_id.index() < TheISA::NumIntRegs; + reg_id.index()++) { PhysRegIdPtr phys_reg = freeList.getIntReg(); renameMap[tid].setEntry(reg_id, phys_reg); scoreboard.setReg(phys_reg); } //Bind Float Regs to Rename Map - for (RegId reg_id(FloatRegClass, 0); reg_id.regIdx < TheISA::NumFloatRegs; - reg_id.regIdx++) { + for (RegId reg_id(FloatRegClass, 0); reg_id.index() < TheISA::NumFloatRegs; + reg_id.index()++) { PhysRegIdPtr phys_reg = freeList.getFloatReg(); renameMap[tid].setEntry(reg_id, phys_reg); scoreboard.setReg(phys_reg); } //Bind condition-code Regs to Rename Map - for (RegId reg_id(CCRegClass, 0); reg_id.regIdx < TheISA::NumCCRegs; - reg_id.regIdx++) { + for (RegId reg_id(CCRegClass, 0); reg_id.index() < TheISA::NumCCRegs; + reg_id.index()++) { PhysRegIdPtr phys_reg = freeList.getCCReg(); renameMap[tid].setEntry(reg_id, phys_reg); scoreboard.setReg(phys_reg); @@ -842,24 +843,24 @@ FullO3CPU<Impl>::removeThread(ThreadID tid) // in SMT workloads. // Unbind Int Regs from Rename Map - for (RegId reg_id(IntRegClass, 0); reg_id.regIdx < TheISA::NumIntRegs; - reg_id.regIdx++) { + for (RegId reg_id(IntRegClass, 0); reg_id.index() < TheISA::NumIntRegs; + reg_id.index()++) { PhysRegIdPtr phys_reg = renameMap[tid].lookup(reg_id); scoreboard.unsetReg(phys_reg); freeList.addReg(phys_reg); } // Unbind Float Regs from Rename Map - for (RegId reg_id(FloatRegClass, 0); reg_id.regIdx < TheISA::NumFloatRegs; - reg_id.regIdx++) { + for (RegId reg_id(FloatRegClass, 0); reg_id.index() < TheISA::NumFloatRegs; + reg_id.index()++) { PhysRegIdPtr phys_reg = renameMap[tid].lookup(reg_id); scoreboard.unsetReg(phys_reg); freeList.addReg(phys_reg); } // Unbind condition-code Regs from Rename Map - for (RegId reg_id(CCRegClass, 0); reg_id.regIdx < TheISA::NumCCRegs; - reg_id.regIdx++) { + for (RegId reg_id(CCRegClass, 0); reg_id.index() < TheISA::NumCCRegs; + reg_id.index()++) { PhysRegIdPtr phys_reg = renameMap[tid].lookup(reg_id); scoreboard.unsetReg(phys_reg); freeList.addReg(phys_reg); @@ -1300,7 +1301,8 @@ uint64_t FullO3CPU<Impl>::readArchIntReg(int reg_idx, ThreadID tid) { intRegfileReads++; - PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupInt(reg_idx); + PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup( + RegId(IntRegClass, reg_idx)); return regFile.readIntReg(phys_reg); } @@ -1310,7 +1312,8 @@ float FullO3CPU<Impl>::readArchFloatReg(int reg_idx, ThreadID tid) { fpRegfileReads++; - PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupFloat(reg_idx); + PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup( + RegId(FloatRegClass, reg_idx)); return regFile.readFloatReg(phys_reg); } @@ -1320,7 +1323,8 @@ uint64_t FullO3CPU<Impl>::readArchFloatRegInt(int reg_idx, ThreadID tid) { fpRegfileReads++; - PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupFloat(reg_idx); + PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup( + RegId(FloatRegClass, reg_idx)); return regFile.readFloatRegBits(phys_reg); } @@ -1330,7 +1334,8 @@ CCReg FullO3CPU<Impl>::readArchCCReg(int reg_idx, ThreadID tid) { ccRegfileReads++; - PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupCC(reg_idx); + PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup( + RegId(CCRegClass, reg_idx)); return regFile.readCCReg(phys_reg); } @@ -1340,7 +1345,8 @@ void FullO3CPU<Impl>::setArchIntReg(int reg_idx, uint64_t val, ThreadID tid) { intRegfileWrites++; - PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupInt(reg_idx); + PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup( + RegId(IntRegClass, reg_idx)); regFile.setIntReg(phys_reg, val); } @@ -1350,7 +1356,8 @@ void FullO3CPU<Impl>::setArchFloatReg(int reg_idx, float val, ThreadID tid) { fpRegfileWrites++; - PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupFloat(reg_idx); + PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup( + RegId(FloatRegClass, reg_idx)); regFile.setFloatReg(phys_reg, val); } @@ -1360,7 +1367,8 @@ void FullO3CPU<Impl>::setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid) { fpRegfileWrites++; - PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupFloat(reg_idx); + PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup( + RegId(FloatRegClass, reg_idx)); regFile.setFloatRegBits(phys_reg, val); } @@ -1370,7 +1378,8 @@ void FullO3CPU<Impl>::setArchCCReg(int reg_idx, CCReg val, ThreadID tid) { ccRegfileWrites++; - PhysRegIdPtr phys_reg = commitRenameMap[tid].lookupCC(reg_idx); + PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup( + RegId(CCRegClass, reg_idx)); regFile.setCCReg(phys_reg, val); } diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh index b200a328a..a6adb4c20 100644 --- a/src/cpu/o3/dyn_inst.hh +++ b/src/cpu/o3/dyn_inst.hh @@ -123,7 +123,7 @@ class BaseO3DynInst : public BaseDynInst<Impl> public: #if TRACING_ON /** Tick records used for the pipeline activity viewer. */ - Tick fetchTick; // instruction fetch is completed. + Tick fetchTick; // instruction fetch is completed. int32_t decodeTick; // instruction enters decode phase int32_t renameTick; // instruction enters rename phase int32_t dispatchTick; @@ -170,9 +170,9 @@ class BaseO3DynInst : public BaseDynInst<Impl> */ TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx) { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == MiscRegClass); - return this->cpu->readMiscReg(reg.regIdx, this->threadNumber); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isMiscReg()); + return this->cpu->readMiscReg(reg.index(), this->threadNumber); } /** Sets a misc. register, including any side-effects the write @@ -181,9 +181,9 @@ class BaseO3DynInst : public BaseDynInst<Impl> void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val) { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == MiscRegClass); - setMiscReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isMiscReg()); + setMiscReg(reg.index(), val); } /** Called at the commit stage to update the misc. registers. */ @@ -208,9 +208,9 @@ class BaseO3DynInst : public BaseDynInst<Impl> for (int idx = 0; idx < this->numDestRegs(); idx++) { PhysRegIdPtr prev_phys_reg = this->prevDestRegIdx(idx); - RegId original_dest_reg = + const RegId& original_dest_reg = this->staticInst->destRegIdx(idx); - switch (original_dest_reg.regClass) { + switch (original_dest_reg.classValue()) { case IntRegClass: this->setIntRegOperand(this->staticInst.get(), idx, this->cpu->readIntReg(prev_phys_reg)); @@ -300,13 +300,13 @@ class BaseO3DynInst : public BaseDynInst<Impl> } #if THE_ISA == MIPS_ISA - MiscReg readRegOtherThread(RegId misc_reg, ThreadID tid) + MiscReg readRegOtherThread(const RegId& misc_reg, ThreadID tid) { panic("MIPS MT not defined for O3 CPU.\n"); return 0; } - void setRegOtherThread(RegId misc_reg, MiscReg val, ThreadID tid) + void setRegOtherThread(const RegId& misc_reg, MiscReg val, ThreadID tid) { panic("MIPS MT not defined for O3 CPU.\n"); } diff --git a/src/cpu/o3/free_list.hh b/src/cpu/o3/free_list.hh index 3e6740e57..6fc6cc909 100644 --- a/src/cpu/o3/free_list.hh +++ b/src/cpu/o3/free_list.hh @@ -183,11 +183,11 @@ class UnifiedFreeList inline void UnifiedFreeList::addReg(PhysRegIdPtr freed_reg) { - DPRINTF(FreeList,"Freeing register %i (%s).\n", freed_reg->regIdx, - RegClassStrings[freed_reg->regClass]); + DPRINTF(FreeList,"Freeing register %i (%s).\n", freed_reg->index(), + freed_reg->className()); //Might want to add in a check for whether or not this register is //already in there. A bit vector or something similar would be useful. - switch (freed_reg->regClass) { + switch (freed_reg->classValue()) { case IntRegClass: intList.addReg(freed_reg); break; @@ -199,7 +199,7 @@ UnifiedFreeList::addReg(PhysRegIdPtr freed_reg) break; default: panic("Unexpected RegClass (%s)", - RegClassStrings[freed_reg->regClass]); + freed_reg->className()); } // These assert conditions ensure that the number of free diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh index cdb6b26e2..80d7adc54 100644 --- a/src/cpu/o3/iew_impl.hh +++ b/src/cpu/o3/iew_impl.hh @@ -1434,8 +1434,8 @@ DefaultIEW<Impl>::writebackInsts() for (int i = 0; i < inst->numDestRegs(); i++) { //mark as Ready DPRINTF(IEW,"Setting Destination Register %i (%s)\n", - inst->renamedDestRegIdx(i)->regIdx, - RegClassStrings[inst->renamedDestRegIdx(i)->regClass]); + inst->renamedDestRegIdx(i)->index(), + inst->renamedDestRegIdx(i)->className()); scoreboard->setReg(inst->renamedDestRegIdx(i)); } diff --git a/src/cpu/o3/inst_queue_impl.hh b/src/cpu/o3/inst_queue_impl.hh index c46fd6ba7..f52cf2d6c 100644 --- a/src/cpu/o3/inst_queue_impl.hh +++ b/src/cpu/o3/inst_queue_impl.hh @@ -986,17 +986,17 @@ InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst) // handled by the IQ and thus have no dependency graph entry. if (dest_reg->isFixedMapping()) { DPRINTF(IQ, "Reg %d [%s] is part of a fix mapping, skipping\n", - dest_reg->regIdx, RegClassStrings[dest_reg->regClass]); + dest_reg->index(), dest_reg->className()); continue; } DPRINTF(IQ, "Waking any dependents on register %i (%s).\n", - dest_reg->regIdx, - RegClassStrings[dest_reg->regClass]); + dest_reg->index(), + dest_reg->className()); //Go through the dependency chain, marking the registers as //ready within the waiting instructions. - DynInstPtr dep_inst = dependGraph.pop(dest_reg->flatIdx); + DynInstPtr dep_inst = dependGraph.pop(dest_reg->flatIndex()); while (dep_inst) { DPRINTF(IQ, "Waking up a dependent instruction, [sn:%lli] " @@ -1010,18 +1010,18 @@ InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst) addIfReady(dep_inst); - dep_inst = dependGraph.pop(dest_reg->flatIdx); + dep_inst = dependGraph.pop(dest_reg->flatIndex()); ++dependents; } // Reset the head node now that all of its dependents have // been woken up. - assert(dependGraph.empty(dest_reg->flatIdx)); - dependGraph.clearInst(dest_reg->flatIdx); + assert(dependGraph.empty(dest_reg->flatIndex())); + dependGraph.clearInst(dest_reg->flatIndex()); // Mark the scoreboard as having that register ready. - regScoreboard[dest_reg->flatIdx] = true; + regScoreboard[dest_reg->flatIndex()] = true; } return dependents; } @@ -1233,7 +1233,8 @@ InstructionQueue<Impl>::doSquash(ThreadID tid) if (!squashed_inst->isReadySrcRegIdx(src_reg_idx) && !src_reg->isFixedMapping()) { - dependGraph.remove(src_reg->flatIdx, squashed_inst); + dependGraph.remove(src_reg->flatIndex(), + squashed_inst); } @@ -1308,13 +1309,13 @@ InstructionQueue<Impl>::addToDependents(DynInstPtr &new_inst) // it be added to the dependency graph. if (src_reg->isFixedMapping()) { continue; - } else if (!regScoreboard[src_reg->flatIdx]) { + } else if (!regScoreboard[src_reg->flatIndex()]) { DPRINTF(IQ, "Instruction PC %s has src reg %i (%s) that " "is being added to the dependency chain.\n", - new_inst->pcState(), src_reg->regIdx, - RegClassStrings[src_reg->regClass]); + new_inst->pcState(), src_reg->index(), + src_reg->className()); - dependGraph.insert(src_reg->flatIdx, new_inst); + dependGraph.insert(src_reg->flatIndex(), new_inst); // Change the return value to indicate that something // was added to the dependency graph. @@ -1322,8 +1323,8 @@ InstructionQueue<Impl>::addToDependents(DynInstPtr &new_inst) } else { DPRINTF(IQ, "Instruction PC %s has src reg %i (%s) that " "became ready before it reached the IQ.\n", - new_inst->pcState(), src_reg->regIdx, - RegClassStrings[src_reg->regClass]); + new_inst->pcState(), src_reg->index(), + src_reg->className()); // Mark a register ready within the instruction. new_inst->markSrcRegReady(src_reg_idx); } @@ -1355,17 +1356,17 @@ InstructionQueue<Impl>::addToProducers(DynInstPtr &new_inst) continue; } - if (!dependGraph.empty(dest_reg->flatIdx)) { + if (!dependGraph.empty(dest_reg->flatIndex())) { dependGraph.dump(); panic("Dependency graph %i (%s) (flat: %i) not empty!", - dest_reg->regIdx, RegClassStrings[dest_reg->regClass], - dest_reg->flatIdx); + dest_reg->index(), dest_reg->className(), + dest_reg->flatIndex()); } - dependGraph.setInst(dest_reg->flatIdx, new_inst); + dependGraph.setInst(dest_reg->flatIndex(), new_inst); // Mark the scoreboard to say it's not yet ready. - regScoreboard[dest_reg->flatIdx] = false; + regScoreboard[dest_reg->flatIndex()] = false; } } diff --git a/src/cpu/o3/probe/elastic_trace.cc b/src/cpu/o3/probe/elastic_trace.cc index 76f7e439a..08ef6654d 100644 --- a/src/cpu/o3/probe/elastic_trace.cc +++ b/src/cpu/o3/probe/elastic_trace.cc @@ -242,8 +242,8 @@ ElasticTrace::updateRegDep(const DynInstPtr &dyn_inst) PhysRegIdPtr src_reg = dyn_inst->renamedSrcRegIdx(src_idx); DPRINTFR(ElasticTrace, "[sn:%lli] Check map for src reg" " %i (%s)\n", seq_num, - src_reg->regIdx, RegClassStrings[src_reg->regClass]); - auto itr_last_writer = physRegDepMap.find(src_reg->flatIdx); + src_reg->index(), src_reg->className()); + auto itr_last_writer = physRegDepMap.find(src_reg->flatIndex()); if (itr_last_writer != physRegDepMap.end()) { InstSeqNum last_writer = itr_last_writer->second; // Additionally the dependency distance is kept less than the window @@ -263,16 +263,16 @@ ElasticTrace::updateRegDep(const DynInstPtr &dyn_inst) for (int dest_idx = 0; dest_idx < max_regs; dest_idx++) { // For data dependency tracking the register must be an int, float or // CC register and not a Misc register. - RegId dest_reg = dyn_inst->destRegIdx(dest_idx); - if (dest_reg.isRenameable() && + const RegId& dest_reg = dyn_inst->destRegIdx(dest_idx); + if (!dest_reg.isMiscReg() && !dest_reg.isZeroReg()) { // Get the physical register index of the i'th destination // register. PhysRegIdPtr phys_dest_reg = dyn_inst->renamedDestRegIdx(dest_idx); DPRINTFR(ElasticTrace, "[sn:%lli] Update map for dest reg" - " %i (%s)\n", seq_num, dest_reg.regIdx, - RegClassStrings[dest_reg.regClass]); - physRegDepMap[phys_dest_reg->flatIdx] = seq_num; + " %i (%s)\n", seq_num, dest_reg.index(), + dest_reg.className()); + physRegDepMap[phys_dest_reg->flatIndex()] = seq_num; } } maxPhysRegDepMapSize = std::max(physRegDepMap.size(), diff --git a/src/cpu/o3/regfile.cc b/src/cpu/o3/regfile.cc index ee8d07b3e..ea4370f48 100644 --- a/src/cpu/o3/regfile.cc +++ b/src/cpu/o3/regfile.cc @@ -89,21 +89,21 @@ PhysRegFile::initFreeList(UnifiedFreeList *freeList) // The initial batch of registers are the integer ones for (reg_idx = 0; reg_idx < numPhysicalIntRegs; reg_idx++) { - assert(intRegIds[reg_idx].regIdx == reg_idx); + assert(intRegIds[reg_idx].index() == reg_idx); freeList->addIntReg(&intRegIds[reg_idx]); } // The next batch of the registers are the floating-point physical // registers; put them onto the floating-point free list. for (reg_idx = 0; reg_idx < numPhysicalFloatRegs; reg_idx++) { - assert(floatRegIds[reg_idx].regIdx == reg_idx); + assert(floatRegIds[reg_idx].index() == reg_idx); freeList->addFloatReg(&floatRegIds[reg_idx]); } // The rest of the registers are the condition-code physical // registers; put them onto the condition-code free list. for (reg_idx = 0; reg_idx < numPhysicalCCRegs; reg_idx++) { - assert(ccRegIds[reg_idx].regIdx == reg_idx); + assert(ccRegIds[reg_idx].index() == reg_idx); freeList->addCCReg(&ccRegIds[reg_idx]); } } diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh index c7935c55c..c353b2746 100644 --- a/src/cpu/o3/regfile.hh +++ b/src/cpu/o3/regfile.hh @@ -135,8 +135,8 @@ class PhysRegFile assert(phys_reg->isIntPhysReg()); DPRINTF(IEW, "RegFile: Access to int register %i, has data " - "%#x\n", phys_reg->regIdx, intRegFile[phys_reg->regIdx]); - return intRegFile[phys_reg->regIdx]; + "%#x\n", phys_reg->index(), intRegFile[phys_reg->index()]); + return intRegFile[phys_reg->index()]; } /** Reads a floating point register (double precision). */ @@ -145,20 +145,20 @@ class PhysRegFile assert(phys_reg->isFloatPhysReg()); DPRINTF(IEW, "RegFile: Access to float register %i, has " - "data %#x\n", phys_reg->regIdx, - floatRegFile[phys_reg->regIdx].q); + "data %#x\n", phys_reg->index(), + floatRegFile[phys_reg->index()].q); - return floatRegFile[phys_reg->regIdx].d; + return floatRegFile[phys_reg->index()].d; } FloatRegBits readFloatRegBits(PhysRegIdPtr phys_reg) const { assert(phys_reg->isFloatPhysReg()); - FloatRegBits floatRegBits = floatRegFile[phys_reg->regIdx].q; + FloatRegBits floatRegBits = floatRegFile[phys_reg->index()].q; DPRINTF(IEW, "RegFile: Access to float register %i as int, " - "has data %#x\n", phys_reg->regIdx, + "has data %#x\n", phys_reg->index(), (uint64_t)floatRegBits); return floatRegBits; @@ -170,10 +170,10 @@ class PhysRegFile assert(phys_reg->isCCPhysReg()); DPRINTF(IEW, "RegFile: Access to cc register %i, has " - "data %#x\n", phys_reg->regIdx, - ccRegFile[phys_reg->regIdx]); + "data %#x\n", phys_reg->index(), + ccRegFile[phys_reg->index()]); - return ccRegFile[phys_reg->regIdx]; + return ccRegFile[phys_reg->index()]; } /** Sets an integer register to the given value. */ @@ -182,10 +182,10 @@ class PhysRegFile assert(phys_reg->isIntPhysReg()); DPRINTF(IEW, "RegFile: Setting int register %i to %#x\n", - phys_reg->regIdx, val); + phys_reg->index(), val); if (!phys_reg->isZeroReg()) - intRegFile[phys_reg->regIdx] = val; + intRegFile[phys_reg->index()] = val; } /** Sets a double precision floating point register to the given value. */ @@ -194,10 +194,10 @@ class PhysRegFile assert(phys_reg->isFloatPhysReg()); DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n", - phys_reg->regIdx, (uint64_t)val); + phys_reg->index(), (uint64_t)val); if (!phys_reg->isZeroReg()) - floatRegFile[phys_reg->regIdx].d = val; + floatRegFile[phys_reg->index()].d = val; } void setFloatRegBits(PhysRegIdPtr phys_reg, FloatRegBits val) @@ -205,9 +205,9 @@ class PhysRegFile assert(phys_reg->isFloatPhysReg()); DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n", - phys_reg->regIdx, (uint64_t)val); + phys_reg->index(), (uint64_t)val); - floatRegFile[phys_reg->regIdx].q = val; + floatRegFile[phys_reg->index()].q = val; } /** Sets a condition-code register to the given value. */ @@ -216,9 +216,9 @@ class PhysRegFile assert(phys_reg->isCCPhysReg()); DPRINTF(IEW, "RegFile: Setting cc register %i to %#x\n", - phys_reg->regIdx, (uint64_t)val); + phys_reg->index(), (uint64_t)val); - ccRegFile[phys_reg->regIdx] = val; + ccRegFile[phys_reg->index()] = val; } }; diff --git a/src/cpu/o3/rename.hh b/src/cpu/o3/rename.hh index ab7ae5f8b..6d3861ba6 100644 --- a/src/cpu/o3/rename.hh +++ b/src/cpu/o3/rename.hh @@ -298,7 +298,7 @@ class DefaultRename * register for that arch. register, and the new physical register. */ struct RenameHistory { - RenameHistory(InstSeqNum _instSeqNum, RegId _archReg, + RenameHistory(InstSeqNum _instSeqNum, const RegId& _archReg, PhysRegIdPtr _newPhysReg, PhysRegIdPtr _prevPhysReg) : instSeqNum(_instSeqNum), archReg(_archReg), diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh index a92792639..9c9b030f5 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2012, 2014-2015 ARM Limited + * Copyright (c) 2010-2012, 2014-2016 ARM Limited * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved. * @@ -985,8 +985,8 @@ DefaultRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num, ThreadID tid) DPRINTF(Rename, "[tid:%u]: Freeing up older rename of reg %i (%s), " "[sn:%lli].\n", - tid, hb_it->prevPhysReg->regIdx, - RegClassStrings[hb_it->prevPhysReg->regClass], + tid, hb_it->prevPhysReg->index(), + hb_it->prevPhysReg->className(), hb_it->instSeqNum); // Don't free special phys regs like misc and zero regs, which @@ -1013,59 +1013,46 @@ DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid) // Get the architectual register numbers from the source and // operands, and redirect them to the right physical register. for (int src_idx = 0; src_idx < num_src_regs; src_idx++) { - RegId src_reg = inst->srcRegIdx(src_idx); - RegIndex flat_src_reg; + const RegId& src_reg = inst->srcRegIdx(src_idx); PhysRegIdPtr renamed_reg; - switch (src_reg.regClass) { + renamed_reg = map->lookup(tc->flattenRegId(src_reg)); + switch (src_reg.classValue()) { case IntRegClass: - flat_src_reg = tc->flattenIntIndex(src_reg.regIdx); - renamed_reg = map->lookupInt(flat_src_reg); intRenameLookups++; break; - case FloatRegClass: - flat_src_reg = tc->flattenFloatIndex(src_reg.regIdx); - renamed_reg = map->lookupFloat(flat_src_reg); fpRenameLookups++; break; - case CCRegClass: - flat_src_reg = tc->flattenCCIndex(src_reg.regIdx); - renamed_reg = map->lookupCC(flat_src_reg); - break; - case MiscRegClass: - // misc regs don't get flattened - flat_src_reg = src_reg.regIdx; - renamed_reg = map->lookupMisc(flat_src_reg); break; default: - panic("Invalid register class: %d.", src_reg.regClass); + panic("Invalid register class: %d.", src_reg.classValue()); } DPRINTF(Rename, "[tid:%u]: Looking up %s arch reg %i" - " (flattened %i), got phys reg %i (%s)\n", tid, - RegClassStrings[src_reg.regClass], src_reg.regIdx, - flat_src_reg, renamed_reg->regIdx, - RegClassStrings[renamed_reg->regClass]); + ", got phys reg %i (%s)\n", tid, + src_reg.className(), src_reg.index(), + renamed_reg->index(), + renamed_reg->className()); inst->renameSrcReg(src_idx, renamed_reg); // See if the register is ready or not. if (scoreboard->getReg(renamed_reg)) { DPRINTF(Rename, "[tid:%u]: Register %d (flat: %d) (%s)" - " is ready.\n", tid, renamed_reg->regIdx, - renamed_reg->flatIdx, - RegClassStrings[renamed_reg->regClass]); + " is ready.\n", tid, renamed_reg->index(), + renamed_reg->flatIndex(), + renamed_reg->className()); inst->markSrcRegReady(src_idx); } else { DPRINTF(Rename, "[tid:%u]: Register %d (flat: %d) (%s)" - " is not ready.\n", tid, renamed_reg->regIdx, - renamed_reg->flatIdx, - RegClassStrings[renamed_reg->regClass]); + " is not ready.\n", tid, renamed_reg->index(), + renamed_reg->flatIndex(), + renamed_reg->className()); } ++renameRenameLookups; @@ -1082,51 +1069,26 @@ DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid) // Rename the destination registers. for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) { - RegId dest_reg = inst->destRegIdx(dest_idx); - RegIndex flat_dest_reg; + const RegId& dest_reg = inst->destRegIdx(dest_idx); typename RenameMap::RenameInfo rename_result; - switch (dest_reg.regClass) { - case IntRegClass: - flat_dest_reg = tc->flattenIntIndex(dest_reg.regIdx); - rename_result = map->renameInt(flat_dest_reg); - break; - - case FloatRegClass: - flat_dest_reg = tc->flattenFloatIndex(dest_reg.regIdx); - rename_result = map->renameFloat(flat_dest_reg); - break; - - case CCRegClass: - flat_dest_reg = tc->flattenCCIndex(dest_reg.regIdx); - rename_result = map->renameCC(flat_dest_reg); - break; - - case MiscRegClass: - // misc regs don't get flattened - flat_dest_reg = dest_reg.regIdx; - rename_result = map->renameMisc(dest_reg.regIdx); - break; - - default: - panic("Invalid register class: %d.", dest_reg.regClass); - } + RegId flat_dest_regid = tc->flattenRegId(dest_reg); - RegId flat_uni_dest_reg(dest_reg.regClass, flat_dest_reg); + rename_result = map->rename(flat_dest_regid); - inst->flattenDestReg(dest_idx, flat_uni_dest_reg); + inst->flattenDestReg(dest_idx, flat_dest_regid); // Mark Scoreboard entry as not ready scoreboard->unsetReg(rename_result.first); DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i (%s) to physical " - "reg %i (%i).\n", tid, dest_reg.regIdx, - RegClassStrings[dest_reg.regClass], - rename_result.first->regIdx, - rename_result.first->flatIdx); + "reg %i (%i).\n", tid, dest_reg.index(), + dest_reg.className(), + rename_result.first->index(), + rename_result.first->flatIndex()); // Record the rename information so that a history can be kept. - RenameHistory hb_entry(inst->seqNum, flat_uni_dest_reg, + RenameHistory hb_entry(inst->seqNum, flat_dest_regid, rename_result.first, rename_result.second); @@ -1439,12 +1401,12 @@ DefaultRename<Impl>::dumpHistory() cprintf("Seq num: %i\nArch reg[%s]: %i New phys reg:" " %i[%s] Old phys reg: %i[%s]\n", (*buf_it).instSeqNum, - RegClassStrings[(*buf_it).archReg.regClass], - (*buf_it).archReg.regIdx, - (*buf_it).newPhysReg->regIdx, - RegClassStrings[(*buf_it).newPhysReg->regClass], - (*buf_it).prevPhysReg->regIdx, - RegClassStrings[(*buf_it).prevPhysReg->regClass]); + (*buf_it).archReg.className(), + (*buf_it).archReg.index(), + (*buf_it).newPhysReg->index(), + (*buf_it).newPhysReg->className(), + (*buf_it).prevPhysReg->index(), + (*buf_it).prevPhysReg->className()); buf_it++; } diff --git a/src/cpu/o3/rename_map.cc b/src/cpu/o3/rename_map.cc index 4555946c2..38ccc7ec9 100644 --- a/src/cpu/o3/rename_map.cc +++ b/src/cpu/o3/rename_map.cc @@ -33,6 +33,7 @@ #include <vector> +#include "cpu/reg_class_impl.hh" #include "debug/Rename.hh" using namespace std; @@ -40,7 +41,7 @@ using namespace std; /**** SimpleRenameMap methods ****/ SimpleRenameMap::SimpleRenameMap() - : freeList(NULL), zeroReg(0) + : freeList(NULL), zeroReg(IntRegClass,0) { } @@ -54,24 +55,23 @@ SimpleRenameMap::init(unsigned size, SimpleFreeList *_freeList, map.resize(size); freeList = _freeList; - zeroReg = _zeroReg; + zeroReg = RegId(IntRegClass, _zeroReg); } SimpleRenameMap::RenameInfo -SimpleRenameMap::rename(RegIndex arch_reg) +SimpleRenameMap::rename(const RegId& arch_reg) { PhysRegIdPtr renamed_reg; - // Record the current physical register that is renamed to the // requested architected register. - PhysRegIdPtr prev_reg = map[arch_reg]; + PhysRegIdPtr prev_reg = map[arch_reg.index()]; // If it's not referencing the zero register, then rename the // register. if (arch_reg != zeroReg) { renamed_reg = freeList->getReg(); - map[arch_reg] = renamed_reg; + map[arch_reg.index()] = renamed_reg; } else { // Otherwise return the zero register so nothing bad happens. assert(prev_reg->isZeroReg()); @@ -80,8 +80,8 @@ SimpleRenameMap::rename(RegIndex arch_reg) DPRINTF(Rename, "Renamed reg %d to physical reg %d (%d) old mapping was" " %d (%d)\n", - arch_reg, renamed_reg->regIdx, renamed_reg->flatIdx, - prev_reg->regIdx, prev_reg->flatIdx); + arch_reg, renamed_reg->index(), renamed_reg->flatIndex(), + prev_reg->index(), prev_reg->flatIndex()); return RenameInfo(renamed_reg, prev_reg); } @@ -105,75 +105,3 @@ UnifiedRenameMap::init(PhysRegFile *_regFile, } - -UnifiedRenameMap::RenameInfo -UnifiedRenameMap::rename(RegId arch_reg) -{ - switch (arch_reg.regClass) { - case IntRegClass: - return renameInt(arch_reg.regIdx); - - case FloatRegClass: - return renameFloat(arch_reg.regIdx); - - case CCRegClass: - return renameCC(arch_reg.regIdx); - - case MiscRegClass: - return renameMisc(arch_reg.regIdx); - - default: - panic("rename rename(): unknown reg class %s\n", - RegClassStrings[arch_reg.regClass]); - } -} - - -PhysRegIdPtr -UnifiedRenameMap::lookup(RegId arch_reg) const -{ - switch (arch_reg.regClass) { - case IntRegClass: - return lookupInt(arch_reg.regIdx); - - case FloatRegClass: - return lookupFloat(arch_reg.regIdx); - - case CCRegClass: - return lookupCC(arch_reg.regIdx); - - case MiscRegClass: - return lookupMisc(arch_reg.regIdx); - - default: - panic("rename lookup(): unknown reg class %s\n", - RegClassStrings[arch_reg.regClass]); - } -} - -void -UnifiedRenameMap::setEntry(RegId arch_reg, PhysRegIdPtr phys_reg) -{ - switch (arch_reg.regClass) { - case IntRegClass: - return setIntEntry(arch_reg.regIdx, phys_reg); - - case FloatRegClass: - return setFloatEntry(arch_reg.regIdx, phys_reg); - - case CCRegClass: - return setCCEntry(arch_reg.regIdx, phys_reg); - - case MiscRegClass: - // Misc registers do not actually rename, so don't change - // their mappings. We end up here when a commit or squash - // tries to update or undo a hardwired misc reg nmapping, - // which should always be setting it to what it already is. - assert(phys_reg == lookupMisc(arch_reg.regIdx)); - return; - - default: - panic("rename setEntry(): unknown reg class %s\n", - RegClassStrings[arch_reg.regClass]); - } -} diff --git a/src/cpu/o3/rename_map.hh b/src/cpu/o3/rename_map.hh index f51cf5922..028c32e3a 100644 --- a/src/cpu/o3/rename_map.hh +++ b/src/cpu/o3/rename_map.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 ARM Limited + * Copyright (c) 2015-2016 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -65,9 +65,9 @@ class SimpleRenameMap { private: - + using Arch2PhysMap = std::vector<PhysRegIdPtr>; /** The acutal arch-to-phys register map */ - std::vector<PhysRegIdPtr> map; + Arch2PhysMap map; /** * Pointer to the free list from which new physical registers @@ -82,7 +82,7 @@ class SimpleRenameMap * table, it should be set to an invalid index so that it never * matches. */ - RegIndex zeroReg; + RegId zeroReg; public: @@ -112,17 +112,17 @@ class SimpleRenameMap * @return A RenameInfo pair indicating both the new and previous * physical registers. */ - RenameInfo rename(RegIndex arch_reg); + RenameInfo rename(const RegId& arch_reg); /** * Look up the physical register mapped to an architectural register. * @param arch_reg The architectural register to look up. * @return The physical register it is currently mapped to. */ - PhysRegIdPtr lookup(RegIndex arch_reg) const + PhysRegIdPtr lookup(const RegId& arch_reg) const { - assert(arch_reg < map.size()); - return map[arch_reg]; + assert(arch_reg.flatIndex() <= map.size()); + return map[arch_reg.flatIndex()]; } /** @@ -131,9 +131,10 @@ class SimpleRenameMap * @param arch_reg The architectural register to remap. * @param phys_reg The physical register to remap it to. */ - void setEntry(RegIndex arch_reg, PhysRegIdPtr phys_reg) + void setEntry(const RegId& arch_reg, PhysRegIdPtr phys_reg) { - map[arch_reg] = phys_reg; + assert(arch_reg.flatIndex() <= map.size()); + map[arch_reg.flatIndex()] = phys_reg; } /** Return the number of free entries on the associated free list. */ @@ -186,100 +187,63 @@ class UnifiedRenameMap /** * Tell rename map to get a new free physical register to remap * the specified architectural register. This version takes a - * flattened architectural register id and calls the - * appropriate class-specific rename table. - * @param arch_reg The architectural register index to remap. + * RegId and reads the appropriate class-specific rename table. + * @param arch_reg The architectural register id to remap. * @return A RenameInfo pair indicating both the new and previous * physical registers. */ - RenameInfo rename(RegId arch_reg); - - /** - * Perform rename() on an integer register, given a - * integer register index. - */ - RenameInfo renameInt(RegIndex rel_arch_reg) - { - return intMap.rename(rel_arch_reg); - } - - /** - * Perform rename() on a floating-point register, given a - * floating-point register index. - */ - RenameInfo renameFloat(RegIndex rel_arch_reg) - { - return floatMap.rename(rel_arch_reg); - } - - /** - * Perform rename() on a condition-code register, given a - * condition-code register index. - */ - RenameInfo renameCC(RegIndex rel_arch_reg) + RenameInfo rename(const RegId& arch_reg) { - return ccMap.rename(rel_arch_reg); + switch (arch_reg.classValue()) { + case IntRegClass: + return intMap.rename(arch_reg); + case FloatRegClass: + return floatMap.rename(arch_reg); + case CCRegClass: + return ccMap.rename(arch_reg); + case MiscRegClass: + { + // misc regs aren't really renamed, just remapped + PhysRegIdPtr phys_reg = lookup(arch_reg); + // Set the new register to the previous one to keep the same + // mapping throughout the execution. + return RenameInfo(phys_reg, phys_reg); + } + + default: + panic("rename rename(): unknown reg class %s\n", + arch_reg.className()); + } } /** - * Perform rename() on a misc register, given a - * misc register index. - */ - RenameInfo renameMisc(RegIndex rel_arch_reg) - { - // misc regs aren't really renamed, just remapped - PhysRegIdPtr phys_reg = lookupMisc(rel_arch_reg); - // Set the new register to the previous one to keep the same - // mapping throughout the execution. - return RenameInfo(phys_reg, phys_reg); - } - - - /** * Look up the physical register mapped to an architectural register. * This version takes a flattened architectural register id * and calls the appropriate class-specific rename table. * @param arch_reg The architectural register to look up. * @return The physical register it is currently mapped to. */ - PhysRegIdPtr lookup(RegId arch_reg) const; - - /** - * Perform lookup() on an integer register, given a - * integer register index. - */ - PhysRegIdPtr lookupInt(RegIndex rel_arch_reg) const + PhysRegIdPtr lookup(const RegId& arch_reg) const { - return intMap.lookup(rel_arch_reg); - } + switch (arch_reg.classValue()) { + case IntRegClass: + return intMap.lookup(arch_reg); - /** - * Perform lookup() on a floating-point register, given a - * floating-point register index. - */ - PhysRegIdPtr lookupFloat(RegIndex rel_arch_reg) const - { - return floatMap.lookup(rel_arch_reg); - } + case FloatRegClass: + return floatMap.lookup(arch_reg); - /** - * Perform lookup() on a condition-code register, given a - * condition-code register index. - */ - PhysRegIdPtr lookupCC(RegIndex rel_arch_reg) const - { - return ccMap.lookup(rel_arch_reg); - } + case CCRegClass: + return ccMap.lookup(arch_reg); - /** - * Perform lookup() on a misc register, given a relative - * misc register index. - */ - PhysRegIdPtr lookupMisc(RegIndex rel_arch_reg) const - { - // misc regs aren't really renamed, they keep the same - // mapping throughout the execution. - return regFile->getMiscRegId(rel_arch_reg); + case MiscRegClass: + // misc regs aren't really renamed, they keep the same + // mapping throughout the execution. + return regFile->getMiscRegId(arch_reg.flatIndex()); + + default: + panic("rename lookup(): unknown reg class %s\n", + arch_reg.className()); + } } /** @@ -290,36 +254,33 @@ class UnifiedRenameMap * @param arch_reg The architectural register to remap. * @param phys_reg The physical register to remap it to. */ - void setEntry(RegId arch_reg, PhysRegIdPtr phys_reg); - - /** - * Perform setEntry() on an integer register, given a - * integer register index. - */ - void setIntEntry(RegIndex arch_reg, PhysRegIdPtr phys_reg) - { - assert(phys_reg->isIntPhysReg()); - intMap.setEntry(arch_reg, phys_reg); - } - - /** - * Perform setEntry() on a floating-point register, given a - * floating-point register index. - */ - void setFloatEntry(RegIndex arch_reg, PhysRegIdPtr phys_reg) - { - assert(phys_reg->isFloatPhysReg()); - floatMap.setEntry(arch_reg, phys_reg); - } - - /** - * Perform setEntry() on a condition-code register, given a - * condition-code register index. - */ - void setCCEntry(RegIndex arch_reg, PhysRegIdPtr phys_reg) + void setEntry(const RegId& arch_reg, PhysRegIdPtr phys_reg) { - assert(phys_reg->isCCPhysReg()); - ccMap.setEntry(arch_reg, phys_reg); + switch (arch_reg.classValue()) { + case IntRegClass: + assert(phys_reg->isIntPhysReg()); + return intMap.setEntry(arch_reg, phys_reg); + + case FloatRegClass: + assert(phys_reg->isFloatPhysReg()); + return floatMap.setEntry(arch_reg, phys_reg); + + case CCRegClass: + assert(phys_reg->isCCPhysReg()); + return ccMap.setEntry(arch_reg, phys_reg); + + case MiscRegClass: + // Misc registers do not actually rename, so don't change + // their mappings. We end up here when a commit or squash + // tries to update or undo a hardwired misc reg nmapping, + // which should always be setting it to what it already is. + assert(phys_reg == lookup(arch_reg)); + return; + + default: + panic("rename setEntry(): unknown reg class %s\n", + arch_reg.className()); + } } /** diff --git a/src/cpu/o3/scoreboard.hh b/src/cpu/o3/scoreboard.hh index 44e449944..1012bae59 100644 --- a/src/cpu/o3/scoreboard.hh +++ b/src/cpu/o3/scoreboard.hh @@ -80,14 +80,14 @@ class Scoreboard /** Checks if the register is ready. */ bool getReg(PhysRegIdPtr phys_reg) const { - assert(phys_reg->flatIdx < numPhysRegs); + assert(phys_reg->flatIndex() < numPhysRegs); if (phys_reg->isFixedMapping()) { // Fixed mapping regs are always ready return true; } - bool ready = regScoreBoard[phys_reg->flatIdx]; + bool ready = regScoreBoard[phys_reg->flatIndex()]; if (phys_reg->isZeroReg()) assert(ready); @@ -98,7 +98,7 @@ class Scoreboard /** Sets the register as ready. */ void setReg(PhysRegIdPtr phys_reg) { - assert(phys_reg->flatIdx < numPhysRegs); + assert(phys_reg->flatIndex() < numPhysRegs); if (phys_reg->isFixedMapping()) { // Fixed mapping regs are always ready, ignore attempts to change @@ -106,16 +106,16 @@ class Scoreboard return; } - DPRINTF(Scoreboard, "Setting reg %i (%s) as ready\n", phys_reg->regIdx, - RegClassStrings[phys_reg->regClass]); + DPRINTF(Scoreboard, "Setting reg %i (%s) as ready\n", + phys_reg->index(), phys_reg->className()); - regScoreBoard[phys_reg->flatIdx] = true; + regScoreBoard[phys_reg->flatIndex()] = true; } /** Sets the register as not ready. */ void unsetReg(PhysRegIdPtr phys_reg) { - assert(phys_reg->flatIdx < numPhysRegs); + assert(phys_reg->flatIndex() < numPhysRegs); if (phys_reg->isFixedMapping()) { // Fixed mapping regs are always ready, ignore attempts to @@ -127,7 +127,7 @@ class Scoreboard if (phys_reg->isZeroReg()) return; - regScoreBoard[phys_reg->flatIdx] = false; + regScoreBoard[phys_reg->flatIndex()] = false; } }; diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh index 78b88ac2a..161d70b28 100755 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@ -175,37 +175,47 @@ class O3ThreadContext : public ThreadContext virtual void clearArchRegs(); /** Reads an integer register. */ + virtual uint64_t readReg(int reg_idx) { + return readIntRegFlat(flattenRegId(RegId(IntRegClass, + reg_idx)).index()); + } virtual uint64_t readIntReg(int reg_idx) { - return readIntRegFlat(flattenIntIndex(reg_idx)); + return readIntRegFlat(flattenRegId(RegId(IntRegClass, + reg_idx)).index()); } virtual FloatReg readFloatReg(int reg_idx) { - return readFloatRegFlat(flattenFloatIndex(reg_idx)); + return readFloatRegFlat(flattenRegId(RegId(FloatRegClass, + reg_idx)).index()); } virtual FloatRegBits readFloatRegBits(int reg_idx) { - return readFloatRegBitsFlat(flattenFloatIndex(reg_idx)); + return readFloatRegBitsFlat(flattenRegId(RegId(FloatRegClass, + reg_idx)).index()); } virtual CCReg readCCReg(int reg_idx) { - return readCCRegFlat(flattenCCIndex(reg_idx)); + return readCCRegFlat(flattenRegId(RegId(CCRegClass, + reg_idx)).index()); } /** Sets an integer register to a value. */ virtual void setIntReg(int reg_idx, uint64_t val) { - setIntRegFlat(flattenIntIndex(reg_idx), val); + setIntRegFlat(flattenRegId(RegId(IntRegClass, reg_idx)).index(), val); } virtual void setFloatReg(int reg_idx, FloatReg val) { - setFloatRegFlat(flattenFloatIndex(reg_idx), val); + setFloatRegFlat(flattenRegId(RegId(FloatRegClass, + reg_idx)).index(), val); } virtual void setFloatRegBits(int reg_idx, FloatRegBits val) { - setFloatRegBitsFlat(flattenFloatIndex(reg_idx), val); + setFloatRegBitsFlat(flattenRegId(RegId(FloatRegClass, + reg_idx)).index(), val); } virtual void setCCReg(int reg_idx, CCReg val) { - setCCRegFlat(flattenCCIndex(reg_idx), val); + setCCRegFlat(flattenRegId(RegId(CCRegClass, reg_idx)).index(), val); } /** Reads this thread's PC state. */ @@ -245,10 +255,7 @@ class O3ThreadContext : public ThreadContext * write might have as defined by the architecture. */ virtual void setMiscReg(int misc_reg, const MiscReg &val); - virtual int flattenIntIndex(int reg); - virtual int flattenFloatIndex(int reg); - virtual int flattenCCIndex(int reg); - virtual int flattenMiscIndex(int reg); + virtual RegId flattenRegId(const RegId& regId) const; /** Returns the number of consecutive store conditional failures. */ // @todo: Figure out where these store cond failures should go. diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh index e6a3d5083..c3f894275 100755 --- a/src/cpu/o3/thread_context_impl.hh +++ b/src/cpu/o3/thread_context_impl.hh @@ -270,31 +270,10 @@ O3ThreadContext<Impl>::pcStateNoRecord(const TheISA::PCState &val) } template <class Impl> -int -O3ThreadContext<Impl>::flattenIntIndex(int reg) +RegId +O3ThreadContext<Impl>::flattenRegId(const RegId& regId) const { - return cpu->isa[thread->threadId()]->flattenIntIndex(reg); -} - -template <class Impl> -int -O3ThreadContext<Impl>::flattenFloatIndex(int reg) -{ - return cpu->isa[thread->threadId()]->flattenFloatIndex(reg); -} - -template <class Impl> -int -O3ThreadContext<Impl>::flattenCCIndex(int reg) -{ - return cpu->isa[thread->threadId()]->flattenCCIndex(reg); -} - -template <class Impl> -int -O3ThreadContext<Impl>::flattenMiscIndex(int reg) -{ - return cpu->isa[thread->threadId()]->flattenMiscIndex(reg); + return cpu->isa[thread->threadId()]->flattenRegId(regId); } template <class Impl> |