free_list.hh revision 2665
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
311755SN/A#ifndef __CPU_O3_CPU_FREE_LIST_HH__
321755SN/A#define __CPU_O3_CPU_FREE_LIST_HH__
331060SN/A
341060SN/A#include <iostream>
351060SN/A#include <queue>
361060SN/A
372107SN/A#include "arch/isa_traits.hh"
381684SN/A#include "base/trace.hh"
391684SN/A#include "base/traceflags.hh"
401717SN/A#include "cpu/o3/comm.hh"
411060SN/A
421060SN/A/**
431060SN/A * FreeList class that simply holds the list of free integer and floating
441060SN/A * point registers.  Can request for a free register of either type, and
451060SN/A * also send back free registers of either type.  This is a very simple
461060SN/A * class, but it should be sufficient for most implementations.  Like all
471060SN/A * other classes, it assumes that the indices for the floating point
481060SN/A * registers starts after the integer registers end.  Hence the variable
491060SN/A * numPhysicalIntRegs is logically equivalent to the baseFP dependency.
501060SN/A * Note that
511060SN/A * while this most likely should be called FreeList, the name "FreeList"
521060SN/A * is used in a typedef within the CPU Policy, and therefore no class
531060SN/A * 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
801061SN/A    /** DEBUG stuff below. */
811061SN/A    std::vector<int> freeIntRegsScoreboard;
821061SN/A
831061SN/A    std::vector<bool> freeFloatRegsScoreboard;
841061SN/A
851060SN/A  public:
861060SN/A    SimpleFreeList(unsigned _numLogicalIntRegs,
871060SN/A                   unsigned _numPhysicalIntRegs,
881060SN/A                   unsigned _numLogicalFloatRegs,
891060SN/A                   unsigned _numPhysicalFloatRegs);
901060SN/A
911684SN/A    inline PhysRegIndex getIntReg();
921060SN/A
931684SN/A    inline PhysRegIndex getFloatReg();
941060SN/A
951684SN/A    inline void addReg(PhysRegIndex freed_reg);
961060SN/A
971684SN/A    inline void addIntReg(PhysRegIndex freed_reg);
981060SN/A
991684SN/A    inline void addFloatReg(PhysRegIndex freed_reg);
1001060SN/A
1011060SN/A    bool hasFreeIntRegs()
1021060SN/A    { return !freeIntRegs.empty(); }
1031060SN/A
1041060SN/A    bool hasFreeFloatRegs()
1051060SN/A    { return !freeFloatRegs.empty(); }
1061060SN/A
1071060SN/A    int numFreeIntRegs()
1081060SN/A    { return freeIntRegs.size(); }
1091060SN/A
1101060SN/A    int numFreeFloatRegs()
1111060SN/A    { return freeFloatRegs.size(); }
1121060SN/A};
1131060SN/A
1141060SN/Ainline PhysRegIndex
1151060SN/ASimpleFreeList::getIntReg()
1161060SN/A{
1171060SN/A    DPRINTF(Rename, "FreeList: Trying to get free integer register.\n");
1181060SN/A    if (freeIntRegs.empty()) {
1191060SN/A        panic("No free integer registers!");
1201060SN/A    }
1211060SN/A
1221060SN/A    PhysRegIndex free_reg = freeIntRegs.front();
1231060SN/A
1241060SN/A    freeIntRegs.pop();
1251060SN/A
1261061SN/A    // DEBUG
1271061SN/A    assert(freeIntRegsScoreboard[free_reg]);
1281061SN/A    freeIntRegsScoreboard[free_reg] = 0;
1291061SN/A
1301060SN/A    return(free_reg);
1311060SN/A}
1321060SN/A
1331060SN/Ainline PhysRegIndex
1341060SN/ASimpleFreeList::getFloatReg()
1351060SN/A{
1361060SN/A    DPRINTF(Rename, "FreeList: Trying to get free float register.\n");
1371060SN/A    if (freeFloatRegs.empty()) {
1381060SN/A        panic("No free integer registers!");
1391060SN/A    }
1401060SN/A
1411060SN/A    PhysRegIndex free_reg = freeFloatRegs.front();
1421060SN/A
1431060SN/A    freeFloatRegs.pop();
1441060SN/A
1451061SN/A    // DEBUG
1461061SN/A    assert(freeFloatRegsScoreboard[free_reg]);
1471061SN/A    freeFloatRegsScoreboard[free_reg] = 0;
1481061SN/A
1491060SN/A    return(free_reg);
1501060SN/A}
1511060SN/A
1521060SN/Ainline void
1531060SN/ASimpleFreeList::addReg(PhysRegIndex freed_reg)
1541060SN/A{
1551060SN/A    DPRINTF(Rename, "Freelist: Freeing register %i.\n", freed_reg);
1561060SN/A    //Might want to add in a check for whether or not this register is
1571060SN/A    //already in there.  A bit vector or something similar would be useful.
1581060SN/A    if (freed_reg < numPhysicalIntRegs) {
1591060SN/A        freeIntRegs.push(freed_reg);
1601061SN/A
1611061SN/A        // DEBUG
1621061SN/A        assert(freeIntRegsScoreboard[freed_reg] == false);
1631061SN/A        freeIntRegsScoreboard[freed_reg] = 1;
1641060SN/A    } else if (freed_reg < numPhysicalRegs) {
1651060SN/A        freeFloatRegs.push(freed_reg);
1661061SN/A
1671061SN/A        // DEBUG
1681061SN/A        assert(freeFloatRegsScoreboard[freed_reg] == false);
1691061SN/A        freeFloatRegsScoreboard[freed_reg] = 1;
1701060SN/A    }
1711060SN/A}
1721060SN/A
1731060SN/Ainline void
1741060SN/ASimpleFreeList::addIntReg(PhysRegIndex freed_reg)
1751060SN/A{
1761060SN/A    DPRINTF(Rename, "Freelist: Freeing int register %i.\n", freed_reg);
1771060SN/A
1781061SN/A    // DEBUG
1791061SN/A    assert(!freeIntRegsScoreboard[freed_reg]);
1801061SN/A    freeIntRegsScoreboard[freed_reg] = 1;
1811061SN/A
1821060SN/A    freeIntRegs.push(freed_reg);
1831060SN/A}
1841060SN/A
1851060SN/Ainline void
1861060SN/ASimpleFreeList::addFloatReg(PhysRegIndex freed_reg)
1871060SN/A{
1881060SN/A    DPRINTF(Rename, "Freelist: Freeing float register %i.\n", freed_reg);
1891060SN/A
1901061SN/A    // DEBUG
1911061SN/A    assert(!freeFloatRegsScoreboard[freed_reg]);
1921061SN/A    freeFloatRegsScoreboard[freed_reg] = 1;
1931061SN/A
1941060SN/A    freeFloatRegs.push(freed_reg);
1951060SN/A}
1961060SN/A
1971755SN/A#endif // __CPU_O3_CPU_FREE_LIST_HH__
198