rename_map.cc revision 2665:a124942bacb8
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Kevin Lim
29 */
30
31#include <vector>
32
33#include "cpu/o3/rename_map.hh"
34
35using namespace std;
36
37// Todo: Consider making functions inline.  Avoid having things that are
38// using the zero register or misc registers from adding on the registers
39// to the free list.  Possibly remove the direct communication between
40// this and the freelist.  Considering making inline bool functions that
41// determine if the register is a logical int, logical fp, physical int,
42// physical fp, etc.
43
44SimpleRenameMap::SimpleRenameMap(unsigned _numLogicalIntRegs,
45                                 unsigned _numPhysicalIntRegs,
46                                 unsigned _numLogicalFloatRegs,
47                                 unsigned _numPhysicalFloatRegs,
48                                 unsigned _numMiscRegs,
49                                 RegIndex _intZeroReg,
50                                 RegIndex _floatZeroReg)
51    : numLogicalIntRegs(_numLogicalIntRegs),
52      numPhysicalIntRegs(_numPhysicalIntRegs),
53      numLogicalFloatRegs(_numLogicalFloatRegs),
54      numPhysicalFloatRegs(_numPhysicalFloatRegs),
55      numMiscRegs(_numMiscRegs),
56      intZeroReg(_intZeroReg),
57      floatZeroReg(_floatZeroReg)
58{
59    DPRINTF(Rename, "Rename: Creating rename map.  Phys: %i / %i, Float: "
60            "%i / %i.\n", numLogicalIntRegs, numPhysicalIntRegs,
61            numLogicalFloatRegs, numPhysicalFloatRegs);
62
63    numLogicalRegs = numLogicalIntRegs + numLogicalFloatRegs;
64
65    numPhysicalRegs = numPhysicalIntRegs + numPhysicalFloatRegs;
66
67    //Create the rename maps, and their scoreboards.
68    intRenameMap = new RenameEntry[numLogicalIntRegs];
69    floatRenameMap = new RenameEntry[numLogicalRegs];
70
71    // Should combine this into one scoreboard.
72    intScoreboard.resize(numPhysicalIntRegs);
73    floatScoreboard.resize(numPhysicalRegs);
74    miscScoreboard.resize(numPhysicalRegs + numMiscRegs);
75
76    // Initialize the entries in the integer rename map to point to the
77    // physical registers of the same index, and consider each register
78    // ready until the first rename occurs.
79    for (RegIndex index = 0; index < numLogicalIntRegs; ++index)
80    {
81        intRenameMap[index].physical_reg = index;
82        intScoreboard[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 = numLogicalIntRegs;
88         index < numPhysicalIntRegs;
89         ++index)
90    {
91        intScoreboard[index] = 0;
92    }
93
94    int float_reg_idx = numPhysicalIntRegs;
95
96    // Initialize the entries in the floating point rename map to point to
97    // the physical registers of the same index, and consider each register
98    // ready until the first rename occurs.
99    // Although the index refers purely to architected registers, because
100    // the floating reg indices come after the integer reg indices, they
101    // may exceed the size of a normal RegIndex (short).
102    for (PhysRegIndex index = numLogicalIntRegs;
103         index < numLogicalRegs; ++index)
104    {
105        floatRenameMap[index].physical_reg = float_reg_idx++;
106    }
107
108    for (PhysRegIndex index = numPhysicalIntRegs;
109         index < numPhysicalIntRegs + numLogicalFloatRegs; ++index)
110    {
111        floatScoreboard[index] = 1;
112    }
113
114    // Initialize the rest of the physical registers (the ones that don't
115    // directly map to a logical register) as unready.
116    for (PhysRegIndex index = numPhysicalIntRegs + numLogicalFloatRegs;
117         index < numPhysicalRegs;
118         ++index)
119    {
120        floatScoreboard[index] = 0;
121    }
122
123    // Initialize the entries in the misc register scoreboard to be ready.
124    for (PhysRegIndex index = numPhysicalRegs;
125         index < numPhysicalRegs + numMiscRegs; ++index)
126    {
127        miscScoreboard[index] = 1;
128    }
129}
130
131SimpleRenameMap::~SimpleRenameMap()
132{
133    // Delete the rename maps as they were allocated with new.
134    delete [] intRenameMap;
135    delete [] floatRenameMap;
136}
137
138void
139SimpleRenameMap::setFreeList(SimpleFreeList *fl_ptr)
140{
141    //Setup the interface to the freelist.
142    freeList = fl_ptr;
143}
144
145
146// Don't allow this stage to fault; force that check to the rename stage.
147// Simply ask to rename a logical register and get back a new physical
148// register index.
149SimpleRenameMap::RenameInfo
150SimpleRenameMap::rename(RegIndex arch_reg)
151{
152    PhysRegIndex renamed_reg;
153    PhysRegIndex prev_reg;
154
155    if (arch_reg < numLogicalIntRegs) {
156
157        // Record the current physical register that is renamed to the
158        // requested architected register.
159        prev_reg = intRenameMap[arch_reg].physical_reg;
160
161        // If it's not referencing the zero register, then mark the register
162        // as not ready.
163        if (arch_reg != intZeroReg) {
164            // Get a free physical register to rename to.
165            renamed_reg = freeList->getIntReg();
166
167            // Update the integer rename map.
168            intRenameMap[arch_reg].physical_reg = renamed_reg;
169
170            assert(renamed_reg >= 0 && renamed_reg < numPhysicalIntRegs);
171
172            // Mark register as not ready.
173            intScoreboard[renamed_reg] = false;
174        } else {
175            // Otherwise return the zero register so nothing bad happens.
176            renamed_reg = intZeroReg;
177        }
178    } else if (arch_reg < numLogicalRegs) {
179        // Subtract off the base offset for floating point registers.
180//        arch_reg = arch_reg - numLogicalIntRegs;
181
182        // Record the current physical register that is renamed to the
183        // requested architected register.
184        prev_reg = floatRenameMap[arch_reg].physical_reg;
185
186        // If it's not referencing the zero register, then mark the register
187        // as not ready.
188        if (arch_reg != floatZeroReg) {
189            // Get a free floating point register to rename to.
190            renamed_reg = freeList->getFloatReg();
191
192            // Update the floating point rename map.
193            floatRenameMap[arch_reg].physical_reg = renamed_reg;
194
195            assert(renamed_reg < numPhysicalRegs &&
196                   renamed_reg >= numPhysicalIntRegs);
197
198            // Mark register as not ready.
199            floatScoreboard[renamed_reg] = false;
200        } else {
201            // Otherwise return the zero register so nothing bad happens.
202            renamed_reg = floatZeroReg;
203        }
204    } else {
205        // Subtract off the base offset for miscellaneous registers.
206        arch_reg = arch_reg - numLogicalRegs;
207
208        // No renaming happens to the misc. registers.  They are simply the
209        // registers that come after all the  physical registers; thus
210        // take the base architected register and add the physical registers
211        // to it.
212        renamed_reg = arch_reg + numPhysicalRegs;
213
214        // Set the previous register to the same register; mainly it must be
215        // known that the prev reg was outside the range of normal registers
216        // so the free list can avoid adding it.
217        prev_reg = renamed_reg;
218
219        assert(renamed_reg < numPhysicalRegs + numMiscRegs);
220
221        miscScoreboard[renamed_reg] = false;
222    }
223
224    return RenameInfo(renamed_reg, prev_reg);
225}
226
227//Perhaps give this a pair as a return value, of the physical register
228//and whether or not it's ready.
229PhysRegIndex
230SimpleRenameMap::lookup(RegIndex arch_reg)
231{
232    if (arch_reg < numLogicalIntRegs) {
233        return intRenameMap[arch_reg].physical_reg;
234    } else if (arch_reg < numLogicalRegs) {
235        // Subtract off the base FP offset.
236//        arch_reg = arch_reg - numLogicalIntRegs;
237
238        return floatRenameMap[arch_reg].physical_reg;
239    } else {
240        // Subtract off the misc registers offset.
241        arch_reg = arch_reg - numLogicalRegs;
242
243        // Misc. regs don't rename, so simply add the base arch reg to
244        // the number of physical registers.
245        return numPhysicalRegs + arch_reg;
246    }
247}
248
249bool
250SimpleRenameMap::isReady(PhysRegIndex phys_reg)
251{
252    if (phys_reg < numPhysicalIntRegs) {
253        return intScoreboard[phys_reg];
254    } else if (phys_reg < numPhysicalRegs) {
255
256        // Subtract off the base FP offset.
257//        phys_reg = phys_reg - numPhysicalIntRegs;
258
259        return floatScoreboard[phys_reg];
260    } else {
261        // Subtract off the misc registers offset.
262//        phys_reg = phys_reg - numPhysicalRegs;
263
264        return miscScoreboard[phys_reg];
265    }
266}
267
268// In this implementation the miscellaneous registers do not actually rename,
269// so this function does not allow you to try to change their mappings.
270void
271SimpleRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex renamed_reg)
272{
273    if (arch_reg < numLogicalIntRegs) {
274        DPRINTF(Rename, "Rename Map: Integer register %i being set to %i.\n",
275                (int)arch_reg, renamed_reg);
276
277        intRenameMap[arch_reg].physical_reg = renamed_reg;
278    } else {
279        assert(arch_reg < (numLogicalIntRegs + numLogicalFloatRegs));
280
281        DPRINTF(Rename, "Rename Map: Float register %i being set to %i.\n",
282                (int)arch_reg - numLogicalIntRegs, renamed_reg);
283
284        floatRenameMap[arch_reg].physical_reg = renamed_reg;
285    }
286}
287
288void
289SimpleRenameMap::squash(vector<RegIndex> freed_regs,
290                        vector<UnmapInfo> unmaps)
291{
292    panic("Not sure this function should be called.");
293
294    // Not sure the rename map should be able to access the free list
295    // like this.
296    while (!freed_regs.empty()) {
297        RegIndex free_register = freed_regs.back();
298
299        if (free_register < numPhysicalIntRegs) {
300            freeList->addIntReg(free_register);
301        } else {
302            // Subtract off the base FP dependence tag.
303            free_register = free_register - numPhysicalIntRegs;
304            freeList->addFloatReg(free_register);
305        }
306
307        freed_regs.pop_back();
308    }
309
310    // Take unmap info and roll back the rename map.
311}
312
313void
314SimpleRenameMap::markAsReady(PhysRegIndex ready_reg)
315{
316    DPRINTF(Rename, "Rename map: Marking register %i as ready.\n",
317            (int)ready_reg);
318
319    if (ready_reg < numPhysicalIntRegs) {
320        assert(ready_reg >= 0);
321
322        intScoreboard[ready_reg] = 1;
323    } else if (ready_reg < numPhysicalRegs) {
324
325        // Subtract off the base FP offset.
326//        ready_reg = ready_reg - numPhysicalIntRegs;
327
328        floatScoreboard[ready_reg] = 1;
329    } else {
330        //Subtract off the misc registers offset.
331//        ready_reg = ready_reg - numPhysicalRegs;
332
333        miscScoreboard[ready_reg] = 1;
334    }
335}
336
337int
338SimpleRenameMap::numFreeEntries()
339{
340    int free_int_regs = freeList->numFreeIntRegs();
341    int free_float_regs = freeList->numFreeFloatRegs();
342
343    if (free_int_regs < free_float_regs) {
344        return free_int_regs;
345    } else {
346        return free_float_regs;
347    }
348}
349