free_list.hh revision 8232
11689SN/A/*
21689SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
31689SN/A * All rights reserved.
41689SN/A *
51689SN/A * Redistribution and use in source and binary forms, with or without
61689SN/A * modification, are permitted provided that the following conditions are
71689SN/A * met: redistributions of source code must retain the above copyright
81689SN/A * notice, this list of conditions and the following disclaimer;
91689SN/A * redistributions in binary form must reproduce the above copyright
101689SN/A * notice, this list of conditions and the following disclaimer in the
111689SN/A * documentation and/or other materials provided with the distribution;
121689SN/A * neither the name of the copyright holders nor the names of its
131689SN/A * contributors may be used to endorse or promote products derived from
141689SN/A * this software without specific prior written permission.
151689SN/A *
161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Kevin Lim
291689SN/A */
301689SN/A
312292SN/A#ifndef __CPU_O3_FREE_LIST_HH__
322292SN/A#define __CPU_O3_FREE_LIST_HH__
331060SN/A
341060SN/A#include <iostream>
351060SN/A#include <queue>
361060SN/A
376329Sgblack@eecs.umich.edu#include "arch/registers.hh"
382669Sktlim@umich.edu#include "base/misc.hh"
391684SN/A#include "base/trace.hh"
406658Snate@binkert.org#include "config/the_isa.hh"
411717SN/A#include "cpu/o3/comm.hh"
428232Snate@binkert.org#include "debug/FreeList.hh"
431060SN/A
441060SN/A/**
451060SN/A * FreeList class that simply holds the list of free integer and floating
461060SN/A * point registers.  Can request for a free register of either type, and
471060SN/A * also send back free registers of either type.  This is a very simple
481060SN/A * class, but it should be sufficient for most implementations.  Like all
491060SN/A * other classes, it assumes that the indices for the floating point
501060SN/A * registers starts after the integer registers end.  Hence the variable
511060SN/A * numPhysicalIntRegs is logically equivalent to the baseFP dependency.
522292SN/A * Note that while this most likely should be called FreeList, the name
532292SN/A * "FreeList" is used in a typedef within the CPU Policy, and therefore no
542292SN/A * class can be named simply "FreeList".
551060SN/A * @todo: Give a better name to the base FP dependency.
561060SN/A */
571060SN/Aclass SimpleFreeList
581060SN/A{
591060SN/A  private:
601060SN/A    /** The list of free integer registers. */
611061SN/A    std::queue<PhysRegIndex> freeIntRegs;
621060SN/A
631060SN/A    /** The list of free floating point registers. */
641061SN/A    std::queue<PhysRegIndex> freeFloatRegs;
651060SN/A
661060SN/A    /** Number of logical integer registers. */
671060SN/A    int numLogicalIntRegs;
681060SN/A
691060SN/A    /** Number of physical integer registers. */
701060SN/A    int numPhysicalIntRegs;
711060SN/A
721060SN/A    /** Number of logical floating point registers. */
731060SN/A    int numLogicalFloatRegs;
741060SN/A
751060SN/A    /** Number of physical floating point registers. */
761060SN/A    int numPhysicalFloatRegs;
771060SN/A
781060SN/A    /** Total number of physical registers. */
791060SN/A    int numPhysicalRegs;
801060SN/A
811060SN/A  public:
822292SN/A    /** Constructs a free list.
832292SN/A     *  @param activeThreads Number of active threads.
842292SN/A     *  @param _numLogicalIntRegs Number of logical integer registers.
852292SN/A     *  @param _numPhysicalIntRegs Number of physical integer registers.
862292SN/A     *  @param _numLogicalFloatRegs Number of logical fp registers.
872292SN/A     *  @param _numPhysicalFloatRegs Number of physical fp registers.
882292SN/A     */
896221Snate@binkert.org    SimpleFreeList(ThreadID activeThreads,
902292SN/A                   unsigned _numLogicalIntRegs,
911060SN/A                   unsigned _numPhysicalIntRegs,
921060SN/A                   unsigned _numLogicalFloatRegs,
931060SN/A                   unsigned _numPhysicalFloatRegs);
941060SN/A
952292SN/A    /** Gives the name of the freelist. */
962292SN/A    std::string name() const;
972292SN/A
982292SN/A    /** Gets a free integer register. */
991684SN/A    inline PhysRegIndex getIntReg();
1001060SN/A
1012292SN/A    /** Gets a free fp register. */
1021684SN/A    inline PhysRegIndex getFloatReg();
1031060SN/A
1042292SN/A    /** Adds a register back to the free list. */
1051684SN/A    inline void addReg(PhysRegIndex freed_reg);
1061060SN/A
1072292SN/A    /** Adds an integer register back to the free list. */
1081684SN/A    inline void addIntReg(PhysRegIndex freed_reg);
1091060SN/A
1102292SN/A    /** Adds a fp register back to the free list. */
1111684SN/A    inline void addFloatReg(PhysRegIndex freed_reg);
1121060SN/A
1132292SN/A    /** Checks if there are any free integer registers. */
1141060SN/A    bool hasFreeIntRegs()
1151060SN/A    { return !freeIntRegs.empty(); }
1161060SN/A
1172292SN/A    /** Checks if there are any free fp registers. */
1181060SN/A    bool hasFreeFloatRegs()
1191060SN/A    { return !freeFloatRegs.empty(); }
1201060SN/A
1212292SN/A    /** Returns the number of free integer registers. */
1221060SN/A    int numFreeIntRegs()
1231060SN/A    { return freeIntRegs.size(); }
1241060SN/A
1252292SN/A    /** Returns the number of free fp registers. */
1261060SN/A    int numFreeFloatRegs()
1271060SN/A    { return freeFloatRegs.size(); }
1281060SN/A};
1291060SN/A
1301060SN/Ainline PhysRegIndex
1311060SN/ASimpleFreeList::getIntReg()
1321060SN/A{
1332292SN/A    DPRINTF(FreeList, "Trying to get free integer register.\n");
1342292SN/A
1351060SN/A    if (freeIntRegs.empty()) {
1361060SN/A        panic("No free integer registers!");
1371060SN/A    }
1381060SN/A
1391060SN/A    PhysRegIndex free_reg = freeIntRegs.front();
1401060SN/A
1411060SN/A    freeIntRegs.pop();
1421060SN/A
1431060SN/A    return(free_reg);
1441060SN/A}
1451060SN/A
1461060SN/Ainline PhysRegIndex
1471060SN/ASimpleFreeList::getFloatReg()
1481060SN/A{
1492292SN/A    DPRINTF(FreeList, "Trying to get free float register.\n");
1502292SN/A
1511060SN/A    if (freeFloatRegs.empty()) {
1521060SN/A        panic("No free integer registers!");
1531060SN/A    }
1541060SN/A
1551060SN/A    PhysRegIndex free_reg = freeFloatRegs.front();
1561060SN/A
1571060SN/A    freeFloatRegs.pop();
1581060SN/A
1591060SN/A    return(free_reg);
1601060SN/A}
1611060SN/A
1621060SN/Ainline void
1631060SN/ASimpleFreeList::addReg(PhysRegIndex freed_reg)
1641060SN/A{
1652292SN/A    DPRINTF(FreeList,"Freeing register %i.\n", freed_reg);
1661060SN/A    //Might want to add in a check for whether or not this register is
1671060SN/A    //already in there.  A bit vector or something similar would be useful.
1681060SN/A    if (freed_reg < numPhysicalIntRegs) {
1692292SN/A        if (freed_reg != TheISA::ZeroReg)
1702292SN/A            freeIntRegs.push(freed_reg);
1711060SN/A    } else if (freed_reg < numPhysicalRegs) {
1724642Sgblack@eecs.umich.edu#if THE_ISA == ALPHA_ISA
1732292SN/A        if (freed_reg != (TheISA::ZeroReg + numPhysicalIntRegs))
1744642Sgblack@eecs.umich.edu#endif
1752292SN/A            freeFloatRegs.push(freed_reg);
1761060SN/A    }
1775362Sksewell@umich.edu
1785364Sksewell@umich.edu    // These assert conditions ensure that the number of free
1795364Sksewell@umich.edu    // registers are not more than the # of total Physical  Registers.
1805364Sksewell@umich.edu    // If this were false, it would mean that registers
1815364Sksewell@umich.edu    // have been freed twice, overflowing the free register
1825364Sksewell@umich.edu    // pool and potentially crashing SMT workloads.
1835364Sksewell@umich.edu    // ----
1845364Sksewell@umich.edu    // Comment out for now so as to not potentially break
1855364Sksewell@umich.edu    // CMP and single-threaded workloads
1865364Sksewell@umich.edu    // ----
1875364Sksewell@umich.edu    // assert(freeIntRegs.size() <= numPhysicalIntRegs);
1885364Sksewell@umich.edu    // assert(freeFloatRegs.size() <= numPhysicalFloatRegs);
1891060SN/A}
1901060SN/A
1911060SN/Ainline void
1921060SN/ASimpleFreeList::addIntReg(PhysRegIndex freed_reg)
1931060SN/A{
1942292SN/A    DPRINTF(FreeList,"Freeing int register %i.\n", freed_reg);
1951061SN/A
1961060SN/A    freeIntRegs.push(freed_reg);
1971060SN/A}
1981060SN/A
1991060SN/Ainline void
2001060SN/ASimpleFreeList::addFloatReg(PhysRegIndex freed_reg)
2011060SN/A{
2022292SN/A    DPRINTF(FreeList,"Freeing float register %i.\n", freed_reg);
2031061SN/A
2041060SN/A    freeFloatRegs.push(freed_reg);
2051060SN/A}
2061060SN/A
2072292SN/A#endif // __CPU_O3_FREE_LIST_HH__
208