2 * Copyright (c) 2016-2018 ARM Limited
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
14 * Copyright (c) 2004-2005 The Regents of The University of Michigan
15 * Copyright (c) 2013 Advanced Micro Devices, Inc.
16 * All rights reserved.
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46 #include "cpu/o3/regfile.hh"
48 #include "cpu/o3/free_list.hh"
49 #include "arch/generic/types.hh"
50 #include "cpu/o3/free_list.hh"
52 PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs
,
53 unsigned _numPhysicalFloatRegs
,
54 unsigned _numPhysicalVecRegs
,
55 unsigned _numPhysicalVecPredRegs
,
56 unsigned _numPhysicalCCRegs
,
58 : intRegFile(_numPhysicalIntRegs
),
59 floatRegFile(_numPhysicalFloatRegs
),
60 vectorRegFile(_numPhysicalVecRegs
),
61 vecPredRegFile(_numPhysicalVecPredRegs
),
62 ccRegFile(_numPhysicalCCRegs
),
63 numPhysicalIntRegs(_numPhysicalIntRegs
),
64 numPhysicalFloatRegs(_numPhysicalFloatRegs
),
65 numPhysicalVecRegs(_numPhysicalVecRegs
),
66 numPhysicalVecElemRegs(_numPhysicalVecRegs
*
68 numPhysicalVecPredRegs(_numPhysicalVecPredRegs
),
69 numPhysicalCCRegs(_numPhysicalCCRegs
),
70 totalNumRegs(_numPhysicalIntRegs
71 + _numPhysicalFloatRegs
73 + _numPhysicalVecRegs
* NumVecElemPerVecReg
74 + _numPhysicalVecPredRegs
75 + _numPhysicalCCRegs
),
78 PhysRegIndex phys_reg
;
79 PhysRegIndex flat_reg_idx
= 0;
81 if (TheISA::NumCCRegs
== 0 && _numPhysicalCCRegs
!= 0) {
82 // Just make this a warning and go ahead and allocate them
83 // anyway, to keep from having to add checks everywhere
84 warn("Non-zero number of physical CC regs specified, even though\n"
85 " ISA does not use them.\n");
87 // The initial batch of registers are the integer ones
88 for (phys_reg
= 0; phys_reg
< numPhysicalIntRegs
; phys_reg
++) {
89 intRegIds
.emplace_back(IntRegClass
, phys_reg
, flat_reg_idx
++);
92 // The next batch of the registers are the floating-point physical
93 // registers; put them onto the floating-point free list.
94 for (phys_reg
= 0; phys_reg
< numPhysicalFloatRegs
; phys_reg
++) {
95 floatRegIds
.emplace_back(FloatRegClass
, phys_reg
, flat_reg_idx
++);
98 // The next batch of the registers are the vector physical
99 // registers; put them onto the vector free list.
100 for (phys_reg
= 0; phys_reg
< numPhysicalVecRegs
; phys_reg
++) {
101 vectorRegFile
[phys_reg
].zero();
102 vecRegIds
.emplace_back(VecRegClass
, phys_reg
, flat_reg_idx
++);
104 // The next batch of the registers are the vector element physical
105 // registers; they refer to the same containers as the vector
106 // registers, just a different (and incompatible) way to access
107 // them; put them onto the vector free list.
108 for (phys_reg
= 0; phys_reg
< numPhysicalVecRegs
; phys_reg
++) {
109 for (ElemIndex eIdx
= 0; eIdx
< NumVecElemPerVecReg
; eIdx
++) {
110 vecElemIds
.emplace_back(VecElemClass
, phys_reg
,
111 eIdx
, flat_reg_idx
++);
115 // The next batch of the registers are the predicate physical
116 // registers; put them onto the predicate free list.
117 for (phys_reg
= 0; phys_reg
< numPhysicalVecPredRegs
; phys_reg
++) {
118 vecPredRegIds
.emplace_back(VecPredRegClass
, phys_reg
, flat_reg_idx
++);
121 // The rest of the registers are the condition-code physical
122 // registers; put them onto the condition-code free list.
123 for (phys_reg
= 0; phys_reg
< numPhysicalCCRegs
; phys_reg
++) {
124 ccRegIds
.emplace_back(CCRegClass
, phys_reg
, flat_reg_idx
++);
127 // Misc regs have a fixed mapping but still need PhysRegIds.
128 for (phys_reg
= 0; phys_reg
< TheISA::NumMiscRegs
; phys_reg
++) {
129 miscRegIds
.emplace_back(MiscRegClass
, phys_reg
, 0);
135 PhysRegFile::initFreeList(UnifiedFreeList
*freeList
)
137 // Initialize the free lists.
140 // The initial batch of registers are the integer ones
141 for (reg_idx
= 0; reg_idx
< numPhysicalIntRegs
; reg_idx
++) {
142 assert(intRegIds
[reg_idx
].index() == reg_idx
);
144 freeList
->addRegs(intRegIds
.begin(), intRegIds
.end());
146 // The next batch of the registers are the floating-point physical
147 // registers; put them onto the floating-point free list.
148 for (reg_idx
= 0; reg_idx
< numPhysicalFloatRegs
; reg_idx
++) {
149 assert(floatRegIds
[reg_idx
].index() == reg_idx
);
151 freeList
->addRegs(floatRegIds
.begin(), floatRegIds
.end());
153 /* The next batch of the registers are the vector physical
154 * registers; put them onto the vector free list. */
155 for (reg_idx
= 0; reg_idx
< numPhysicalVecRegs
; reg_idx
++) {
156 assert(vecRegIds
[reg_idx
].index() == reg_idx
);
157 for (ElemIndex elemIdx
= 0; elemIdx
< NumVecElemPerVecReg
; elemIdx
++) {
158 assert(vecElemIds
[reg_idx
* NumVecElemPerVecReg
+
159 elemIdx
].index() == reg_idx
);
160 assert(vecElemIds
[reg_idx
* NumVecElemPerVecReg
+
161 elemIdx
].elemIndex() == elemIdx
);
165 /* depending on the mode we add the vector registers as whole units or
166 * as different elements. */
167 if (vecMode
== Enums::Full
)
168 freeList
->addRegs(vecRegIds
.begin(), vecRegIds
.end());
170 freeList
->addRegs(vecElemIds
.begin(), vecElemIds
.end());
172 // The next batch of the registers are the predicate physical
173 // registers; put them onto the predicate free list.
174 for (reg_idx
= 0; reg_idx
< numPhysicalVecPredRegs
; reg_idx
++) {
175 assert(vecPredRegIds
[reg_idx
].index() == reg_idx
);
177 freeList
->addRegs(vecPredRegIds
.begin(), vecPredRegIds
.end());
179 // The rest of the registers are the condition-code physical
180 // registers; put them onto the condition-code free list.
181 for (reg_idx
= 0; reg_idx
< numPhysicalCCRegs
; reg_idx
++) {
182 assert(ccRegIds
[reg_idx
].index() == reg_idx
);
184 freeList
->addRegs(ccRegIds
.begin(), ccRegIds
.end());
188 PhysRegFile::getRegElemIds(PhysRegIdPtr reg
) -> IdRange
190 panic_if(!reg
->isVectorPhysReg(),
191 "Trying to get elems of a %s register", reg
->className());
192 auto idx
= reg
->index();
193 return std::make_pair(
194 vecElemIds
.begin() + idx
* NumVecElemPerVecReg
,
195 vecElemIds
.begin() + (idx
+1) * NumVecElemPerVecReg
);
199 PhysRegFile::getRegIds(RegClass cls
) -> IdRange
204 return std::make_pair(intRegIds
.begin(), intRegIds
.end());
206 return std::make_pair(floatRegIds
.begin(), floatRegIds
.end());
208 return std::make_pair(vecRegIds
.begin(), vecRegIds
.end());
210 return std::make_pair(vecElemIds
.begin(), vecElemIds
.end());
211 case VecPredRegClass
:
212 return std::make_pair(vecPredRegIds
.begin(), vecPredRegIds
.end());
214 return std::make_pair(ccRegIds
.begin(), ccRegIds
.end());
216 return std::make_pair(miscRegIds
.begin(), miscRegIds
.end());
218 /* There is no way to make an empty iterator */
219 return std::make_pair(PhysIds::iterator(),
220 PhysIds::iterator());
224 PhysRegFile::getTrueId(PhysRegIdPtr reg
)
226 switch (reg
->classValue()) {
228 return &vecRegIds
[reg
->index()];
230 return &vecElemIds
[reg
->index() * NumVecElemPerVecReg
+
233 panic_if(!reg
->isVectorPhysElem(),
234 "Trying to get the register of a %s register", reg
->className());