free_list.hh revision 1684
1#ifndef __CPU_BETA_CPU_FREE_LIST_HH__
2#define __CPU_BETA_CPU_FREE_LIST_HH__
3
4#include <iostream>
5#include <queue>
6
7#include "arch/alpha/isa_traits.hh"
8#include "base/trace.hh"
9#include "base/traceflags.hh"
10#include "cpu/beta_cpu/comm.hh"
11
12/**
13 * FreeList class that simply holds the list of free integer and floating
14 * point registers.  Can request for a free register of either type, and
15 * also send back free registers of either type.  This is a very simple
16 * class, but it should be sufficient for most implementations.  Like all
17 * other classes, it assumes that the indices for the floating point
18 * registers starts after the integer registers end.  Hence the variable
19 * numPhysicalIntRegs is logically equivalent to the baseFP dependency.
20 * Note that
21 * while this most likely should be called FreeList, the name "FreeList"
22 * is used in a typedef within the CPU Policy, and therefore no class
23 * can be named simply "FreeList".
24 * @todo: Give a better name to the base FP dependency.
25 */
26class SimpleFreeList
27{
28  private:
29    /** The list of free integer registers. */
30    std::queue<PhysRegIndex> freeIntRegs;
31
32    /** The list of free floating point registers. */
33    std::queue<PhysRegIndex> freeFloatRegs;
34
35    /** Number of logical integer registers. */
36    int numLogicalIntRegs;
37
38    /** Number of physical integer registers. */
39    int numPhysicalIntRegs;
40
41    /** Number of logical floating point registers. */
42    int numLogicalFloatRegs;
43
44    /** Number of physical floating point registers. */
45    int numPhysicalFloatRegs;
46
47    /** Total number of physical registers. */
48    int numPhysicalRegs;
49
50    /** DEBUG stuff below. */
51    std::vector<int> freeIntRegsScoreboard;
52
53    std::vector<bool> freeFloatRegsScoreboard;
54
55  public:
56    SimpleFreeList(unsigned _numLogicalIntRegs,
57                   unsigned _numPhysicalIntRegs,
58                   unsigned _numLogicalFloatRegs,
59                   unsigned _numPhysicalFloatRegs);
60
61    inline PhysRegIndex getIntReg();
62
63    inline PhysRegIndex getFloatReg();
64
65    inline void addReg(PhysRegIndex freed_reg);
66
67    inline void addIntReg(PhysRegIndex freed_reg);
68
69    inline void addFloatReg(PhysRegIndex freed_reg);
70
71    bool hasFreeIntRegs()
72    { return !freeIntRegs.empty(); }
73
74    bool hasFreeFloatRegs()
75    { return !freeFloatRegs.empty(); }
76
77    int numFreeIntRegs()
78    { return freeIntRegs.size(); }
79
80    int numFreeFloatRegs()
81    { return freeFloatRegs.size(); }
82};
83
84inline PhysRegIndex
85SimpleFreeList::getIntReg()
86{
87    DPRINTF(Rename, "FreeList: Trying to get free integer register.\n");
88    if (freeIntRegs.empty()) {
89        panic("No free integer registers!");
90    }
91
92    PhysRegIndex free_reg = freeIntRegs.front();
93
94    freeIntRegs.pop();
95
96    // DEBUG
97    assert(freeIntRegsScoreboard[free_reg]);
98    freeIntRegsScoreboard[free_reg] = 0;
99
100    return(free_reg);
101}
102
103inline PhysRegIndex
104SimpleFreeList::getFloatReg()
105{
106    DPRINTF(Rename, "FreeList: Trying to get free float register.\n");
107    if (freeFloatRegs.empty()) {
108        panic("No free integer registers!");
109    }
110
111    PhysRegIndex free_reg = freeFloatRegs.front();
112
113    freeFloatRegs.pop();
114
115    // DEBUG
116    assert(freeFloatRegsScoreboard[free_reg]);
117    freeFloatRegsScoreboard[free_reg] = 0;
118
119    return(free_reg);
120}
121
122inline void
123SimpleFreeList::addReg(PhysRegIndex freed_reg)
124{
125    DPRINTF(Rename, "Freelist: Freeing register %i.\n", freed_reg);
126    //Might want to add in a check for whether or not this register is
127    //already in there.  A bit vector or something similar would be useful.
128    if (freed_reg < numPhysicalIntRegs) {
129        freeIntRegs.push(freed_reg);
130
131        // DEBUG
132        assert(freeIntRegsScoreboard[freed_reg] == false);
133        freeIntRegsScoreboard[freed_reg] = 1;
134    } else if (freed_reg < numPhysicalRegs) {
135        freeFloatRegs.push(freed_reg);
136
137        // DEBUG
138        assert(freeFloatRegsScoreboard[freed_reg] == false);
139        freeFloatRegsScoreboard[freed_reg] = 1;
140    }
141}
142
143inline void
144SimpleFreeList::addIntReg(PhysRegIndex freed_reg)
145{
146    DPRINTF(Rename, "Freelist: Freeing int register %i.\n", freed_reg);
147
148    // DEBUG
149    assert(!freeIntRegsScoreboard[freed_reg]);
150    freeIntRegsScoreboard[freed_reg] = 1;
151
152    freeIntRegs.push(freed_reg);
153}
154
155inline void
156SimpleFreeList::addFloatReg(PhysRegIndex freed_reg)
157{
158    DPRINTF(Rename, "Freelist: Freeing float register %i.\n", freed_reg);
159
160    // DEBUG
161    assert(!freeFloatRegsScoreboard[freed_reg]);
162    freeFloatRegsScoreboard[freed_reg] = 1;
163
164    freeFloatRegs.push(freed_reg);
165}
166
167#endif // __CPU_BETA_CPU_FREE_LIST_HH__
168