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.
33 #include "cpu/o3/rename_map.hh"
34 #include "debug/Rename.hh"
38 // @todo: Consider making inline bool functions that determine if the
39 // register is a logical int, logical fp, physical int, physical fp,
42 SimpleRenameMap::~SimpleRenameMap()
47 SimpleRenameMap::init(unsigned _numLogicalIntRegs
,
48 unsigned _numPhysicalIntRegs
,
49 PhysRegIndex
&ireg_idx
,
51 unsigned _numLogicalFloatRegs
,
52 unsigned _numPhysicalFloatRegs
,
53 PhysRegIndex
&freg_idx
,
55 unsigned _numMiscRegs
,
58 RegIndex _floatZeroReg
,
65 numLogicalIntRegs
= _numLogicalIntRegs
;
67 numLogicalFloatRegs
= _numLogicalFloatRegs
;
69 numPhysicalIntRegs
= _numPhysicalIntRegs
;
71 numPhysicalFloatRegs
= _numPhysicalFloatRegs
;
73 numMiscRegs
= _numMiscRegs
;
75 intZeroReg
= _intZeroReg
;
76 floatZeroReg
= _floatZeroReg
;
78 DPRINTF(Rename
, "Creating rename map %i. Phys: %i / %i, Float: "
79 "%i / %i.\n", id
, numLogicalIntRegs
, numPhysicalIntRegs
,
80 numLogicalFloatRegs
, numPhysicalFloatRegs
);
82 numLogicalRegs
= numLogicalIntRegs
+ numLogicalFloatRegs
;
84 numPhysicalRegs
= numPhysicalIntRegs
+ numPhysicalFloatRegs
;
86 //Create the rename maps
87 intRenameMap
.resize(numLogicalIntRegs
);
88 floatRenameMap
.resize(numLogicalRegs
);
91 DPRINTF(Rename
, "Binding registers into rename map %i\n",id
);
93 // Initialize the entries in the integer rename map to point to the
94 // physical registers of the same index
95 for (RegIndex index
= 0; index
< numLogicalIntRegs
; ++index
)
97 intRenameMap
[index
].physical_reg
= ireg_idx
++;
100 // Initialize the entries in the floating point rename map to point to
101 // the physical registers of the same index
102 // Although the index refers purely to architected registers, because
103 // the floating reg indices come after the integer reg indices, they
104 // may exceed the size of a normal RegIndex (short).
105 for (PhysRegIndex index
= numLogicalIntRegs
;
106 index
< numLogicalRegs
; ++index
)
108 floatRenameMap
[index
].physical_reg
= freg_idx
++;
111 DPRINTF(Rename
, "Binding registers into rename map %i\n",id
);
113 PhysRegIndex temp_ireg
= ireg_idx
;
115 for (RegIndex index
= 0; index
< numLogicalIntRegs
; ++index
)
117 intRenameMap
[index
].physical_reg
= temp_ireg
++;
120 PhysRegIndex temp_freg
= freg_idx
;
122 for (PhysRegIndex index
= numLogicalIntRegs
;
123 index
< numLogicalRegs
; ++index
)
125 floatRenameMap
[index
].physical_reg
= temp_freg
++;
131 SimpleRenameMap::setFreeList(SimpleFreeList
*fl_ptr
)
137 SimpleRenameMap::RenameInfo
138 SimpleRenameMap::rename(RegIndex arch_reg
)
140 PhysRegIndex renamed_reg
;
141 PhysRegIndex prev_reg
;
143 if (arch_reg
< numLogicalIntRegs
) {
145 // Record the current physical register that is renamed to the
146 // requested architected register.
147 prev_reg
= intRenameMap
[arch_reg
].physical_reg
;
149 // If it's not referencing the zero register, then rename the
151 if (arch_reg
!= intZeroReg
) {
152 renamed_reg
= freeList
->getIntReg();
154 intRenameMap
[arch_reg
].physical_reg
= renamed_reg
;
156 assert(renamed_reg
>= 0 && renamed_reg
< numPhysicalIntRegs
);
159 // Otherwise return the zero register so nothing bad happens.
160 renamed_reg
= intZeroReg
;
162 } else if (arch_reg
< numLogicalRegs
) {
163 // Record the current physical register that is renamed to the
164 // requested architected register.
165 prev_reg
= floatRenameMap
[arch_reg
].physical_reg
;
167 // If it's not referencing the zero register, then rename the
169 #if THE_ISA == ALPHA_ISA
170 if (arch_reg
!= floatZeroReg
) {
172 renamed_reg
= freeList
->getFloatReg();
174 floatRenameMap
[arch_reg
].physical_reg
= renamed_reg
;
176 assert(renamed_reg
< numPhysicalRegs
&&
177 renamed_reg
>= numPhysicalIntRegs
);
178 #if THE_ISA == ALPHA_ISA
180 // Otherwise return the zero register so nothing bad happens.
181 renamed_reg
= floatZeroReg
;
185 // Subtract off the base offset for miscellaneous registers.
186 arch_reg
= arch_reg
- numLogicalRegs
;
188 DPRINTF(Rename
, "Renamed misc reg %d\n", arch_reg
);
190 // No renaming happens to the misc. registers. They are
191 // simply the registers that come after all the physical
192 // registers; thus take the base architected register and add
193 // the physical registers to it.
194 renamed_reg
= arch_reg
+ numPhysicalRegs
;
196 // Set the previous register to the same register; mainly it must be
197 // known that the prev reg was outside the range of normal registers
198 // so the free list can avoid adding it.
199 prev_reg
= renamed_reg
;
202 DPRINTF(Rename
, "Renamed reg %d to physical reg %d old mapping was %d\n",
203 arch_reg
, renamed_reg
, prev_reg
);
205 return RenameInfo(renamed_reg
, prev_reg
);
209 SimpleRenameMap::lookup(RegIndex arch_reg
)
211 if (arch_reg
< numLogicalIntRegs
) {
212 return intRenameMap
[arch_reg
].physical_reg
;
213 } else if (arch_reg
< numLogicalRegs
) {
214 return floatRenameMap
[arch_reg
].physical_reg
;
216 // Subtract off the misc registers offset.
217 arch_reg
= arch_reg
- numLogicalRegs
;
219 // Misc. regs don't rename, so simply add the base arch reg to
220 // the number of physical registers.
221 return numPhysicalRegs
+ arch_reg
;
226 SimpleRenameMap::setEntry(RegIndex arch_reg
, PhysRegIndex renamed_reg
)
228 // In this implementation the miscellaneous registers do not
229 // actually rename, so this function does not allow you to try to
230 // change their mappings.
231 if (arch_reg
< numLogicalIntRegs
) {
232 DPRINTF(Rename
, "Rename Map: Integer register %i being set to %i.\n",
233 (int)arch_reg
, renamed_reg
);
235 intRenameMap
[arch_reg
].physical_reg
= renamed_reg
;
236 } else if (arch_reg
< numLogicalIntRegs
+ numLogicalFloatRegs
) {
237 DPRINTF(Rename
, "Rename Map: Float register %i being set to %i.\n",
238 (int)arch_reg
- numLogicalIntRegs
, renamed_reg
);
240 floatRenameMap
[arch_reg
].physical_reg
= renamed_reg
;
245 SimpleRenameMap::numFreeEntries()
247 int free_int_regs
= freeList
->numFreeIntRegs();
248 int free_float_regs
= freeList
->numFreeFloatRegs();
250 if (free_int_regs
< free_float_regs
) {
251 return free_int_regs
;
253 return free_float_regs
;