de9cd5ecbfdfdaf02243029f9ec2408a4c9e3a29
[gem5.git] / src / cpu / o3 / regfile.cc
1 /*
2 * Copyright (c) 2016-2018 ARM Limited
3 * All rights reserved
4 *
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.
13 *
14 * Copyright (c) 2004-2005 The Regents of The University of Michigan
15 * Copyright (c) 2013 Advanced Micro Devices, Inc.
16 * All rights reserved.
17 *
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.
28 *
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.
40 */
41
42 #include "cpu/o3/regfile.hh"
43
44 #include "cpu/o3/free_list.hh"
45 #include "arch/generic/types.hh"
46 #include "cpu/o3/free_list.hh"
47
48 PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs,
49 unsigned _numPhysicalFloatRegs,
50 unsigned _numPhysicalVecRegs,
51 unsigned _numPhysicalVecPredRegs,
52 unsigned _numPhysicalCCRegs,
53 VecMode vmode)
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 *
63 NumVecElemPerVecReg),
64 numPhysicalVecPredRegs(_numPhysicalVecPredRegs),
65 numPhysicalCCRegs(_numPhysicalCCRegs),
66 totalNumRegs(_numPhysicalIntRegs
67 + _numPhysicalFloatRegs
68 + _numPhysicalVecRegs
69 + _numPhysicalVecRegs * NumVecElemPerVecReg
70 + _numPhysicalVecPredRegs
71 + _numPhysicalCCRegs),
72 vecMode(vmode)
73 {
74 PhysRegIndex phys_reg;
75 PhysRegIndex flat_reg_idx = 0;
76
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");
82 }
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++);
86 }
87
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++);
92 }
93
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++);
99 }
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++);
108 }
109 }
110
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++);
115 }
116
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++);
121 }
122
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);
126 }
127 }
128
129
130 void
131 PhysRegFile::initFreeList(UnifiedFreeList *freeList)
132 {
133 // Initialize the free lists.
134 int reg_idx = 0;
135
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);
139 }
140 freeList->addRegs(intRegIds.begin(), intRegIds.end());
141
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);
146 }
147 freeList->addRegs(floatRegIds.begin(), floatRegIds.end());
148
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);
158 }
159 }
160
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());
165 else
166 freeList->addRegs(vecElemIds.begin(), vecElemIds.end());
167
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);
172 }
173 freeList->addRegs(vecPredRegIds.begin(), vecPredRegIds.end());
174
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);
179 }
180 freeList->addRegs(ccRegIds.begin(), ccRegIds.end());
181 }
182
183 auto
184 PhysRegFile::getRegElemIds(PhysRegIdPtr reg) -> IdRange
185 {
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);
192 }
193
194 auto
195 PhysRegFile::getRegIds(RegClass cls) -> IdRange
196 {
197 switch (cls)
198 {
199 case IntRegClass:
200 return std::make_pair(intRegIds.begin(), intRegIds.end());
201 case FloatRegClass:
202 return std::make_pair(floatRegIds.begin(), floatRegIds.end());
203 case VecRegClass:
204 return std::make_pair(vecRegIds.begin(), vecRegIds.end());
205 case VecElemClass:
206 return std::make_pair(vecElemIds.begin(), vecElemIds.end());
207 case VecPredRegClass:
208 return std::make_pair(vecPredRegIds.begin(), vecPredRegIds.end());
209 case CCRegClass:
210 return std::make_pair(ccRegIds.begin(), ccRegIds.end());
211 case MiscRegClass:
212 return std::make_pair(miscRegIds.begin(), miscRegIds.end());
213 }
214 /* There is no way to make an empty iterator */
215 return std::make_pair(PhysIds::iterator(),
216 PhysIds::iterator());
217 }
218
219 PhysRegIdPtr
220 PhysRegFile::getTrueId(PhysRegIdPtr reg)
221 {
222 switch (reg->classValue()) {
223 case VecRegClass:
224 return &vecRegIds[reg->index()];
225 case VecElemClass:
226 return &vecElemIds[reg->index() * NumVecElemPerVecReg +
227 reg->elemIndex()];
228 default:
229 panic_if(!reg->isVectorPhysElem(),
230 "Trying to get the register of a %s register", reg->className());
231 }
232 return nullptr;
233 }
234