Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: RegisterArray.h | |
5 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
6 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. | |
7 | * | |
8 | * The above named program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public | |
10 | * License version 2 as published by the Free Software Foundation. | |
11 | * | |
12 | * The above named program is distributed in the hope that it will be | |
13 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public | |
18 | * License along with this work; if not, write to the Free Software | |
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. | |
20 | * | |
21 | * ========== Copyright Header End ============================================ | |
22 | */ | |
23 | #ifndef __RegisterArray_h | |
24 | #define __RegisterArray_h | |
25 | ||
26 | #include <stddef.h> | |
27 | #include <assert.h> | |
28 | #include <iostream> | |
29 | #include <fstream> | |
30 | #include <string> | |
31 | #include "Block.h" | |
32 | #include "Object.h" | |
33 | #include "Datatype.h" | |
34 | #include "Signature.h" | |
35 | #include "Register.h" | |
36 | using namespace std; | |
37 | ||
38 | /** @file RegisterArray.h | |
39 | * RegisterArray.h provides a set of classes for representing arrays | |
40 | * of registers. | |
41 | * | |
42 | * @see RegisterArrayModule | |
43 | */ | |
44 | ||
45 | /** @defgroup RegisterArrayModule The RegisterArray Module | |
46 | * | |
47 | * Registers are 8, 16, 32 or 64 bits wide, and are composed of Fields. | |
48 | * Fields are contiguous collections of bits within a Register. The value | |
49 | * of a Register can be accessed at the Register level or at the | |
50 | * Field level. Care is taken to ensure that large arrays of 64-bit registers | |
51 | * are implemented efficiently - in terms of memory usage and run-time | |
52 | * cost. Note that there is significant waste in the storage of narrower | |
53 | * registers since they are held in 64-bit containers (with unused upper bits | |
54 | * always zero). | |
55 | * | |
56 | * The classes and types defined here are: | |
57 | * - RegisterArray | |
58 | * - RegisterArrayOf | |
59 | * | |
60 | * The "public" interface provided by this file are RegisterArray | |
61 | * and RegisterArrayOf. RegisterArray is used to form arrays of | |
62 | * Register instances, and forms the base class for RegisterArrayOf. | |
63 | * RegisterArrayOf<T> is a template class and represents an array | |
64 | * of type T, where T is a subclass of Register. This is the more | |
65 | * useful class since the standard way of describing a specific | |
66 | * kind of Register is to subclass the Register class and add | |
67 | * appropriate fields. The RegisterArrayOf class is designed to | |
68 | * have the following properties: | |
69 | * - support a natural syntax for accessing array elements | |
70 | * - be storage efficient, it does not allocate an array of Register | |
71 | * instances since this adds a lot of overhead. Instead the array | |
72 | * is carefully constructed out of RegisterState, RegisterInfo | |
73 | * and RegisterType instances. | |
74 | * - to support efficient indexing of the array to an element. | |
75 | * - to maintain the correct subclass for elements in the array. | |
76 | * This is important to ensure that Field instances and virtual | |
77 | * methods of the Register subclass are correctly propagated. | |
78 | * | |
79 | * The following syntax can be used to access an element in a | |
80 | * RegisterArrayOf<T> at the Register and Field level: | |
81 | * - arrayname[index].get() to get the whole Register | |
82 | * - arrayname[index].set() to set the whole Register | |
83 | * - arrayname[index].fieldname.get() to get a Field | |
84 | * - arrayname[index].fieldname.set() to get a Field | |
85 | * | |
86 | * See also Register.h | |
87 | * | |
88 | * @{ | |
89 | */ | |
90 | ||
91 | /** RegisterArray is used to constructs arrays of registers, | |
92 | * and index into the array to a Register element. All registers in the | |
93 | * array are systematically named, have the same RegisterType, belong to | |
94 | * the same Block and are assigned an address using a base address and a | |
95 | * step value. | |
96 | */ | |
97 | ||
98 | class RegisterArray | |
99 | { | |
100 | public: | |
101 | /** Constructor for RegisterArray. | |
102 | * @param n the basename for this RegisterArray. The basename of a | |
103 | * Register in the array will be this basename appended by | |
104 | * "[i]" where i is the index of that Register in the array. | |
105 | * @param b a pointer to the Block with which this RegisterArray is | |
106 | * associated. The fullname of this RegisterArray and its | |
107 | * Registers are scoped within that Block. | |
108 | * @param a the base address of this RegisterArray. | |
109 | * @param c the number of registers in this RegisterArray. | |
110 | * @param s the step between addresses for registers in this | |
111 | * RegisterArray. The step must be greater than 0, and an | |
112 | * exact integral multiple of the width. | |
113 | * @param w the width of each register in bytes, defaults to 8 bytes. | |
114 | * | |
115 | * The address of the Register with index i is given by a + (i * s). | |
116 | */ | |
117 | RegisterArray(string n, Block *b, Addr a, uint c=1, | |
118 | Addr s=Addr(8), uint w=8); | |
119 | ||
120 | /** Destructor for RegisterArray. This is virtual so that the appropriate | |
121 | * destructor for any derived class is used. */ | |
122 | virtual ~RegisterArray(); | |
123 | ||
124 | /** Get the basename for this RegisterArray. */ | |
125 | string getBaseName() const { return baseName; } | |
126 | ||
127 | /** Get the fullname for this RegisterArray. */ | |
128 | string getFullName() const { return fullName; } | |
129 | ||
130 | /** Get the start address for this RegisterArray. */ | |
131 | Addr getStartAddr() const { return startAddr; } | |
132 | ||
133 | /** Get the end address for this RegisterArray. */ | |
134 | Addr getEndAddr() const { return endAddr; } | |
135 | ||
136 | /** Get the number of element in this RegisterArray. */ | |
137 | uint getCount() const { return count; } | |
138 | ||
139 | /** Get the step between addresses in this RegisterArray. */ | |
140 | Addr getStep() const { return step; } | |
141 | ||
142 | /** Get the width in bytes of each register in this RegisterArray. */ | |
143 | uint getWidth() const { return regType->widthBytes; } | |
144 | ||
145 | /** Lookup a register in this RegisterArray by its address. | |
146 | * @param a the address to look-up. | |
147 | * @param i if the address matches a register and i is not the NULL | |
148 | * pointer, then the index of that Register in the array | |
149 | * will be copied into *i. This index can subsequently | |
150 | * be used to index into the RegisterArray to find the | |
151 | * Register instance. If i is NULL the index is not returned; | |
152 | * this can be useful when checking whether an address matches | |
153 | * an element in a register array. | |
154 | * @return returns true if the address matches a register in this | |
155 | * RegisterArray, otherwise false. | |
156 | */ | |
157 | bool lookup(Addr a, uint *i = NULL); | |
158 | ||
159 | /** Get the address of a Register in this RegisterArray. | |
160 | * @param index the index of a Register in this RegisterArray. | |
161 | * @return the address of the Register with that index. | |
162 | */ | |
163 | Addr getAddr(uint index) const | |
164 | { | |
165 | assert(index < count); | |
166 | return startAddr + step * index; | |
167 | } | |
168 | ||
169 | /** Return true if this is a small RegisterArray, otherwise false. | |
170 | * The break-points are somewhat arbitrary. This classification is | |
171 | * used as follows: | |
172 | * - small: trace enabled, print enabled, map enabled. | |
173 | * - large: trace disabled, print disabled, map enabled. | |
174 | * - huge: trace disabled, print disabled, map disabled. | |
175 | */ | |
176 | bool isSmall() const { return count <= 64; } | |
177 | ||
178 | /** Return true if this is a large RegisterArray, otherwise false. | |
179 | * The break-points are somewhat arbitrary. This classification is | |
180 | * used as follows: | |
181 | * - small: trace enabled, print enabled, map enabled. | |
182 | * - large: trace disabled, print disabled, map enabled. | |
183 | * - huge: trace disabled, print disabled, map disabled. | |
184 | */ | |
185 | bool isLarge() const { return count > 64 && count <= 1024; } | |
186 | ||
187 | /** Return true if this is a huge RegisterArray, otherwise false. | |
188 | * The break-points are somewhat arbitrary. This classification is | |
189 | * used as follows: | |
190 | * - small: trace enabled, print enabled, map enabled. | |
191 | * - large: trace disabled, print disabled, map enabled. | |
192 | * - huge: trace disabled, print disabled, map disabled. | |
193 | */ | |
194 | bool isHuge() const { return count > 1024; } | |
195 | ||
196 | /** Enable write Block-level call-backs for this RegisterArray. */ | |
197 | void enableWriteBlockCB() | |
198 | { | |
199 | assert(block != NULL); | |
200 | regType->writeBlockCB = true; | |
201 | } | |
202 | ||
203 | /** Disable write Block-level call-backs for this RegisterArray. */ | |
204 | void disableWriteBlockCB() | |
205 | { | |
206 | regType->writeBlockCB = false; | |
207 | } | |
208 | ||
209 | /** Enable read Block-level call-backs for this RegisterArray. */ | |
210 | void enableReadBlockCB() | |
211 | { | |
212 | assert(block != NULL); | |
213 | regType->readBlockCB = true; | |
214 | } | |
215 | ||
216 | /** Disable read Block-level call-backs for this RegisterArray. */ | |
217 | void disableReadBlockCB() | |
218 | { | |
219 | regType->readBlockCB = false; | |
220 | } | |
221 | ||
222 | /** Print this RegisterArray to the specified output stream - note | |
223 | * that the values will not be printed for any large RegisterArray. | |
224 | */ | |
225 | void printThis(ostream &os); | |
226 | ||
227 | /** Reset this RegisterArray to its initial value. */ | |
228 | void resetThis(); | |
229 | ||
230 | /** Create the Signature for this RegisterArray so that it can | |
231 | * subsequently be traced. | |
232 | * @param ofs the output file stream.*/ | |
233 | void signThis(ofstream &ofs); | |
234 | ||
235 | /** Trace this RegisterArray to the specified output stream. | |
236 | * @param ofs the output file stream.*/ | |
237 | void traceThis(ofstream &ofs); | |
238 | ||
239 | /** Index operator for RegisterArray. This indexes into the | |
240 | * RegisterArray and returns the Register instance at the | |
241 | * specified index by *reference*. This method is virtual | |
242 | * to allow over-riding by sub-classes (e.g. RegisterArrayOf). | |
243 | * @param index the index into the RegisterArray. */ | |
244 | virtual Register &operator[](uint index); | |
245 | ||
246 | protected: | |
247 | void reinitRegister(Register *r); | |
248 | ||
249 | void bindRegisterToIndex(Register *r, uint index); | |
250 | ||
251 | private: | |
252 | string baseName; | |
253 | string fullName; | |
254 | Block *block; | |
255 | ||
256 | Addr startAddr; | |
257 | Addr endAddr; | |
258 | uint count; | |
259 | Addr step; | |
260 | ||
261 | RegisterType *regType; | |
262 | RegisterState *regState; | |
263 | RegisterInfo *regInfo; | |
264 | Signature **mySignature; | |
265 | ||
266 | Register valueR; | |
267 | }; | |
268 | ||
269 | /** RegisterArrayOf is used to constructs arrays of registers, and index into | |
270 | * the array to a Register element. All registers in the array are | |
271 | * systematically named, have the same RegisterType, belong to the same | |
272 | * Block and are assigned an address using a base address and a step value. | |
273 | * RegisterArrayOf is a template class where the template parameter | |
274 | * specifies the Register class of which the array is constructed. | |
275 | * | |
276 | * The class T must be derived from Register and must provide a constructor | |
277 | * of the form: | |
278 | * T::T(Block *b) | |
279 | * | |
280 | */ | |
281 | ||
282 | template<class T> class RegisterArrayOf : public RegisterArray | |
283 | { | |
284 | public: | |
285 | /** Constructor for RegisterArrayOf. | |
286 | * @param n the basename for this RegisterArrayOf. The basename of a | |
287 | * Register in the array will be this basename appended by | |
288 | * "[i]" where i is the index of that Register in the array. | |
289 | * @param b a pointer to the Block with which this RegisterArrayOf is | |
290 | * associated. The fullname of this RegisterArrayOf and its | |
291 | * Registers are scoped within that Block. | |
292 | * @param a the base address of this RegisterArrayOf. | |
293 | * @param c the number of registers in this RegisterArrayOf. | |
294 | * @param s the step between addresses for registers in this | |
295 | * RegisterArrayOf. The step must be greater than 0, and an | |
296 | * exact integral multiple of the width. | |
297 | * @param w the width of each register in bytes, defaults to 8 bytes. | |
298 | * | |
299 | * The address of the Register with index i is given by a + (i * s). | |
300 | */ | |
301 | RegisterArrayOf(string n, Block *b, Addr a, uint c=1, | |
302 | Addr s=Addr(8), uint w=8); | |
303 | ||
304 | /** Index operator for RegisterArrayOf. This indexes into the | |
305 | * RegisterArrayOf and returns the instance of type T at the specified | |
306 | * index by *reference*. | |
307 | * @param index the index into the RegisterArrayOf. */ | |
308 | T &operator[](uint index); | |
309 | ||
310 | private: | |
311 | T valueT; | |
312 | }; | |
313 | ||
314 | /** @} */ | |
315 | ||
316 | #include "pRegisterArray.h" | |
317 | ||
318 | #endif |