rename_map.cc revision 2292
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()
43{
44    // Delete the rename maps as they were allocated with new.
45    //delete [] intRenameMap;
46    //delete [] floatRenameMap;
47}
48
49void
50SimpleRenameMap::init(unsigned _numLogicalIntRegs,
51                      unsigned _numPhysicalIntRegs,
52                      PhysRegIndex &ireg_idx,
53
54                      unsigned _numLogicalFloatRegs,
55                      unsigned _numPhysicalFloatRegs,
56                      PhysRegIndex &freg_idx,
57
58                      unsigned _numMiscRegs,
59
60                      RegIndex _intZeroReg,
61                      RegIndex _floatZeroReg,
62
63                      int map_id,
64                      bool bindRegs)
65{
66    id = map_id;
67
68    numLogicalIntRegs = _numLogicalIntRegs;
69
70    numLogicalFloatRegs = _numLogicalFloatRegs;
71
72    numPhysicalIntRegs = _numPhysicalIntRegs;
73
74    numPhysicalFloatRegs = _numPhysicalFloatRegs;
75
76    numMiscRegs = _numMiscRegs;
77
78    intZeroReg = _intZeroReg;
79    floatZeroReg = _floatZeroReg;
80
81    DPRINTF(Rename, "Creating rename map %i.  Phys: %i / %i, Float: "
82            "%i / %i.\n", id, numLogicalIntRegs, numPhysicalIntRegs,
83            numLogicalFloatRegs, numPhysicalFloatRegs);
84
85    numLogicalRegs = numLogicalIntRegs + numLogicalFloatRegs;
86
87    numPhysicalRegs = numPhysicalIntRegs + numPhysicalFloatRegs;
88
89    //Create the rename maps
90    intRenameMap.resize(numLogicalIntRegs);
91    floatRenameMap.resize(numLogicalRegs);
92
93    if (bindRegs) {
94        DPRINTF(Rename, "Binding registers into rename map %i",id);
95
96        // Initialize the entries in the integer rename map to point to the
97        // physical registers of the same index
98        for (RegIndex index = 0; index < numLogicalIntRegs; ++index)
99        {
100            intRenameMap[index].physical_reg = ireg_idx++;
101        }
102
103        // Initialize the entries in the floating point rename map to point to
104        // the physical registers of the same index
105        // Although the index refers purely to architected registers, because
106        // the floating reg indices come after the integer reg indices, they
107        // may exceed the size of a normal RegIndex (short).
108        for (PhysRegIndex index = numLogicalIntRegs; index < numLogicalRegs; ++index)
109        {
110            floatRenameMap[index].physical_reg = freg_idx++;
111        }
112    } else {
113        DPRINTF(Rename, "Binding registers into rename map %i",id);
114
115        PhysRegIndex temp_ireg = ireg_idx;
116
117        for (RegIndex index = 0; index < numLogicalIntRegs; ++index)
118        {
119            intRenameMap[index].physical_reg = temp_ireg++;
120        }
121
122        PhysRegIndex temp_freg = freg_idx;
123
124        for (PhysRegIndex index = numLogicalIntRegs;
125             index < numLogicalRegs; ++index)
126        {
127            floatRenameMap[index].physical_reg = temp_freg++;
128        }
129    }
130}
131
132void
133SimpleRenameMap::setFreeList(SimpleFreeList *fl_ptr)
134{
135    //Setup the interface to the freelist.
136    freeList = fl_ptr;
137}
138
139
140// Don't allow this stage to fault; force that check to the rename stage.
141// Simply ask to rename a logical register and get back a new physical
142// register index.
143SimpleRenameMap::RenameInfo
144SimpleRenameMap::rename(RegIndex arch_reg)
145{
146    PhysRegIndex renamed_reg;
147    PhysRegIndex prev_reg;
148
149    if (arch_reg < numLogicalIntRegs) {
150
151        // Record the current physical register that is renamed to the
152        // requested architected register.
153        prev_reg = intRenameMap[arch_reg].physical_reg;
154
155        // If it's not referencing the zero register, then mark the register
156        // as not ready.
157        if (arch_reg != intZeroReg) {
158            // Get a free physical register to rename to.
159            renamed_reg = freeList->getIntReg();
160
161            // Update the integer rename map.
162            intRenameMap[arch_reg].physical_reg = renamed_reg;
163
164            assert(renamed_reg >= 0 && renamed_reg < numPhysicalIntRegs);
165
166        } else {
167            // Otherwise return the zero register so nothing bad happens.
168            renamed_reg = intZeroReg;
169        }
170    } else if (arch_reg < numLogicalRegs) {
171        // Subtract off the base offset for floating point registers.
172//        arch_reg = arch_reg - numLogicalIntRegs;
173
174        // Record the current physical register that is renamed to the
175        // requested architected register.
176        prev_reg = floatRenameMap[arch_reg].physical_reg;
177
178        // If it's not referencing the zero register, then mark the register
179        // as not ready.
180        if (arch_reg != floatZeroReg) {
181            // Get a free floating point register to rename to.
182            renamed_reg = freeList->getFloatReg();
183
184            // Update the floating point rename map.
185            floatRenameMap[arch_reg].physical_reg = renamed_reg;
186
187            assert(renamed_reg < numPhysicalRegs &&
188                   renamed_reg >= numPhysicalIntRegs);
189        } else {
190            // Otherwise return the zero register so nothing bad happens.
191            renamed_reg = floatZeroReg;
192        }
193    } else {
194        // Subtract off the base offset for miscellaneous registers.
195        arch_reg = arch_reg - numLogicalRegs;
196
197        // No renaming happens to the misc. registers.  They are simply the
198        // registers that come after all the  physical registers; thus
199        // take the base architected register and add the physical registers
200        // to it.
201        renamed_reg = arch_reg + numPhysicalRegs;
202
203        // Set the previous register to the same register; mainly it must be
204        // known that the prev reg was outside the range of normal registers
205        // so the free list can avoid adding it.
206        prev_reg = renamed_reg;
207
208        assert(renamed_reg < numPhysicalRegs + numMiscRegs);
209    }
210
211    return RenameInfo(renamed_reg, prev_reg);
212}
213
214//Perhaps give this a pair as a return value, of the physical register
215//and whether or not it's ready.
216PhysRegIndex
217SimpleRenameMap::lookup(RegIndex arch_reg)
218{
219    if (arch_reg < numLogicalIntRegs) {
220        return intRenameMap[arch_reg].physical_reg;
221    } else if (arch_reg < numLogicalRegs) {
222        // Subtract off the base FP offset.
223//        arch_reg = arch_reg - numLogicalIntRegs;
224
225        return floatRenameMap[arch_reg].physical_reg;
226    } else {
227        // Subtract off the misc registers offset.
228        arch_reg = arch_reg - numLogicalRegs;
229
230        // Misc. regs don't rename, so simply add the base arch reg to
231        // the number of physical registers.
232        return numPhysicalRegs + arch_reg;
233    }
234}
235
236// In this implementation the miscellaneous registers do not actually rename,
237// so this function does not allow you to try to change their mappings.
238void
239SimpleRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex renamed_reg)
240{
241    if (arch_reg < numLogicalIntRegs) {
242        DPRINTF(Rename, "Rename Map: Integer register %i being set to %i.\n",
243                (int)arch_reg, renamed_reg);
244
245        intRenameMap[arch_reg].physical_reg = renamed_reg;
246    } else if (arch_reg < numLogicalIntRegs + numLogicalFloatRegs) {
247
248
249        DPRINTF(Rename, "Rename Map: Float register %i being set to %i.\n",
250                (int)arch_reg - numLogicalIntRegs, renamed_reg);
251
252        floatRenameMap[arch_reg].physical_reg = renamed_reg;
253    }
254
255    //assert(arch_reg < (numLogicalIntRegs + numLogicalFloatRegs));
256}
257
258void
259SimpleRenameMap::squash(vector<RegIndex> freed_regs,
260                        vector<UnmapInfo> unmaps)
261{
262    panic("Not sure this function should be called.");
263
264    // Not sure the rename map should be able to access the free list
265    // like this.
266    while (!freed_regs.empty()) {
267        RegIndex free_register = freed_regs.back();
268
269        if (free_register < numPhysicalIntRegs) {
270            freeList->addIntReg(free_register);
271        } else {
272            // Subtract off the base FP dependence tag.
273            free_register = free_register - numPhysicalIntRegs;
274            freeList->addFloatReg(free_register);
275        }
276
277        freed_regs.pop_back();
278    }
279
280    // Take unmap info and roll back the rename map.
281}
282
283int
284SimpleRenameMap::numFreeEntries()
285{
286    int free_int_regs = freeList->numFreeIntRegs();
287    int free_float_regs = freeList->numFreeFloatRegs();
288
289    if (free_int_regs < free_float_regs) {
290        return free_int_regs;
291    } else {
292        return free_float_regs;
293    }
294}
295