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