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