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.
42 #include "cpu/o3/regfile.hh"
44 #include "cpu/o3/free_list.hh"
45 #include "arch/generic/types.hh"
46 #include "cpu/o3/free_list.hh"
48 PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs
,
49 unsigned _numPhysicalFloatRegs
,
50 unsigned _numPhysicalVecRegs
,
51 unsigned _numPhysicalVecPredRegs
,
52 unsigned _numPhysicalCCRegs
,
54 : intRegFile(_numPhysicalIntRegs
),
55 floatRegFile(_numPhysicalFloatRegs
),
56 vectorRegFile(_numPhysicalVecRegs
),
57 vecPredRegFile(_numPhysicalVecPredRegs
),
58 ccRegFile(_numPhysicalCCRegs
),
59 numPhysicalIntRegs(_numPhysicalIntRegs
),
60 numPhysicalFloatRegs(_numPhysicalFloatRegs
),
61 numPhysicalVecRegs(_numPhysicalVecRegs
),
62 numPhysicalVecElemRegs(_numPhysicalVecRegs
*
64 numPhysicalVecPredRegs(_numPhysicalVecPredRegs
),
65 numPhysicalCCRegs(_numPhysicalCCRegs
),
66 totalNumRegs(_numPhysicalIntRegs
67 + _numPhysicalFloatRegs
69 + _numPhysicalVecRegs
* NumVecElemPerVecReg
70 + _numPhysicalVecPredRegs
71 + _numPhysicalCCRegs
),
74 PhysRegIndex phys_reg
;
75 PhysRegIndex flat_reg_idx
= 0;
77 if (TheISA::NumCCRegs
== 0 && _numPhysicalCCRegs
!= 0) {
78 // Just make this a warning and go ahead and allocate them
79 // anyway, to keep from having to add checks everywhere
80 warn("Non-zero number of physical CC regs specified, even though\n"
81 " ISA does not use them.\n");
83 // The initial batch of registers are the integer ones
84 for (phys_reg
= 0; phys_reg
< numPhysicalIntRegs
; phys_reg
++) {
85 intRegIds
.emplace_back(IntRegClass
, phys_reg
, flat_reg_idx
++);
88 // The next batch of the registers are the floating-point physical
89 // registers; put them onto the floating-point free list.
90 for (phys_reg
= 0; phys_reg
< numPhysicalFloatRegs
; phys_reg
++) {
91 floatRegIds
.emplace_back(FloatRegClass
, phys_reg
, flat_reg_idx
++);
94 // The next batch of the registers are the vector physical
95 // registers; put them onto the vector free list.
96 for (phys_reg
= 0; phys_reg
< numPhysicalVecRegs
; phys_reg
++) {
97 vectorRegFile
[phys_reg
].zero();
98 vecRegIds
.emplace_back(VecRegClass
, phys_reg
, flat_reg_idx
++);
100 // The next batch of the registers are the vector element physical
101 // registers; they refer to the same containers as the vector
102 // registers, just a different (and incompatible) way to access
103 // them; put them onto the vector free list.
104 for (phys_reg
= 0; phys_reg
< numPhysicalVecRegs
; phys_reg
++) {
105 for (ElemIndex eIdx
= 0; eIdx
< NumVecElemPerVecReg
; eIdx
++) {
106 vecElemIds
.emplace_back(VecElemClass
, phys_reg
,
107 eIdx
, flat_reg_idx
++);
111 // The next batch of the registers are the predicate physical
112 // registers; put them onto the predicate free list.
113 for (phys_reg
= 0; phys_reg
< numPhysicalVecPredRegs
; phys_reg
++) {
114 vecPredRegIds
.emplace_back(VecPredRegClass
, phys_reg
, flat_reg_idx
++);
117 // The rest of the registers are the condition-code physical
118 // registers; put them onto the condition-code free list.
119 for (phys_reg
= 0; phys_reg
< numPhysicalCCRegs
; phys_reg
++) {
120 ccRegIds
.emplace_back(CCRegClass
, phys_reg
, flat_reg_idx
++);
123 // Misc regs have a fixed mapping but still need PhysRegIds.
124 for (phys_reg
= 0; phys_reg
< TheISA::NumMiscRegs
; phys_reg
++) {
125 miscRegIds
.emplace_back(MiscRegClass
, phys_reg
, 0);
131 PhysRegFile::initFreeList(UnifiedFreeList
*freeList
)
133 // Initialize the free lists.
136 // The initial batch of registers are the integer ones
137 for (reg_idx
= 0; reg_idx
< numPhysicalIntRegs
; reg_idx
++) {
138 assert(intRegIds
[reg_idx
].index() == reg_idx
);
140 freeList
->addRegs(intRegIds
.begin(), intRegIds
.end());
142 // The next batch of the registers are the floating-point physical
143 // registers; put them onto the floating-point free list.
144 for (reg_idx
= 0; reg_idx
< numPhysicalFloatRegs
; reg_idx
++) {
145 assert(floatRegIds
[reg_idx
].index() == reg_idx
);
147 freeList
->addRegs(floatRegIds
.begin(), floatRegIds
.end());
149 /* The next batch of the registers are the vector physical
150 * registers; put them onto the vector free list. */
151 for (reg_idx
= 0; reg_idx
< numPhysicalVecRegs
; reg_idx
++) {
152 assert(vecRegIds
[reg_idx
].index() == reg_idx
);
153 for (ElemIndex elemIdx
= 0; elemIdx
< NumVecElemPerVecReg
; elemIdx
++) {
154 assert(vecElemIds
[reg_idx
* NumVecElemPerVecReg
+
155 elemIdx
].index() == reg_idx
);
156 assert(vecElemIds
[reg_idx
* NumVecElemPerVecReg
+
157 elemIdx
].elemIndex() == elemIdx
);
161 /* depending on the mode we add the vector registers as whole units or
162 * as different elements. */
163 if (vecMode
== Enums::Full
)
164 freeList
->addRegs(vecRegIds
.begin(), vecRegIds
.end());
166 freeList
->addRegs(vecElemIds
.begin(), vecElemIds
.end());
168 // The next batch of the registers are the predicate physical
169 // registers; put them onto the predicate free list.
170 for (reg_idx
= 0; reg_idx
< numPhysicalVecPredRegs
; reg_idx
++) {
171 assert(vecPredRegIds
[reg_idx
].index() == reg_idx
);
173 freeList
->addRegs(vecPredRegIds
.begin(), vecPredRegIds
.end());
175 // The rest of the registers are the condition-code physical
176 // registers; put them onto the condition-code free list.
177 for (reg_idx
= 0; reg_idx
< numPhysicalCCRegs
; reg_idx
++) {
178 assert(ccRegIds
[reg_idx
].index() == reg_idx
);
180 freeList
->addRegs(ccRegIds
.begin(), ccRegIds
.end());
184 PhysRegFile::getRegElemIds(PhysRegIdPtr reg
) -> IdRange
186 panic_if(!reg
->isVectorPhysReg(),
187 "Trying to get elems of a %s register", reg
->className());
188 auto idx
= reg
->index();
189 return std::make_pair(
190 vecElemIds
.begin() + idx
* NumVecElemPerVecReg
,
191 vecElemIds
.begin() + (idx
+1) * NumVecElemPerVecReg
);
195 PhysRegFile::getRegIds(RegClass cls
) -> IdRange
200 return std::make_pair(intRegIds
.begin(), intRegIds
.end());
202 return std::make_pair(floatRegIds
.begin(), floatRegIds
.end());
204 return std::make_pair(vecRegIds
.begin(), vecRegIds
.end());
206 return std::make_pair(vecElemIds
.begin(), vecElemIds
.end());
207 case VecPredRegClass
:
208 return std::make_pair(vecPredRegIds
.begin(), vecPredRegIds
.end());
210 return std::make_pair(ccRegIds
.begin(), ccRegIds
.end());
212 return std::make_pair(miscRegIds
.begin(), miscRegIds
.end());
214 /* There is no way to make an empty iterator */
215 return std::make_pair(PhysIds::iterator(),
216 PhysIds::iterator());
220 PhysRegFile::getTrueId(PhysRegIdPtr reg
)
222 switch (reg
->classValue()) {
224 return &vecRegIds
[reg
->index()];
226 return &vecElemIds
[reg
->index() * NumVecElemPerVecReg
+
229 panic_if(!reg
->isVectorPhysElem(),
230 "Trying to get the register of a %s register", reg
->className());