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