free_list.hh revision 5362
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
372107SN/A#include "arch/isa_traits.hh"
382669Sktlim@umich.edu#include "base/misc.hh"
391684SN/A#include "base/trace.hh"
401684SN/A#include "base/traceflags.hh"
411717SN/A#include "cpu/o3/comm.hh"
421060SN/A
431060SN/A/**
441060SN/A * FreeList class that simply holds the list of free integer and floating
451060SN/A * point registers.  Can request for a free register of either type, and
461060SN/A * also send back free registers of either type.  This is a very simple
471060SN/A * class, but it should be sufficient for most implementations.  Like all
481060SN/A * other classes, it assumes that the indices for the floating point
491060SN/A * registers starts after the integer registers end.  Hence the variable
501060SN/A * numPhysicalIntRegs is logically equivalent to the baseFP dependency.
512292SN/A * Note that while this most likely should be called FreeList, the name
522292SN/A * "FreeList" is used in a typedef within the CPU Policy, and therefore no
532292SN/A * class can be named simply "FreeList".
541060SN/A * @todo: Give a better name to the base FP dependency.
551060SN/A */
561060SN/Aclass SimpleFreeList
571060SN/A{
581060SN/A  private:
591060SN/A    /** The list of free integer registers. */
601061SN/A    std::queue<PhysRegIndex> freeIntRegs;
611060SN/A
621060SN/A    /** The list of free floating point registers. */
631061SN/A    std::queue<PhysRegIndex> freeFloatRegs;
641060SN/A
651060SN/A    /** Number of logical integer registers. */
661060SN/A    int numLogicalIntRegs;
671060SN/A
681060SN/A    /** Number of physical integer registers. */
691060SN/A    int numPhysicalIntRegs;
701060SN/A
711060SN/A    /** Number of logical floating point registers. */
721060SN/A    int numLogicalFloatRegs;
731060SN/A
741060SN/A    /** Number of physical floating point registers. */
751060SN/A    int numPhysicalFloatRegs;
761060SN/A
771060SN/A    /** Total number of physical registers. */
781060SN/A    int numPhysicalRegs;
791060SN/A
801060SN/A  public:
812292SN/A    /** Constructs a free list.
822292SN/A     *  @param activeThreads Number of active threads.
832292SN/A     *  @param _numLogicalIntRegs Number of logical integer registers.
842292SN/A     *  @param _numPhysicalIntRegs Number of physical integer registers.
852292SN/A     *  @param _numLogicalFloatRegs Number of logical fp registers.
862292SN/A     *  @param _numPhysicalFloatRegs Number of physical fp registers.
872292SN/A     */
882292SN/A    SimpleFreeList(unsigned activeThreads,
892292SN/A                   unsigned _numLogicalIntRegs,
901060SN/A                   unsigned _numPhysicalIntRegs,
911060SN/A                   unsigned _numLogicalFloatRegs,
921060SN/A                   unsigned _numPhysicalFloatRegs);
931060SN/A
942292SN/A    /** Gives the name of the freelist. */
952292SN/A    std::string name() const;
962292SN/A
972292SN/A    /** Gets a free integer register. */
981684SN/A    inline PhysRegIndex getIntReg();
991060SN/A
1002292SN/A    /** Gets a free fp register. */
1011684SN/A    inline PhysRegIndex getFloatReg();
1021060SN/A
1032292SN/A    /** Adds a register back to the free list. */
1041684SN/A    inline void addReg(PhysRegIndex freed_reg);
1051060SN/A
1062292SN/A    /** Adds an integer register back to the free list. */
1071684SN/A    inline void addIntReg(PhysRegIndex freed_reg);
1081060SN/A
1092292SN/A    /** Adds a fp register back to the free list. */
1101684SN/A    inline void addFloatReg(PhysRegIndex freed_reg);
1111060SN/A
1122292SN/A    /** Checks if there are any free integer registers. */
1131060SN/A    bool hasFreeIntRegs()
1141060SN/A    { return !freeIntRegs.empty(); }
1151060SN/A
1162292SN/A    /** Checks if there are any free fp registers. */
1171060SN/A    bool hasFreeFloatRegs()
1181060SN/A    { return !freeFloatRegs.empty(); }
1191060SN/A
1202292SN/A    /** Returns the number of free integer registers. */
1211060SN/A    int numFreeIntRegs()
1221060SN/A    { return freeIntRegs.size(); }
1231060SN/A
1242292SN/A    /** Returns the number of free fp registers. */
1251060SN/A    int numFreeFloatRegs()
1261060SN/A    { return freeFloatRegs.size(); }
1271060SN/A};
1281060SN/A
1291060SN/Ainline PhysRegIndex
1301060SN/ASimpleFreeList::getIntReg()
1311060SN/A{
1322292SN/A    DPRINTF(FreeList, "Trying to get free integer register.\n");
1332292SN/A
1341060SN/A    if (freeIntRegs.empty()) {
1351060SN/A        panic("No free integer registers!");
1361060SN/A    }
1371060SN/A
1381060SN/A    PhysRegIndex free_reg = freeIntRegs.front();
1391060SN/A
1401060SN/A    freeIntRegs.pop();
1411060SN/A
1421060SN/A    return(free_reg);
1431060SN/A}
1441060SN/A
1451060SN/Ainline PhysRegIndex
1461060SN/ASimpleFreeList::getFloatReg()
1471060SN/A{
1482292SN/A    DPRINTF(FreeList, "Trying to get free float register.\n");
1492292SN/A
1501060SN/A    if (freeFloatRegs.empty()) {
1511060SN/A        panic("No free integer registers!");
1521060SN/A    }
1531060SN/A
1541060SN/A    PhysRegIndex free_reg = freeFloatRegs.front();
1551060SN/A
1561060SN/A    freeFloatRegs.pop();
1571060SN/A
1581060SN/A    return(free_reg);
1591060SN/A}
1601060SN/A
1611060SN/Ainline void
1621060SN/ASimpleFreeList::addReg(PhysRegIndex freed_reg)
1631060SN/A{
1642292SN/A    DPRINTF(FreeList,"Freeing register %i.\n", freed_reg);
1651060SN/A    //Might want to add in a check for whether or not this register is
1661060SN/A    //already in there.  A bit vector or something similar would be useful.
1671060SN/A    if (freed_reg < numPhysicalIntRegs) {
1682292SN/A        if (freed_reg != TheISA::ZeroReg)
1692292SN/A            freeIntRegs.push(freed_reg);
1701060SN/A    } else if (freed_reg < numPhysicalRegs) {
1714642Sgblack@eecs.umich.edu#if THE_ISA == ALPHA_ISA
1722292SN/A        if (freed_reg != (TheISA::ZeroReg + numPhysicalIntRegs))
1734642Sgblack@eecs.umich.edu#endif
1742292SN/A            freeFloatRegs.push(freed_reg);
1751060SN/A    }
1765362Sksewell@umich.edu
1775362Sksewell@umich.edu    //assert(freeIntRegs.size() <= numPhysicalIntRegs);
1781060SN/A}
1791060SN/A
1801060SN/Ainline void
1811060SN/ASimpleFreeList::addIntReg(PhysRegIndex freed_reg)
1821060SN/A{
1832292SN/A    DPRINTF(FreeList,"Freeing int register %i.\n", freed_reg);
1841061SN/A
1851060SN/A    freeIntRegs.push(freed_reg);
1861060SN/A}
1871060SN/A
1881060SN/Ainline void
1891060SN/ASimpleFreeList::addFloatReg(PhysRegIndex freed_reg)
1901060SN/A{
1912292SN/A    DPRINTF(FreeList,"Freeing float register %i.\n", freed_reg);
1921061SN/A
1931060SN/A    freeFloatRegs.push(freed_reg);
1941060SN/A}
1951060SN/A
1962292SN/A#endif // __CPU_O3_FREE_LIST_HH__
197