diff options
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/base_dyn_inst.hh | 13 | ||||
-rw-r--r-- | src/cpu/checker/cpu.hh | 52 | ||||
-rw-r--r-- | src/cpu/checker/cpu_impl.hh | 25 | ||||
-rw-r--r-- | src/cpu/exec_context.hh | 5 | ||||
-rw-r--r-- | src/cpu/minor/dyn_inst.cc | 14 | ||||
-rw-r--r-- | src/cpu/minor/dyn_inst.hh | 2 | ||||
-rw-r--r-- | src/cpu/minor/exec_context.hh | 93 | ||||
-rw-r--r-- | src/cpu/minor/scoreboard.cc | 45 | ||||
-rw-r--r-- | src/cpu/minor/scoreboard.hh | 5 | ||||
-rw-r--r-- | src/cpu/o3/cpu.cc | 39 | ||||
-rw-r--r-- | src/cpu/o3/dyn_inst.hh | 25 | ||||
-rw-r--r-- | src/cpu/o3/dyn_inst_impl.hh | 4 | ||||
-rw-r--r-- | src/cpu/o3/probe/elastic_trace.cc | 18 | ||||
-rw-r--r-- | src/cpu/o3/rename.hh | 7 | ||||
-rw-r--r-- | src/cpu/o3/rename_impl.hh | 69 | ||||
-rw-r--r-- | src/cpu/o3/rename_map.cc | 48 | ||||
-rw-r--r-- | src/cpu/o3/rename_map.hh | 49 | ||||
-rw-r--r-- | src/cpu/o3/rob.hh | 2 | ||||
-rw-r--r-- | src/cpu/reg_class.cc | 2 | ||||
-rw-r--r-- | src/cpu/reg_class.hh | 93 | ||||
-rw-r--r-- | src/cpu/simple/exec_context.hh | 53 | ||||
-rw-r--r-- | src/cpu/static_inst.hh | 11 | ||||
-rw-r--r-- | src/cpu/thread_context.hh | 5 | ||||
-rw-r--r-- | src/cpu/timing_expr.cc | 2 |
24 files changed, 355 insertions, 326 deletions
diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh index 6d9a53253..84a6540af 100644 --- a/src/cpu/base_dyn_inst.hh +++ b/src/cpu/base_dyn_inst.hh @@ -82,9 +82,6 @@ class BaseDynInst : public ExecContext, public RefCounted typedef typename Impl::CPUType ImplCPU; typedef typename ImplCPU::ImplState ImplState; - // Logical register index type. - typedef TheISA::RegIndex RegIndex; - // The DynInstPtr type. typedef typename Impl::DynInstPtr DynInstPtr; typedef RefCountingPtr<BaseDynInst<Impl> > BaseDynInstPtr; @@ -265,7 +262,7 @@ class BaseDynInst : public ExecContext, public RefCounted /** Flattened register index of the destination registers of this * instruction. */ - std::array<TheISA::RegIndex, TheISA::MaxInstDestRegs> _flatDestRegIdx; + std::array<RegId, TheISA::MaxInstDestRegs> _flatDestRegIdx; /** Physical register index of the destination registers of this * instruction. @@ -386,7 +383,7 @@ class BaseDynInst : public ExecContext, public RefCounted /** Returns the flattened register index of the i'th destination * register. */ - TheISA::RegIndex flattenedDestRegIdx(int idx) const + RegId flattenedDestRegIdx(int idx) const { return _flatDestRegIdx[idx]; } @@ -422,7 +419,7 @@ class BaseDynInst : public ExecContext, public RefCounted /** Flattens a destination architectural register index into a logical * index. */ - void flattenDestReg(int idx, TheISA::RegIndex flattened_dest) + void flattenDestReg(int idx, RegId flattened_dest) { _flatDestRegIdx[idx] = flattened_dest; } @@ -604,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. */ - RegIndex destRegIdx(int i) const { return staticInst->destRegIdx(i); } + RegId destRegIdx(int i) const { return staticInst->destRegIdx(i); } /** Returns the logical register index of the i'th source register. */ - RegIndex srcRegIdx(int i) const { return staticInst->srcRegIdx(i); } + 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 e47c88484..3afbc31fb 100644 --- a/src/cpu/checker/cpu.hh +++ b/src/cpu/checker/cpu.hh @@ -213,26 +213,31 @@ class CheckerCPU : public BaseCPU, public ExecContext IntReg readIntRegOperand(const StaticInst *si, int idx) override { - return thread->readIntReg(si->srcRegIdx(idx)); + RegId reg = si->srcRegIdx(idx); + assert(reg.regClass == IntRegClass); + return thread->readIntReg(reg.regIdx); } FloatReg readFloatRegOperand(const StaticInst *si, int idx) override { - int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base; - return thread->readFloatReg(reg_idx); + RegId reg = si->srcRegIdx(idx); + assert(reg.regClass == FloatRegClass); + return thread->readFloatReg(reg.regIdx); } FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) override { - int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base; - return thread->readFloatRegBits(reg_idx); + RegId reg = si->srcRegIdx(idx); + assert(reg.regClass == FloatRegClass); + return thread->readFloatRegBits(reg.regIdx); } CCReg readCCRegOperand(const StaticInst *si, int idx) override { - int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base; - return thread->readCCReg(reg_idx); + RegId reg = si->srcRegIdx(idx); + assert(reg.regClass == CCRegClass); + return thread->readCCReg(reg.regIdx); } template <class T> @@ -246,30 +251,35 @@ class CheckerCPU : public BaseCPU, public ExecContext void setIntRegOperand(const StaticInst *si, int idx, IntReg val) override { - thread->setIntReg(si->destRegIdx(idx), val); + RegId reg = si->destRegIdx(idx); + assert(reg.regClass == IntRegClass); + thread->setIntReg(reg.regIdx, val); setResult<uint64_t>(val); } void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) override { - int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base; - thread->setFloatReg(reg_idx, val); + RegId reg = si->destRegIdx(idx); + assert(reg.regClass == FloatRegClass); + thread->setFloatReg(reg.regIdx, val); setResult<double>(val); } void setFloatRegOperandBits(const StaticInst *si, int idx, FloatRegBits val) override { - int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base; - thread->setFloatRegBits(reg_idx, val); + RegId reg = si->destRegIdx(idx); + assert(reg.regClass == FloatRegClass); + thread->setFloatRegBits(reg.regIdx, val); setResult<uint64_t>(val); } void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override { - int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base; - thread->setCCReg(reg_idx, val); + RegId reg = si->destRegIdx(idx); + assert(reg.regClass == CCRegClass); + thread->setCCReg(reg.regIdx, val); setResult<uint64_t>(val); } @@ -317,25 +327,27 @@ class CheckerCPU : public BaseCPU, public ExecContext MiscReg readMiscRegOperand(const StaticInst *si, int idx) override { - int reg_idx = si->srcRegIdx(idx) - TheISA::Misc_Reg_Base; - return thread->readMiscReg(reg_idx); + RegId reg = si->srcRegIdx(idx); + assert(reg.regClass == MiscRegClass); + return thread->readMiscReg(reg.regIdx); } void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val) override { - int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base; - return this->setMiscReg(reg_idx, val); + RegId reg = si->destRegIdx(idx); + assert(reg.regClass == MiscRegClass); + return this->setMiscReg(reg.regIdx, val); } #if THE_ISA == MIPS_ISA - MiscReg readRegOtherThread(int misc_reg, ThreadID tid) override + MiscReg readRegOtherThread(RegId misc_reg, ThreadID tid) override { panic("MIPS MT not defined for CheckerCPU.\n"); return 0; } - void setRegOtherThread(int misc_reg, MiscReg val, ThreadID tid) override + void setRegOtherThread(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 5d5900aae..47a088aa6 100644 --- a/src/cpu/checker/cpu_impl.hh +++ b/src/cpu/checker/cpu_impl.hh @@ -595,41 +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) { - RegIndex idx = inst->destRegIdx(start_idx); - switch (regIdxToClass(idx)) { + RegId idx = inst->destRegIdx(start_idx); + switch (idx.regClass) { case IntRegClass: - thread->setIntReg(idx, mismatch_val); + thread->setIntReg(idx.regIdx, mismatch_val); break; case FloatRegClass: - thread->setFloatRegBits(idx - TheISA::FP_Reg_Base, mismatch_val); + thread->setFloatRegBits(idx.regIdx, mismatch_val); break; case CCRegClass: - thread->setCCReg(idx - TheISA::CC_Reg_Base, mismatch_val); + thread->setCCReg(idx.regIdx, mismatch_val); break; case MiscRegClass: - thread->setMiscReg(idx - TheISA::Misc_Reg_Base, - mismatch_val); + thread->setMiscReg(idx.regIdx, mismatch_val); break; } } start_idx++; uint64_t res = 0; for (int i = start_idx; i < inst->numDestRegs(); i++) { - RegIndex idx = inst->destRegIdx(i); + RegId idx = inst->destRegIdx(i); inst->template popResult<uint64_t>(res); - switch (regIdxToClass(idx)) { + switch (idx.regClass) { case IntRegClass: - thread->setIntReg(idx, res); + thread->setIntReg(idx.regIdx, res); break; case FloatRegClass: - thread->setFloatRegBits(idx - TheISA::FP_Reg_Base, res); + thread->setFloatRegBits(idx.regIdx, res); break; case CCRegClass: - thread->setCCReg(idx - TheISA::CC_Reg_Base, res); + thread->setCCReg(idx.regIdx, res); break; case MiscRegClass: // Try to get the proper misc register index for ARM here... - thread->setMiscReg(idx - TheISA::Misc_Reg_Base, res); + thread->setMiscReg(idx.regIdx, res); break; // else Register is out of range... } diff --git a/src/cpu/exec_context.hh b/src/cpu/exec_context.hh index b21f0767a..1b6084e27 100644 --- a/src/cpu/exec_context.hh +++ b/src/cpu/exec_context.hh @@ -49,6 +49,7 @@ #include "base/types.hh" #include "config/the_isa.hh" #include "cpu/base.hh" +#include "cpu/reg_class.hh" #include "cpu/static_inst_fwd.hh" #include "cpu/translation.hh" #include "mem/request.hh" @@ -286,9 +287,9 @@ class ExecContext { */ #if THE_ISA == MIPS_ISA - virtual MiscReg readRegOtherThread(int regIdx, + virtual MiscReg readRegOtherThread(RegId reg, ThreadID tid = InvalidThreadID) = 0; - virtual void setRegOtherThread(int regIdx, MiscReg val, + virtual void setRegOtherThread(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 16af15bd7..42c370a70 100644 --- a/src/cpu/minor/dyn_inst.cc +++ b/src/cpu/minor/dyn_inst.cc @@ -133,15 +133,15 @@ 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, TheISA::RegIndex reg) +printRegName(std::ostream &os, RegId reg) { - RegClass reg_class = regIdxToClass(reg); + RegClass reg_class = reg.regClass; switch (reg_class) { case MiscRegClass: { - TheISA::RegIndex misc_reg = reg - TheISA::Misc_Reg_Base; + RegIndex misc_reg = reg.regIdx; /* This is an ugly test because not all archs. have miscRegName */ #if THE_ISA == ARM_ISA @@ -153,17 +153,17 @@ printRegName(std::ostream &os, TheISA::RegIndex reg) } break; case FloatRegClass: - os << 'f' << static_cast<unsigned int>(reg - TheISA::FP_Reg_Base); + os << 'f' << static_cast<unsigned int>(reg.regIdx); break; case IntRegClass: - if (reg == TheISA::ZeroReg) { + if (reg.isZeroReg()) { os << 'z'; } else { - os << 'r' << static_cast<unsigned int>(reg); + os << 'r' << static_cast<unsigned int>(reg.regIdx); } break; case CCRegClass: - os << 'c' << static_cast<unsigned int>(reg - TheISA::CC_Reg_Base); + os << 'c' << static_cast<unsigned int>(reg.regIdx); } } diff --git a/src/cpu/minor/dyn_inst.hh b/src/cpu/minor/dyn_inst.hh index a30d68819..79c9ca4a4 100644 --- a/src/cpu/minor/dyn_inst.hh +++ b/src/cpu/minor/dyn_inst.hh @@ -219,7 +219,7 @@ class MinorDynInst : public RefCounted /** Flat register indices so that, when clearing the scoreboard, we * have the same register indices as when the instruction was marked * up */ - TheISA::RegIndex flatDestRegIdx[TheISA::MaxInstDestRegs]; + RegId flatDestRegIdx[TheISA::MaxInstDestRegs]; /** Effective address as set by ExecContext::setEA */ Addr ea; diff --git a/src/cpu/minor/exec_context.hh b/src/cpu/minor/exec_context.hh index 6b2eae0f1..d517d5abb 100644 --- a/src/cpu/minor/exec_context.hh +++ b/src/cpu/minor/exec_context.hh @@ -124,43 +124,51 @@ class ExecContext : public ::ExecContext IntReg readIntRegOperand(const StaticInst *si, int idx) override { - return thread.readIntReg(si->srcRegIdx(idx)); + RegId reg = si->srcRegIdx(idx); + assert(reg.regClass == IntRegClass); + return thread.readIntReg(reg.regIdx); } TheISA::FloatReg readFloatRegOperand(const StaticInst *si, int idx) override { - int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base; - return thread.readFloatReg(reg_idx); + RegId reg = si->srcRegIdx(idx); + assert(reg.regClass == FloatRegClass); + return thread.readFloatReg(reg.regIdx); } TheISA::FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) override { - int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base; - return thread.readFloatRegBits(reg_idx); + RegId reg = si->srcRegIdx(idx); + assert(reg.regClass == FloatRegClass); + return thread.readFloatRegBits(reg.regIdx); } void setIntRegOperand(const StaticInst *si, int idx, IntReg val) override { - thread.setIntReg(si->destRegIdx(idx), val); + RegId reg = si->destRegIdx(idx); + assert(reg.regClass == IntRegClass); + thread.setIntReg(reg.regIdx, val); } void setFloatRegOperand(const StaticInst *si, int idx, TheISA::FloatReg val) override { - int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base; - thread.setFloatReg(reg_idx, val); + RegId reg = si->destRegIdx(idx); + assert(reg.regClass == FloatRegClass); + thread.setFloatReg(reg.regIdx, val); } void setFloatRegOperandBits(const StaticInst *si, int idx, TheISA::FloatRegBits val) override { - int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base; - thread.setFloatRegBits(reg_idx, val); + RegId reg = si->destRegIdx(idx); + assert(reg.regClass == FloatRegClass); + thread.setFloatRegBits(reg.regIdx, val); } bool @@ -208,16 +216,18 @@ class ExecContext : public ::ExecContext TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx) override { - int reg_idx = si->srcRegIdx(idx) - TheISA::Misc_Reg_Base; - return thread.readMiscReg(reg_idx); + RegId reg = si->srcRegIdx(idx); + assert(reg.regClass == MiscRegClass); + return thread.readMiscReg(reg.regIdx); } void setMiscRegOperand(const StaticInst *si, int idx, const TheISA::MiscReg &val) override { - int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base; - return thread.setMiscReg(reg_idx, val); + RegId reg = si->destRegIdx(idx); + assert(reg.regClass == MiscRegClass); + return thread.setMiscReg(reg.regIdx, val); } Fault @@ -269,15 +279,17 @@ class ExecContext : public ::ExecContext TheISA::CCReg readCCRegOperand(const StaticInst *si, int idx) override { - int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base; - return thread.readCCReg(reg_idx); + RegId reg = si->srcRegIdx(idx); + assert(reg.regClass == CCRegClass); + return thread.readCCReg(reg.regIdx); } void setCCRegOperand(const StaticInst *si, int idx, TheISA::CCReg val) override { - int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base; - thread.setCCReg(reg_idx, val); + RegId reg = si->destRegIdx(idx); + assert(reg.regClass == CCRegClass); + thread.setCCReg(reg.regIdx, val); } void @@ -308,37 +320,46 @@ class ExecContext : public ::ExecContext /* MIPS: other thread register reading/writing */ uint64_t - readRegOtherThread(int idx, ThreadID tid = InvalidThreadID) + readRegOtherThread(RegId reg, ThreadID tid = InvalidThreadID) { SimpleThread *other_thread = (tid == InvalidThreadID ? &thread : cpu.threads[tid]); - if (idx < TheISA::FP_Reg_Base) { /* Integer */ - return other_thread->readIntReg(idx); - } else if (idx < TheISA::Misc_Reg_Base) { /* Float */ - return other_thread->readFloatRegBits(idx - - TheISA::FP_Reg_Base); - } else { /* Misc */ - return other_thread->readMiscReg(idx - - TheISA::Misc_Reg_Base); + switch(reg.regClass) { + case IntRegClass: + return other_thread->readIntReg(reg.regIdx); + break; + case FloatRegClass: + return other_thread->readFloatRegBits(reg.regIdx); + break; + case MiscRegClass: + return other_thread->readMiscReg(reg.regIdx); + default: + panic("Unexpected reg class! (%s)", + RegClassStrings[reg.regClass]); + return 0; } } void - setRegOtherThread(int idx, const TheISA::MiscReg &val, + setRegOtherThread(RegId reg, const TheISA::MiscReg &val, ThreadID tid = InvalidThreadID) { SimpleThread *other_thread = (tid == InvalidThreadID ? &thread : cpu.threads[tid]); - if (idx < TheISA::FP_Reg_Base) { /* Integer */ - return other_thread->setIntReg(idx, val); - } else if (idx < TheISA::Misc_Reg_Base) { /* Float */ - return other_thread->setFloatRegBits(idx - - TheISA::FP_Reg_Base, val); - } else { /* Misc */ - return other_thread->setMiscReg(idx - - TheISA::Misc_Reg_Base, val); + switch(reg.regClass) { + case IntRegClass: + return other_thread->setIntReg(reg.regIdx, val); + break; + case FloatRegClass: + return other_thread->setFloatRegBits(reg.regIdx, val); + break; + case MiscRegClass: + return other_thread->setMiscReg(reg.regIdx, val); + default: + panic("Unexpected reg class! (%s)", + RegClassStrings[reg.regClass]); } } diff --git a/src/cpu/minor/scoreboard.cc b/src/cpu/minor/scoreboard.cc index 4de3f9522..31657b310 100644 --- a/src/cpu/minor/scoreboard.cc +++ b/src/cpu/minor/scoreboard.cc @@ -48,28 +48,27 @@ namespace Minor { bool -Scoreboard::findIndex(RegIndex reg, Index &scoreboard_index) +Scoreboard::findIndex(RegId reg, Index &scoreboard_index) { - RegClass reg_class = regIdxToClass(reg); bool ret = false; - if (reg == TheISA::ZeroReg) { + if (reg.isZeroReg()) { /* Don't bother with the zero register */ ret = false; } else { - switch (reg_class) + switch (reg.regClass) { case IntRegClass: - scoreboard_index = reg; + scoreboard_index = reg.regIdx; ret = true; break; case FloatRegClass: scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs + - reg - TheISA::FP_Reg_Base; + reg.regIdx; ret = true; break; case CCRegClass: - scoreboard_index = TheISA::NumIntRegs + reg - TheISA::FP_Reg_Base; + scoreboard_index = TheISA::NumIntRegs + reg.regIdx; ret = true; break; case MiscRegClass: @@ -82,32 +81,28 @@ Scoreboard::findIndex(RegIndex reg, Index &scoreboard_index) return ret; } -/** Flatten a RegIndex, irrespective of what reg type it's pointing to */ -static TheISA::RegIndex -flattenRegIndex(TheISA::RegIndex reg, ThreadContext *thread_context) +/** Flatten a RegId, irrespective of what reg type it's pointing to */ +static RegId +flattenRegIndex(RegId reg, ThreadContext *thread_context) { - RegClass reg_class = regIdxToClass(reg); - TheISA::RegIndex ret = reg; - - switch (reg_class) + switch (reg.regClass) { case IntRegClass: - ret = thread_context->flattenIntIndex(reg); + reg.regIdx = thread_context->flattenIntIndex(reg.regIdx); break; case FloatRegClass: - ret = thread_context->flattenFloatIndex(reg); + reg.regIdx = thread_context->flattenFloatIndex(reg.regIdx); break; case CCRegClass: - ret = thread_context->flattenCCIndex(reg); + 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); */ - ret = reg; break; } - return ret; + return reg; } void @@ -124,8 +119,8 @@ Scoreboard::markupInstDests(MinorDynInstPtr inst, Cycles retire_time, for (unsigned int dest_index = 0; dest_index < num_dests; dest_index++) { - RegIndex reg = flattenRegIndex( - staticInst->destRegIdx(dest_index), thread_context); + RegId reg = flattenRegIndex( + staticInst->destRegIdx(dest_index), thread_context); Index index; if (findIndex(reg, index)) { @@ -148,7 +143,7 @@ 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] = TheISA::ZeroReg; + inst->flatDestRegIdx[dest_index] = RegId::zeroReg; } } } @@ -166,7 +161,7 @@ Scoreboard::execSeqNumToWaitFor(MinorDynInstPtr inst, unsigned int num_srcs = staticInst->numSrcRegs(); for (unsigned int src_index = 0; src_index < num_srcs; src_index++) { - RegIndex reg = flattenRegIndex(staticInst->srcRegIdx(src_index), + RegId reg = flattenRegIndex(staticInst->srcRegIdx(src_index), thread_context); unsigned short int index; @@ -195,7 +190,7 @@ Scoreboard::clearInstDests(MinorDynInstPtr inst, bool clear_unpredictable) for (unsigned int dest_index = 0; dest_index < num_dests; dest_index++) { - RegIndex reg = inst->flatDestRegIdx[dest_index]; + RegId reg = inst->flatDestRegIdx[dest_index]; Index index; if (findIndex(reg, index)) { @@ -252,7 +247,7 @@ Scoreboard::canInstIssue(MinorDynInstPtr inst, while (src_index < num_srcs && /* More registers */ ret /* Still possible */) { - RegIndex reg = flattenRegIndex(staticInst->srcRegIdx(src_index), + RegId reg = flattenRegIndex(staticInst->srcRegIdx(src_index), thread_context); unsigned short int index; diff --git a/src/cpu/minor/scoreboard.hh b/src/cpu/minor/scoreboard.hh index 711bcafb2..815d81408 100644 --- a/src/cpu/minor/scoreboard.hh +++ b/src/cpu/minor/scoreboard.hh @@ -67,9 +67,6 @@ class Scoreboard : public Named * [NumIntRegs+NumCCRegs, NumFloatRegs+NumIntRegs+NumCCRegs-1] */ const unsigned numRegs; - /** Type to use for thread context registers */ - typedef TheISA::RegIndex RegIndex; - /** Type to use when indexing numResults */ typedef unsigned short int Index; @@ -109,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(RegIndex reg, Index &scoreboard_index); + bool findIndex(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/cpu.cc b/src/cpu/o3/cpu.cc index 8d38ed1f2..a2d8147ea 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -788,29 +788,27 @@ FullO3CPU<Impl>::insertThread(ThreadID tid) src_tc = tcBase(tid); //Bind Int Regs to Rename Map - for (int ireg = 0; ireg < TheISA::NumIntRegs; ireg++) { - PhysRegIndex phys_reg = freeList.getIntReg(); - renameMap[tid].setEntry(ireg,phys_reg); + for (RegId reg_id(IntRegClass, 0); reg_id.regIdx < TheISA::NumIntRegs; + reg_id.regIdx++) { + PhysRegIndex phys_reg = freeList.getIntReg(); + renameMap[tid].setEntry(reg_id, phys_reg); scoreboard.setReg(phys_reg); } //Bind Float Regs to Rename Map - int max_reg = TheISA::FP_Reg_Base + TheISA::NumFloatRegs; - for (int freg = TheISA::FP_Reg_Base; freg < max_reg; freg++) { + for (RegId reg_id(FloatRegClass, 0); reg_id.regIdx < TheISA::NumFloatRegs; + reg_id.regIdx++) { PhysRegIndex phys_reg = freeList.getFloatReg(); - - renameMap[tid].setEntry(freg,phys_reg); + renameMap[tid].setEntry(reg_id, phys_reg); scoreboard.setReg(phys_reg); } //Bind condition-code Regs to Rename Map - max_reg = TheISA::CC_Reg_Base + TheISA::NumCCRegs; - for (int creg = TheISA::CC_Reg_Base; - creg < max_reg; creg++) { + for (RegId reg_id(CCRegClass, 0); reg_id.regIdx < TheISA::NumCCRegs; + reg_id.regIdx++) { PhysRegIndex phys_reg = freeList.getCCReg(); - - renameMap[tid].setEntry(creg,phys_reg); + renameMap[tid].setEntry(reg_id, phys_reg); scoreboard.setReg(phys_reg); } @@ -845,24 +843,25 @@ FullO3CPU<Impl>::removeThread(ThreadID tid) // in SMT workloads. // Unbind Int Regs from Rename Map - for (int ireg = 0; ireg < TheISA::NumIntRegs; ireg++) { - PhysRegIndex phys_reg = renameMap[tid].lookup(ireg); + for (RegId reg_id(IntRegClass, 0); reg_id.regIdx < TheISA::NumIntRegs; + reg_id.regIdx++) { + PhysRegIndex phys_reg = renameMap[tid].lookup(reg_id); scoreboard.unsetReg(phys_reg); freeList.addReg(phys_reg); } // Unbind Float Regs from Rename Map - int max_reg = TheISA::FP_Reg_Base + TheISA::NumFloatRegs; - for (int freg = TheISA::FP_Reg_Base; freg < max_reg; freg++) { - PhysRegIndex phys_reg = renameMap[tid].lookup(freg); + for (RegId reg_id(FloatRegClass, 0); reg_id.regIdx < TheISA::NumFloatRegs; + reg_id.regIdx++) { + PhysRegIndex phys_reg = renameMap[tid].lookup(reg_id); scoreboard.unsetReg(phys_reg); freeList.addReg(phys_reg); } // Unbind condition-code Regs from Rename Map - max_reg = TheISA::CC_Reg_Base + TheISA::NumCCRegs; - for (int creg = TheISA::CC_Reg_Base; creg < max_reg; creg++) { - PhysRegIndex phys_reg = renameMap[tid].lookup(creg); + for (RegId reg_id(CCRegClass, 0); reg_id.regIdx < TheISA::NumCCRegs; + reg_id.regIdx++) { + PhysRegIndex phys_reg = renameMap[tid].lookup(reg_id); scoreboard.unsetReg(phys_reg); freeList.addReg(phys_reg); } diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh index 8ab9979d2..3096e5946 100644 --- a/src/cpu/o3/dyn_inst.hh +++ b/src/cpu/o3/dyn_inst.hh @@ -67,15 +67,13 @@ class BaseO3DynInst : public BaseDynInst<Impl> typedef TheISA::MachInst MachInst; /** Extended machine instruction type. */ typedef TheISA::ExtMachInst ExtMachInst; - /** Logical register index type. */ - typedef TheISA::RegIndex RegIndex; - /** Integer register index type. */ + /** Register types. */ typedef TheISA::IntReg IntReg; typedef TheISA::FloatReg FloatReg; typedef TheISA::FloatRegBits FloatRegBits; typedef TheISA::CCReg CCReg; - /** Misc register index type. */ + /** Misc register type. */ typedef TheISA::MiscReg MiscReg; enum { @@ -172,9 +170,9 @@ class BaseO3DynInst : public BaseDynInst<Impl> */ TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx) { - return this->cpu->readMiscReg( - si->srcRegIdx(idx) - TheISA::Misc_Reg_Base, - this->threadNumber); + RegId reg = si->srcRegIdx(idx); + assert(reg.regClass == MiscRegClass); + return this->cpu->readMiscReg(reg.regIdx, this->threadNumber); } /** Sets a misc. register, including any side-effects the write @@ -183,8 +181,9 @@ class BaseO3DynInst : public BaseDynInst<Impl> void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val) { - int misc_reg = si->destRegIdx(idx) - TheISA::Misc_Reg_Base; - setMiscReg(misc_reg, val); + RegId reg = si->destRegIdx(idx); + assert(reg.regClass == MiscRegClass); + setMiscReg(reg.regIdx, val); } /** Called at the commit stage to update the misc. registers. */ @@ -209,9 +208,9 @@ class BaseO3DynInst : public BaseDynInst<Impl> for (int idx = 0; idx < this->numDestRegs(); idx++) { PhysRegIndex prev_phys_reg = this->prevDestRegIdx(idx); - TheISA::RegIndex original_dest_reg = + RegId original_dest_reg = this->staticInst->destRegIdx(idx); - switch (regIdxToClass(original_dest_reg)) { + switch (original_dest_reg.regClass) { case IntRegClass: this->setIntRegOperand(this->staticInst.get(), idx, this->cpu->readIntReg(prev_phys_reg)); @@ -301,13 +300,13 @@ class BaseO3DynInst : public BaseDynInst<Impl> } #if THE_ISA == MIPS_ISA - MiscReg readRegOtherThread(int misc_reg, ThreadID tid) + MiscReg readRegOtherThread(RegId misc_reg, ThreadID tid) { panic("MIPS MT not defined for O3 CPU.\n"); return 0; } - void setRegOtherThread(int misc_reg, MiscReg val, ThreadID tid) + void setRegOtherThread(RegId misc_reg, MiscReg val, ThreadID tid) { panic("MIPS MT not defined for O3 CPU.\n"); } diff --git a/src/cpu/o3/dyn_inst_impl.hh b/src/cpu/o3/dyn_inst_impl.hh index 00bcb3345..f6a42c398 100644 --- a/src/cpu/o3/dyn_inst_impl.hh +++ b/src/cpu/o3/dyn_inst_impl.hh @@ -110,11 +110,11 @@ BaseO3DynInst<Impl>::initVars() // as the normal register entries. It will allow the IQ to work // without any modifications. for (int i = 0; i < this->staticInst->numDestRegs(); i++) { - this->_destRegIdx[i] = this->staticInst->destRegIdx(i); + this->_destRegIdx[i] = this->staticInst->destRegIdx(i).regIdx; } for (int i = 0; i < this->staticInst->numSrcRegs(); i++) { - this->_srcRegIdx[i] = this->staticInst->srcRegIdx(i); + this->_srcRegIdx[i] = this->staticInst->srcRegIdx(i).regIdx; } this->_readySrcRegIdx.reset(); diff --git a/src/cpu/o3/probe/elastic_trace.cc b/src/cpu/o3/probe/elastic_trace.cc index c97bf7877..05b16805f 100644 --- a/src/cpu/o3/probe/elastic_trace.cc +++ b/src/cpu/o3/probe/elastic_trace.cc @@ -262,15 +262,15 @@ 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. - TheISA::RegIndex dest_reg = dyn_inst->destRegIdx(dest_idx); - if (regIdxToClass(dest_reg) != MiscRegClass) { - // Get the physical register index of the i'th destination register. - dest_reg = dyn_inst->renamedDestRegIdx(dest_idx); - if (dest_reg != TheISA::ZeroReg) { - DPRINTFR(ElasticTrace, "[sn:%lli] Update map for dest reg %i\n", - seq_num, dest_reg); - physRegDepMap[dest_reg] = seq_num; - } + RegId dest_reg = dyn_inst->destRegIdx(dest_idx); + if (dest_reg.isRenameable() && + !dest_reg.isZeroReg()) { + // Get the physical register index of the i'th destination + // register. + PhysRegIndex phys_dest_reg = dyn_inst->renamedDestRegIdx(dest_idx); + DPRINTFR(ElasticTrace, "[sn:%lli] Update map for dest reg %i\n", + seq_num, dest_reg.regIdx); + physRegDepMap[phys_dest_reg] = seq_num; } } maxPhysRegDepMapSize = std::max(physRegDepMap.size(), diff --git a/src/cpu/o3/rename.hh b/src/cpu/o3/rename.hh index f8becc114..c0483d445 100644 --- a/src/cpu/o3/rename.hh +++ b/src/cpu/o3/rename.hh @@ -85,9 +85,6 @@ class DefaultRename typedef typename CPUPol::IEW IEW; typedef typename CPUPol::Commit Commit; - // Typedefs from the ISA. - typedef TheISA::RegIndex RegIndex; - // A deque is used to queue the instructions. Barrier insts must // be added to the front of the queue, which is the only reason for // using a deque instead of a queue. (Most other stages use a @@ -301,7 +298,7 @@ class DefaultRename * register for that arch. register, and the new physical register. */ struct RenameHistory { - RenameHistory(InstSeqNum _instSeqNum, RegIndex _archReg, + RenameHistory(InstSeqNum _instSeqNum, RegId _archReg, PhysRegIndex _newPhysReg, PhysRegIndex _prevPhysReg) : instSeqNum(_instSeqNum), archReg(_archReg), newPhysReg(_newPhysReg), prevPhysReg(_prevPhysReg) @@ -311,7 +308,7 @@ class DefaultRename /** The sequence number of the instruction that renamed. */ InstSeqNum instSeqNum; /** The architectural register index that was renamed. */ - RegIndex archReg; + RegId archReg; /** The new physical register that the arch. register is renamed to. */ PhysRegIndex newPhysReg; /** The old physical register that the arch. register was renamed to. */ diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh index 00179faae..e675efcd5 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -1011,42 +1011,41 @@ 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++) { - RegIndex src_reg = inst->srcRegIdx(src_idx); - RegIndex rel_src_reg; - RegIndex flat_rel_src_reg; + RegId src_reg = inst->srcRegIdx(src_idx); + RegIndex flat_src_reg; PhysRegIndex renamed_reg; - switch (regIdxToClass(src_reg, &rel_src_reg)) { + switch (src_reg.regClass) { case IntRegClass: - flat_rel_src_reg = tc->flattenIntIndex(rel_src_reg); - renamed_reg = map->lookupInt(flat_rel_src_reg); + flat_src_reg = tc->flattenIntIndex(src_reg.regIdx); + renamed_reg = map->lookupInt(flat_src_reg); intRenameLookups++; break; case FloatRegClass: - flat_rel_src_reg = tc->flattenFloatIndex(rel_src_reg); - renamed_reg = map->lookupFloat(flat_rel_src_reg); + flat_src_reg = tc->flattenFloatIndex(src_reg.regIdx); + renamed_reg = map->lookupFloat(flat_src_reg); fpRenameLookups++; break; case CCRegClass: - flat_rel_src_reg = tc->flattenCCIndex(rel_src_reg); - renamed_reg = map->lookupCC(flat_rel_src_reg); + 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_rel_src_reg = rel_src_reg; - renamed_reg = map->lookupMisc(flat_rel_src_reg); + flat_src_reg = src_reg.regIdx; + renamed_reg = map->lookupMisc(flat_src_reg); break; default: - panic("Reg index is out of bound: %d.", src_reg); + panic("Invalid register class: %d.", src_reg.regClass); } DPRINTF(Rename, "[tid:%u]: Looking up %s arch reg %i (flattened %i), " - "got phys reg %i\n", tid, RegClassStrings[regIdxToClass(src_reg)], - (int)src_reg, (int)flat_rel_src_reg, (int)renamed_reg); + "got phys reg %i\n", tid, RegClassStrings[src_reg.regClass], + (int)src_reg.regIdx, (int)flat_src_reg, (int)renamed_reg); inst->renameSrcReg(src_idx, renamed_reg); @@ -1075,49 +1074,45 @@ DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid) // Rename the destination registers. for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) { - RegIndex dest_reg = inst->destRegIdx(dest_idx); - RegIndex rel_dest_reg; - RegIndex flat_rel_dest_reg; - RegIndex flat_uni_dest_reg; + RegId dest_reg = inst->destRegIdx(dest_idx); + RegIndex flat_dest_reg; typename RenameMap::RenameInfo rename_result; - switch (regIdxToClass(dest_reg, &rel_dest_reg)) { + switch (dest_reg.regClass) { case IntRegClass: - flat_rel_dest_reg = tc->flattenIntIndex(rel_dest_reg); - rename_result = map->renameInt(flat_rel_dest_reg); - flat_uni_dest_reg = flat_rel_dest_reg; // 1:1 mapping + flat_dest_reg = tc->flattenIntIndex(dest_reg.regIdx); + rename_result = map->renameInt(flat_dest_reg); break; case FloatRegClass: - flat_rel_dest_reg = tc->flattenFloatIndex(rel_dest_reg); - rename_result = map->renameFloat(flat_rel_dest_reg); - flat_uni_dest_reg = flat_rel_dest_reg + TheISA::FP_Reg_Base; + flat_dest_reg = tc->flattenFloatIndex(dest_reg.regIdx); + rename_result = map->renameFloat(flat_dest_reg); break; case CCRegClass: - flat_rel_dest_reg = tc->flattenCCIndex(rel_dest_reg); - rename_result = map->renameCC(flat_rel_dest_reg); - flat_uni_dest_reg = flat_rel_dest_reg + TheISA::CC_Reg_Base; + 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_rel_dest_reg = rel_dest_reg; - rename_result = map->renameMisc(flat_rel_dest_reg); - flat_uni_dest_reg = flat_rel_dest_reg + TheISA::Misc_Reg_Base; + flat_dest_reg = dest_reg.regIdx; + rename_result = map->renameMisc(dest_reg.regIdx); break; default: - panic("Reg index is out of bound: %d.", dest_reg); + panic("Invalid register class: %d.", dest_reg.regClass); } + RegId flat_uni_dest_reg(dest_reg.regClass, flat_dest_reg); + inst->flattenDestReg(dest_idx, flat_uni_dest_reg); // Mark Scoreboard entry as not ready scoreboard->unsetReg(rename_result.first); DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i to physical " - "reg %i.\n", tid, (int)flat_rel_dest_reg, + "reg %i.\n", tid, (int)flat_dest_reg, (int)rename_result.first); // Record the rename information so that a history can be kept. @@ -1431,8 +1426,10 @@ DefaultRename<Impl>::dumpHistory() buf_it = historyBuffer[tid].begin(); while (buf_it != historyBuffer[tid].end()) { - cprintf("Seq num: %i\nArch reg: %i New phys reg: %i Old phys " - "reg: %i\n", (*buf_it).instSeqNum, (int)(*buf_it).archReg, + cprintf("Seq num: %i\nArch reg[%s]: %i New phys reg: %i Old phys " + "reg: %i\n", (*buf_it).instSeqNum, + RegClassStrings[(*buf_it).archReg.regClass], + (*buf_it).archReg.regIdx, (int)(*buf_it).newPhysReg, (int)(*buf_it).prevPhysReg); buf_it++; diff --git a/src/cpu/o3/rename_map.cc b/src/cpu/o3/rename_map.cc index 18c20cf8c..6307b58de 100644 --- a/src/cpu/o3/rename_map.cc +++ b/src/cpu/o3/rename_map.cc @@ -104,79 +104,73 @@ UnifiedRenameMap::init(PhysRegFile *_regFile, UnifiedRenameMap::RenameInfo -UnifiedRenameMap::rename(RegIndex arch_reg) +UnifiedRenameMap::rename(RegId arch_reg) { - RegIndex rel_arch_reg; - - switch (regIdxToClass(arch_reg, &rel_arch_reg)) { + switch (arch_reg.regClass) { case IntRegClass: - return renameInt(rel_arch_reg); + return renameInt(arch_reg.regIdx); case FloatRegClass: - return renameFloat(rel_arch_reg); + return renameFloat(arch_reg.regIdx); case CCRegClass: - return renameCC(rel_arch_reg); + return renameCC(arch_reg.regIdx); case MiscRegClass: - return renameMisc(rel_arch_reg); + return renameMisc(arch_reg.regIdx); default: panic("rename rename(): unknown reg class %s\n", - RegClassStrings[regIdxToClass(arch_reg)]); + RegClassStrings[arch_reg.regClass]); } } PhysRegIndex -UnifiedRenameMap::lookup(RegIndex arch_reg) const +UnifiedRenameMap::lookup(RegId arch_reg) const { - RegIndex rel_arch_reg; - - switch (regIdxToClass(arch_reg, &rel_arch_reg)) { + switch (arch_reg.regClass) { case IntRegClass: - return lookupInt(rel_arch_reg); + return lookupInt(arch_reg.regIdx); case FloatRegClass: - return lookupFloat(rel_arch_reg); + return lookupFloat(arch_reg.regIdx); case CCRegClass: - return lookupCC(rel_arch_reg); + return lookupCC(arch_reg.regIdx); case MiscRegClass: - return lookupMisc(rel_arch_reg); + return lookupMisc(arch_reg.regIdx); default: panic("rename lookup(): unknown reg class %s\n", - RegClassStrings[regIdxToClass(arch_reg)]); + RegClassStrings[arch_reg.regClass]); } } void -UnifiedRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex phys_reg) +UnifiedRenameMap::setEntry(RegId arch_reg, PhysRegIndex phys_reg) { - RegIndex rel_arch_reg; - - switch (regIdxToClass(arch_reg, &rel_arch_reg)) { + switch (arch_reg.regClass) { case IntRegClass: - return setIntEntry(rel_arch_reg, phys_reg); + return setIntEntry(arch_reg.regIdx, phys_reg); case FloatRegClass: - return setFloatEntry(rel_arch_reg, phys_reg); + return setFloatEntry(arch_reg.regIdx, phys_reg); case CCRegClass: - return setCCEntry(rel_arch_reg, phys_reg); + 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(rel_arch_reg)); + assert(phys_reg == lookupMisc(arch_reg.regIdx)); return; default: panic("rename setEntry(): unknown reg class %s\n", - RegClassStrings[regIdxToClass(arch_reg)]); + RegClassStrings[arch_reg.regClass]); } } diff --git a/src/cpu/o3/rename_map.hh b/src/cpu/o3/rename_map.hh index 9d91f232e..2cce29913 100644 --- a/src/cpu/o3/rename_map.hh +++ b/src/cpu/o3/rename_map.hh @@ -68,10 +68,6 @@ */ class SimpleRenameMap { - public: - - typedef TheISA::RegIndex RegIndex; - private: /** The acutal arch-to-phys register map */ @@ -152,9 +148,9 @@ class SimpleRenameMap /** * Unified register rename map for all classes of registers. Wraps a * set of class-specific rename maps. Methods that do not specify a - * register class (e.g., rename()) take unified register indices, + * register class (e.g., rename()) take register ids, * while methods that do specify a register class (e.g., renameInt()) - * take relative register indices. See http://gem5.org/Register_Indexing. + * take register indices. */ class UnifiedRenameMap { @@ -179,7 +175,6 @@ class UnifiedRenameMap SimpleRenameMap ccMap; public: - typedef TheISA::RegIndex RegIndex; typedef SimpleRenameMap::RenameInfo RenameInfo; @@ -197,17 +192,17 @@ class UnifiedRenameMap /** * Tell rename map to get a new free physical register to remap - * the specified architectural register. This version takes a - * unified flattened architectural register index and calls the + * the specified architectural register. This version takes a + * flattened architectural register id and calls the * appropriate class-specific rename table. - * @param arch_reg The unified architectural register index to remap. + * @param arch_reg The architectural register index to remap. * @return A RenameInfo pair indicating both the new and previous * physical registers. */ - RenameInfo rename(RegIndex arch_reg); + RenameInfo rename(RegId arch_reg); /** - * Perform rename() on an integer register, given a relative + * Perform rename() on an integer register, given a * integer register index. */ RenameInfo renameInt(RegIndex rel_arch_reg) @@ -218,7 +213,7 @@ class UnifiedRenameMap } /** - * Perform rename() on a floating-point register, given a relative + * Perform rename() on a floating-point register, given a * floating-point register index. */ RenameInfo renameFloat(RegIndex rel_arch_reg) @@ -229,7 +224,7 @@ class UnifiedRenameMap } /** - * Perform rename() on a condition-code register, given a relative + * Perform rename() on a condition-code register, given a * condition-code register index. */ RenameInfo renameCC(RegIndex rel_arch_reg) @@ -240,7 +235,7 @@ class UnifiedRenameMap } /** - * Perform rename() on a misc register, given a relative + * Perform rename() on a misc register, given a * misc register index. */ RenameInfo renameMisc(RegIndex rel_arch_reg) @@ -256,15 +251,15 @@ class UnifiedRenameMap /** * Look up the physical register mapped to an architectural register. - * This version takes a unified flattened architectural register index + * This version takes a flattened architectural register id * and calls the appropriate class-specific rename table. - * @param arch_reg The unified architectural register to look up. + * @param arch_reg The architectural register to look up. * @return The physical register it is currently mapped to. */ - PhysRegIndex lookup(RegIndex arch_reg) const; + PhysRegIndex lookup(RegId arch_reg) const; /** - * Perform lookup() on an integer register, given a relative + * Perform lookup() on an integer register, given a * integer register index. */ PhysRegIndex lookupInt(RegIndex rel_arch_reg) const @@ -275,7 +270,7 @@ class UnifiedRenameMap } /** - * Perform lookup() on a floating-point register, given a relative + * Perform lookup() on a floating-point register, given a * floating-point register index. */ PhysRegIndex lookupFloat(RegIndex rel_arch_reg) const @@ -286,7 +281,7 @@ class UnifiedRenameMap } /** - * Perform lookup() on a condition-code register, given a relative + * Perform lookup() on a condition-code register, given a * condition-code register index. */ PhysRegIndex lookupCC(RegIndex rel_arch_reg) const @@ -311,15 +306,15 @@ class UnifiedRenameMap /** * Update rename map with a specific mapping. Generally used to * roll back to old mappings on a squash. This version takes a - * unified flattened architectural register index and calls the + * flattened architectural register id and calls the * appropriate class-specific rename table. - * @param arch_reg The unified architectural register to remap. + * @param arch_reg The architectural register to remap. * @param phys_reg The physical register to remap it to. */ - void setEntry(RegIndex arch_reg, PhysRegIndex phys_reg); + void setEntry(RegId arch_reg, PhysRegIndex phys_reg); /** - * Perform setEntry() on an integer register, given a relative + * Perform setEntry() on an integer register, given a * integer register index. */ void setIntEntry(RegIndex arch_reg, PhysRegIndex phys_reg) @@ -329,7 +324,7 @@ class UnifiedRenameMap } /** - * Perform setEntry() on a floating-point register, given a relative + * Perform setEntry() on a floating-point register, given a * floating-point register index. */ void setFloatEntry(RegIndex arch_reg, PhysRegIndex phys_reg) @@ -339,7 +334,7 @@ class UnifiedRenameMap } /** - * Perform setEntry() on a condition-code register, given a relative + * Perform setEntry() on a condition-code register, given a * condition-code register index. */ void setCCEntry(RegIndex arch_reg, PhysRegIndex phys_reg) diff --git a/src/cpu/o3/rob.hh b/src/cpu/o3/rob.hh index b5651de11..1c3cc2815 100644 --- a/src/cpu/o3/rob.hh +++ b/src/cpu/o3/rob.hh @@ -60,8 +60,6 @@ struct DerivO3CPUParams; template <class Impl> class ROB { - protected: - typedef TheISA::RegIndex RegIndex; public: //Typedefs from the Impl. typedef typename Impl::O3CPU O3CPU; diff --git a/src/cpu/reg_class.cc b/src/cpu/reg_class.cc index 1805eae13..75be4679d 100644 --- a/src/cpu/reg_class.cc +++ b/src/cpu/reg_class.cc @@ -36,3 +36,5 @@ const char *RegClassStrings[] = { "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 549ebab26..25c882c58 100644 --- a/src/cpu/reg_class.hh +++ b/src/cpu/reg_class.hh @@ -1,4 +1,16 @@ /* + * 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. + * * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved *. @@ -26,6 +38,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Steve Reinhardt + * Nathanael Premillieu */ #ifndef __CPU__REG_CLASS_HH__ @@ -34,6 +47,7 @@ #include <cassert> #include <cstddef> +#include "arch/generic/types.hh" #include "arch/registers.hh" #include "config/the_isa.hh" @@ -50,50 +64,49 @@ enum RegClass { /// unhandled cases in some switch statements. const int NumRegClasses = MiscRegClass + 1; -/** - * Map a 'unified' architectural register index to its register class. - * The unified architectural register index space is used to represent - * all architectural register identifiers in a single contiguous - * index space. See http://gem5.org/Register_Indexing. - * - * @param reg_idx Unified-space register index - * @param rel_reg_idx Optional output param pointer; if non-NULL, location - * will be written with the relative register index for reg_idx - * - * @return Register class of reg_idx - */ -inline -RegClass regIdxToClass(TheISA::RegIndex reg_idx, - TheISA::RegIndex *rel_reg_idx = NULL) -{ - assert(reg_idx < TheISA::Max_Reg_Index); - RegClass cl; - int offset; +/// 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 { + RegClass regClass; + RegIndex regIdx; + RegId() {}; + RegId(RegClass reg_class, RegIndex reg_idx) + : regClass(reg_class), regIdx(reg_idx) + {} - if (reg_idx < TheISA::FP_Reg_Base) { - cl = IntRegClass; - offset = 0; - } else if (reg_idx < TheISA::CC_Reg_Base) { - cl = FloatRegClass; - offset = TheISA::FP_Reg_Base; - } else if (reg_idx < TheISA::Misc_Reg_Base) { - // if there are no CC regs, the ISA should set - // CC_Reg_Base == Misc_Reg_Base so the if above - // never succeeds - cl = CCRegClass; - offset = TheISA::CC_Reg_Base; - } else { - cl = MiscRegClass; - offset = TheISA::Misc_Reg_Base; + bool operator==(const RegId& that) const { + return regClass == that.regClass && regIdx == that.regIdx; } - if (rel_reg_idx) - *rel_reg_idx = reg_idx - offset; - return cl; -} + bool operator!=(const RegId& that) const { + return !(*this==that); + } -/// Map enum values to strings for debugging -extern const char *RegClassStrings[]; + /** + * Returns true if this register is a zero register (needs to have a + * constant zero value throughout the execution) + */ + bool isZeroReg() const + { + return (regIdx == TheISA::ZeroReg && + (regClass == IntRegClass || + (THE_ISA == ALPHA_ISA && regClass == FloatRegClass))); + } + /** + * Return true if this register can be renamed + */ + bool isRenameable() + { + return regClass != MiscRegClass; + } + static const RegId zeroReg; +}; + +/// Map enum values to strings for debugging +extern const char *RegClassStrings[]; #endif // __CPU__REG_CLASS_HH__ diff --git a/src/cpu/simple/exec_context.hh b/src/cpu/simple/exec_context.hh index bfae118ad..9689796f3 100644 --- a/src/cpu/simple/exec_context.hh +++ b/src/cpu/simple/exec_context.hh @@ -50,6 +50,7 @@ #include "config/the_isa.hh" #include "cpu/base.hh" #include "cpu/exec_context.hh" +#include "cpu/reg_class.hh" #include "cpu/simple/base.hh" #include "cpu/static_inst_fwd.hh" #include "cpu/translation.hh" @@ -164,22 +165,27 @@ class SimpleExecContext : public ExecContext { IntReg readIntRegOperand(const StaticInst *si, int idx) override { numIntRegReads++; - return thread->readIntReg(si->srcRegIdx(idx)); + RegId reg = si->srcRegIdx(idx); + assert(reg.regClass == IntRegClass); + return thread->readIntReg(reg.regIdx); } /** Sets an integer register to a value. */ void setIntRegOperand(const StaticInst *si, int idx, IntReg val) override { numIntRegWrites++; - thread->setIntReg(si->destRegIdx(idx), val); + RegId reg = si->destRegIdx(idx); + assert(reg.regClass == IntRegClass); + thread->setIntReg(reg.regIdx, val); } /** Reads a floating point register of single register width. */ FloatReg readFloatRegOperand(const StaticInst *si, int idx) override { numFpRegReads++; - int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base; - return thread->readFloatReg(reg_idx); + RegId reg = si->srcRegIdx(idx); + assert(reg.regClass == FloatRegClass); + return thread->readFloatReg(reg.regIdx); } /** Reads a floating point register in its binary format, instead @@ -187,8 +193,9 @@ class SimpleExecContext : public ExecContext { FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) override { numFpRegReads++; - int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base; - return thread->readFloatRegBits(reg_idx); + RegId reg = si->srcRegIdx(idx); + assert(reg.regClass == FloatRegClass); + return thread->readFloatRegBits(reg.regIdx); } /** Sets a floating point register of single width to a value. */ @@ -196,8 +203,9 @@ class SimpleExecContext : public ExecContext { FloatReg val) override { numFpRegWrites++; - int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base; - thread->setFloatReg(reg_idx, val); + RegId reg = si->destRegIdx(idx); + assert(reg.regClass == FloatRegClass); + thread->setFloatReg(reg.regIdx, val); } /** Sets the bits of a floating point register of single width @@ -206,37 +214,42 @@ class SimpleExecContext : public ExecContext { FloatRegBits val) override { numFpRegWrites++; - int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base; - thread->setFloatRegBits(reg_idx, val); + RegId reg = si->destRegIdx(idx); + assert(reg.regClass == FloatRegClass); + thread->setFloatRegBits(reg.regIdx, val); } CCReg readCCRegOperand(const StaticInst *si, int idx) override { numCCRegReads++; - int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base; - return thread->readCCReg(reg_idx); + RegId reg = si->srcRegIdx(idx); + assert(reg.regClass == CCRegClass); + return thread->readCCReg(reg.regIdx); } void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override { numCCRegWrites++; - int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base; - thread->setCCReg(reg_idx, val); + RegId reg = si->destRegIdx(idx); + assert(reg.regClass == CCRegClass); + thread->setCCReg(reg.regIdx, val); } MiscReg readMiscRegOperand(const StaticInst *si, int idx) override { numIntRegReads++; - int reg_idx = si->srcRegIdx(idx) - TheISA::Misc_Reg_Base; - return thread->readMiscReg(reg_idx); + RegId reg = si->srcRegIdx(idx); + assert(reg.regClass == MiscRegClass); + return thread->readMiscReg(reg.regIdx); } void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val) override { numIntRegWrites++; - int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base; - thread->setMiscReg(reg_idx, val); + RegId reg = si->destRegIdx(idx); + assert(reg.regClass == MiscRegClass); + thread->setMiscReg(reg.regIdx, val); } /** @@ -398,14 +411,14 @@ class SimpleExecContext : public ExecContext { } #if THE_ISA == MIPS_ISA - MiscReg readRegOtherThread(int regIdx, ThreadID tid = InvalidThreadID) + MiscReg readRegOtherThread(RegId reg, ThreadID tid = InvalidThreadID) override { panic("Simple CPU models do not support multithreaded " "register access."); } - void setRegOtherThread(int regIdx, MiscReg val, + void setRegOtherThread(RegId reg, MiscReg val, ThreadID tid = InvalidThreadID) override { panic("Simple CPU models do not support multithreaded " diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh index 684a22856..751301095 100644 --- a/src/cpu/static_inst.hh +++ b/src/cpu/static_inst.hh @@ -42,6 +42,7 @@ #include "base/types.hh" #include "config/the_isa.hh" #include "cpu/op_class.hh" +#include "cpu/reg_class.hh" #include "cpu/static_inst_fwd.hh" #include "cpu/thread_context.hh" #include "enums/StaticInstFlags.hh" @@ -70,8 +71,6 @@ class StaticInst : public RefCounted, public StaticInstFlags public: /// Binary extended machine instruction type. typedef TheISA::ExtMachInst ExtMachInst; - /// Logical register index type. - typedef TheISA::RegIndex RegIndex; enum { MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs @@ -185,11 +184,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. - RegIndex destRegIdx(int i) const { return _destRegIdx[i]; } + 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. - RegIndex srcRegIdx(int i) const { return _srcRegIdx[i]; } + 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 @@ -220,9 +219,9 @@ class StaticInst : public RefCounted, public StaticInstFlags protected: /// See destRegIdx(). - RegIndex _destRegIdx[MaxInstDestRegs]; + RegId _destRegIdx[MaxInstDestRegs]; /// See srcRegIdx(). - RegIndex _srcRegIdx[MaxInstSrcRegs]; + RegId _srcRegIdx[MaxInstSrcRegs]; /** * Base mnemonic (e.g., "add"). Used by generateDisassembly() diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh index bb6b54c08..efa0b2162 100644 --- a/src/cpu/thread_context.hh +++ b/src/cpu/thread_context.hh @@ -51,6 +51,7 @@ #include "arch/types.hh" #include "base/types.hh" #include "config/the_isa.hh" +#include "cpu/reg_class.hh" // @todo: Figure out a more architecture independent way to obtain the ITB and // DTB pointers. @@ -255,13 +256,13 @@ class ThreadContext virtual int flattenMiscIndex(int reg) = 0; virtual uint64_t - readRegOtherThread(int misc_reg, ThreadID tid) + readRegOtherThread(RegId misc_reg, ThreadID tid) { return 0; } virtual void - setRegOtherThread(int misc_reg, const MiscReg &val, ThreadID tid) + setRegOtherThread(RegId misc_reg, const MiscReg &val, ThreadID tid) { } diff --git a/src/cpu/timing_expr.cc b/src/cpu/timing_expr.cc index 88bc5476f..99b4eb6aa 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); + return context.inst->srcRegIdx(index).regIdx; } uint64_t TimingExprReadIntReg::eval(TimingExprEvalContext &context) |