# Node ID b2e43d792a9e4705ab1f5363e66b771c2236dd1c # Parent b55ab0dc9abccf0293205ea51f47ffa151ed9b29 diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc --- 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 @@ params->smtROBPolicy, params->smtROBThreshold, params->numThreads), - scoreboard(params->numThreads, - TheISA::NumIntRegs, params->numPhysIntRegs, - TheISA::NumFloatRegs, params->numPhysFloatRegs, - TheISA::NumMiscRegs * numThreads, - TheISA::ZeroReg), + scoreboard(regFile.totalNumPhysRegs(), + TheISA::NumMiscRegs, + TheISA::ZeroReg, TheISA::ZeroReg), isa(numThreads, NULL), diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh --- a/src/cpu/o3/regfile.hh +++ b/src/cpu/o3/regfile.hh @@ -91,35 +91,36 @@ */ ~PhysRegFile(); - /** Return the number of integer physical registers. */ - unsigned numIntPhysRegs() { return baseFloatRegIndex; } + /** @return the number of integer physical registers. */ + unsigned numIntPhysRegs() const { return baseFloatRegIndex; } - /** Return the number of floating-point physical registers. */ - unsigned numFloatPhysRegs() { return totalNumRegs - baseFloatRegIndex; } + /** @return the number of floating-point physical registers. */ + unsigned numFloatPhysRegs() const + { return totalNumRegs - baseFloatRegIndex; } - /** Return the total number of physical registers. */ - unsigned totalNumPhysRegs() { return totalNumRegs; } + /** @return the total number of physical registers. */ + unsigned totalNumPhysRegs() const { return totalNumRegs; } /** - * Return true if the specified physical register index + * @return true if the specified physical register index * corresponds to an integer physical register. */ - bool isIntPhysReg(PhysRegIndex reg_idx) + bool isIntPhysReg(PhysRegIndex reg_idx) const { return 0 <= reg_idx && reg_idx < baseFloatRegIndex; } /** - * Return true if the specified physical register index + * @return true if the specified physical register index * corresponds to a floating-point physical register. */ - bool isFloatPhysReg(PhysRegIndex reg_idx) + bool isFloatPhysReg(PhysRegIndex reg_idx) const { return (baseFloatRegIndex <= reg_idx && reg_idx < totalNumRegs); } /** Reads an integer register. */ - uint64_t readIntReg(PhysRegIndex reg_idx) + uint64_t readIntReg(PhysRegIndex reg_idx) const { assert(isIntPhysReg(reg_idx)); @@ -129,7 +130,7 @@ } /** Reads a floating point register (double precision). */ - FloatReg readFloatReg(PhysRegIndex reg_idx) + FloatReg readFloatReg(PhysRegIndex reg_idx) const { assert(isFloatPhysReg(reg_idx)); @@ -142,7 +143,7 @@ return floatRegFile[reg_offset].d; } - FloatRegBits readFloatRegBits(PhysRegIndex reg_idx) + FloatRegBits readFloatRegBits(PhysRegIndex reg_idx) const { assert(isFloatPhysReg(reg_idx)); diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -884,11 +884,6 @@ // 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 @@ 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.hh b/src/cpu/o3/scoreboard.hh --- 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,35 +39,62 @@ #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: + /** Scoreboard of physical integer registers, saying whether or not they + * are ready. + */ + std::vector regScoreBoard; + + /** The number of actual physical registers */ + int 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. + */ + int numTotalRegs; + + /** The index of the zero register. */ + PhysRegIndex zeroRegIdx; + + /** The index of the FP zero register. */ + PhysRegIndex fpZeroRegIdx; + + bool isZeroReg(PhysRegIndex idx) + { + 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(unsigned _numPhysicalRegs, unsigned _numMiscRegs, - unsigned _zeroRegIdx); + PhysRegIndex _zeroRegIdx, + PhysRegIndex _fpZeroRegIdx); /** Destructor. */ ~Scoreboard() {} @@ -74,58 +103,56 @@ std::string name() const; /** Checks if the register is ready. */ - bool getReg(PhysRegIndex ready_reg); + bool getReg(PhysRegIndex reg_idx) + { + 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); + void unsetReg(PhysRegIndex reg_idx) + { + assert(reg_idx < numTotalRegs); - private: - /** Scoreboard of physical integer registers, saying whether or not they - * are ready. - */ - std::vector regScoreBoard; + if (reg_idx >= numPhysRegs) { + // misc regs are always ready, ignore attempts to change that + return; + } - /** Number of logical integer registers. */ - int numLogicalIntRegs; + // zero reg should never be marked unready + if (isZeroReg(reg_idx)) + return; - /** 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) - { - currentSize = newSize; - regScoreBoard.resize(newSize); + regScoreBoard[reg_idx] = false; } - bool - indexInBounds(int idx) - { - return idx < currentSize; - } }; #endif diff --git a/src/cpu/o3/scoreboard.cc b/src/cpu/o3/scoreboard.cc --- 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,46 +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(unsigned _numPhysicalRegs, unsigned _numMiscRegs, + PhysRegIndex _zeroRegIdx, PhysRegIndex _fpZeroRegIdx) + : 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 @@ -80,52 +48,3 @@ { 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; -}