10963f7de488ae2aac73aa0eb31bd36373d1535c
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
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.
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.
31 #include "cpu/o3/rename_map.hh"
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,
42 SimpleRenameMap::SimpleRenameMap(unsigned _numLogicalIntRegs
,
43 unsigned _numPhysicalIntRegs
,
44 unsigned _numLogicalFloatRegs
,
45 unsigned _numPhysicalFloatRegs
,
46 unsigned _numMiscRegs
,
48 RegIndex _floatZeroReg
)
49 : numLogicalIntRegs(_numLogicalIntRegs
),
50 numPhysicalIntRegs(_numPhysicalIntRegs
),
51 numLogicalFloatRegs(_numLogicalFloatRegs
),
52 numPhysicalFloatRegs(_numPhysicalFloatRegs
),
53 numMiscRegs(_numMiscRegs
),
54 intZeroReg(_intZeroReg
),
55 floatZeroReg(_floatZeroReg
)
57 DPRINTF(Rename
, "Rename: Creating rename map. Phys: %i / %i, Float: "
58 "%i / %i.\n", numLogicalIntRegs
, numPhysicalIntRegs
,
59 numLogicalFloatRegs
, numPhysicalFloatRegs
);
61 numLogicalRegs
= numLogicalIntRegs
+ numLogicalFloatRegs
;
63 numPhysicalRegs
= numPhysicalIntRegs
+ numPhysicalFloatRegs
;
65 //Create the rename maps, and their scoreboards.
66 intRenameMap
= new RenameEntry
[numLogicalIntRegs
];
67 floatRenameMap
= new RenameEntry
[numLogicalRegs
];
69 // Should combine this into one scoreboard.
70 intScoreboard
.resize(numPhysicalIntRegs
);
71 floatScoreboard
.resize(numPhysicalRegs
);
72 miscScoreboard
.resize(numPhysicalRegs
+ numMiscRegs
);
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
)
79 intRenameMap
[index
].physical_reg
= index
;
80 intScoreboard
[index
] = 1;
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
;
89 intScoreboard
[index
] = 0;
92 int float_reg_idx
= numPhysicalIntRegs
;
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
)
103 floatRenameMap
[index
].physical_reg
= float_reg_idx
++;
106 for (PhysRegIndex index
= numPhysicalIntRegs
;
107 index
< numPhysicalIntRegs
+ numLogicalFloatRegs
; ++index
)
109 floatScoreboard
[index
] = 1;
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
;
118 floatScoreboard
[index
] = 0;
121 // Initialize the entries in the misc register scoreboard to be ready.
122 for (PhysRegIndex index
= numPhysicalRegs
;
123 index
< numPhysicalRegs
+ numMiscRegs
; ++index
)
125 miscScoreboard
[index
] = 1;
129 SimpleRenameMap::~SimpleRenameMap()
131 // Delete the rename maps as they were allocated with new.
132 delete [] intRenameMap
;
133 delete [] floatRenameMap
;
137 SimpleRenameMap::setFreeList(SimpleFreeList
*fl_ptr
)
139 //Setup the interface to the freelist.
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
147 SimpleRenameMap::RenameInfo
148 SimpleRenameMap::rename(RegIndex arch_reg
)
150 PhysRegIndex renamed_reg
;
151 PhysRegIndex prev_reg
;
153 if (arch_reg
< numLogicalIntRegs
) {
155 // Record the current physical register that is renamed to the
156 // requested architected register.
157 prev_reg
= intRenameMap
[arch_reg
].physical_reg
;
159 // If it's not referencing the zero register, then mark the register
161 if (arch_reg
!= intZeroReg
) {
162 // Get a free physical register to rename to.
163 renamed_reg
= freeList
->getIntReg();
165 // Update the integer rename map.
166 intRenameMap
[arch_reg
].physical_reg
= renamed_reg
;
168 assert(renamed_reg
>= 0 && renamed_reg
< numPhysicalIntRegs
);
170 // Mark register as not ready.
171 intScoreboard
[renamed_reg
] = false;
173 // Otherwise return the zero register so nothing bad happens.
174 renamed_reg
= intZeroReg
;
176 } else if (arch_reg
< numLogicalRegs
) {
177 // Subtract off the base offset for floating point registers.
178 // arch_reg = arch_reg - numLogicalIntRegs;
180 // Record the current physical register that is renamed to the
181 // requested architected register.
182 prev_reg
= floatRenameMap
[arch_reg
].physical_reg
;
184 // If it's not referencing the zero register, then mark the register
186 if (arch_reg
!= floatZeroReg
) {
187 // Get a free floating point register to rename to.
188 renamed_reg
= freeList
->getFloatReg();
190 // Update the floating point rename map.
191 floatRenameMap
[arch_reg
].physical_reg
= renamed_reg
;
193 assert(renamed_reg
< numPhysicalRegs
&&
194 renamed_reg
>= numPhysicalIntRegs
);
196 // Mark register as not ready.
197 floatScoreboard
[renamed_reg
] = false;
199 // Otherwise return the zero register so nothing bad happens.
200 renamed_reg
= floatZeroReg
;
203 // Subtract off the base offset for miscellaneous registers.
204 arch_reg
= arch_reg
- numLogicalRegs
;
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
210 renamed_reg
= arch_reg
+ numPhysicalRegs
;
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
;
217 assert(renamed_reg
< numPhysicalRegs
+ numMiscRegs
);
219 miscScoreboard
[renamed_reg
] = false;
222 return RenameInfo(renamed_reg
, prev_reg
);
225 //Perhaps give this a pair as a return value, of the physical register
226 //and whether or not it's ready.
228 SimpleRenameMap::lookup(RegIndex arch_reg
)
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;
236 return floatRenameMap
[arch_reg
].physical_reg
;
238 // Subtract off the misc registers offset.
239 arch_reg
= arch_reg
- numLogicalRegs
;
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
;
248 SimpleRenameMap::isReady(PhysRegIndex phys_reg
)
250 if (phys_reg
< numPhysicalIntRegs
) {
251 return intScoreboard
[phys_reg
];
252 } else if (phys_reg
< numPhysicalRegs
) {
254 // Subtract off the base FP offset.
255 // phys_reg = phys_reg - numPhysicalIntRegs;
257 return floatScoreboard
[phys_reg
];
259 // Subtract off the misc registers offset.
260 // phys_reg = phys_reg - numPhysicalRegs;
262 return miscScoreboard
[phys_reg
];
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.
269 SimpleRenameMap::setEntry(RegIndex arch_reg
, PhysRegIndex renamed_reg
)
271 if (arch_reg
< numLogicalIntRegs
) {
272 DPRINTF(Rename
, "Rename Map: Integer register %i being set to %i.\n",
273 (int)arch_reg
, renamed_reg
);
275 intRenameMap
[arch_reg
].physical_reg
= renamed_reg
;
277 assert(arch_reg
< (numLogicalIntRegs
+ numLogicalFloatRegs
));
279 DPRINTF(Rename
, "Rename Map: Float register %i being set to %i.\n",
280 (int)arch_reg
- numLogicalIntRegs
, renamed_reg
);
282 floatRenameMap
[arch_reg
].physical_reg
= renamed_reg
;
287 SimpleRenameMap::squash(vector
<RegIndex
> freed_regs
,
288 vector
<UnmapInfo
> unmaps
)
290 panic("Not sure this function should be called.");
292 // Not sure the rename map should be able to access the free list
294 while (!freed_regs
.empty()) {
295 RegIndex free_register
= freed_regs
.back();
297 if (free_register
< numPhysicalIntRegs
) {
298 freeList
->addIntReg(free_register
);
300 // Subtract off the base FP dependence tag.
301 free_register
= free_register
- numPhysicalIntRegs
;
302 freeList
->addFloatReg(free_register
);
305 freed_regs
.pop_back();
308 // Take unmap info and roll back the rename map.
312 SimpleRenameMap::markAsReady(PhysRegIndex ready_reg
)
314 DPRINTF(Rename
, "Rename map: Marking register %i as ready.\n",
317 if (ready_reg
< numPhysicalIntRegs
) {
318 assert(ready_reg
>= 0);
320 intScoreboard
[ready_reg
] = 1;
321 } else if (ready_reg
< numPhysicalRegs
) {
323 // Subtract off the base FP offset.
324 // ready_reg = ready_reg - numPhysicalIntRegs;
326 floatScoreboard
[ready_reg
] = 1;
328 //Subtract off the misc registers offset.
329 // ready_reg = ready_reg - numPhysicalRegs;
331 miscScoreboard
[ready_reg
] = 1;
336 SimpleRenameMap::numFreeEntries()
338 int free_int_regs
= freeList
->numFreeIntRegs();
339 int free_float_regs
= freeList
->numFreeFloatRegs();
341 if (free_int_regs
< free_float_regs
) {
342 return free_int_regs
;
344 return free_float_regs
;