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