diff options
Diffstat (limited to 'src/cpu')
33 files changed, 588 insertions, 660 deletions
diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh index 369d7a02a..9c6952310 100644 --- a/src/cpu/base_dyn_inst.hh +++ b/src/cpu/base_dyn_inst.hh @@ -383,7 +383,7 @@ class BaseDynInst : public ExecContext, public RefCounted /** Returns the flattened register index of the i'th destination * register. */ - RegId flattenedDestRegIdx(int idx) const + const RegId& flattenedDestRegIdx(int idx) const { return _flatDestRegIdx[idx]; } @@ -419,7 +419,7 @@ class BaseDynInst : public ExecContext, public RefCounted /** Flattens a destination architectural register index into a logical * index. */ - void flattenDestReg(int idx, RegId flattened_dest) + void flattenDestReg(int idx, const RegId& flattened_dest) { _flatDestRegIdx[idx] = flattened_dest; } @@ -601,10 +601,10 @@ class BaseDynInst : public ExecContext, public RefCounted int8_t numCCDestRegs() const { return staticInst->numCCDestRegs(); } /** Returns the logical register index of the i'th destination register. */ - RegId destRegIdx(int i) const { return staticInst->destRegIdx(i); } + const RegId& destRegIdx(int i) const { return staticInst->destRegIdx(i); } /** Returns the logical register index of the i'th source register. */ - RegId srcRegIdx(int i) const { return staticInst->srcRegIdx(i); } + const RegId& srcRegIdx(int i) const { return staticInst->srcRegIdx(i); } /** Pops a result off the instResult queue */ template <class T> diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh index 3afbc31fb..304caaa85 100644 --- a/src/cpu/checker/cpu.hh +++ b/src/cpu/checker/cpu.hh @@ -213,31 +213,31 @@ class CheckerCPU : public BaseCPU, public ExecContext IntReg readIntRegOperand(const StaticInst *si, int idx) override { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == IntRegClass); - return thread->readIntReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isIntReg()); + return thread->readIntReg(reg.index()); } FloatReg readFloatRegOperand(const StaticInst *si, int idx) override { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == FloatRegClass); - return thread->readFloatReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isFloatReg()); + return thread->readFloatReg(reg.index()); } FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) override { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == FloatRegClass); - return thread->readFloatRegBits(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isFloatReg()); + return thread->readFloatRegBits(reg.index()); } CCReg readCCRegOperand(const StaticInst *si, int idx) override { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == CCRegClass); - return thread->readCCReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isCCReg()); + return thread->readCCReg(reg.index()); } template <class T> @@ -251,35 +251,35 @@ class CheckerCPU : public BaseCPU, public ExecContext void setIntRegOperand(const StaticInst *si, int idx, IntReg val) override { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == IntRegClass); - thread->setIntReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isIntReg()); + thread->setIntReg(reg.index(), val); setResult<uint64_t>(val); } void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) override { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == FloatRegClass); - thread->setFloatReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isFloatReg()); + thread->setFloatReg(reg.index(), val); setResult<double>(val); } void setFloatRegOperandBits(const StaticInst *si, int idx, FloatRegBits val) override { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == FloatRegClass); - thread->setFloatRegBits(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isFloatReg()); + thread->setFloatRegBits(reg.index(), val); setResult<uint64_t>(val); } void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == CCRegClass); - thread->setCCReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isCCReg()); + thread->setCCReg(reg.index(), val); setResult<uint64_t>(val); } @@ -327,27 +327,28 @@ class CheckerCPU : public BaseCPU, public ExecContext MiscReg readMiscRegOperand(const StaticInst *si, int idx) override { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == MiscRegClass); - return thread->readMiscReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isMiscReg()); + return thread->readMiscReg(reg.index()); } void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val) override { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == MiscRegClass); - return this->setMiscReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isMiscReg()); + return this->setMiscReg(reg.index(), val); } #if THE_ISA == MIPS_ISA - MiscReg readRegOtherThread(RegId misc_reg, ThreadID tid) override + MiscReg readRegOtherThread(const RegId& misc_reg, ThreadID tid) override { panic("MIPS MT not defined for CheckerCPU.\n"); return 0; } - void setRegOtherThread(RegId misc_reg, MiscReg val, ThreadID tid) override + void setRegOtherThread(const RegId& misc_reg, MiscReg val, + ThreadID tid) override { panic("MIPS MT not defined for CheckerCPU.\n"); } diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh index 47a088aa6..0c90590c7 100644 --- a/src/cpu/checker/cpu_impl.hh +++ b/src/cpu/checker/cpu_impl.hh @@ -595,40 +595,40 @@ Checker<Impl>::copyResult(DynInstPtr &inst, uint64_t mismatch_val, // We've already popped one dest off the queue, // so do the fix-up then start with the next dest reg; if (start_idx >= 0) { - RegId idx = inst->destRegIdx(start_idx); - switch (idx.regClass) { + const RegId& idx = inst->destRegIdx(start_idx); + switch (idx.classValue()) { case IntRegClass: - thread->setIntReg(idx.regIdx, mismatch_val); + thread->setIntReg(idx.index(), mismatch_val); break; case FloatRegClass: - thread->setFloatRegBits(idx.regIdx, mismatch_val); + thread->setFloatRegBits(idx.index(), mismatch_val); break; case CCRegClass: - thread->setCCReg(idx.regIdx, mismatch_val); + thread->setCCReg(idx.index(), mismatch_val); break; case MiscRegClass: - thread->setMiscReg(idx.regIdx, mismatch_val); + thread->setMiscReg(idx.index(), mismatch_val); break; } } start_idx++; uint64_t res = 0; for (int i = start_idx; i < inst->numDestRegs(); i++) { - RegId idx = inst->destRegIdx(i); + const RegId& idx = inst->destRegIdx(i); inst->template popResult<uint64_t>(res); - switch (idx.regClass) { + switch (idx.classValue()) { case IntRegClass: - thread->setIntReg(idx.regIdx, res); + thread->setIntReg(idx.index(), res); break; case FloatRegClass: - thread->setFloatRegBits(idx.regIdx, res); + thread->setFloatRegBits(idx.index(), res); break; case CCRegClass: - thread->setCCReg(idx.regIdx, res); + thread->setCCReg(idx.index(), res); break; case MiscRegClass: // Try to get the proper misc register index for ARM here... - thread->setMiscReg(idx.regIdx, res); + thread->setMiscReg(idx.index(), res); break; // else Register is out of range... } diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh index 7b09dde90..e48f5936b 100644 --- a/src/cpu/checker/thread_context.hh +++ b/src/cpu/checker/thread_context.hh @@ -301,10 +301,9 @@ class CheckerThreadContext : public ThreadContext actualTC->setMiscReg(misc_reg, val); } - int flattenIntIndex(int reg) { return actualTC->flattenIntIndex(reg); } - int flattenFloatIndex(int reg) { return actualTC->flattenFloatIndex(reg); } - int flattenCCIndex(int reg) { return actualTC->flattenCCIndex(reg); } - int flattenMiscIndex(int reg) { return actualTC->flattenMiscIndex(reg); } + RegId flattenRegId(const RegId& regId) const { + return actualTC->flattenRegId(regId); + } unsigned readStCondFailures() { return actualTC->readStCondFailures(); } diff --git a/src/cpu/exec_context.hh b/src/cpu/exec_context.hh index 1b6084e27..d33147240 100644 --- a/src/cpu/exec_context.hh +++ b/src/cpu/exec_context.hh @@ -287,9 +287,9 @@ class ExecContext { */ #if THE_ISA == MIPS_ISA - virtual MiscReg readRegOtherThread(RegId reg, + virtual MiscReg readRegOtherThread(const RegId& reg, ThreadID tid = InvalidThreadID) = 0; - virtual void setRegOtherThread(RegId reg, MiscReg val, + virtual void setRegOtherThread(const RegId& reg, MiscReg val, ThreadID tid = InvalidThreadID) = 0; #endif diff --git a/src/cpu/minor/dyn_inst.cc b/src/cpu/minor/dyn_inst.cc index 42c370a70..1ed598833 100644 --- a/src/cpu/minor/dyn_inst.cc +++ b/src/cpu/minor/dyn_inst.cc @@ -133,15 +133,13 @@ operator <<(std::ostream &os, const MinorDynInst &inst) /** Print a register in the form r<n>, f<n>, m<n>(<name>), z for integer, * float, misc and zero registers given an 'architectural register number' */ static void -printRegName(std::ostream &os, RegId reg) +printRegName(std::ostream &os, const RegId& reg) { - RegClass reg_class = reg.regClass; - - switch (reg_class) + switch (reg.classValue()) { case MiscRegClass: { - RegIndex misc_reg = reg.regIdx; + RegIndex misc_reg = reg.index(); /* This is an ugly test because not all archs. have miscRegName */ #if THE_ISA == ARM_ISA @@ -153,17 +151,17 @@ printRegName(std::ostream &os, RegId reg) } break; case FloatRegClass: - os << 'f' << static_cast<unsigned int>(reg.regIdx); + os << 'f' << static_cast<unsigned int>(reg.index()); break; case IntRegClass: if (reg.isZeroReg()) { os << 'z'; } else { - os << 'r' << static_cast<unsigned int>(reg.regIdx); + os << 'r' << static_cast<unsigned int>(reg.index()); } break; case CCRegClass: - os << 'c' << static_cast<unsigned int>(reg.regIdx); + os << 'c' << static_cast<unsigned int>(reg.index()); } } diff --git a/src/cpu/minor/exec_context.hh b/src/cpu/minor/exec_context.hh index d517d5abb..e91b7a6dd 100644 --- a/src/cpu/minor/exec_context.hh +++ b/src/cpu/minor/exec_context.hh @@ -124,51 +124,51 @@ class ExecContext : public ::ExecContext IntReg readIntRegOperand(const StaticInst *si, int idx) override { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == IntRegClass); - return thread.readIntReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isIntReg()); + return thread.readIntReg(reg.index()); } TheISA::FloatReg readFloatRegOperand(const StaticInst *si, int idx) override { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == FloatRegClass); - return thread.readFloatReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isFloatReg()); + return thread.readFloatReg(reg.index()); } TheISA::FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) override { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == FloatRegClass); - return thread.readFloatRegBits(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isFloatReg()); + return thread.readFloatRegBits(reg.index()); } void setIntRegOperand(const StaticInst *si, int idx, IntReg val) override { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == IntRegClass); - thread.setIntReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isIntReg()); + thread.setIntReg(reg.index(), val); } void setFloatRegOperand(const StaticInst *si, int idx, TheISA::FloatReg val) override { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == FloatRegClass); - thread.setFloatReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isFloatReg()); + thread.setFloatReg(reg.index(), val); } void setFloatRegOperandBits(const StaticInst *si, int idx, TheISA::FloatRegBits val) override { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == FloatRegClass); - thread.setFloatRegBits(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isFloatReg()); + thread.setFloatRegBits(reg.index(), val); } bool @@ -216,18 +216,18 @@ class ExecContext : public ::ExecContext TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx) override { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == MiscRegClass); - return thread.readMiscReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isMiscReg()); + return thread.readMiscReg(reg.index()); } void setMiscRegOperand(const StaticInst *si, int idx, const TheISA::MiscReg &val) override { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == MiscRegClass); - return thread.setMiscReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isMiscReg()); + return thread.setMiscReg(reg.index(), val); } Fault @@ -279,17 +279,17 @@ class ExecContext : public ::ExecContext TheISA::CCReg readCCRegOperand(const StaticInst *si, int idx) override { - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == CCRegClass); - return thread.readCCReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isCCReg()); + return thread.readCCReg(reg.index()); } void setCCRegOperand(const StaticInst *si, int idx, TheISA::CCReg val) override { - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == CCRegClass); - thread.setCCReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isCCReg()); + thread.setCCReg(reg.index(), val); } void @@ -320,46 +320,46 @@ class ExecContext : public ::ExecContext /* MIPS: other thread register reading/writing */ uint64_t - readRegOtherThread(RegId reg, ThreadID tid = InvalidThreadID) + readRegOtherThread(const RegId& reg, ThreadID tid = InvalidThreadID) { SimpleThread *other_thread = (tid == InvalidThreadID ? &thread : cpu.threads[tid]); - switch(reg.regClass) { + switch (reg.classValue()) { case IntRegClass: - return other_thread->readIntReg(reg.regIdx); + return other_thread->readIntReg(reg.index()); break; case FloatRegClass: - return other_thread->readFloatRegBits(reg.regIdx); + return other_thread->readFloatRegBits(reg.index()); break; case MiscRegClass: - return other_thread->readMiscReg(reg.regIdx); + return other_thread->readMiscReg(reg.index()); default: panic("Unexpected reg class! (%s)", - RegClassStrings[reg.regClass]); + reg.className()); return 0; } } void - setRegOtherThread(RegId reg, const TheISA::MiscReg &val, + setRegOtherThread(const RegId& reg, const TheISA::MiscReg &val, ThreadID tid = InvalidThreadID) { SimpleThread *other_thread = (tid == InvalidThreadID ? &thread : cpu.threads[tid]); - switch(reg.regClass) { + switch (reg.classValue()) { case IntRegClass: - return other_thread->setIntReg(reg.regIdx, val); + return other_thread->setIntReg(reg.index(), val); break; case FloatRegClass: - return other_thread->setFloatRegBits(reg.regIdx, val); + return other_thread->setFloatRegBits(reg.index(), val); break; case MiscRegClass: - return other_thread->setMiscReg(reg.regIdx, val); + return other_thread->setMiscReg(reg.index(), val); default: panic("Unexpected reg class! (%s)", - RegClassStrings[reg.regClass]); + reg.className()); } } diff --git a/src/cpu/minor/scoreboard.cc b/src/cpu/minor/scoreboard.cc index 31657b310..e3497a5cf 100644 --- a/src/cpu/minor/scoreboard.cc +++ b/src/cpu/minor/scoreboard.cc @@ -48,7 +48,7 @@ namespace Minor { bool -Scoreboard::findIndex(RegId reg, Index &scoreboard_index) +Scoreboard::findIndex(const RegId& reg, Index &scoreboard_index) { bool ret = false; @@ -56,19 +56,19 @@ Scoreboard::findIndex(RegId reg, Index &scoreboard_index) /* Don't bother with the zero register */ ret = false; } else { - switch (reg.regClass) + switch (reg.classValue()) { case IntRegClass: - scoreboard_index = reg.regIdx; + scoreboard_index = reg.index(); ret = true; break; case FloatRegClass: scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs + - reg.regIdx; + reg.index(); ret = true; break; case CCRegClass: - scoreboard_index = TheISA::NumIntRegs + reg.regIdx; + scoreboard_index = TheISA::NumIntRegs + reg.index(); ret = true; break; case MiscRegClass: @@ -83,26 +83,9 @@ Scoreboard::findIndex(RegId reg, Index &scoreboard_index) /** Flatten a RegId, irrespective of what reg type it's pointing to */ static RegId -flattenRegIndex(RegId reg, ThreadContext *thread_context) +flattenRegIndex(const RegId& reg, ThreadContext *thread_context) { - switch (reg.regClass) - { - case IntRegClass: - reg.regIdx = thread_context->flattenIntIndex(reg.regIdx); - break; - case FloatRegClass: - reg.regIdx = thread_context->flattenFloatIndex(reg.regIdx); - break; - case CCRegClass: - reg.regIdx = thread_context->flattenCCIndex(reg.regIdx); - break; - case MiscRegClass: - /* Don't bother to flatten misc regs as we don't need them here */ - /* return thread_context->flattenMiscIndex(reg); */ - break; - } - - return reg; + return thread_context->flattenRegId(reg); } void @@ -143,7 +126,8 @@ Scoreboard::markupInstDests(MinorDynInstPtr inst, Cycles retire_time, *inst, index, numResults[index], returnCycle[index]); } else { /* Use ZeroReg to mark invalid/untracked dests */ - inst->flatDestRegIdx[dest_index] = RegId::zeroReg; + inst->flatDestRegIdx[dest_index] = RegId(IntRegClass, + TheISA::ZeroReg); } } } @@ -190,7 +174,7 @@ Scoreboard::clearInstDests(MinorDynInstPtr inst, bool clear_unpredictable) for (unsigned int dest_index = 0; dest_index < num_dests; dest_index++) { - RegId reg = inst->flatDestRegIdx[dest_index]; + const RegId& reg = inst->flatDestRegIdx[dest_index]; Index index; if (findIndex(reg, index)) { diff --git a/src/cpu/minor/scoreboard.hh b/src/cpu/minor/scoreboard.hh index 815d81408..7fe5002f9 100644 --- a/src/cpu/minor/scoreboard.hh +++ b/src/cpu/minor/scoreboard.hh @@ -106,7 +106,7 @@ class Scoreboard : public Named /** Sets scoreboard_index to the index into numResults of the * given register index. Returns true if the given register * is in the scoreboard and false if it isn't */ - bool findIndex(RegId reg, Index &scoreboard_index); + bool findIndex(const RegId& reg, Index &scoreboard_index); /** Mark up an instruction's effects by incrementing * numResults counts. If mark_unpredictable is true, the inst's 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> diff --git a/src/cpu/reg_class.cc b/src/cpu/reg_class.cc index 75be4679d..53a50ce8e 100644 --- a/src/cpu/reg_class.cc +++ b/src/cpu/reg_class.cc @@ -30,11 +30,10 @@ #include "cpu/reg_class.hh" -const char *RegClassStrings[] = { +const char *RegId::regClassStrings[] = { "IntRegClass", "FloatRegClass", "CCRegClass", "MiscRegClass" }; -const RegId RegId::zeroReg = RegId(IntRegClass, TheISA::ZeroReg); diff --git a/src/cpu/reg_class.hh b/src/cpu/reg_class.hh index 25c882c58..05869e8fb 100644 --- a/src/cpu/reg_class.hh +++ b/src/cpu/reg_class.hh @@ -51,7 +51,7 @@ #include "arch/registers.hh" #include "config/the_isa.hh" -/// Enumerate the classes of registers. +/** Enumerate the classes of registers. */ enum RegClass { IntRegClass, ///< Integer register FloatRegClass, ///< Floating-point register @@ -59,54 +59,91 @@ enum RegClass { MiscRegClass ///< Control (misc) register }; -/// Number of register classes. This value is not part of the enum, -/// because putting it there makes the compiler complain about -/// unhandled cases in some switch statements. +/** Number of register classes. + * This value is not part of the enum, because putting it there makes the + * compiler complain about unhandled cases in some switch statements. + */ const int NumRegClasses = MiscRegClass + 1; -/// Register ID: describe an architectural register with its class and index. -/// This structure is used instead of just the register index to disambiguate -/// between different classes of registers. -/// For example, a integer register with index 3 is represented by -/// Regid(IntRegClass, 3). -struct RegId { +/** Register ID: describe an architectural register with its class and index. + * This structure is used instead of just the register index to disambiguate + * between different classes of registers. For example, a integer register with + * index 3 is represented by Regid(IntRegClass, 3). + */ +class RegId { + private: + static const char* regClassStrings[]; RegClass regClass; RegIndex regIdx; + public: RegId() {}; RegId(RegClass reg_class, RegIndex reg_idx) : regClass(reg_class), regIdx(reg_idx) {} bool operator==(const RegId& that) const { - return regClass == that.regClass && regIdx == that.regIdx; + return regClass == that.classValue() && regIdx == that.index(); } bool operator!=(const RegId& that) const { return !(*this==that); } - /** - * Returns true if this register is a zero register (needs to have a - * constant zero value throughout the execution) + /** Order operator. + * The order is required to implement maps with key type RegId */ - bool isZeroReg() const - { - return (regIdx == TheISA::ZeroReg && - (regClass == IntRegClass || - (THE_ISA == ALPHA_ISA && regClass == FloatRegClass))); + bool operator<(const RegId& that) const { + return regClass < that.classValue() || + (regClass == that.classValue() && regIdx < that.index()); } /** * Return true if this register can be renamed */ - bool isRenameable() + bool isRenameable() const { return regClass != MiscRegClass; } - static const RegId zeroReg; -}; + /** + * Check if this is the zero register. + * Returns true if this register is a zero register (needs to have a + * constant zero value throughout the execution). + */ + + inline bool isZeroReg() const; -/// Map enum values to strings for debugging -extern const char *RegClassStrings[]; + /** @return true if it is an integer physical register. */ + bool isIntReg() const { return regClass == IntRegClass; } + + /** @return true if it is a floating-point physical register. */ + bool isFloatReg() const { return regClass == FloatRegClass; } + + /** @Return true if it is a condition-code physical register. */ + bool isCCReg() const { return regClass == CCRegClass; } + + /** @Return true if it is a condition-code physical register. */ + bool isMiscReg() const { return regClass == MiscRegClass; } + + /** Index accessors */ + /** @{ */ + const RegIndex& index() const { return regIdx; } + RegIndex& index() { return regIdx; } + + /** Index flattening. + * Required to be able to use a vector for the register mapping. + */ + inline RegIndex flatIndex() const; + /** @} */ + + /** Class accessor */ + const RegClass& classValue() const { return regClass; } + /** Return a const char* with the register class name. */ + const char* className() const { return regClassStrings[regClass]; } + + friend std::ostream& + operator<<(std::ostream& os, const RegId& rid) { + return os << rid.className() << "{" << rid.index() << "}"; + } +}; #endif // __CPU__REG_CLASS_HH__ diff --git a/src/cpu/reg_class_impl.hh b/src/cpu/reg_class_impl.hh new file mode 100644 index 000000000..a47328b10 --- /dev/null +++ b/src/cpu/reg_class_impl.hh @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Rekai Gonzalez + */ + +#ifndef __CPU__REG_CLASS_IMPL_HH__ +#define __CPU__REG_CLASS_IMPL_HH__ + +#include <cassert> +#include <cstddef> +#include <iostream> + +#include "arch/registers.hh" +#include "config/the_isa.hh" +#include "cpu/reg_class.hh" + +bool RegId::isZeroReg() const +{ + return ((regClass == IntRegClass && regIdx == TheISA::ZeroReg) || + (THE_ISA == ALPHA_ISA && regClass == FloatRegClass && + regIdx == TheISA::ZeroReg)); +} + +RegIndex RegId::flatIndex() const { + switch (regClass) { + case IntRegClass: + case FloatRegClass: + case CCRegClass: + case MiscRegClass: + return regIdx; + } + panic("Trying to flatten a register without class!"); + return -1; +} + +#endif // __CPU__REG_CLASS_IMPL_HH__ diff --git a/src/cpu/simple/exec_context.hh b/src/cpu/simple/exec_context.hh index 9689796f3..f221d6c93 100644 --- a/src/cpu/simple/exec_context.hh +++ b/src/cpu/simple/exec_context.hh @@ -165,27 +165,27 @@ class SimpleExecContext : public ExecContext { IntReg readIntRegOperand(const StaticInst *si, int idx) override { numIntRegReads++; - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == IntRegClass); - return thread->readIntReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isIntReg()); + return thread->readIntReg(reg.index()); } /** Sets an integer register to a value. */ void setIntRegOperand(const StaticInst *si, int idx, IntReg val) override { numIntRegWrites++; - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == IntRegClass); - thread->setIntReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isIntReg()); + thread->setIntReg(reg.index(), val); } /** Reads a floating point register of single register width. */ FloatReg readFloatRegOperand(const StaticInst *si, int idx) override { numFpRegReads++; - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == FloatRegClass); - return thread->readFloatReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isFloatReg()); + return thread->readFloatReg(reg.index()); } /** Reads a floating point register in its binary format, instead @@ -193,9 +193,9 @@ class SimpleExecContext : public ExecContext { FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) override { numFpRegReads++; - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == FloatRegClass); - return thread->readFloatRegBits(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isFloatReg()); + return thread->readFloatRegBits(reg.index()); } /** Sets a floating point register of single width to a value. */ @@ -203,9 +203,9 @@ class SimpleExecContext : public ExecContext { FloatReg val) override { numFpRegWrites++; - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == FloatRegClass); - thread->setFloatReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isFloatReg()); + thread->setFloatReg(reg.index(), val); } /** Sets the bits of a floating point register of single width @@ -214,42 +214,42 @@ class SimpleExecContext : public ExecContext { FloatRegBits val) override { numFpRegWrites++; - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == FloatRegClass); - thread->setFloatRegBits(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isFloatReg()); + thread->setFloatRegBits(reg.index(), val); } CCReg readCCRegOperand(const StaticInst *si, int idx) override { numCCRegReads++; - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == CCRegClass); - return thread->readCCReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isCCReg()); + return thread->readCCReg(reg.index()); } void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override { numCCRegWrites++; - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == CCRegClass); - thread->setCCReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isCCReg()); + thread->setCCReg(reg.index(), val); } MiscReg readMiscRegOperand(const StaticInst *si, int idx) override { numIntRegReads++; - RegId reg = si->srcRegIdx(idx); - assert(reg.regClass == MiscRegClass); - return thread->readMiscReg(reg.regIdx); + const RegId& reg = si->srcRegIdx(idx); + assert(reg.isMiscReg()); + return thread->readMiscReg(reg.index()); } void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val) override { numIntRegWrites++; - RegId reg = si->destRegIdx(idx); - assert(reg.regClass == MiscRegClass); - thread->setMiscReg(reg.regIdx, val); + const RegId& reg = si->destRegIdx(idx); + assert(reg.isMiscReg()); + thread->setMiscReg(reg.index(), val); } /** @@ -411,14 +411,15 @@ class SimpleExecContext : public ExecContext { } #if THE_ISA == MIPS_ISA - MiscReg readRegOtherThread(RegId reg, ThreadID tid = InvalidThreadID) + MiscReg readRegOtherThread(const RegId& reg, + ThreadID tid = InvalidThreadID) override { panic("Simple CPU models do not support multithreaded " "register access."); } - void setRegOtherThread(RegId reg, MiscReg val, + void setRegOtherThread(const RegId& reg, MiscReg val, ThreadID tid = InvalidThreadID) override { panic("Simple CPU models do not support multithreaded " diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index bdf93b0e4..286d91766 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -401,28 +401,10 @@ class SimpleThread : public ThreadState return isa->setMiscReg(misc_reg, val, tc); } - int - flattenIntIndex(int reg) + RegId + flattenRegId(const RegId& regId) const { - return isa->flattenIntIndex(reg); - } - - int - flattenFloatIndex(int reg) - { - return isa->flattenFloatIndex(reg); - } - - int - flattenCCIndex(int reg) - { - return isa->flattenCCIndex(reg); - } - - int - flattenMiscIndex(int reg) - { - return isa->flattenMiscIndex(reg); + return isa->flattenRegId(regId); } unsigned readStCondFailures() { return storeCondFailures; } diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh index 751301095..d60afc019 100644 --- a/src/cpu/static_inst.hh +++ b/src/cpu/static_inst.hh @@ -43,6 +43,7 @@ #include "config/the_isa.hh" #include "cpu/op_class.hh" #include "cpu/reg_class.hh" +#include "cpu/reg_class_impl.hh" #include "cpu/static_inst_fwd.hh" #include "cpu/thread_context.hh" #include "enums/StaticInstFlags.hh" @@ -184,11 +185,11 @@ class StaticInst : public RefCounted, public StaticInstFlags /// Return logical index (architectural reg num) of i'th destination reg. /// Only the entries from 0 through numDestRegs()-1 are valid. - RegId destRegIdx(int i) const { return _destRegIdx[i]; } + const RegId& destRegIdx(int i) const { return _destRegIdx[i]; } /// Return logical index (architectural reg num) of i'th source reg. /// Only the entries from 0 through numSrcRegs()-1 are valid. - RegId srcRegIdx(int i) const { return _srcRegIdx[i]; } + const RegId& srcRegIdx(int i) const { return _srcRegIdx[i]; } /// Pointer to a statically allocated "null" instruction object. /// Used to give eaCompInst() and memAccInst() something to return diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh index efa0b2162..43c40481e 100644 --- a/src/cpu/thread_context.hh +++ b/src/cpu/thread_context.hh @@ -250,19 +250,16 @@ class ThreadContext virtual void setMiscReg(int misc_reg, const MiscReg &val) = 0; - virtual int flattenIntIndex(int reg) = 0; - virtual int flattenFloatIndex(int reg) = 0; - virtual int flattenCCIndex(int reg) = 0; - virtual int flattenMiscIndex(int reg) = 0; + virtual RegId flattenRegId(const RegId& regId) const = 0; virtual uint64_t - readRegOtherThread(RegId misc_reg, ThreadID tid) + readRegOtherThread(const RegId& misc_reg, ThreadID tid) { return 0; } virtual void - setRegOtherThread(RegId misc_reg, const MiscReg &val, ThreadID tid) + setRegOtherThread(const RegId& misc_reg, const MiscReg &val, ThreadID tid) { } @@ -291,7 +288,7 @@ class ThreadContext * * Some architectures have different registers visible in * different modes. Such architectures "flatten" a register (see - * flattenIntIndex() and flattenFloatIndex()) to map it into the + * flattenRegId()) to map it into the * gem5 register file. This interface provides a flat interface to * the underlying register file, which allows for example * serialization code to access all registers. @@ -466,17 +463,8 @@ class ProxyThreadContext : public ThreadContext void setMiscReg(int misc_reg, const MiscReg &val) { return actualTC->setMiscReg(misc_reg, val); } - int flattenIntIndex(int reg) - { return actualTC->flattenIntIndex(reg); } - - int flattenFloatIndex(int reg) - { return actualTC->flattenFloatIndex(reg); } - - int flattenCCIndex(int reg) - { return actualTC->flattenCCIndex(reg); } - - int flattenMiscIndex(int reg) - { return actualTC->flattenMiscIndex(reg); } + RegId flattenRegId(const RegId& regId) const + { return actualTC->flattenRegId(regId); } unsigned readStCondFailures() { return actualTC->readStCondFailures(); } diff --git a/src/cpu/timing_expr.cc b/src/cpu/timing_expr.cc index 99b4eb6aa..da5c6489e 100644 --- a/src/cpu/timing_expr.cc +++ b/src/cpu/timing_expr.cc @@ -58,7 +58,7 @@ TimingExprEvalContext::TimingExprEvalContext(const StaticInstPtr &inst_, uint64_t TimingExprSrcReg::eval(TimingExprEvalContext &context) { - return context.inst->srcRegIdx(index).regIdx; + return context.inst->srcRegIdx(index).index(); } uint64_t TimingExprReadIntReg::eval(TimingExprEvalContext &context) |