diff options
Diffstat (limited to 'src/cpu/o3/free_list.hh')
-rw-r--r-- | src/cpu/o3/free_list.hh | 176 |
1 files changed, 80 insertions, 96 deletions
diff --git a/src/cpu/o3/free_list.hh b/src/cpu/o3/free_list.hh index fec076097..3919d0afb 100644 --- a/src/cpu/o3/free_list.hh +++ b/src/cpu/o3/free_list.hh @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2005 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 @@ -34,14 +35,51 @@ #include <iostream> #include <queue> -#include "arch/registers.hh" #include "base/misc.hh" #include "base/trace.hh" -#include "config/the_isa.hh" #include "cpu/o3/comm.hh" +#include "cpu/o3/regfile.hh" #include "debug/FreeList.hh" /** + * Free list for a single class of registers (e.g., integer + * or floating point). Because the register class is implicitly + * determined by the rename map instance being accessed, all + * architectural register index parameters and values in this class + * are relative (e.g., %fp2 is just index 2). + */ +class SimpleFreeList +{ + private: + + /** The actual free list */ + std::queue<PhysRegIndex> freeRegs; + + public: + + SimpleFreeList() {}; + + /** Add a physical register to the free list */ + void addReg(PhysRegIndex reg) { freeRegs.push(reg); } + + /** Get the next available register from the free list */ + PhysRegIndex getReg() + { + assert(!freeRegs.empty()); + PhysRegIndex free_reg = freeRegs.front(); + freeRegs.pop(); + return free_reg; + } + + /** Return the number of free registers on the list. */ + unsigned numFreeRegs() const { return freeRegs.size(); } + + /** True iff there are free registers on the list. */ + bool hasFreeRegs() const { return !freeRegs.empty(); } +}; + + +/** * FreeList class that simply holds the list of free integer and floating * point registers. Can request for a free register of either type, and * also send back free registers of either type. This is a very simple @@ -54,125 +92,86 @@ * class can be named simply "FreeList". * @todo: Give a better name to the base FP dependency. */ -class SimpleFreeList +class UnifiedFreeList { private: - /** The list of free integer registers. */ - std::queue<PhysRegIndex> freeIntRegs; - /** The list of free floating point registers. */ - std::queue<PhysRegIndex> freeFloatRegs; - - /** Number of logical integer registers. */ - int numLogicalIntRegs; + /** The object name, for DPRINTF. We have to declare this + * explicitly because Scoreboard is not a SimObject. */ + const std::string _name; - /** Number of physical integer registers. */ - int numPhysicalIntRegs; + /** The list of free integer registers. */ + SimpleFreeList intList; - /** Number of logical floating point registers. */ - int numLogicalFloatRegs; + /** The list of free floating point registers. */ + SimpleFreeList floatList; - /** Number of physical floating point registers. */ - int numPhysicalFloatRegs; + /** + * The register file object is used only to distinguish integer + * from floating-point physical register indices. + */ + PhysRegFile *regFile; - /** Total number of physical registers. */ - int numPhysicalRegs; + /* + * We give UnifiedRenameMap internal access so it can get at the + * internal per-class free lists and associate those with its + * per-class rename maps. See UnifiedRenameMap::init(). + */ + friend class UnifiedRenameMap; public: /** Constructs a free list. - * @param activeThreads 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 reservedIntRegs Number of integer registers already + * used by initial mappings. * @param _numPhysicalFloatRegs Number of physical fp registers. + * @param reservedFloatRegs Number of fp registers already + * used by initial mappings. */ - SimpleFreeList(ThreadID activeThreads, - unsigned _numLogicalIntRegs, - unsigned _numPhysicalIntRegs, - unsigned _numLogicalFloatRegs, - unsigned _numPhysicalFloatRegs); + UnifiedFreeList(const std::string &_my_name, PhysRegFile *_regFile); /** Gives the name of the freelist. */ - std::string name() const; + std::string name() const { return _name; }; /** Gets a free integer register. */ - inline PhysRegIndex getIntReg(); + PhysRegIndex getIntReg() { return intList.getReg(); } /** Gets a free fp register. */ - inline PhysRegIndex getFloatReg(); + PhysRegIndex getFloatReg() { return floatList.getReg(); } /** Adds a register back to the free list. */ - inline void addReg(PhysRegIndex freed_reg); + void addReg(PhysRegIndex freed_reg); /** Adds an integer register back to the free list. */ - inline void addIntReg(PhysRegIndex freed_reg); + void addIntReg(PhysRegIndex freed_reg) { intList.addReg(freed_reg); } /** Adds a fp register back to the free list. */ - inline void addFloatReg(PhysRegIndex freed_reg); + void addFloatReg(PhysRegIndex freed_reg) { floatList.addReg(freed_reg); } /** Checks if there are any free integer registers. */ - bool hasFreeIntRegs() - { return !freeIntRegs.empty(); } + bool hasFreeIntRegs() const { return intList.hasFreeRegs(); } /** Checks if there are any free fp registers. */ - bool hasFreeFloatRegs() - { return !freeFloatRegs.empty(); } + bool hasFreeFloatRegs() const { return floatList.hasFreeRegs(); } /** Returns the number of free integer registers. */ - int numFreeIntRegs() - { return freeIntRegs.size(); } + unsigned numFreeIntRegs() const { return intList.numFreeRegs(); } /** Returns the number of free fp registers. */ - int numFreeFloatRegs() - { return freeFloatRegs.size(); } + unsigned numFreeFloatRegs() const { return floatList.numFreeRegs(); } }; -inline PhysRegIndex -SimpleFreeList::getIntReg() -{ - DPRINTF(FreeList, "Trying to get free integer register.\n"); - - if (freeIntRegs.empty()) { - panic("No free integer registers!"); - } - - PhysRegIndex free_reg = freeIntRegs.front(); - - freeIntRegs.pop(); - - return(free_reg); -} - -inline PhysRegIndex -SimpleFreeList::getFloatReg() -{ - DPRINTF(FreeList, "Trying to get free float register.\n"); - - if (freeFloatRegs.empty()) { - panic("No free integer registers!"); - } - - PhysRegIndex free_reg = freeFloatRegs.front(); - - freeFloatRegs.pop(); - - return(free_reg); -} - inline void -SimpleFreeList::addReg(PhysRegIndex freed_reg) +UnifiedFreeList::addReg(PhysRegIndex freed_reg) { DPRINTF(FreeList,"Freeing register %i.\n", freed_reg); //Might want to add in a check for whether or not this register is //already in there. A bit vector or something similar would be useful. - if (freed_reg < numPhysicalIntRegs) { - if (freed_reg != TheISA::ZeroReg) - freeIntRegs.push(freed_reg); - } else if (freed_reg < numPhysicalRegs) { -#if THE_ISA == ALPHA_ISA - if (freed_reg != (TheISA::ZeroReg + numPhysicalIntRegs)) -#endif - freeFloatRegs.push(freed_reg); + if (regFile->isIntPhysReg(freed_reg)) { + intList.addReg(freed_reg); + } else { + assert(regFile->isFloatPhysReg(freed_reg)); + floatList.addReg(freed_reg); } // These assert conditions ensure that the number of free @@ -188,20 +187,5 @@ SimpleFreeList::addReg(PhysRegIndex freed_reg) // assert(freeFloatRegs.size() <= numPhysicalFloatRegs); } -inline void -SimpleFreeList::addIntReg(PhysRegIndex freed_reg) -{ - DPRINTF(FreeList,"Freeing int register %i.\n", freed_reg); - - freeIntRegs.push(freed_reg); -} - -inline void -SimpleFreeList::addFloatReg(PhysRegIndex freed_reg) -{ - DPRINTF(FreeList,"Freeing float register %i.\n", freed_reg); - - freeFloatRegs.push(freed_reg); -} #endif // __CPU_O3_FREE_LIST_HH__ |