rename_map.cc revision 1464
1
2#include <vector>
3
4#include "cpu/beta_cpu/rename_map.hh"
5
6using namespace std;
7
8// Todo: Consider making functions inline.  Avoid having things that are
9// using the zero register or misc registers from adding on the registers
10// to the free list.  Possibly remove the direct communication between
11// this and the freelist.  Considering making inline bool functions that
12// determine if the register is a logical int, logical fp, physical int,
13// physical fp, etc.
14
15SimpleRenameMap::SimpleRenameMap(unsigned _numLogicalIntRegs,
16                                 unsigned _numPhysicalIntRegs,
17                                 unsigned _numLogicalFloatRegs,
18                                 unsigned _numPhysicalFloatRegs,
19                                 unsigned _numMiscRegs,
20                                 RegIndex _intZeroReg,
21                                 RegIndex _floatZeroReg)
22    : numLogicalIntRegs(_numLogicalIntRegs),
23      numPhysicalIntRegs(_numPhysicalIntRegs),
24      numLogicalFloatRegs(_numLogicalFloatRegs),
25      numPhysicalFloatRegs(_numPhysicalFloatRegs),
26      numMiscRegs(_numMiscRegs),
27      intZeroReg(_intZeroReg),
28      floatZeroReg(_floatZeroReg)
29{
30    DPRINTF(Rename, "Rename: Creating rename map.  Phys: %i / %i, Float: "
31            "%i / %i.\n", numLogicalIntRegs, numPhysicalIntRegs,
32            numLogicalFloatRegs, numPhysicalFloatRegs);
33
34    numLogicalRegs = numLogicalIntRegs + numLogicalFloatRegs;
35
36    numPhysicalRegs = numPhysicalIntRegs + numPhysicalFloatRegs;
37
38    //Create the rename maps, and their scoreboards.
39    intRenameMap = new RenameEntry[numLogicalIntRegs];
40    floatRenameMap = new RenameEntry[numLogicalRegs];
41
42    // Should combine this into one scoreboard.
43    intScoreboard.resize(numPhysicalIntRegs);
44    floatScoreboard.resize(numPhysicalRegs);
45    miscScoreboard.resize(numPhysicalRegs + numMiscRegs);
46
47    // Initialize the entries in the integer rename map to point to the
48    // physical registers of the same index, and consider each register
49    // ready until the first rename occurs.
50    for (RegIndex index = 0; index < numLogicalIntRegs; ++index)
51    {
52        intRenameMap[index].physical_reg = index;
53        intScoreboard[index] = 1;
54    }
55
56    // Initialize the rest of the physical registers (the ones that don't
57    // directly map to a logical register) as unready.
58    for (PhysRegIndex index = numLogicalIntRegs;
59         index < numPhysicalIntRegs;
60         ++index)
61    {
62        intScoreboard[index] = 0;
63    }
64
65    int float_reg_idx = numPhysicalIntRegs;
66
67    // Initialize the entries in the floating point rename map to point to
68    // the physical registers of the same index, and consider each register
69    // ready until the first rename occurs.
70    // Although the index refers purely to architected registers, because
71    // the floating reg indices come after the integer reg indices, they
72    // may exceed the size of a normal RegIndex (short).
73    for (PhysRegIndex index = numLogicalIntRegs;
74         index < numLogicalRegs; ++index)
75    {
76        floatRenameMap[index].physical_reg = float_reg_idx++;
77    }
78
79    for (PhysRegIndex index = numPhysicalIntRegs;
80         index < numPhysicalIntRegs + numLogicalFloatRegs; ++index)
81    {
82        floatScoreboard[index] = 1;
83    }
84
85    // Initialize the rest of the physical registers (the ones that don't
86    // directly map to a logical register) as unready.
87    for (PhysRegIndex index = numPhysicalIntRegs + numLogicalFloatRegs;
88         index < numPhysicalRegs;
89         ++index)
90    {
91        floatScoreboard[index] = 0;
92    }
93
94    // Initialize the entries in the misc register scoreboard to be ready.
95    for (PhysRegIndex index = numPhysicalRegs;
96         index < numPhysicalRegs + numMiscRegs; ++index)
97    {
98        miscScoreboard[index] = 1;
99    }
100}
101
102SimpleRenameMap::~SimpleRenameMap()
103{
104    // Delete the rename maps as they were allocated with new.
105    delete [] intRenameMap;
106    delete [] floatRenameMap;
107}
108
109void
110SimpleRenameMap::setFreeList(SimpleFreeList *fl_ptr)
111{
112    //Setup the interface to the freelist.
113    freeList = fl_ptr;
114}
115
116
117// Don't allow this stage to fault; force that check to the rename stage.
118// Simply ask to rename a logical register and get back a new physical
119// register index.
120SimpleRenameMap::RenameInfo
121SimpleRenameMap::rename(RegIndex arch_reg)
122{
123    PhysRegIndex renamed_reg;
124    PhysRegIndex prev_reg;
125
126    if (arch_reg < numLogicalIntRegs) {
127
128        // Record the current physical register that is renamed to the
129        // requested architected register.
130        prev_reg = intRenameMap[arch_reg].physical_reg;
131
132        // If it's not referencing the zero register, then mark the register
133        // as not ready.
134        if (arch_reg != intZeroReg) {
135            // Get a free physical register to rename to.
136            renamed_reg = freeList->getIntReg();
137
138            // Update the integer rename map.
139            intRenameMap[arch_reg].physical_reg = renamed_reg;
140
141            assert(renamed_reg >= 0 && renamed_reg < numPhysicalIntRegs);
142
143            // Mark register as not ready.
144            intScoreboard[renamed_reg] = false;
145        } else {
146            // Otherwise return the zero register so nothing bad happens.
147            renamed_reg = intZeroReg;
148        }
149    } else if (arch_reg < numLogicalRegs) {
150        // Subtract off the base offset for floating point registers.
151//        arch_reg = arch_reg - numLogicalIntRegs;
152
153        // Record the current physical register that is renamed to the
154        // requested architected register.
155        prev_reg = floatRenameMap[arch_reg].physical_reg;
156
157        // If it's not referencing the zero register, then mark the register
158        // as not ready.
159        if (arch_reg != floatZeroReg) {
160            // Get a free floating point register to rename to.
161            renamed_reg = freeList->getFloatReg();
162
163            // Update the floating point rename map.
164            floatRenameMap[arch_reg].physical_reg = renamed_reg;
165
166            assert(renamed_reg < numPhysicalRegs &&
167                   renamed_reg >= numPhysicalIntRegs);
168
169            // Mark register as not ready.
170            floatScoreboard[renamed_reg] = false;
171        } else {
172            // Otherwise return the zero register so nothing bad happens.
173            renamed_reg = floatZeroReg;
174        }
175    } else {
176        // Subtract off the base offset for miscellaneous registers.
177        arch_reg = arch_reg - numLogicalRegs;
178
179        // No renaming happens to the misc. registers.  They are simply the
180        // registers that come after all the  physical registers; thus
181        // take the base architected register and add the physical registers
182        // to it.
183        renamed_reg = arch_reg + numPhysicalRegs;
184
185        // Set the previous register to the same register; mainly it must be
186        // known that the prev reg was outside the range of normal registers
187        // so the free list can avoid adding it.
188        prev_reg = renamed_reg;
189
190        assert(renamed_reg < numPhysicalRegs + numMiscRegs);
191
192        miscScoreboard[renamed_reg] = false;
193    }
194
195    return RenameInfo(renamed_reg, prev_reg);
196}
197
198//Perhaps give this a pair as a return value, of the physical register
199//and whether or not it's ready.
200PhysRegIndex
201SimpleRenameMap::lookup(RegIndex arch_reg)
202{
203    if (arch_reg < numLogicalIntRegs) {
204        return intRenameMap[arch_reg].physical_reg;
205    } else if (arch_reg < numLogicalRegs) {
206        // Subtract off the base FP offset.
207//        arch_reg = arch_reg - numLogicalIntRegs;
208
209        return floatRenameMap[arch_reg].physical_reg;
210    } else {
211        // Subtract off the misc registers offset.
212        arch_reg = arch_reg - numLogicalRegs;
213
214        // Misc. regs don't rename, so simply add the base arch reg to
215        // the number of physical registers.
216        return numPhysicalRegs + arch_reg;
217    }
218}
219
220bool
221SimpleRenameMap::isReady(PhysRegIndex phys_reg)
222{
223    if (phys_reg < numPhysicalIntRegs) {
224        return intScoreboard[phys_reg];
225    } else if (phys_reg < numPhysicalRegs) {
226
227        // Subtract off the base FP offset.
228//        phys_reg = phys_reg - numPhysicalIntRegs;
229
230        return floatScoreboard[phys_reg];
231    } else {
232        // Subtract off the misc registers offset.
233//        phys_reg = phys_reg - numPhysicalRegs;
234
235        return miscScoreboard[phys_reg];
236    }
237}
238
239// In this implementation the miscellaneous registers do not actually rename,
240// so this function does not allow you to try to change their mappings.
241void
242SimpleRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex renamed_reg)
243{
244    if (arch_reg < numLogicalIntRegs) {
245        DPRINTF(Rename, "Rename Map: Integer register %i being set to %i.\n",
246                (int)arch_reg, renamed_reg);
247
248        intRenameMap[arch_reg].physical_reg = renamed_reg;
249    } else {
250        assert(arch_reg < (numLogicalIntRegs + numLogicalFloatRegs));
251
252        DPRINTF(Rename, "Rename Map: Float register %i being set to %i.\n",
253                (int)arch_reg - numLogicalIntRegs, renamed_reg);
254
255        floatRenameMap[arch_reg].physical_reg = renamed_reg;
256    }
257}
258
259void
260SimpleRenameMap::squash(vector<RegIndex> freed_regs,
261                        vector<UnmapInfo> unmaps)
262{
263    panic("Not sure this function should be called.");
264
265    // Not sure the rename map should be able to access the free list
266    // like this.
267    while (!freed_regs.empty()) {
268        RegIndex free_register = freed_regs.back();
269
270        if (free_register < numPhysicalIntRegs) {
271            freeList->addIntReg(free_register);
272        } else {
273            // Subtract off the base FP dependence tag.
274            free_register = free_register - numPhysicalIntRegs;
275            freeList->addFloatReg(free_register);
276        }
277
278        freed_regs.pop_back();
279    }
280
281    // Take unmap info and roll back the rename map.
282}
283
284void
285SimpleRenameMap::markAsReady(PhysRegIndex ready_reg)
286{
287    DPRINTF(Rename, "Rename map: Marking register %i as ready.\n",
288            (int)ready_reg);
289
290    if (ready_reg < numPhysicalIntRegs) {
291        assert(ready_reg >= 0);
292
293        intScoreboard[ready_reg] = 1;
294    } else if (ready_reg < numPhysicalRegs) {
295
296        // Subtract off the base FP offset.
297//        ready_reg = ready_reg - numPhysicalIntRegs;
298
299        floatScoreboard[ready_reg] = 1;
300    } else {
301        //Subtract off the misc registers offset.
302//        ready_reg = ready_reg - numPhysicalRegs;
303
304        miscScoreboard[ready_reg] = 1;
305    }
306}
307
308int
309SimpleRenameMap::numFreeEntries()
310{
311    int free_int_regs = freeList->numFreeIntRegs();
312    int free_float_regs = freeList->numFreeFloatRegs();
313
314    if (free_int_regs < free_float_regs) {
315        return free_int_regs;
316    } else {
317        return free_float_regs;
318    }
319}
320