diff options
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> |