free_list.hh revision 2669
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.
271689SN/A */
281689SN/A
292292SN/A#ifndef __CPU_O3_FREE_LIST_HH__
302292SN/A#define __CPU_O3_FREE_LIST_HH__
311060SN/A
321060SN/A#include <iostream>
331060SN/A#include <queue>
341060SN/A
352107SN/A#include "arch/isa_traits.hh"
362669Sktlim@umich.edu#include "base/misc.hh"
371684SN/A#include "base/trace.hh"
381684SN/A#include "base/traceflags.hh"
391717SN/A#include "cpu/o3/comm.hh"
401060SN/A
411060SN/A/**
421060SN/A * FreeList class that simply holds the list of free integer and floating
431060SN/A * point registers.  Can request for a free register of either type, and
441060SN/A * also send back free registers of either type.  This is a very simple
451060SN/A * class, but it should be sufficient for most implementations.  Like all
461060SN/A * other classes, it assumes that the indices for the floating point
471060SN/A * registers starts after the integer registers end.  Hence the variable
481060SN/A * numPhysicalIntRegs is logically equivalent to the baseFP dependency.
492292SN/A * Note that while this most likely should be called FreeList, the name
502292SN/A * "FreeList" is used in a typedef within the CPU Policy, and therefore no
512292SN/A * class can be named simply "FreeList".
521060SN/A * @todo: Give a better name to the base FP dependency.
531060SN/A */
541060SN/Aclass SimpleFreeList
551060SN/A{
561060SN/A  private:
571060SN/A    /** The list of free integer registers. */
581061SN/A    std::queue<PhysRegIndex> freeIntRegs;
591060SN/A
601060SN/A    /** The list of free floating point registers. */
611061SN/A    std::queue<PhysRegIndex> freeFloatRegs;
621060SN/A
631060SN/A    /** Number of logical integer registers. */
641060SN/A    int numLogicalIntRegs;
651060SN/A
661060SN/A    /** Number of physical integer registers. */
671060SN/A    int numPhysicalIntRegs;
681060SN/A
691060SN/A    /** Number of logical floating point registers. */
701060SN/A    int numLogicalFloatRegs;
711060SN/A
721060SN/A    /** Number of physical floating point registers. */
731060SN/A    int numPhysicalFloatRegs;
741060SN/A
751060SN/A    /** Total number of physical registers. */
761060SN/A    int numPhysicalRegs;
771060SN/A
781060SN/A  public:
792292SN/A    /** Constructs a free list.
802292SN/A     *  @param activeThreads Number of active threads.
812292SN/A     *  @param _numLogicalIntRegs Number of logical integer registers.
822292SN/A     *  @param _numPhysicalIntRegs Number of physical integer registers.
832292SN/A     *  @param _numLogicalFloatRegs Number of logical fp registers.
842292SN/A     *  @param _numPhysicalFloatRegs Number of physical fp registers.
852292SN/A     */
862292SN/A    SimpleFreeList(unsigned activeThreads,
872292SN/A                   unsigned _numLogicalIntRegs,
881060SN/A                   unsigned _numPhysicalIntRegs,
891060SN/A                   unsigned _numLogicalFloatRegs,
901060SN/A                   unsigned _numPhysicalFloatRegs);
911060SN/A
922292SN/A    /** Gives the name of the freelist. */
932292SN/A    std::string name() const;
942292SN/A
952292SN/A    /** Gets a free integer register. */
961684SN/A    inline PhysRegIndex getIntReg();
971060SN/A
982292SN/A    /** Gets a free fp register. */
991684SN/A    inline PhysRegIndex getFloatReg();
1001060SN/A
1012292SN/A    /** Adds a register back to the free list. */
1021684SN/A    inline void addReg(PhysRegIndex freed_reg);
1031060SN/A
1042292SN/A    /** Adds an integer register back to the free list. */
1051684SN/A    inline void addIntReg(PhysRegIndex freed_reg);
1061060SN/A
1072292SN/A    /** Adds a fp register back to the free list. */
1081684SN/A    inline void addFloatReg(PhysRegIndex freed_reg);
1091060SN/A
1102292SN/A    /** Checks if there are any free integer registers. */
1111060SN/A    bool hasFreeIntRegs()
1121060SN/A    { return !freeIntRegs.empty(); }
1131060SN/A
1142292SN/A    /** Checks if there are any free fp registers. */
1151060SN/A    bool hasFreeFloatRegs()
1161060SN/A    { return !freeFloatRegs.empty(); }
1171060SN/A
1182292SN/A    /** Returns the number of free integer registers. */
1191060SN/A    int numFreeIntRegs()
1201060SN/A    { return freeIntRegs.size(); }
1211060SN/A
1222292SN/A    /** Returns the number of free fp registers. */
1231060SN/A    int numFreeFloatRegs()
1241060SN/A    { return freeFloatRegs.size(); }
1251060SN/A};
1261060SN/A
1271060SN/Ainline PhysRegIndex
1281060SN/ASimpleFreeList::getIntReg()
1291060SN/A{
1302292SN/A    DPRINTF(FreeList, "Trying to get free integer register.\n");
1312292SN/A
1321060SN/A    if (freeIntRegs.empty()) {
1331060SN/A        panic("No free integer registers!");
1341060SN/A    }
1351060SN/A
1361060SN/A    PhysRegIndex free_reg = freeIntRegs.front();
1371060SN/A
1381060SN/A    freeIntRegs.pop();
1391060SN/A
1401060SN/A    return(free_reg);
1411060SN/A}
1421060SN/A
1431060SN/Ainline PhysRegIndex
1441060SN/ASimpleFreeList::getFloatReg()
1451060SN/A{
1462292SN/A    DPRINTF(FreeList, "Trying to get free float register.\n");
1472292SN/A
1481060SN/A    if (freeFloatRegs.empty()) {
1491060SN/A        panic("No free integer registers!");
1501060SN/A    }
1511060SN/A
1521060SN/A    PhysRegIndex free_reg = freeFloatRegs.front();
1531060SN/A
1541060SN/A    freeFloatRegs.pop();
1551060SN/A
1561060SN/A    return(free_reg);
1571060SN/A}
1581060SN/A
1591060SN/Ainline void
1601060SN/ASimpleFreeList::addReg(PhysRegIndex freed_reg)
1611060SN/A{
1622292SN/A    DPRINTF(FreeList,"Freeing register %i.\n", freed_reg);
1631060SN/A    //Might want to add in a check for whether or not this register is
1641060SN/A    //already in there.  A bit vector or something similar would be useful.
1651060SN/A    if (freed_reg < numPhysicalIntRegs) {
1662292SN/A        if (freed_reg != TheISA::ZeroReg)
1672292SN/A            freeIntRegs.push(freed_reg);
1681060SN/A    } else if (freed_reg < numPhysicalRegs) {
1692292SN/A        if (freed_reg != (TheISA::ZeroReg + numPhysicalIntRegs))
1702292SN/A            freeFloatRegs.push(freed_reg);
1711060SN/A    }
1721060SN/A}
1731060SN/A
1741060SN/Ainline void
1751060SN/ASimpleFreeList::addIntReg(PhysRegIndex freed_reg)
1761060SN/A{
1772292SN/A    DPRINTF(FreeList,"Freeing int register %i.\n", freed_reg);
1781061SN/A
1791060SN/A    freeIntRegs.push(freed_reg);
1801060SN/A}
1811060SN/A
1821060SN/Ainline void
1831060SN/ASimpleFreeList::addFloatReg(PhysRegIndex freed_reg)
1841060SN/A{
1852292SN/A    DPRINTF(FreeList,"Freeing float register %i.\n", freed_reg);
1861061SN/A
1871060SN/A    freeFloatRegs.push(freed_reg);
1881060SN/A}
1891060SN/A
1902292SN/A#endif // __CPU_O3_FREE_LIST_HH__
191