diff options
author | Yasuko Eckert <yasuko.eckert@amd.com> | 2013-10-15 14:22:44 -0400 |
---|---|---|
committer | Yasuko Eckert <yasuko.eckert@amd.com> | 2013-10-15 14:22:44 -0400 |
commit | 2c293823aa7cb6d2cac4c0ff35e2023ff132a8f2 (patch) | |
tree | 040fdd5bad814d7cb7ee40934974d2b38b28d67a /src/cpu/o3 | |
parent | 552622184752dc798bc81f9b0b395db68aee9511 (diff) | |
download | gem5-2c293823aa7cb6d2cac4c0ff35e2023ff132a8f2.tar.xz |
cpu: add a condition-code register class
Add a third register class for condition codes,
in parallel with the integer and FP classes.
No ISAs use the CC class at this point though.
Diffstat (limited to 'src/cpu/o3')
-rw-r--r-- | src/cpu/o3/O3CPU.py | 1 | ||||
-rw-r--r-- | src/cpu/o3/cpu.cc | 88 | ||||
-rw-r--r-- | src/cpu/o3/cpu.hh | 11 | ||||
-rw-r--r-- | src/cpu/o3/dyn_inst.hh | 18 | ||||
-rw-r--r-- | src/cpu/o3/free_list.cc | 2 | ||||
-rw-r--r-- | src/cpu/o3/free_list.hh | 24 | ||||
-rw-r--r-- | src/cpu/o3/inst_queue.hh | 7 | ||||
-rw-r--r-- | src/cpu/o3/inst_queue_impl.hh | 8 | ||||
-rw-r--r-- | src/cpu/o3/regfile.cc | 25 | ||||
-rw-r--r-- | src/cpu/o3/regfile.hh | 57 | ||||
-rw-r--r-- | src/cpu/o3/rename_impl.hh | 14 | ||||
-rw-r--r-- | src/cpu/o3/rename_map.cc | 11 | ||||
-rw-r--r-- | src/cpu/o3/rename_map.hh | 35 | ||||
-rwxr-xr-x | src/cpu/o3/thread_context.hh | 13 | ||||
-rwxr-xr-x | src/cpu/o3/thread_context_impl.hh | 24 |
15 files changed, 315 insertions, 23 deletions
diff --git a/src/cpu/o3/O3CPU.py b/src/cpu/o3/O3CPU.py index e19881248..4b94f3581 100644 --- a/src/cpu/o3/O3CPU.py +++ b/src/cpu/o3/O3CPU.py @@ -112,6 +112,7 @@ class DerivO3CPU(BaseCPU): numPhysIntRegs = Param.Unsigned(256, "Number of physical integer registers") numPhysFloatRegs = Param.Unsigned(256, "Number of physical floating point " "registers") + numPhysCCRegs = Param.Unsigned(0, "Number of physical cc registers") numIQEntries = Param.Unsigned(64, "Number of instruction queue entries") numROBEntries = Param.Unsigned(192, "Number of reorder buffer entries") diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 3e33e139a..f379b1068 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -225,7 +225,8 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params) commit(this, params), regFile(params->numPhysIntRegs, - params->numPhysFloatRegs), + params->numPhysFloatRegs, + params->numPhysCCRegs), freeList(name() + ".freelist", ®File), @@ -327,6 +328,7 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params) //Make Sure That this a Valid Architeture assert(params->numPhysIntRegs >= numThreads * TheISA::NumIntRegs); assert(params->numPhysFloatRegs >= numThreads * TheISA::NumFloatRegs); + assert(params->numPhysCCRegs >= numThreads * TheISA::NumCCRegs); rename.setScoreboard(&scoreboard); iew.setScoreboard(&scoreboard); @@ -368,6 +370,12 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params) renameMap[tid].setFloatEntry(ridx, phys_reg); commitRenameMap[tid].setFloatEntry(ridx, phys_reg); } + + for (RegIndex ridx = 0; ridx < TheISA::NumCCRegs; ++ridx) { + PhysRegIndex phys_reg = freeList.getCCReg(); + renameMap[tid].setCCEntry(ridx, phys_reg); + commitRenameMap[tid].setCCEntry(ridx, phys_reg); + } } rename.setRenameMap(renameMap); @@ -555,6 +563,16 @@ FullO3CPU<Impl>::regStats() .desc("number of floating regfile writes") .prereq(fpRegfileWrites); + ccRegfileReads + .name(name() + ".cc_regfile_reads") + .desc("number of cc regfile reads") + .prereq(ccRegfileReads); + + ccRegfileWrites + .name(name() + ".cc_regfile_writes") + .desc("number of cc regfile writes") + .prereq(ccRegfileWrites); + miscRegfileReads .name(name() + ".misc_regfile_reads") .desc("number of misc regfile reads") @@ -842,13 +860,24 @@ FullO3CPU<Impl>::insertThread(ThreadID tid) } //Bind Float Regs to Rename Map - for (int freg = 0; freg < TheISA::NumFloatRegs; freg++) { + int max_reg = TheISA::NumIntRegs + TheISA::NumFloatRegs; + for (int freg = TheISA::NumIntRegs; freg < max_reg; freg++) { PhysRegIndex phys_reg = freeList.getFloatReg(); renameMap[tid].setEntry(freg,phys_reg); scoreboard.setReg(phys_reg); } + //Bind condition-code Regs to Rename Map + max_reg = TheISA::NumIntRegs + TheISA::NumFloatRegs + TheISA::NumCCRegs; + for (int creg = TheISA::NumIntRegs + TheISA::NumFloatRegs; + creg < max_reg; creg++) { + PhysRegIndex phys_reg = freeList.getCCReg(); + + renameMap[tid].setEntry(creg,phys_reg); + scoreboard.setReg(phys_reg); + } + //Copy Thread Data Into RegFile //this->copyFromTC(tid); @@ -888,13 +917,24 @@ FullO3CPU<Impl>::removeThread(ThreadID tid) } // Unbind Float Regs from Rename Map - for (int freg = TheISA::NumIntRegs; freg < TheISA::NumFloatRegs; freg++) { + int max_reg = TheISA::NumIntRegs + TheISA::NumFloatRegs; + for (int freg = TheISA::NumIntRegs; freg < max_reg; freg++) { PhysRegIndex phys_reg = renameMap[tid].lookup(freg); scoreboard.unsetReg(phys_reg); freeList.addReg(phys_reg); } + // Unbind condition-code Regs from Rename Map + max_reg = TheISA::NumIntRegs + TheISA::NumFloatRegs + TheISA::NumCCRegs; + for (int creg = TheISA::NumIntRegs + TheISA::NumFloatRegs; + creg < max_reg; creg++) { + PhysRegIndex phys_reg = renameMap[tid].lookup(creg); + + scoreboard.unsetReg(phys_reg); + freeList.addReg(phys_reg); + } + // Squash Throughout Pipeline DynInstPtr inst = commit.rob->readHeadInst(tid); InstSeqNum squash_seq_num = inst->seqNum; @@ -934,6 +974,7 @@ FullO3CPU<Impl>::activateWhenReady(ThreadID tid) bool ready = true; + // Should these all be '<' not '>='? This seems backwards... if (freeList.numFreeIntRegs() >= TheISA::NumIntRegs) { DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough " "Phys. Int. Regs.\n", @@ -944,6 +985,11 @@ FullO3CPU<Impl>::activateWhenReady(ThreadID tid) "Phys. Float. Regs.\n", tid); ready = false; + } else if (freeList.numFreeCCRegs() >= TheISA::NumCCRegs) { + DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough " + "Phys. CC. Regs.\n", + tid); + ready = false; } else if (commit.rob->numFreeEntries() >= commit.rob->entryAmount(activeThreads.size() + 1)) { DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough " @@ -1366,6 +1412,14 @@ FullO3CPU<Impl>::readFloatRegBits(int reg_idx) } template <class Impl> +CCReg +FullO3CPU<Impl>::readCCReg(int reg_idx) +{ + ccRegfileReads++; + return regFile.readCCReg(reg_idx); +} + +template <class Impl> void FullO3CPU<Impl>::setIntReg(int reg_idx, uint64_t val) { @@ -1390,6 +1444,14 @@ FullO3CPU<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val) } template <class Impl> +void +FullO3CPU<Impl>::setCCReg(int reg_idx, CCReg val) +{ + ccRegfileWrites++; + regFile.setCCReg(reg_idx, val); +} + +template <class Impl> uint64_t FullO3CPU<Impl>::readArchIntReg(int reg_idx, ThreadID tid) { @@ -1420,6 +1482,16 @@ FullO3CPU<Impl>::readArchFloatRegInt(int reg_idx, ThreadID tid) } template <class Impl> +CCReg +FullO3CPU<Impl>::readArchCCReg(int reg_idx, ThreadID tid) +{ + ccRegfileReads++; + PhysRegIndex phys_reg = commitRenameMap[tid].lookupCC(reg_idx); + + return regFile.readCCReg(phys_reg); +} + +template <class Impl> void FullO3CPU<Impl>::setArchIntReg(int reg_idx, uint64_t val, ThreadID tid) { @@ -1450,6 +1522,16 @@ FullO3CPU<Impl>::setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid) } template <class Impl> +void +FullO3CPU<Impl>::setArchCCReg(int reg_idx, CCReg val, ThreadID tid) +{ + ccRegfileWrites++; + PhysRegIndex phys_reg = commitRenameMap[tid].lookupCC(reg_idx); + + regFile.setCCReg(phys_reg, val); +} + +template <class Impl> TheISA::PCState FullO3CPU<Impl>::pcState(ThreadID tid) { diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index 1a1f8f8a3..18b75948f 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -540,18 +540,24 @@ class FullO3CPU : public BaseO3CPU TheISA::FloatRegBits readFloatRegBits(int reg_idx); + TheISA::CCReg readCCReg(int reg_idx); + void setIntReg(int reg_idx, uint64_t val); void setFloatReg(int reg_idx, TheISA::FloatReg val); void setFloatRegBits(int reg_idx, TheISA::FloatRegBits val); + void setCCReg(int reg_idx, TheISA::CCReg val); + uint64_t readArchIntReg(int reg_idx, ThreadID tid); float readArchFloatReg(int reg_idx, ThreadID tid); uint64_t readArchFloatRegInt(int reg_idx, ThreadID tid); + TheISA::CCReg readArchCCReg(int reg_idx, ThreadID tid); + /** Architectural register accessors. Looks up in the commit * rename table to obtain the true physical index of the * architected register first, then accesses that physical @@ -563,6 +569,8 @@ class FullO3CPU : public BaseO3CPU void setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid); + void setArchCCReg(int reg_idx, TheISA::CCReg val, ThreadID tid); + /** Sets the commit PC state of a specific thread. */ void pcState(const TheISA::PCState &newPCState, ThreadID tid); @@ -846,6 +854,9 @@ class FullO3CPU : public BaseO3CPU //number of float register file accesses Stats::Scalar fpRegfileReads; Stats::Scalar fpRegfileWrites; + //number of CC register file accesses + Stats::Scalar ccRegfileReads; + Stats::Scalar ccRegfileWrites; //number of misc Stats::Scalar miscRegfileReads; Stats::Scalar miscRegfileWrites; diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh index 15a82851b..5477f46d6 100644 --- a/src/cpu/o3/dyn_inst.hh +++ b/src/cpu/o3/dyn_inst.hh @@ -78,6 +78,9 @@ class BaseO3DynInst : public BaseDynInst<Impl> typedef TheISA::IntReg IntReg; typedef TheISA::FloatReg FloatReg; typedef TheISA::FloatRegBits FloatRegBits; +#ifdef ISA_HAS_CC_REGS + typedef TheISA::CCReg CCReg; +#endif /** Misc register index type. */ typedef TheISA::MiscReg MiscReg; @@ -222,6 +225,10 @@ class BaseO3DynInst : public BaseDynInst<Impl> this->setFloatRegOperandBits(this->staticInst.get(), idx, this->cpu->readFloatRegBits(prev_phys_reg)); break; + case CCRegClass: + this->setCCRegOperand(this->staticInst.get(), idx, + this->cpu->readCCReg(prev_phys_reg)); + break; case MiscRegClass: // no need to forward misc reg values break; @@ -265,6 +272,11 @@ class BaseO3DynInst : public BaseDynInst<Impl> return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]); } + uint64_t readCCRegOperand(const StaticInst *si, int idx) + { + return this->cpu->readCCReg(this->_srcRegIdx[idx]); + } + /** @todo: Make results into arrays so they can handle multiple dest * registers. */ @@ -287,6 +299,12 @@ class BaseO3DynInst : public BaseDynInst<Impl> BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val); } + void setCCRegOperand(const StaticInst *si, int idx, uint64_t val) + { + this->cpu->setCCReg(this->_destRegIdx[idx], val); + BaseDynInst<Impl>::setCCRegOperand(si, idx, val); + } + #if THE_ISA == MIPS_ISA uint64_t readRegOtherThread(int misc_reg) { diff --git a/src/cpu/o3/free_list.cc b/src/cpu/o3/free_list.cc index 0c8a16d0d..a9544587e 100644 --- a/src/cpu/o3/free_list.cc +++ b/src/cpu/o3/free_list.cc @@ -29,7 +29,9 @@ * Authors: Kevin Lim */ +#include "arch/registers.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "cpu/o3/free_list.hh" #include "debug/FreeList.hh" diff --git a/src/cpu/o3/free_list.hh b/src/cpu/o3/free_list.hh index 3919d0afb..aa805e26e 100644 --- a/src/cpu/o3/free_list.hh +++ b/src/cpu/o3/free_list.hh @@ -106,6 +106,9 @@ class UnifiedFreeList /** The list of free floating point registers. */ SimpleFreeList floatList; + /** The list of free condition-code registers. */ + SimpleFreeList ccList; + /** * The register file object is used only to distinguish integer * from floating-point physical register indices. @@ -133,12 +136,18 @@ class UnifiedFreeList /** Gives the name of the freelist. */ std::string name() const { return _name; }; + /** Returns a pointer to the condition-code free list */ + SimpleFreeList *getCCList() { return &ccList; } + /** Gets a free integer register. */ PhysRegIndex getIntReg() { return intList.getReg(); } /** Gets a free fp register. */ PhysRegIndex getFloatReg() { return floatList.getReg(); } + /** Gets a free cc register. */ + PhysRegIndex getCCReg() { return ccList.getReg(); } + /** Adds a register back to the free list. */ void addReg(PhysRegIndex freed_reg); @@ -148,17 +157,26 @@ class UnifiedFreeList /** Adds a fp register back to the free list. */ void addFloatReg(PhysRegIndex freed_reg) { floatList.addReg(freed_reg); } + /** Adds a cc register back to the free list. */ + void addCCReg(PhysRegIndex freed_reg) { ccList.addReg(freed_reg); } + /** Checks if there are any free integer registers. */ bool hasFreeIntRegs() const { return intList.hasFreeRegs(); } /** Checks if there are any free fp registers. */ bool hasFreeFloatRegs() const { return floatList.hasFreeRegs(); } + /** Checks if there are any free cc registers. */ + bool hasFreeCCRegs() const { return ccList.hasFreeRegs(); } + /** Returns the number of free integer registers. */ unsigned numFreeIntRegs() const { return intList.numFreeRegs(); } /** Returns the number of free fp registers. */ unsigned numFreeFloatRegs() const { return floatList.numFreeRegs(); } + + /** Returns the number of free cc registers. */ + unsigned numFreeCCRegs() const { return ccList.numFreeRegs(); } }; inline void @@ -169,9 +187,11 @@ UnifiedFreeList::addReg(PhysRegIndex freed_reg) //already in there. A bit vector or something similar would be useful. if (regFile->isIntPhysReg(freed_reg)) { intList.addReg(freed_reg); - } else { - assert(regFile->isFloatPhysReg(freed_reg)); + } else if (regFile->isFloatPhysReg(freed_reg)) { floatList.addReg(freed_reg); + } else { + assert(regFile->isCCPhysReg(freed_reg)); + ccList.addReg(freed_reg); } // These assert conditions ensure that the number of free diff --git a/src/cpu/o3/inst_queue.hh b/src/cpu/o3/inst_queue.hh index 15190970d..212829ec1 100644 --- a/src/cpu/o3/inst_queue.hh +++ b/src/cpu/o3/inst_queue.hh @@ -1,5 +1,6 @@ /* * Copyright (c) 2011-2012 ARM Limited + * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -414,12 +415,6 @@ class InstructionQueue /** The number of physical registers in the CPU. */ unsigned numPhysRegs; - /** The number of physical integer registers in the CPU. */ - unsigned numPhysIntRegs; - - /** The number of floating point registers in the CPU. */ - unsigned numPhysFloatRegs; - /** Delay between commit stage and the IQ. * @todo: Make there be a distinction between the delays within IEW. */ diff --git a/src/cpu/o3/inst_queue_impl.hh b/src/cpu/o3/inst_queue_impl.hh index 3e3325beb..1c86b7c89 100644 --- a/src/cpu/o3/inst_queue_impl.hh +++ b/src/cpu/o3/inst_queue_impl.hh @@ -1,5 +1,6 @@ /* * Copyright (c) 2011-2012 ARM Limited + * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -87,16 +88,15 @@ InstructionQueue<Impl>::InstructionQueue(O3CPU *cpu_ptr, IEW *iew_ptr, fuPool(params->fuPool), numEntries(params->numIQEntries), totalWidth(params->issueWidth), - numPhysIntRegs(params->numPhysIntRegs), - numPhysFloatRegs(params->numPhysFloatRegs), commitToIEWDelay(params->commitToIEWDelay) { assert(fuPool); numThreads = params->numThreads; - // Set the number of physical registers as the number of int + float - numPhysRegs = numPhysIntRegs + numPhysFloatRegs; + // Set the number of total physical registers + numPhysRegs = params->numPhysIntRegs + params->numPhysFloatRegs + + params->numPhysCCRegs; //Create an entry for each physical register within the //dependency graph. diff --git a/src/cpu/o3/regfile.cc b/src/cpu/o3/regfile.cc index 5ba0caefc..96ce44bdd 100644 --- a/src/cpu/o3/regfile.cc +++ b/src/cpu/o3/regfile.cc @@ -36,12 +36,23 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs, - unsigned _numPhysicalFloatRegs) + unsigned _numPhysicalFloatRegs, + unsigned _numPhysicalCCRegs) : intRegFile(_numPhysicalIntRegs), floatRegFile(_numPhysicalFloatRegs), + ccRegFile(_numPhysicalCCRegs), baseFloatRegIndex(_numPhysicalIntRegs), - totalNumRegs(_numPhysicalIntRegs + _numPhysicalFloatRegs) + baseCCRegIndex(_numPhysicalIntRegs + _numPhysicalFloatRegs), + totalNumRegs(_numPhysicalIntRegs + + _numPhysicalFloatRegs + + _numPhysicalCCRegs) { + if (TheISA::NumCCRegs == 0 && _numPhysicalCCRegs != 0) { + // Just make this a warning and go ahead and allocate them + // anyway, to keep from having to add checks everywhere + warn("Non-zero number of physical CC regs specified, even though\n" + " ISA does not use them.\n"); + } } @@ -56,9 +67,15 @@ PhysRegFile::initFreeList(UnifiedFreeList *freeList) freeList->addIntReg(reg_idx++); } - // The rest of the registers are the floating-point physical + // The next batch of the registers are the floating-point physical // registers; put them onto the floating-point free list. - while (reg_idx < totalNumRegs) { + while (reg_idx < baseCCRegIndex) { freeList->addFloatReg(reg_idx++); } + + // The rest of the registers are the condition-code physical + // registers; put them onto the condition-code free list. + while (reg_idx < totalNumRegs) { + freeList->addCCReg(reg_idx++); + } } diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh index bd3a4f730..8b87725ca 100644 --- a/src/cpu/o3/regfile.hh +++ b/src/cpu/o3/regfile.hh @@ -55,6 +55,7 @@ class PhysRegFile typedef TheISA::IntReg IntReg; typedef TheISA::FloatReg FloatReg; typedef TheISA::FloatRegBits FloatRegBits; + typedef TheISA::CCReg CCReg; typedef union { FloatReg d; @@ -67,6 +68,9 @@ class PhysRegFile /** Floating point register file. */ std::vector<PhysFloatReg> floatRegFile; + /** Condition-code register file. */ + std::vector<CCReg> ccRegFile; + /** * The first floating-point physical register index. The physical * register file has a single continuous index space, with the @@ -83,6 +87,12 @@ class PhysRegFile */ unsigned baseFloatRegIndex; + /** + * The first condition-code physical register index. The + * condition-code registers follow the floating-point registers. + */ + unsigned baseCCRegIndex; + /** Total number of physical registers. */ unsigned totalNumRegs; @@ -92,7 +102,8 @@ class PhysRegFile * integer and floating point registers. */ PhysRegFile(unsigned _numPhysicalIntRegs, - unsigned _numPhysicalFloatRegs); + unsigned _numPhysicalFloatRegs, + unsigned _numPhysicalCCRegs); /** * Destructor to free resources @@ -107,7 +118,11 @@ class PhysRegFile /** @return the number of floating-point physical registers. */ unsigned numFloatPhysRegs() const - { return totalNumRegs - baseFloatRegIndex; } + { return baseCCRegIndex - baseFloatRegIndex; } + + /** @return the number of condition-code physical registers. */ + unsigned numCCPhysRegs() const + { return totalNumRegs - baseCCRegIndex; } /** @return the total number of physical registers. */ unsigned totalNumPhysRegs() const { return totalNumRegs; } @@ -127,7 +142,16 @@ class PhysRegFile */ bool isFloatPhysReg(PhysRegIndex reg_idx) const { - return (baseFloatRegIndex <= reg_idx && reg_idx < totalNumRegs); + return (baseFloatRegIndex <= reg_idx && reg_idx < baseCCRegIndex); + } + + /** + * Return true if the specified physical register index + * corresponds to a condition-code physical register. + */ + bool isCCPhysReg(PhysRegIndex reg_idx) + { + return (baseCCRegIndex <= reg_idx && reg_idx < totalNumRegs); } /** Reads an integer register. */ @@ -169,6 +193,20 @@ class PhysRegFile return floatRegBits; } + /** Reads a condition-code register. */ + CCReg readCCReg(PhysRegIndex reg_idx) + { + assert(isCCPhysReg(reg_idx)); + + // Remove the base CC reg dependency. + PhysRegIndex reg_offset = reg_idx - baseCCRegIndex; + + DPRINTF(IEW, "RegFile: Access to cc register %i, has " + "data %#x\n", int(reg_idx), ccRegFile[reg_offset]); + + return ccRegFile[reg_offset]; + } + /** Sets an integer register to the given value. */ void setIntReg(PhysRegIndex reg_idx, uint64_t val) { @@ -211,6 +249,19 @@ class PhysRegFile floatRegFile[reg_offset].q = val; } + /** Sets a condition-code register to the given value. */ + void setCCReg(PhysRegIndex reg_idx, CCReg val) + { + assert(isCCPhysReg(reg_idx)); + + // Remove the base CC reg dependency. + PhysRegIndex reg_offset = reg_idx - baseCCRegIndex; + + DPRINTF(IEW, "RegFile: Setting cc register %i to %#x\n", + int(reg_idx), (uint64_t)val); + + ccRegFile[reg_offset] = val; + } }; diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh index 6bfc7d952..38191ce36 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -65,7 +65,8 @@ DefaultRename<Impl>::DefaultRename(O3CPU *_cpu, DerivO3CPUParams *params) renameWidth(params->renameWidth), commitWidth(params->commitWidth), numThreads(params->numThreads), - maxPhysicalRegs(params->numPhysIntRegs + params->numPhysFloatRegs) + maxPhysicalRegs(params->numPhysIntRegs + params->numPhysFloatRegs + + params->numPhysCCRegs) { // @todo: Make into a parameter. skidBufferMax = (2 * (decodeToRenameDelay * params->decodeWidth)) + renameWidth; @@ -974,6 +975,11 @@ DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid) fpRenameLookups++; break; + case CCRegClass: + flat_rel_src_reg = tc->flattenCCIndex(rel_src_reg); + renamed_reg = map->lookupCC(flat_rel_src_reg); + break; + case MiscRegClass: // misc regs don't get flattened flat_rel_src_reg = rel_src_reg; @@ -1034,6 +1040,12 @@ DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid) flat_uni_dest_reg = flat_rel_dest_reg + TheISA::FP_Reg_Base; 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; + break; + case MiscRegClass: // misc regs don't get flattened flat_rel_dest_reg = rel_dest_reg; diff --git a/src/cpu/o3/rename_map.cc b/src/cpu/o3/rename_map.cc index ecee4c721..d816bf1fd 100644 --- a/src/cpu/o3/rename_map.cc +++ b/src/cpu/o3/rename_map.cc @@ -97,6 +97,8 @@ UnifiedRenameMap::init(PhysRegFile *_regFile, intMap.init(TheISA::NumIntRegs, &(freeList->intList), _intZeroReg); floatMap.init(TheISA::NumFloatRegs, &(freeList->floatList), _floatZeroReg); + + ccMap.init(TheISA::NumFloatRegs, &(freeList->ccList), (RegIndex)-1); } @@ -112,6 +114,9 @@ UnifiedRenameMap::rename(RegIndex arch_reg) case FloatRegClass: return renameFloat(rel_arch_reg); + case CCRegClass: + return renameCC(rel_arch_reg); + case MiscRegClass: return renameMisc(rel_arch_reg); @@ -134,6 +139,9 @@ UnifiedRenameMap::lookup(RegIndex arch_reg) const case FloatRegClass: return lookupFloat(rel_arch_reg); + case CCRegClass: + return lookupCC(rel_arch_reg); + case MiscRegClass: return lookupMisc(rel_arch_reg); @@ -155,6 +163,9 @@ UnifiedRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex phys_reg) case FloatRegClass: return setFloatEntry(rel_arch_reg, phys_reg); + case CCRegClass: + return setCCEntry(rel_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 diff --git a/src/cpu/o3/rename_map.hh b/src/cpu/o3/rename_map.hh index c989fb88f..751c39f52 100644 --- a/src/cpu/o3/rename_map.hh +++ b/src/cpu/o3/rename_map.hh @@ -163,6 +163,9 @@ class UnifiedRenameMap */ PhysRegFile *regFile; + /** The condition-code register rename map */ + SimpleRenameMap ccMap; + public: typedef TheISA::RegIndex RegIndex; @@ -214,6 +217,17 @@ class UnifiedRenameMap } /** + * Perform rename() on a condition-code register, given a relative + * condition-code register index. + */ + RenameInfo renameCC(RegIndex rel_arch_reg) + { + RenameInfo info = ccMap.rename(rel_arch_reg); + assert(regFile->isCCPhysReg(info.first)); + return info; + } + + /** * Perform rename() on a misc register, given a relative * misc register index. */ @@ -260,6 +274,17 @@ class UnifiedRenameMap } /** + * Perform lookup() on a condition-code register, given a relative + * condition-code register index. + */ + PhysRegIndex lookupCC(RegIndex rel_arch_reg) const + { + PhysRegIndex phys_reg = ccMap.lookup(rel_arch_reg); + assert(regFile->isCCPhysReg(phys_reg)); + return phys_reg; + } + + /** * Perform lookup() on a misc register, given a relative * misc register index. */ @@ -302,6 +327,16 @@ class UnifiedRenameMap } /** + * Perform setEntry() on a condition-code register, given a relative + * condition-code register index. + */ + void setCCEntry(RegIndex arch_reg, PhysRegIndex phys_reg) + { + assert(regFile->isCCPhysReg(phys_reg)); + ccMap.setEntry(arch_reg, phys_reg); + } + + /** * Return the minimum number of free entries across all of the * register classes. The minimum is used so we guarantee that * this number of entries is available regardless of which class diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh index 4201878af..88cf75f4f 100755 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@ -1,5 +1,6 @@ /* * Copyright (c) 2011-2012 ARM Limited + * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved * * The license below extends only to copyright in the software and shall @@ -182,6 +183,10 @@ class O3ThreadContext : public ThreadContext return readFloatRegBitsFlat(flattenFloatIndex(reg_idx)); } + virtual CCReg readCCReg(int reg_idx) { + return readCCRegFlat(flattenCCIndex(reg_idx)); + } + /** Sets an integer register to a value. */ virtual void setIntReg(int reg_idx, uint64_t val) { setIntRegFlat(flattenIntIndex(reg_idx), val); @@ -195,6 +200,10 @@ class O3ThreadContext : public ThreadContext setFloatRegBitsFlat(flattenFloatIndex(reg_idx), val); } + virtual void setCCReg(int reg_idx, CCReg val) { + setCCRegFlat(flattenCCIndex(reg_idx), val); + } + /** Reads this thread's PC state. */ virtual TheISA::PCState pcState() { return cpu->pcState(thread->threadId()); } @@ -234,6 +243,7 @@ class O3ThreadContext : public ThreadContext virtual int flattenIntIndex(int reg); virtual int flattenFloatIndex(int reg); + virtual int flattenCCIndex(int reg); /** Returns the number of consecutive store conditional failures. */ // @todo: Figure out where these store cond failures should go. @@ -283,6 +293,9 @@ class O3ThreadContext : public ThreadContext virtual FloatRegBits readFloatRegBitsFlat(int idx); virtual void setFloatRegBitsFlat(int idx, FloatRegBits val); + + virtual CCReg readCCRegFlat(int idx); + virtual void setCCRegFlat(int idx, CCReg val); }; #endif diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh index f818cc3dc..006d325fc 100755 --- a/src/cpu/o3/thread_context_impl.hh +++ b/src/cpu/o3/thread_context_impl.hh @@ -1,5 +1,6 @@ /* * Copyright (c) 2010-2012 ARM Limited + * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved * * The license below extends only to copyright in the software and shall @@ -206,6 +207,13 @@ O3ThreadContext<Impl>::readFloatRegBitsFlat(int reg_idx) } template <class Impl> +TheISA::CCReg +O3ThreadContext<Impl>::readCCRegFlat(int reg_idx) +{ + return cpu->readArchCCReg(reg_idx, thread->threadId()); +} + +template <class Impl> void O3ThreadContext<Impl>::setIntRegFlat(int reg_idx, uint64_t val) { @@ -234,6 +242,15 @@ O3ThreadContext<Impl>::setFloatRegBitsFlat(int reg_idx, FloatRegBits val) template <class Impl> void +O3ThreadContext<Impl>::setCCRegFlat(int reg_idx, TheISA::CCReg val) +{ + cpu->setArchCCReg(reg_idx, val, thread->threadId()); + + conditionalSquash(); +} + +template <class Impl> +void O3ThreadContext<Impl>::pcState(const TheISA::PCState &val) { cpu->pcState(val, thread->threadId()); @@ -265,6 +282,13 @@ O3ThreadContext<Impl>::flattenFloatIndex(int reg) } template <class Impl> +int +O3ThreadContext<Impl>::flattenCCIndex(int reg) +{ + return cpu->isa[thread->threadId()]->flattenCCIndex(reg); +} + +template <class Impl> void O3ThreadContext<Impl>::setMiscRegNoEffect(int misc_reg, const MiscReg &val) { |