rename_map.cc revision 9479:f9e76b1eb79a
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#include "debug/Rename.hh"
35
36using namespace std;
37
38// @todo: Consider making inline bool functions that determine if the
39// register is a logical int, logical fp, physical int, physical fp,
40// etc.
41
42SimpleRenameMap::~SimpleRenameMap()
43{
44}
45
46void
47SimpleRenameMap::init(unsigned _numLogicalIntRegs,
48                      unsigned _numPhysicalIntRegs,
49                      PhysRegIndex &ireg_idx,
50
51                      unsigned _numLogicalFloatRegs,
52                      unsigned _numPhysicalFloatRegs,
53                      PhysRegIndex &freg_idx,
54
55                      unsigned _numMiscRegs,
56
57                      RegIndex _intZeroReg,
58                      RegIndex _floatZeroReg,
59
60                      int map_id,
61                      bool bindRegs)
62{
63    id = map_id;
64
65    numLogicalIntRegs = _numLogicalIntRegs;
66
67    numLogicalFloatRegs = _numLogicalFloatRegs;
68
69    numPhysicalIntRegs = _numPhysicalIntRegs;
70
71    numPhysicalFloatRegs = _numPhysicalFloatRegs;
72
73    numMiscRegs = _numMiscRegs;
74
75    intZeroReg = _intZeroReg;
76    floatZeroReg = _floatZeroReg;
77
78    DPRINTF(Rename, "Creating rename map %i.  Phys: %i / %i, Float: "
79            "%i / %i.\n", id, numLogicalIntRegs, numPhysicalIntRegs,
80            numLogicalFloatRegs, numPhysicalFloatRegs);
81
82    numLogicalRegs = numLogicalIntRegs + numLogicalFloatRegs;
83
84    numPhysicalRegs = numPhysicalIntRegs + numPhysicalFloatRegs;
85
86    //Create the rename maps
87    intRenameMap.resize(numLogicalIntRegs);
88    floatRenameMap.resize(numLogicalRegs);
89
90    if (bindRegs) {
91        DPRINTF(Rename, "Binding registers into rename map %i\n",id);
92
93        // Initialize the entries in the integer rename map to point to the
94        // physical registers of the same index
95        for (RegIndex index = 0; index < numLogicalIntRegs; ++index)
96        {
97            intRenameMap[index].physical_reg = ireg_idx++;
98        }
99
100        // Initialize the entries in the floating point rename map to point to
101        // the physical registers of the same index
102        // Although the index refers purely to architected registers, because
103        // the floating reg indices come after the integer reg indices, they
104        // may exceed the size of a normal RegIndex (short).
105        for (PhysRegIndex index = numLogicalIntRegs;
106             index < numLogicalRegs; ++index)
107        {
108            floatRenameMap[index].physical_reg = freg_idx++;
109        }
110    } else {
111        DPRINTF(Rename, "Binding registers into rename map %i\n",id);
112
113        PhysRegIndex temp_ireg = ireg_idx;
114
115        for (RegIndex index = 0; index < numLogicalIntRegs; ++index)
116        {
117            intRenameMap[index].physical_reg = temp_ireg++;
118        }
119
120        PhysRegIndex temp_freg = freg_idx;
121
122        for (PhysRegIndex index = numLogicalIntRegs;
123             index < numLogicalRegs; ++index)
124        {
125            floatRenameMap[index].physical_reg = temp_freg++;
126        }
127    }
128}
129
130void
131SimpleRenameMap::setFreeList(SimpleFreeList *fl_ptr)
132{
133    freeList = fl_ptr;
134}
135
136
137SimpleRenameMap::RenameInfo
138SimpleRenameMap::rename(RegIndex arch_reg)
139{
140    PhysRegIndex renamed_reg;
141    PhysRegIndex prev_reg;
142
143    if (arch_reg < numLogicalIntRegs) {
144
145        // Record the current physical register that is renamed to the
146        // requested architected register.
147        prev_reg = intRenameMap[arch_reg].physical_reg;
148
149        // If it's not referencing the zero register, then rename the
150        // register.
151        if (arch_reg != intZeroReg) {
152            renamed_reg = freeList->getIntReg();
153
154            intRenameMap[arch_reg].physical_reg = renamed_reg;
155
156            assert(renamed_reg >= 0 && renamed_reg < numPhysicalIntRegs);
157
158        } else {
159            // Otherwise return the zero register so nothing bad happens.
160            renamed_reg = intZeroReg;
161            prev_reg = intZeroReg;
162        }
163    } else if (arch_reg < numLogicalRegs) {
164        // Record the current physical register that is renamed to the
165        // requested architected register.
166        prev_reg = floatRenameMap[arch_reg].physical_reg;
167
168        // If it's not referencing the zero register, then rename the
169        // register.
170#if THE_ISA == ALPHA_ISA
171        if (arch_reg != floatZeroReg) {
172#endif
173            renamed_reg = freeList->getFloatReg();
174
175            floatRenameMap[arch_reg].physical_reg = renamed_reg;
176
177            assert(renamed_reg < numPhysicalRegs &&
178                   renamed_reg >= numPhysicalIntRegs);
179#if THE_ISA == ALPHA_ISA
180        } else {
181            // Otherwise return the zero register so nothing bad happens.
182            renamed_reg = floatZeroReg;
183        }
184#endif
185    } else {
186        // Subtract off the base offset for miscellaneous registers.
187        arch_reg = arch_reg - numLogicalRegs;
188
189        DPRINTF(Rename, "Renamed misc reg %d\n", arch_reg);
190
191        // No renaming happens to the misc. registers.  They are
192        // simply the registers that come after all the physical
193        // registers; thus take the base architected register and add
194        // the physical registers to it.
195        renamed_reg = arch_reg + numPhysicalRegs;
196
197        // Set the previous register to the same register; mainly it must be
198        // known that the prev reg was outside the range of normal registers
199        // so the free list can avoid adding it.
200        prev_reg = renamed_reg;
201    }
202
203    DPRINTF(Rename, "Renamed reg %d to physical reg %d old mapping was %d\n",
204            arch_reg, renamed_reg, prev_reg);
205
206    return RenameInfo(renamed_reg, prev_reg);
207}
208
209PhysRegIndex
210SimpleRenameMap::lookup(RegIndex arch_reg)
211{
212    if (arch_reg < numLogicalIntRegs) {
213        return intRenameMap[arch_reg].physical_reg;
214    } else if (arch_reg < numLogicalRegs) {
215        return floatRenameMap[arch_reg].physical_reg;
216    } else {
217        // Subtract off the misc registers offset.
218        arch_reg = arch_reg - numLogicalRegs;
219
220        // Misc. regs don't rename, so simply add the base arch reg to
221        // the number of physical registers.
222        return numPhysicalRegs + arch_reg;
223    }
224}
225
226void
227SimpleRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex renamed_reg)
228{
229    // In this implementation the miscellaneous registers do not
230    // actually rename, so this function does not allow you to try to
231    // change their mappings.
232    if (arch_reg < numLogicalIntRegs) {
233        DPRINTF(Rename, "Rename Map: Integer register %i being set to %i.\n",
234                (int)arch_reg, renamed_reg);
235
236        intRenameMap[arch_reg].physical_reg = renamed_reg;
237    } else if (arch_reg < numLogicalIntRegs + numLogicalFloatRegs) {
238        DPRINTF(Rename, "Rename Map: Float register %i being set to %i.\n",
239                (int)arch_reg - numLogicalIntRegs, renamed_reg);
240
241        floatRenameMap[arch_reg].physical_reg = renamed_reg;
242    }
243}
244
245int
246SimpleRenameMap::numFreeEntries()
247{
248    int free_int_regs = freeList->numFreeIntRegs();
249    int free_float_regs = freeList->numFreeFloatRegs();
250
251    if (free_int_regs < free_float_regs) {
252        return free_int_regs;
253    } else {
254        return free_float_regs;
255    }
256}
257