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