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"
37 // @todo: Consider making inline bool functions that determine if the
38 // register is a logical int, logical fp, physical int, physical fp,
41 SimpleRenameMap::~SimpleRenameMap()
46 SimpleRenameMap::init(unsigned _numLogicalIntRegs
,
47 unsigned _numPhysicalIntRegs
,
48 PhysRegIndex
&ireg_idx
,
50 unsigned _numLogicalFloatRegs
,
51 unsigned _numPhysicalFloatRegs
,
52 PhysRegIndex
&freg_idx
,
54 unsigned _numMiscRegs
,
57 RegIndex _floatZeroReg
,
64 numLogicalIntRegs
= _numLogicalIntRegs
;
66 numLogicalFloatRegs
= _numLogicalFloatRegs
;
68 numPhysicalIntRegs
= _numPhysicalIntRegs
;
70 numPhysicalFloatRegs
= _numPhysicalFloatRegs
;
72 numMiscRegs
= _numMiscRegs
;
74 intZeroReg
= _intZeroReg
;
75 floatZeroReg
= _floatZeroReg
;
77 DPRINTF(Rename
, "Creating rename map %i. Phys: %i / %i, Float: "
78 "%i / %i.\n", id
, numLogicalIntRegs
, numPhysicalIntRegs
,
79 numLogicalFloatRegs
, numPhysicalFloatRegs
);
81 numLogicalRegs
= numLogicalIntRegs
+ numLogicalFloatRegs
;
83 numPhysicalRegs
= numPhysicalIntRegs
+ numPhysicalFloatRegs
;
85 //Create the rename maps
86 intRenameMap
.resize(numLogicalIntRegs
);
87 floatRenameMap
.resize(numLogicalRegs
);
90 DPRINTF(Rename
, "Binding registers into rename map %i",id
);
92 // Initialize the entries in the integer rename map to point to the
93 // physical registers of the same index
94 for (RegIndex index
= 0; index
< numLogicalIntRegs
; ++index
)
96 intRenameMap
[index
].physical_reg
= ireg_idx
++;
99 // Initialize the entries in the floating point rename map to point to
100 // the physical registers of the same index
101 // Although the index refers purely to architected registers, because
102 // the floating reg indices come after the integer reg indices, they
103 // may exceed the size of a normal RegIndex (short).
104 for (PhysRegIndex index
= numLogicalIntRegs
;
105 index
< numLogicalRegs
; ++index
)
107 floatRenameMap
[index
].physical_reg
= freg_idx
++;
110 DPRINTF(Rename
, "Binding registers into rename map %i",id
);
112 PhysRegIndex temp_ireg
= ireg_idx
;
114 for (RegIndex index
= 0; index
< numLogicalIntRegs
; ++index
)
116 intRenameMap
[index
].physical_reg
= temp_ireg
++;
119 PhysRegIndex temp_freg
= freg_idx
;
121 for (PhysRegIndex index
= numLogicalIntRegs
;
122 index
< numLogicalRegs
; ++index
)
124 floatRenameMap
[index
].physical_reg
= temp_freg
++;
130 SimpleRenameMap::setFreeList(SimpleFreeList
*fl_ptr
)
136 SimpleRenameMap::RenameInfo
137 SimpleRenameMap::rename(RegIndex arch_reg
)
139 PhysRegIndex renamed_reg
;
140 PhysRegIndex prev_reg
;
142 if (arch_reg
< numLogicalIntRegs
) {
144 // Record the current physical register that is renamed to the
145 // requested architected register.
146 prev_reg
= intRenameMap
[arch_reg
].physical_reg
;
148 // If it's not referencing the zero register, then rename the
150 if (arch_reg
!= intZeroReg
) {
151 renamed_reg
= freeList
->getIntReg();
153 intRenameMap
[arch_reg
].physical_reg
= renamed_reg
;
155 assert(renamed_reg
>= 0 && renamed_reg
< numPhysicalIntRegs
);
158 // Otherwise return the zero register so nothing bad happens.
159 renamed_reg
= intZeroReg
;
161 } else if (arch_reg
< numLogicalRegs
) {
162 // Record the current physical register that is renamed to the
163 // requested architected register.
164 prev_reg
= floatRenameMap
[arch_reg
].physical_reg
;
166 // If it's not referencing the zero register, then rename the
168 #if THE_ISA == ALPHA_ISA
169 if (arch_reg
!= floatZeroReg
) {
171 renamed_reg
= freeList
->getFloatReg();
173 floatRenameMap
[arch_reg
].physical_reg
= renamed_reg
;
175 assert(renamed_reg
< numPhysicalRegs
&&
176 renamed_reg
>= numPhysicalIntRegs
);
177 #if THE_ISA == ALPHA_ISA
179 // Otherwise return the zero register so nothing bad happens.
180 renamed_reg
= floatZeroReg
;
184 // Subtract off the base offset for miscellaneous registers.
185 arch_reg
= arch_reg
- numLogicalRegs
;
187 DPRINTF(Rename
, "Renamed misc reg %d\n", arch_reg
);
189 // No renaming happens to the misc. registers. They are
190 // simply the registers that come after all the physical
191 // registers; thus take the base architected register and add
192 // the physical registers to it.
193 renamed_reg
= arch_reg
+ numPhysicalRegs
;
195 // Set the previous register to the same register; mainly it must be
196 // known that the prev reg was outside the range of normal registers
197 // so the free list can avoid adding it.
198 prev_reg
= renamed_reg
;
201 DPRINTF(Rename
, "Renamed reg %d to physical reg %d old mapping was %d\n",
202 arch_reg
, renamed_reg
, prev_reg
);
204 return RenameInfo(renamed_reg
, prev_reg
);
208 SimpleRenameMap::lookup(RegIndex arch_reg
)
210 if (arch_reg
< numLogicalIntRegs
) {
211 return intRenameMap
[arch_reg
].physical_reg
;
212 } else if (arch_reg
< numLogicalRegs
) {
213 return floatRenameMap
[arch_reg
].physical_reg
;
215 // Subtract off the misc registers offset.
216 arch_reg
= arch_reg
- numLogicalRegs
;
218 // Misc. regs don't rename, so simply add the base arch reg to
219 // the number of physical registers.
220 return numPhysicalRegs
+ arch_reg
;
225 SimpleRenameMap::setEntry(RegIndex arch_reg
, PhysRegIndex renamed_reg
)
227 // In this implementation the miscellaneous registers do not
228 // actually rename, so this function does not allow you to try to
229 // change their mappings.
230 if (arch_reg
< numLogicalIntRegs
) {
231 DPRINTF(Rename
, "Rename Map: Integer register %i being set to %i.\n",
232 (int)arch_reg
, renamed_reg
);
234 intRenameMap
[arch_reg
].physical_reg
= renamed_reg
;
235 } else if (arch_reg
< numLogicalIntRegs
+ numLogicalFloatRegs
) {
236 DPRINTF(Rename
, "Rename Map: Float register %i being set to %i.\n",
237 (int)arch_reg
- numLogicalIntRegs
, renamed_reg
);
239 floatRenameMap
[arch_reg
].physical_reg
= renamed_reg
;
244 SimpleRenameMap::numFreeEntries()
246 int free_int_regs
= freeList
->numFreeIntRegs();
247 int free_float_regs
= freeList
->numFreeFloatRegs();
249 if (free_int_regs
< free_float_regs
) {
250 return free_int_regs
;
252 return free_float_regs
;