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