Deleted Added
sdiff udiff text old ( 2632:1bb2f91485ea ) new ( 2654:9559cfa91b9d )
full compact
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;

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

27 */
28
29#include <vector>
30
31#include "cpu/o3/rename_map.hh"
32
33using 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
42SimpleRenameMap::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
129SimpleRenameMap::~SimpleRenameMap()
130{
131 // Delete the rename maps as they were allocated with new.
132 delete [] intRenameMap;
133 delete [] floatRenameMap;
134}
135
136void
137SimpleRenameMap::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.
147SimpleRenameMap::RenameInfo
148SimpleRenameMap::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.
227PhysRegIndex
228SimpleRenameMap::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
247bool
248SimpleRenameMap::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.
268void
269SimpleRenameMap::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
286void
287SimpleRenameMap::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
311void
312SimpleRenameMap::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
335int
336SimpleRenameMap::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}