free_list.hh revision 5364:66d1251b7ae6
17861Sgblack@eecs.umich.edu/*
28332Snate@binkert.org * Copyright (c) 2004-2005 The Regents of The University of Michigan
37861Sgblack@eecs.umich.edu * All rights reserved.
47861Sgblack@eecs.umich.edu *
57861Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
67861Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
77861Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
87861Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
97861Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
107861Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
117861Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
127861Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
137861Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
147861Sgblack@eecs.umich.edu * this software without specific prior written permission.
157861Sgblack@eecs.umich.edu *
167861Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
177861Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
187861Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
197861Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
207861Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
217861Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
227861Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
237861Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
247861Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
257861Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
267861Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
277861Sgblack@eecs.umich.edu *
287861Sgblack@eecs.umich.edu * Authors: Kevin Lim
297861Sgblack@eecs.umich.edu */
307861Sgblack@eecs.umich.edu
317861Sgblack@eecs.umich.edu#ifndef __CPU_O3_FREE_LIST_HH__
327861Sgblack@eecs.umich.edu#define __CPU_O3_FREE_LIST_HH__
337861Sgblack@eecs.umich.edu
347861Sgblack@eecs.umich.edu#include <iostream>
357861Sgblack@eecs.umich.edu#include <queue>
367861Sgblack@eecs.umich.edu
377861Sgblack@eecs.umich.edu#include "arch/isa_traits.hh"
387861Sgblack@eecs.umich.edu#include "base/misc.hh"
397861Sgblack@eecs.umich.edu#include "base/trace.hh"
407861Sgblack@eecs.umich.edu#include "base/traceflags.hh"
417861Sgblack@eecs.umich.edu#include "cpu/o3/comm.hh"
427861Sgblack@eecs.umich.edu
437861Sgblack@eecs.umich.edu/**
447861Sgblack@eecs.umich.edu * FreeList class that simply holds the list of free integer and floating
457861Sgblack@eecs.umich.edu * point registers.  Can request for a free register of either type, and
467861Sgblack@eecs.umich.edu * also send back free registers of either type.  This is a very simple
477861Sgblack@eecs.umich.edu * class, but it should be sufficient for most implementations.  Like all
487861Sgblack@eecs.umich.edu * other classes, it assumes that the indices for the floating point
497861Sgblack@eecs.umich.edu * registers starts after the integer registers end.  Hence the variable
507861Sgblack@eecs.umich.edu * numPhysicalIntRegs is logically equivalent to the baseFP dependency.
517861Sgblack@eecs.umich.edu * Note that while this most likely should be called FreeList, the name
527861Sgblack@eecs.umich.edu * "FreeList" is used in a typedef within the CPU Policy, and therefore no
537861Sgblack@eecs.umich.edu * class can be named simply "FreeList".
547861Sgblack@eecs.umich.edu * @todo: Give a better name to the base FP dependency.
557861Sgblack@eecs.umich.edu */
567861Sgblack@eecs.umich.educlass SimpleFreeList
577861Sgblack@eecs.umich.edu{
587861Sgblack@eecs.umich.edu  private:
597861Sgblack@eecs.umich.edu    /** The list of free integer registers. */
607861Sgblack@eecs.umich.edu    std::queue<PhysRegIndex> freeIntRegs;
617861Sgblack@eecs.umich.edu
627861Sgblack@eecs.umich.edu    /** The list of free floating point registers. */
637861Sgblack@eecs.umich.edu    std::queue<PhysRegIndex> freeFloatRegs;
647861Sgblack@eecs.umich.edu
657861Sgblack@eecs.umich.edu    /** Number of logical integer registers. */
667861Sgblack@eecs.umich.edu    int numLogicalIntRegs;
677861Sgblack@eecs.umich.edu
687861Sgblack@eecs.umich.edu    /** Number of physical integer registers. */
697861Sgblack@eecs.umich.edu    int numPhysicalIntRegs;
707861Sgblack@eecs.umich.edu
717861Sgblack@eecs.umich.edu    /** Number of logical floating point registers. */
727861Sgblack@eecs.umich.edu    int numLogicalFloatRegs;
737861Sgblack@eecs.umich.edu
747861Sgblack@eecs.umich.edu    /** Number of physical floating point registers. */
757861Sgblack@eecs.umich.edu    int numPhysicalFloatRegs;
767861Sgblack@eecs.umich.edu
777861Sgblack@eecs.umich.edu    /** Total number of physical registers. */
787861Sgblack@eecs.umich.edu    int numPhysicalRegs;
797861Sgblack@eecs.umich.edu
807861Sgblack@eecs.umich.edu  public:
817861Sgblack@eecs.umich.edu    /** Constructs a free list.
827861Sgblack@eecs.umich.edu     *  @param activeThreads Number of active threads.
837861Sgblack@eecs.umich.edu     *  @param _numLogicalIntRegs Number of logical integer registers.
847861Sgblack@eecs.umich.edu     *  @param _numPhysicalIntRegs Number of physical integer registers.
857861Sgblack@eecs.umich.edu     *  @param _numLogicalFloatRegs Number of logical fp registers.
867861Sgblack@eecs.umich.edu     *  @param _numPhysicalFloatRegs Number of physical fp registers.
877861Sgblack@eecs.umich.edu     */
887861Sgblack@eecs.umich.edu    SimpleFreeList(unsigned activeThreads,
897861Sgblack@eecs.umich.edu                   unsigned _numLogicalIntRegs,
907861Sgblack@eecs.umich.edu                   unsigned _numPhysicalIntRegs,
917861Sgblack@eecs.umich.edu                   unsigned _numLogicalFloatRegs,
927861Sgblack@eecs.umich.edu                   unsigned _numPhysicalFloatRegs);
937861Sgblack@eecs.umich.edu
947861Sgblack@eecs.umich.edu    /** Gives the name of the freelist. */
957861Sgblack@eecs.umich.edu    std::string name() const;
967861Sgblack@eecs.umich.edu
977861Sgblack@eecs.umich.edu    /** Gets a free integer register. */
987942SAli.Saidi@ARM.com    inline PhysRegIndex getIntReg();
997942SAli.Saidi@ARM.com
1007942SAli.Saidi@ARM.com    /** Gets a free fp register. */
1017942SAli.Saidi@ARM.com    inline PhysRegIndex getFloatReg();
1027942SAli.Saidi@ARM.com
1037942SAli.Saidi@ARM.com    /** Adds a register back to the free list. */
1047942SAli.Saidi@ARM.com    inline void addReg(PhysRegIndex freed_reg);
1057942SAli.Saidi@ARM.com
1067942SAli.Saidi@ARM.com    /** Adds an integer register back to the free list. */
1077942SAli.Saidi@ARM.com    inline void addIntReg(PhysRegIndex freed_reg);
1087942SAli.Saidi@ARM.com
10911168Sandreas.hansson@arm.com    /** Adds a fp register back to the free list. */
1107942SAli.Saidi@ARM.com    inline void addFloatReg(PhysRegIndex freed_reg);
1117942SAli.Saidi@ARM.com
1127942SAli.Saidi@ARM.com    /** Checks if there are any free integer registers. */
1137942SAli.Saidi@ARM.com    bool hasFreeIntRegs()
1149048SAli.Saidi@ARM.com    { return !freeIntRegs.empty(); }
11511168Sandreas.hansson@arm.com
11611168Sandreas.hansson@arm.com    /** Checks if there are any free fp registers. */
1177861Sgblack@eecs.umich.edu    bool hasFreeFloatRegs()
1187861Sgblack@eecs.umich.edu    { return !freeFloatRegs.empty(); }
1197861Sgblack@eecs.umich.edu
120    /** Returns the number of free integer registers. */
121    int numFreeIntRegs()
122    { return freeIntRegs.size(); }
123
124    /** Returns the number of free fp registers. */
125    int numFreeFloatRegs()
126    { return freeFloatRegs.size(); }
127};
128
129inline PhysRegIndex
130SimpleFreeList::getIntReg()
131{
132    DPRINTF(FreeList, "Trying to get free integer register.\n");
133
134    if (freeIntRegs.empty()) {
135        panic("No free integer registers!");
136    }
137
138    PhysRegIndex free_reg = freeIntRegs.front();
139
140    freeIntRegs.pop();
141
142    return(free_reg);
143}
144
145inline PhysRegIndex
146SimpleFreeList::getFloatReg()
147{
148    DPRINTF(FreeList, "Trying to get free float register.\n");
149
150    if (freeFloatRegs.empty()) {
151        panic("No free integer registers!");
152    }
153
154    PhysRegIndex free_reg = freeFloatRegs.front();
155
156    freeFloatRegs.pop();
157
158    return(free_reg);
159}
160
161inline void
162SimpleFreeList::addReg(PhysRegIndex freed_reg)
163{
164    DPRINTF(FreeList,"Freeing register %i.\n", freed_reg);
165    //Might want to add in a check for whether or not this register is
166    //already in there.  A bit vector or something similar would be useful.
167    if (freed_reg < numPhysicalIntRegs) {
168        if (freed_reg != TheISA::ZeroReg)
169            freeIntRegs.push(freed_reg);
170    } else if (freed_reg < numPhysicalRegs) {
171#if THE_ISA == ALPHA_ISA
172        if (freed_reg != (TheISA::ZeroReg + numPhysicalIntRegs))
173#endif
174            freeFloatRegs.push(freed_reg);
175    }
176
177    // These assert conditions ensure that the number of free
178    // registers are not more than the # of total Physical  Registers.
179    // If this were false, it would mean that registers
180    // have been freed twice, overflowing the free register
181    // pool and potentially crashing SMT workloads.
182    // ----
183    // Comment out for now so as to not potentially break
184    // CMP and single-threaded workloads
185    // ----
186    // assert(freeIntRegs.size() <= numPhysicalIntRegs);
187    // assert(freeFloatRegs.size() <= numPhysicalFloatRegs);
188}
189
190inline void
191SimpleFreeList::addIntReg(PhysRegIndex freed_reg)
192{
193    DPRINTF(FreeList,"Freeing int register %i.\n", freed_reg);
194
195    freeIntRegs.push(freed_reg);
196}
197
198inline void
199SimpleFreeList::addFloatReg(PhysRegIndex freed_reg)
200{
201    DPRINTF(FreeList,"Freeing float register %i.\n", freed_reg);
202
203    freeFloatRegs.push(freed_reg);
204}
205
206#endif // __CPU_O3_FREE_LIST_HH__
207