rename_map.cc (2654:9559cfa91b9d) rename_map.cc (2665:a124942bacb8)
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;

--- 10 unchanged lines hidden (view full) ---

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.
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;

--- 10 unchanged lines hidden (view full) ---

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