diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 4b316ae7e..496961380 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -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 @@ -235,11 +236,9 @@ FullO3CPU::FullO3CPU(DerivO3CPUParams *params) params->smtROBPolicy, params->smtROBThreshold, params->numThreads), - scoreboard(params->numThreads, - TheISA::NumIntRegs, params->numPhysIntRegs, - TheISA::NumFloatRegs, params->numPhysFloatRegs, - TheISA::NumMiscRegs * numThreads, - TheISA::ZeroReg), + scoreboard(name() + ".scoreboard", + regFile.totalNumPhysRegs(), TheISA::NumMiscRegs, + TheISA::ZeroReg, TheISA::ZeroReg), isa(numThreads, NULL), diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh index 6e564abab..3ab0afe11 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -884,11 +884,6 @@ DefaultRename::doSquash(const InstSeqNum &squashed_seq_num, ThreadID tid) // Put the renamed physical register back on the free list. freeList->addReg(hb_it->newPhysReg); - // Be sure to mark its register as ready if it's a misc register. - if (hb_it->newPhysReg >= maxPhysicalRegs) { - scoreboard->setReg(hb_it->newPhysReg); - } - historyBuffer[tid].erase(hb_it++); ++renameUndoneMaps; @@ -1050,8 +1045,7 @@ DefaultRename::renameDestRegs(DynInstPtr &inst, ThreadID tid) rename_result = renameMap[tid]->rename(flat_dest_reg); //Mark Scoreboard entry as not ready - if (regIdxToClass(dest_reg) != MiscRegClass) - scoreboard->unsetReg(rename_result.first); + scoreboard->unsetReg(rename_result.first); DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i to physical " "reg %i.\n", tid, (int)flat_dest_reg, diff --git a/src/cpu/o3/scoreboard.cc b/src/cpu/o3/scoreboard.cc index 83a88f213..11b2858da 100644 --- a/src/cpu/o3/scoreboard.cc +++ b/src/cpu/o3/scoreboard.cc @@ -1,5 +1,6 @@ /* * Copyright (c) 2005-2006 The Regents of The University of Michigan + * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,99 +34,13 @@ #include "cpu/o3/scoreboard.hh" #include "debug/Scoreboard.hh" -Scoreboard::Scoreboard(unsigned activeThreads, - unsigned _numLogicalIntRegs, - unsigned _numPhysicalIntRegs, - unsigned _numLogicalFloatRegs, - unsigned _numPhysicalFloatRegs, - unsigned _numMiscRegs, - unsigned _zeroRegIdx) - : numLogicalIntRegs(_numLogicalIntRegs), - numPhysicalIntRegs(_numPhysicalIntRegs), - numLogicalFloatRegs(_numLogicalFloatRegs), - numPhysicalFloatRegs(_numPhysicalFloatRegs), - numMiscRegs(_numMiscRegs), - zeroRegIdx(_zeroRegIdx) +Scoreboard::Scoreboard(const std::string &_my_name, + unsigned _numPhysicalRegs, unsigned _numMiscRegs, + PhysRegIndex _zeroRegIdx, PhysRegIndex _fpZeroRegIdx) + : _name(_my_name), + regScoreBoard(_numPhysicalRegs, true), + numPhysRegs(_numPhysicalRegs), + numTotalRegs(_numPhysicalRegs + _numMiscRegs), + zeroRegIdx(_zeroRegIdx), fpZeroRegIdx(_fpZeroRegIdx) { - //Get Register Sizes - numLogicalRegs = numLogicalIntRegs + numLogicalFloatRegs; - numPhysicalRegs = numPhysicalIntRegs + numPhysicalFloatRegs; - - //Resize scoreboard appropriately - resize(numPhysicalRegs + (numMiscRegs * activeThreads)); - - //Initialize values - for (int i=0; i < numLogicalIntRegs * activeThreads; i++) { - assert(indexInBounds(i)); - regScoreBoard[i] = 1; - } - - for (int i= numPhysicalIntRegs; - i < numPhysicalIntRegs + (numLogicalFloatRegs * activeThreads); - i++) { - assert(indexInBounds(i)); - regScoreBoard[i] = 1; - } - - for (int i = numPhysicalRegs; - i < numPhysicalRegs + (numMiscRegs * activeThreads); - i++) { - assert(indexInBounds(i)); - regScoreBoard[i] = 1; - } -} - -std::string -Scoreboard::name() const -{ - return "cpu.scoreboard"; -} - -bool -Scoreboard::getReg(PhysRegIndex phys_reg) -{ -#if THE_ISA == ALPHA_ISA - // Always ready if int or fp zero reg. - if (phys_reg == zeroRegIdx || - phys_reg == (zeroRegIdx + numPhysicalIntRegs)) { - return 1; - } -#else - // Always ready if int zero reg. - if (phys_reg == zeroRegIdx) { - return 1; - } -#endif - - assert(indexInBounds(phys_reg)); - return regScoreBoard[phys_reg]; -} - -void -Scoreboard::setReg(PhysRegIndex phys_reg) -{ - DPRINTF(Scoreboard, "Setting reg %i as ready\n", phys_reg); - - assert(indexInBounds(phys_reg)); - regScoreBoard[phys_reg] = 1; -} - -void -Scoreboard::unsetReg(PhysRegIndex ready_reg) -{ -#if THE_ISA == ALPHA_ISA - if (ready_reg == zeroRegIdx || - ready_reg == (zeroRegIdx + numPhysicalIntRegs)) { - // Don't do anything if int or fp zero reg. - return; - } -#else - if (ready_reg == zeroRegIdx) { - // Don't do anything if int zero reg. - return; - } -#endif - - assert(indexInBounds(ready_reg)); - regScoreBoard[ready_reg] = 0; } diff --git a/src/cpu/o3/scoreboard.hh b/src/cpu/o3/scoreboard.hh index 8a49d7a3a..79271082d 100644 --- a/src/cpu/o3/scoreboard.hh +++ b/src/cpu/o3/scoreboard.hh @@ -1,5 +1,6 @@ /* * Copyright (c) 2005-2006 The Regents of The University of Michigan + * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,6 +28,7 @@ * * Authors: Korey Sewell * Kevin Lim + * Steve Reinhardt */ #ifndef __CPU_O3_SCOREBOARD_HH__ @@ -37,95 +39,124 @@ #include #include "base/trace.hh" +#include "config/the_isa.hh" #include "cpu/o3/comm.hh" +#include "debug/Scoreboard.hh" /** - * Implements a simple scoreboard to track which registers are ready. - * This class assumes that the fp registers start, index wise, right after - * the integer registers. The misc. registers start, index wise, right after - * the fp registers. - * @todo: Fix up handling of the zero register in case the decoder does not - * automatically make insts that write the zero register into nops. + * Implements a simple scoreboard to track which registers are + * ready. This class operates on the unified physical register space, + * so integer and floating-point registers are not distinguished. For + * convenience, it also accepts operations on the physical-space + * mapping of misc registers, which are numbered starting after the + * end of the actual physical register file. However, there is no + * actual scoreboard for misc registers, and they are always + * considered ready. */ class Scoreboard { + private: + /** The object name, for DPRINTF. We have to declare this + * explicitly because Scoreboard is not a SimObject. */ + const std::string _name; + + /** Scoreboard of physical integer registers, saying whether or not they + * are ready. */ + std::vector regScoreBoard; + + /** The number of actual physical registers */ + unsigned numPhysRegs; + + /** + * The total number of registers which can be indexed, including + * the misc registers that come after the physical registers and + * which are hardwired to be always considered ready. + */ + unsigned numTotalRegs; + + /** The index of the zero register. */ + PhysRegIndex zeroRegIdx; + + /** The index of the FP zero register. */ + PhysRegIndex fpZeroRegIdx; + + bool isZeroReg(PhysRegIndex idx) const + { + return (idx == zeroRegIdx || + (THE_ISA == ALPHA_ISA && idx == fpZeroRegIdx)); + } + public: /** Constructs a scoreboard. - * @param activeThreads The number of active threads. - * @param _numLogicalIntRegs Number of logical integer registers. - * @param _numPhysicalIntRegs Number of physical integer registers. - * @param _numLogicalFloatRegs Number of logical fp registers. - * @param _numPhysicalFloatRegs Number of physical fp registers. + * @param _numPhysicalRegs Number of physical registers. * @param _numMiscRegs Number of miscellaneous registers. * @param _zeroRegIdx Index of the zero register. + * @param _fpZeroRegIdx Index of the FP zero register (if any, currently + * used only for Alpha). */ - Scoreboard(unsigned activeThreads, - unsigned _numLogicalIntRegs, - unsigned _numPhysicalIntRegs, - unsigned _numLogicalFloatRegs, - unsigned _numPhysicalFloatRegs, + Scoreboard(const std::string &_my_name, + unsigned _numPhysicalRegs, unsigned _numMiscRegs, - unsigned _zeroRegIdx); + PhysRegIndex _zeroRegIdx, + PhysRegIndex _fpZeroRegIdx); /** Destructor. */ ~Scoreboard() {} /** Returns the name of the scoreboard. */ - std::string name() const; + std::string name() const { return _name; }; /** Checks if the register is ready. */ - bool getReg(PhysRegIndex ready_reg); + bool getReg(PhysRegIndex reg_idx) const + { + assert(reg_idx < numTotalRegs); + + if (reg_idx >= numPhysRegs) { + // misc regs are always ready + return true; + } + + bool ready = regScoreBoard[reg_idx]; + + if (isZeroReg(reg_idx)) + assert(ready); + + return ready; + } /** Sets the register as ready. */ - void setReg(PhysRegIndex phys_reg); + void setReg(PhysRegIndex reg_idx) + { + assert(reg_idx < numTotalRegs); + + if (reg_idx >= numPhysRegs) { + // misc regs are always ready, ignore attempts to change that + return; + } + + DPRINTF(Scoreboard, "Setting reg %i as ready\n", reg_idx); + + assert(reg_idx < numTotalRegs); + regScoreBoard[reg_idx] = true; + } /** Sets the register as not ready. */ - void unsetReg(PhysRegIndex ready_reg); - - private: - /** Scoreboard of physical integer registers, saying whether or not they - * are ready. - */ - std::vector regScoreBoard; - - /** Number of logical integer registers. */ - int numLogicalIntRegs; - - /** Number of physical integer registers. */ - int numPhysicalIntRegs; - - /** Number of logical floating point registers. */ - int numLogicalFloatRegs; - - /** Number of physical floating point registers. */ - int numPhysicalFloatRegs; - - /** Number of miscellaneous registers. */ - int numMiscRegs; - - /** Number of logical integer + float registers. */ - int numLogicalRegs; - - /** Number of physical integer + float registers. */ - int numPhysicalRegs; - - /** The logical index of the zero register. */ - int zeroRegIdx; - - int currentSize; - - void - resize(int newSize) + void unsetReg(PhysRegIndex reg_idx) { - currentSize = newSize; - regScoreBoard.resize(newSize); + assert(reg_idx < numTotalRegs); + + if (reg_idx >= numPhysRegs) { + // misc regs are always ready, ignore attempts to change that + return; + } + + // zero reg should never be marked unready + if (isZeroReg(reg_idx)) + return; + + regScoreBoard[reg_idx] = false; } - bool - indexInBounds(int idx) - { - return idx < currentSize; - } }; #endif