free_list.hh revision 10934:5af8f40d8f2c
17405SAli.Saidi@ARM.com/* 211573SDylan.Johnson@ARM.com * Copyright (c) 2004-2005 The Regents of The University of Michigan 37405SAli.Saidi@ARM.com * Copyright (c) 2013 Advanced Micro Devices, Inc. 47405SAli.Saidi@ARM.com * All rights reserved. 57405SAli.Saidi@ARM.com * 67405SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without 77405SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are 87405SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright 97405SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer; 107405SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright 117405SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the 127405SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution; 137405SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its 147405SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from 157405SAli.Saidi@ARM.com * this software without specific prior written permission. 167405SAli.Saidi@ARM.com * 177405SAli.Saidi@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 187405SAli.Saidi@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 197405SAli.Saidi@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 207405SAli.Saidi@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 217405SAli.Saidi@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 227405SAli.Saidi@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 237405SAli.Saidi@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 247405SAli.Saidi@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 257405SAli.Saidi@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 267405SAli.Saidi@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 277405SAli.Saidi@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 287405SAli.Saidi@ARM.com * 297405SAli.Saidi@ARM.com * Authors: Kevin Lim 307405SAli.Saidi@ARM.com */ 317405SAli.Saidi@ARM.com 327405SAli.Saidi@ARM.com#ifndef __CPU_O3_FREE_LIST_HH__ 337405SAli.Saidi@ARM.com#define __CPU_O3_FREE_LIST_HH__ 347405SAli.Saidi@ARM.com 357405SAli.Saidi@ARM.com#include <iostream> 367405SAli.Saidi@ARM.com#include <queue> 377405SAli.Saidi@ARM.com 387405SAli.Saidi@ARM.com#include "base/misc.hh" 397405SAli.Saidi@ARM.com#include "base/trace.hh" 407405SAli.Saidi@ARM.com#include "cpu/o3/comm.hh" 417405SAli.Saidi@ARM.com#include "cpu/o3/regfile.hh" 4210461SAndreas.Sandberg@ARM.com#include "debug/FreeList.hh" 439050Schander.sudanthi@arm.com 448887Sgeoffrey.blake@arm.com/** 4510461SAndreas.Sandberg@ARM.com * Free list for a single class of registers (e.g., integer 468232Snate@binkert.org * or floating point). Because the register class is implicitly 478232Snate@binkert.org * determined by the rename map instance being accessed, all 4810844Sandreas.sandberg@arm.com * architectural register index parameters and values in this class 499384SAndreas.Sandberg@arm.com * are relative (e.g., %fp2 is just index 2). 507678Sgblack@eecs.umich.edu */ 518059SAli.Saidi@ARM.comclass SimpleFreeList 528284SAli.Saidi@ARM.com{ 537405SAli.Saidi@ARM.com private: 547405SAli.Saidi@ARM.com 557405SAli.Saidi@ARM.com /** The actual free list */ 567405SAli.Saidi@ARM.com std::queue<PhysRegIndex> freeRegs; 5710037SARM gem5 Developers 5810037SARM gem5 Developers public: 5911768SCurtis.Dunham@arm.com 6010037SARM gem5 Developers SimpleFreeList() {}; 6110037SARM gem5 Developers 6210037SARM gem5 Developers /** Add a physical register to the free list */ 6310037SARM gem5 Developers void addReg(PhysRegIndex reg) { freeRegs.push(reg); } 6411768SCurtis.Dunham@arm.com 6510037SARM gem5 Developers /** Get the next available register from the free list */ 6610037SARM gem5 Developers PhysRegIndex getReg() 6711768SCurtis.Dunham@arm.com { 6811768SCurtis.Dunham@arm.com assert(!freeRegs.empty()); 6911768SCurtis.Dunham@arm.com PhysRegIndex free_reg = freeRegs.front(); 7011768SCurtis.Dunham@arm.com freeRegs.pop(); 7111768SCurtis.Dunham@arm.com return free_reg; 7211768SCurtis.Dunham@arm.com } 7311768SCurtis.Dunham@arm.com 7411768SCurtis.Dunham@arm.com /** Return the number of free registers on the list. */ 7511768SCurtis.Dunham@arm.com unsigned numFreeRegs() const { return freeRegs.size(); } 7611768SCurtis.Dunham@arm.com 7711768SCurtis.Dunham@arm.com /** True iff there are free registers on the list. */ 7811768SCurtis.Dunham@arm.com bool hasFreeRegs() const { return !freeRegs.empty(); } 7910037SARM gem5 Developers}; 8010037SARM gem5 Developers 8110037SARM gem5 Developers 8211768SCurtis.Dunham@arm.com/** 8311768SCurtis.Dunham@arm.com * FreeList class that simply holds the list of free integer and floating 8411768SCurtis.Dunham@arm.com * point registers. Can request for a free register of either type, and 8511768SCurtis.Dunham@arm.com * also send back free registers of either type. This is a very simple 8611768SCurtis.Dunham@arm.com * class, but it should be sufficient for most implementations. Like all 8711768SCurtis.Dunham@arm.com * other classes, it assumes that the indices for the floating point 8811768SCurtis.Dunham@arm.com * registers starts after the integer registers end. Hence the variable 8911768SCurtis.Dunham@arm.com * numPhysicalIntRegs is logically equivalent to the baseFP dependency. 9010037SARM gem5 Developers * Note that while this most likely should be called FreeList, the name 9111768SCurtis.Dunham@arm.com * "FreeList" is used in a typedef within the CPU Policy, and therefore no 9211768SCurtis.Dunham@arm.com * class can be named simply "FreeList". 9311768SCurtis.Dunham@arm.com * @todo: Give a better name to the base FP dependency. 9411768SCurtis.Dunham@arm.com */ 9510037SARM gem5 Developersclass UnifiedFreeList 9611768SCurtis.Dunham@arm.com{ 9711768SCurtis.Dunham@arm.com private: 9811768SCurtis.Dunham@arm.com 9911768SCurtis.Dunham@arm.com /** The object name, for DPRINTF. We have to declare this 10011768SCurtis.Dunham@arm.com * explicitly because Scoreboard is not a SimObject. */ 10111768SCurtis.Dunham@arm.com const std::string _name; 10211768SCurtis.Dunham@arm.com 10311768SCurtis.Dunham@arm.com /** The list of free integer registers. */ 10411768SCurtis.Dunham@arm.com SimpleFreeList intList; 10511768SCurtis.Dunham@arm.com 10611768SCurtis.Dunham@arm.com /** The list of free floating point registers. */ 10711768SCurtis.Dunham@arm.com SimpleFreeList floatList; 10811768SCurtis.Dunham@arm.com 10911768SCurtis.Dunham@arm.com /** The list of free condition-code registers. */ 11011768SCurtis.Dunham@arm.com SimpleFreeList ccList; 11111768SCurtis.Dunham@arm.com 11211768SCurtis.Dunham@arm.com /** The list of free vector registers. */ 11311768SCurtis.Dunham@arm.com SimpleFreeList vectorList; 11410037SARM gem5 Developers 11511768SCurtis.Dunham@arm.com /** 11611768SCurtis.Dunham@arm.com * The register file object is used only to distinguish integer 11711768SCurtis.Dunham@arm.com * from floating-point physical register indices. 11811768SCurtis.Dunham@arm.com */ 11910037SARM gem5 Developers PhysRegFile *regFile; 12011768SCurtis.Dunham@arm.com 12111768SCurtis.Dunham@arm.com /* 12211768SCurtis.Dunham@arm.com * We give UnifiedRenameMap internal access so it can get at the 12311768SCurtis.Dunham@arm.com * internal per-class free lists and associate those with its 12411768SCurtis.Dunham@arm.com * per-class rename maps. See UnifiedRenameMap::init(). 12511768SCurtis.Dunham@arm.com */ 12610037SARM gem5 Developers friend class UnifiedRenameMap; 12711768SCurtis.Dunham@arm.com 12811768SCurtis.Dunham@arm.com public: 12911768SCurtis.Dunham@arm.com /** Constructs a free list. 13011768SCurtis.Dunham@arm.com * @param _numPhysicalIntRegs Number of physical integer registers. 13111768SCurtis.Dunham@arm.com * @param reservedIntRegs Number of integer registers already 13211768SCurtis.Dunham@arm.com * used by initial mappings. 13311768SCurtis.Dunham@arm.com * @param _numPhysicalFloatRegs Number of physical fp registers. 13411768SCurtis.Dunham@arm.com * @param reservedFloatRegs Number of fp registers already 13511768SCurtis.Dunham@arm.com * used by initial mappings. 13611768SCurtis.Dunham@arm.com */ 13711768SCurtis.Dunham@arm.com UnifiedFreeList(const std::string &_my_name, PhysRegFile *_regFile); 13811768SCurtis.Dunham@arm.com 13911768SCurtis.Dunham@arm.com /** Gives the name of the freelist. */ 14011768SCurtis.Dunham@arm.com std::string name() const { return _name; }; 14111768SCurtis.Dunham@arm.com 14211768SCurtis.Dunham@arm.com /** Returns a pointer to the condition-code free list */ 14311768SCurtis.Dunham@arm.com SimpleFreeList *getCCList() { return &ccList; } 14411768SCurtis.Dunham@arm.com 14511768SCurtis.Dunham@arm.com /** Gets a free integer register. */ 14611768SCurtis.Dunham@arm.com PhysRegIndex getIntReg() { return intList.getReg(); } 14711768SCurtis.Dunham@arm.com 14811768SCurtis.Dunham@arm.com /** Gets a free fp register. */ 14911768SCurtis.Dunham@arm.com PhysRegIndex getFloatReg() { return floatList.getReg(); } 15011768SCurtis.Dunham@arm.com 15111768SCurtis.Dunham@arm.com /** Gets a free cc register. */ 15211768SCurtis.Dunham@arm.com PhysRegIndex getCCReg() { return ccList.getReg(); } 15311768SCurtis.Dunham@arm.com 15411768SCurtis.Dunham@arm.com /** Gets a free vector register. */ 15511768SCurtis.Dunham@arm.com PhysRegIndex getVectorReg() { return vectorList.getReg(); } 15611768SCurtis.Dunham@arm.com 15711768SCurtis.Dunham@arm.com /** Adds a register back to the free list. */ 15811768SCurtis.Dunham@arm.com void addReg(PhysRegIndex freed_reg); 15911768SCurtis.Dunham@arm.com 16011768SCurtis.Dunham@arm.com /** Adds an integer register back to the free list. */ 16111768SCurtis.Dunham@arm.com void addIntReg(PhysRegIndex freed_reg) { intList.addReg(freed_reg); } 16211768SCurtis.Dunham@arm.com 16311768SCurtis.Dunham@arm.com /** Adds a fp register back to the free list. */ 16411768SCurtis.Dunham@arm.com void addFloatReg(PhysRegIndex freed_reg) { floatList.addReg(freed_reg); } 16511768SCurtis.Dunham@arm.com 16611768SCurtis.Dunham@arm.com /** Adds a cc register back to the free list. */ 16711768SCurtis.Dunham@arm.com void addCCReg(PhysRegIndex freed_reg) { ccList.addReg(freed_reg); } 16811768SCurtis.Dunham@arm.com 16911768SCurtis.Dunham@arm.com /** Adds a vector register back to the free list. */ 17011768SCurtis.Dunham@arm.com void addVectorReg(PhysRegIndex freed_reg) { vectorList.addReg(freed_reg); } 17111768SCurtis.Dunham@arm.com 17211768SCurtis.Dunham@arm.com /** Checks if there are any free integer registers. */ 17311768SCurtis.Dunham@arm.com bool hasFreeIntRegs() const { return intList.hasFreeRegs(); } 17411768SCurtis.Dunham@arm.com 17511768SCurtis.Dunham@arm.com /** Checks if there are any free fp registers. */ 17611768SCurtis.Dunham@arm.com bool hasFreeFloatRegs() const { return floatList.hasFreeRegs(); } 17711768SCurtis.Dunham@arm.com 17811768SCurtis.Dunham@arm.com /** Checks if there are any free cc registers. */ 17911768SCurtis.Dunham@arm.com bool hasFreeCCRegs() const { return ccList.hasFreeRegs(); } 18011768SCurtis.Dunham@arm.com 18111768SCurtis.Dunham@arm.com /** Checks if there are any free vector registers. */ 18211768SCurtis.Dunham@arm.com bool hasFreeVectorRegs() const { return vectorList.hasFreeRegs(); } 18311768SCurtis.Dunham@arm.com 18411768SCurtis.Dunham@arm.com /** Returns the number of free integer registers. */ 18511768SCurtis.Dunham@arm.com unsigned numFreeIntRegs() const { return intList.numFreeRegs(); } 18611768SCurtis.Dunham@arm.com 18711768SCurtis.Dunham@arm.com /** Returns the number of free fp registers. */ 18811768SCurtis.Dunham@arm.com unsigned numFreeFloatRegs() const { return floatList.numFreeRegs(); } 18911768SCurtis.Dunham@arm.com 19011768SCurtis.Dunham@arm.com /** Returns the number of free cc registers. */ 19111768SCurtis.Dunham@arm.com unsigned numFreeCCRegs() const { return ccList.numFreeRegs(); } 19211768SCurtis.Dunham@arm.com 19311768SCurtis.Dunham@arm.com /** Returns the number of free vector registers. */ 19411768SCurtis.Dunham@arm.com unsigned numFreeVectorRegs() const { return vectorList.numFreeRegs(); } 19511768SCurtis.Dunham@arm.com}; 19611768SCurtis.Dunham@arm.com 19711768SCurtis.Dunham@arm.cominline void 19811768SCurtis.Dunham@arm.comUnifiedFreeList::addReg(PhysRegIndex freed_reg) 19911768SCurtis.Dunham@arm.com{ 20011768SCurtis.Dunham@arm.com DPRINTF(FreeList,"Freeing register %i.\n", freed_reg); 20111768SCurtis.Dunham@arm.com //Might want to add in a check for whether or not this register is 20211768SCurtis.Dunham@arm.com //already in there. A bit vector or something similar would be useful. 20311768SCurtis.Dunham@arm.com if (regFile->isIntPhysReg(freed_reg)) { 20410037SARM gem5 Developers intList.addReg(freed_reg); 20510037SARM gem5 Developers } else if (regFile->isFloatPhysReg(freed_reg)) { 20610037SARM gem5 Developers floatList.addReg(freed_reg); 2079384SAndreas.Sandberg@arm.com } else if (regFile->isCCPhysReg(freed_reg)) { 20810461SAndreas.Sandberg@ARM.com ccList.addReg(freed_reg); 20910461SAndreas.Sandberg@ARM.com } else { 21011165SRekai.GonzalezAlberquilla@arm.com assert(regFile->isVectorPhysReg(freed_reg)); 21110461SAndreas.Sandberg@ARM.com vectorList.addReg(freed_reg); 21210461SAndreas.Sandberg@ARM.com } 2139384SAndreas.Sandberg@arm.com 21411770SCurtis.Dunham@arm.com // These assert conditions ensure that the number of free 21510037SARM gem5 Developers // registers are not more than the # of total Physical Registers. 21610461SAndreas.Sandberg@ARM.com // If this were false, it would mean that registers 21710461SAndreas.Sandberg@ARM.com // have been freed twice, overflowing the free register 21810461SAndreas.Sandberg@ARM.com // pool and potentially crashing SMT workloads. 21910461SAndreas.Sandberg@ARM.com // ---- 22010461SAndreas.Sandberg@ARM.com // Comment out for now so as to not potentially break 22110461SAndreas.Sandberg@ARM.com // CMP and single-threaded workloads 22210609Sandreas.sandberg@arm.com // ---- 22310609Sandreas.sandberg@arm.com // assert(freeIntRegs.size() <= numPhysicalIntRegs); 22410609Sandreas.sandberg@arm.com // assert(freeFloatRegs.size() <= numPhysicalFloatRegs); 22510037SARM gem5 Developers} 22610037SARM gem5 Developers 22710037SARM gem5 Developers 22810037SARM gem5 Developers#endif // __CPU_O3_FREE_LIST_HH__ 22911771SCurtis.Dunham@arm.com