free_list.hh revision 12105
1803SN/A/* 21363SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 3803SN/A * Copyright (c) 2013 Advanced Micro Devices, Inc. 4803SN/A * All rights reserved. 5803SN/A * 6803SN/A * Redistribution and use in source and binary forms, with or without 7803SN/A * modification, are permitted provided that the following conditions are 8803SN/A * met: redistributions of source code must retain the above copyright 9803SN/A * notice, this list of conditions and the following disclaimer; 10803SN/A * redistributions in binary form must reproduce the above copyright 11803SN/A * notice, this list of conditions and the following disclaimer in the 12803SN/A * documentation and/or other materials provided with the distribution; 13803SN/A * neither the name of the copyright holders nor the names of its 14803SN/A * contributors may be used to endorse or promote products derived from 15803SN/A * this software without specific prior written permission. 16803SN/A * 17803SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18803SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19803SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20803SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21803SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22803SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23803SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24803SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25803SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26803SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 272665SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282665SN/A * 292665SN/A * Authors: Kevin Lim 302665SN/A */ 31803SN/A 32768SN/A#ifndef __CPU_O3_FREE_LIST_HH__ 331730SN/A#define __CPU_O3_FREE_LIST_HH__ 34773SN/A 35768SN/A#include <iostream> 36768SN/A#include <queue> 37773SN/A#include <vector> 38773SN/A 39768SN/A#include "base/misc.hh" 40768SN/A#include "base/trace.hh" 41768SN/A#include "cpu/o3/comm.hh" 42768SN/A#include "cpu/o3/regfile.hh" 434762Snate@binkert.org#include "debug/FreeList.hh" 44768SN/A 456658Snate@binkert.org/** 462542SN/A * Free list for a single class of registers (e.g., integer 473540Sgblack@eecs.umich.edu * or floating point). Because the register class is implicitly 483540Sgblack@eecs.umich.edu * determined by the rename map instance being accessed, all 493540Sgblack@eecs.umich.edu * architectural register index parameters and values in this class 503540Sgblack@eecs.umich.edu * are relative (e.g., %fp2 is just index 2). 513348SN/A */ 523348SN/Aclass SimpleFreeList 532542SN/A{ 542542SN/A private: 55768SN/A 56768SN/A /** The actual free list */ 572107SN/A std::queue<PhysRegIdPtr> freeRegs; 582107SN/A 59773SN/A public: 605606Snate@binkert.org 615606Snate@binkert.org SimpleFreeList() {}; 625606Snate@binkert.org 631817SN/A /** Add a physical register to the free list */ 64772SN/A void addReg(PhysRegIdPtr reg) { freeRegs.push(reg); } 65772SN/A 664762Snate@binkert.org /** Get the next available register from the free list */ 675606Snate@binkert.org PhysRegIdPtr getReg() 685606Snate@binkert.org { 69768SN/A assert(!freeRegs.empty()); 703846Shsul@eecs.umich.edu PhysRegIdPtr free_reg = freeRegs.front(); 71909SN/A freeRegs.pop(); 72803SN/A return free_reg; 73803SN/A } 74803SN/A 75771SN/A /** Return the number of free registers on the list. */ 76777SN/A unsigned numFreeRegs() const { return freeRegs.size(); } 77777SN/A 78773SN/A /** True iff there are free registers on the list. */ 79773SN/A bool hasFreeRegs() const { return !freeRegs.empty(); } 801634SN/A}; 811634SN/A 821634SN/A 832539SN/A/** 841634SN/A * FreeList class that simply holds the list of free integer and floating 851634SN/A * point registers. Can request for a free register of either type, and 862542SN/A * also send back free registers of either type. This is a very simple 873349SN/A * class, but it should be sufficient for most implementations. Like all 88768SN/A * other classes, it assumes that the indices for the floating point 892641SN/A * registers starts after the integer registers end. Hence the variable 90768SN/A * numPhysicalIntRegs is logically equivalent to the baseFP dependency. 912641SN/A * Note that while this most likely should be called FreeList, the name 92865SN/A * "FreeList" is used in a typedef within the CPU Policy, and therefore no 932641SN/A * class can be named simply "FreeList". 942641SN/A * @todo: Give a better name to the base FP dependency. 95771SN/A */ 962630SN/Aclass UnifiedFreeList 972539SN/A{ 982641SN/A private: 99803SN/A 1001817SN/A /** The object name, for DPRINTF. We have to declare this 1011817SN/A * explicitly because Scoreboard is not a SimObject. */ 1022630SN/A const std::string _name; 1032539SN/A 1041817SN/A /** The list of free integer registers. */ 1052630SN/A SimpleFreeList intList; 1062539SN/A 107865SN/A /** The list of free floating point registers. */ 108865SN/A SimpleFreeList floatList; 109865SN/A 110865SN/A /** The list of free condition-code registers. */ 1112630SN/A SimpleFreeList ccList; 1122539SN/A 113865SN/A /** 114865SN/A * The register file object is used only to distinguish integer 1152630SN/A * from floating-point physical register indices. 1162539SN/A */ 1171817SN/A PhysRegFile *regFile; 1185635Sgblack@eecs.umich.edu 1192542SN/A /* 1201817SN/A * We give UnifiedRenameMap internal access so it can get at the 1215635Sgblack@eecs.umich.edu * internal per-class free lists and associate those with its 1222542SN/A * per-class rename maps. See UnifiedRenameMap::init(). 1231817SN/A */ 1245635Sgblack@eecs.umich.edu friend class UnifiedRenameMap; 1252539SN/A 126803SN/A public: 1275392Sgblack@eecs.umich.edu /** Constructs a free list. 1282539SN/A * @param _numPhysicalIntRegs Number of physical integer registers. 1291817SN/A * @param reservedIntRegs Number of integer registers already 1305635Sgblack@eecs.umich.edu * used by initial mappings. 1312630SN/A * @param _numPhysicalFloatRegs Number of physical fp registers. 1321817SN/A * @param reservedFloatRegs Number of fp registers already 1332630SN/A * used by initial mappings. 1342539SN/A */ 135803SN/A UnifiedFreeList(const std::string &_my_name, PhysRegFile *_regFile); 1362641SN/A 137803SN/A /** Gives the name of the freelist. */ 1382641SN/A std::string name() const { return _name; }; 1392539SN/A 1402630SN/A /** Returns a pointer to the condition-code free list */ 1412539SN/A SimpleFreeList *getCCList() { return &ccList; } 1422539SN/A 1432641SN/A /** Gets a free integer register. */ 1442539SN/A PhysRegIdPtr getIntReg() { return intList.getReg(); } 1452641SN/A 146771SN/A /** Gets a free fp register. */ 1474870Sstever@eecs.umich.edu PhysRegIdPtr getFloatReg() { return floatList.getReg(); } 1482539SN/A 149768SN/A /** Gets a free cc register. */ 150768SN/A PhysRegIdPtr getCCReg() { return ccList.getReg(); } 1512539SN/A 1523349SN/A /** Adds a register back to the free list. */ 153768SN/A void addReg(PhysRegIdPtr freed_reg); 1542641SN/A 1552641SN/A /** Adds an integer register back to the free list. */ 156779SN/A void addIntReg(PhysRegIdPtr freed_reg) { intList.addReg(freed_reg); } 157779SN/A 1582641SN/A /** Adds a fp register back to the free list. */ 159768SN/A void addFloatReg(PhysRegIdPtr freed_reg) { floatList.addReg(freed_reg); } 1602641SN/A 161769SN/A /** Adds a cc register back to the free list. */ 1622539SN/A void addCCReg(PhysRegIdPtr freed_reg) { ccList.addReg(freed_reg); } 1632539SN/A 1642630SN/A /** Checks if there are any free integer registers. */ 1652539SN/A bool hasFreeIntRegs() const { return intList.hasFreeRegs(); } 1662539SN/A 1672539SN/A /** Checks if there are any free fp registers. */ 1682539SN/A bool hasFreeFloatRegs() const { return floatList.hasFreeRegs(); } 169803SN/A 1702539SN/A /** Checks if there are any free cc registers. */ 1712539SN/A bool hasFreeCCRegs() const { return ccList.hasFreeRegs(); } 1722539SN/A 1732539SN/A /** Returns the number of free integer registers. */ 1742539SN/A unsigned numFreeIntRegs() const { return intList.numFreeRegs(); } 1752539SN/A 1762539SN/A /** Returns the number of free fp registers. */ 1772630SN/A unsigned numFreeFloatRegs() const { return floatList.numFreeRegs(); } 1782539SN/A 1792539SN/A /** Returns the number of free cc registers. */ 1802539SN/A unsigned numFreeCCRegs() const { return ccList.numFreeRegs(); } 1812539SN/A}; 1822630SN/A 1832539SN/Ainline void 1842539SN/AUnifiedFreeList::addReg(PhysRegIdPtr freed_reg) 1852539SN/A{ 1862539SN/A DPRINTF(FreeList,"Freeing register %i (%s).\n", freed_reg->regIdx, 1872630SN/A RegClassStrings[freed_reg->regClass]); 1882539SN/A //Might want to add in a check for whether or not this register is 1892539SN/A //already in there. A bit vector or something similar would be useful. 1902630SN/A switch (freed_reg->regClass) { 1912539SN/A case IntRegClass: 1922539SN/A intList.addReg(freed_reg); 1935635Sgblack@eecs.umich.edu break; 1942539SN/A case FloatRegClass: 1952539SN/A floatList.addReg(freed_reg); 1965635Sgblack@eecs.umich.edu break; 1972539SN/A case CCRegClass: 1982539SN/A ccList.addReg(freed_reg); 1995635Sgblack@eecs.umich.edu break; 2002539SN/A default: 2012539SN/A panic("Unexpected RegClass (%s)", 2022630SN/A RegClassStrings[freed_reg->regClass]); 2032539SN/A } 2042539SN/A 2055392Sgblack@eecs.umich.edu // These assert conditions ensure that the number of free 2062539SN/A // registers are not more than the # of total Physical Registers. 2072539SN/A // If this were false, it would mean that registers 2085392Sgblack@eecs.umich.edu // have been freed twice, overflowing the free register 2092539SN/A // pool and potentially crashing SMT workloads. 2102539SN/A // ---- 2112539SN/A // Comment out for now so as to not potentially break 2122539SN/A // CMP and single-threaded workloads 2132539SN/A // ---- 2142539SN/A // assert(freeIntRegs.size() <= numPhysicalIntRegs); 2152539SN/A // assert(freeFloatRegs.size() <= numPhysicalFloatRegs); 2162539SN/A} 2172539SN/A 2182539SN/A 2192539SN/A#endif // __CPU_O3_FREE_LIST_HH__ 2202539SN/A