gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
bitunion.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007-2008 The Regents of The University of Michigan
3  * All rights reserved.
4  *
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.
15  *
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.
27  *
28  * Authors: Gabe Black
29  */
30 
31 #ifndef __BASE_BITUNION_HH__
32 #define __BASE_BITUNION_HH__
33 
34 #include "base/bitfield.hh"
35 
36 // The following implements the BitUnion system of defining bitfields
37 //on top of an underlying class. This is done through the pervasive use of
38 //both named and unnamed unions which all contain the same actual storage.
39 //Since they're unioned with each other, all of these storage locations
40 //overlap. This allows all of the bitfields to manipulate the same data
41 //without having to have access to each other. More details are provided with
42 //the individual components.
43 
44 //This namespace is for classes which implement the backend of the BitUnion
45 //stuff. Don't use any of these directly, except for the Bitfield classes in
46 //the *BitfieldTypes class(es).
47 namespace BitfieldBackend
48 {
49  //A base class for all bitfields. It instantiates the actual storage,
50  //and provides getBits and setBits functions for manipulating it. The
51  //Data template parameter is type of the underlying storage.
52  template<class Data>
54  {
55  protected:
56  Data __data;
57 
58  //This function returns a range of bits from the underlying storage.
59  //It relies on the "bits" function above. It's the user's
60  //responsibility to make sure that there is a properly overloaded
61  //version of this function for whatever type they want to overlay.
62  inline uint64_t
63  getBits(int first, int last) const
64  {
65  return bits(__data, first, last);
66  }
67 
68  //Similar to the above, but for settings bits with replaceBits.
69  inline void
70  setBits(int first, int last, uint64_t val)
71  {
72  replaceBits(__data, first, last, val);
73  }
74  };
75 
76  //This class contains all the "regular" bitfield classes. It is inherited
77  //by all BitUnions which give them access to those types.
78  template<class Type>
80  {
81  protected:
82  //This class implements ordinary bitfields, that is a span of bits
83  //who's msb is "first", and who's lsb is "last".
84  template<int first, int last=first>
85  class Bitfield : public BitfieldBase<Type>
86  {
87  static_assert(first >= last,
88  "Bitfield ranges must be specified as <msb, lsb>");
89 
90  public:
91  operator uint64_t () const
92  {
93  return this->getBits(first, last);
94  }
95 
96  uint64_t
97  operator=(const uint64_t _data)
98  {
99  this->setBits(first, last, _data);
100  return _data;
101  }
102 
103  uint64_t
105  {
106  return *this = (uint64_t)other;
107  }
108  };
109 
110  //A class which specializes the above so that it can only be read
111  //from. This is accomplished explicitly making sure the assignment
112  //operator is blocked. The conversion operator is carried through
113  //inheritance. This will unfortunately need to be copied into each
114  //bitfield type due to limitations with how templates work
115  template<int first, int last=first>
116  class BitfieldRO : public Bitfield<first, last>
117  {
118  private:
119  uint64_t
120  operator=(const uint64_t _data);
121 
122  uint64_t
123  operator=(const Bitfield<first, last>& other);
124  };
125 
126  //Similar to the above, but only allows writing.
127  template<int first, int last=first>
128  class BitfieldWO : public Bitfield<first, last>
129  {
130  private:
131  operator uint64_t () const;
132 
133  public:
135  };
136  };
137 
138  //This class contains all the "regular" bitfield classes. It is inherited
139  //by all BitUnions which give them access to those types.
140  template<class Type>
142  {
143  protected:
144  //This class implements ordinary bitfields, that is a span of bits
145  //who's msb is "first", and who's lsb is "last".
146  template<int first, int last=first>
147  class SignedBitfield : public BitfieldBase<Type>
148  {
149  public:
150  operator int64_t () const
151  {
152  return sext<first - last + 1>(this->getBits(first, last));
153  }
154 
155  int64_t
156  operator=(const int64_t _data)
157  {
158  this->setBits(first, last, _data);
159  return _data;
160  }
161 
162  int64_t
164  {
165  return *this = (int64_t)other;
166  }
167  };
168 
169  //A class which specializes the above so that it can only be read
170  //from. This is accomplished explicitly making sure the assignment
171  //operator is blocked. The conversion operator is carried through
172  //inheritance. This will unfortunately need to be copied into each
173  //bitfield type due to limitations with how templates work
174  template<int first, int last=first>
175  class SignedBitfieldRO : public SignedBitfield<first, last>
176  {
177  private:
178  int64_t
179  operator=(const int64_t _data);
180 
181  int64_t
183  };
184 
185  //Similar to the above, but only allows writing.
186  template<int first, int last=first>
187  class SignedBitfieldWO : public SignedBitfield<first, last>
188  {
189  private:
190  operator int64_t () const;
191 
192  public:
194  };
195  };
196 
197  template<class Type>
198  class BitfieldTypes : public RegularBitfieldTypes<Type>,
199  public SignedBitfieldTypes<Type>
200  {};
201 
202  //When a BitUnion is set up, an underlying class is created which holds
203  //the actual union. This class then inherits from it, and provids the
204  //implementations for various operators. Setting things up this way
205  //prevents having to redefine these functions in every different BitUnion
206  //type. More operators could be implemented in the future, as the need
207  //arises.
208  template <class Type, class Base>
209  class BitUnionOperators : public Base
210  {
211  public:
212  BitUnionOperators(Type const & _data)
213  {
214  Base::__data = _data;
215  }
216 
218 
219  operator const Type () const
220  {
221  return Base::__data;
222  }
223 
224  Type
225  operator=(Type const & _data)
226  {
227  Base::__data = _data;
228  return _data;
229  }
230 
231  Type
233  {
234  Base::__data = other;
235  return Base::__data;
236  }
237 
238  bool
239  operator<(Base const & base) const
240  {
241  return Base::__data < base.__data;
242  }
243 
244  bool
245  operator==(Base const & base) const
246  {
247  return Base::__data == base.__data;
248  }
249  };
250 }
251 
252 //This macro is a backend for other macros that specialize it slightly.
253 //First, it creates/extends a namespace "BitfieldUnderlyingClasses" and
254 //sticks the class which has the actual union in it, which
255 //BitfieldOperators above inherits from. Putting these classes in a special
256 //namespace ensures that there will be no collisions with other names as long
257 //as the BitUnion names themselves are all distinct and nothing else uses
258 //the BitfieldUnderlyingClasses namespace, which is unlikely. The class itself
259 //creates a typedef of the "type" parameter called __DataType. This allows
260 //the type to propagate outside of the macro itself in a controlled way.
261 //Finally, the base storage is defined which BitfieldOperators will refer to
262 //in the operators it defines. This macro is intended to be followed by
263 //bitfield definitions which will end up inside it's union. As explained
264 //above, these is overlayed the __data member in its entirety by each of the
265 //bitfields which are defined in the union, creating shared storage with no
266 //overhead.
267 #define __BitUnion(type, name) \
268  class BitfieldUnderlyingClasses##name : \
269  public BitfieldBackend::BitfieldTypes<type> \
270  { \
271  public: \
272  typedef type __DataType; \
273  union { \
274  type __data;\
275 
276 //This closes off the class and union started by the above macro. It is
277 //followed by a typedef which makes "name" refer to a BitfieldOperator
278 //class inheriting from the class and union just defined, which completes
279 //building up the type for the user.
280 #define EndBitUnion(name) \
281  }; \
282  }; \
283  typedef BitfieldBackend::BitUnionOperators< \
284  BitfieldUnderlyingClasses##name::__DataType, \
285  BitfieldUnderlyingClasses##name> name;
286 
287 //This sets up a bitfield which has other bitfields nested inside of it. The
288 //__data member functions like the "underlying storage" of the top level
289 //BitUnion. Like everything else, it overlays with the top level storage, so
290 //making it a regular bitfield type makes the entire thing function as a
291 //regular bitfield when referred to by itself.
292 #define __SubBitUnion(fieldType, first, last, name) \
293  class : public BitfieldBackend::BitfieldTypes<__DataType> \
294  { \
295  public: \
296  union { \
297  fieldType<first, last> __data;
298 
299 //This closes off the union created above and gives it a name. Unlike the top
300 //level BitUnion, we're interested in creating an object instead of a type.
301 //The operators are defined in the macro itself instead of a class for
302 //technical reasons. If someone determines a way to move them to one, please
303 //do so.
304 #define EndSubBitUnion(name) \
305  }; \
306  inline operator __DataType () const \
307  { return __data; } \
308  \
309  inline __DataType operator = (const __DataType & _data) \
310  { return __data = _data;} \
311  } name;
312 
313 //Regular bitfields
314 //These define macros for read/write regular bitfield based subbitfields.
315 #define SubBitUnion(name, first, last) \
316  __SubBitUnion(Bitfield, first, last, name)
317 
318 //Regular bitfields
319 //These define macros for read/write regular bitfield based subbitfields.
320 #define SignedSubBitUnion(name, first, last) \
321  __SubBitUnion(SignedBitfield, first, last, name)
322 
323 //Use this to define an arbitrary type overlayed with bitfields.
324 #define BitUnion(type, name) __BitUnion(type, name)
325 
326 //Use this to define conveniently sized values overlayed with bitfields.
327 #define BitUnion64(name) __BitUnion(uint64_t, name)
328 #define BitUnion32(name) __BitUnion(uint32_t, name)
329 #define BitUnion16(name) __BitUnion(uint16_t, name)
330 #define BitUnion8(name) __BitUnion(uint8_t, name)
331 
332 #endif // __BASE_BITUNION_HH__
bool operator<(Base const &base) const
Definition: bitunion.hh:239
void setBits(int first, int last, uint64_t val)
Definition: bitunion.hh:70
Type operator=(Type const &_data)
Definition: bitunion.hh:225
uint64_t getBits(int first, int last) const
Definition: bitunion.hh:63
uint64_t operator=(Bitfield< first, last > const &other)
Definition: bitunion.hh:104
BitUnionOperators(Type const &_data)
Definition: bitunion.hh:212
Bitfield< 63 > val
Definition: misc.hh:770
uint64_t operator=(const uint64_t _data)
uint64_t operator=(const uint64_t _data)
Definition: bitunion.hh:97
void replaceBits(T &val, int first, int last, B bit_val)
A convenience function to replace bits first to last of val with bit_val in place.
Definition: bitfield.hh:145
Bitfield< 51, 12 > base
Definition: pagetable.hh:85
Type operator=(BitUnionOperators const &other)
Definition: bitunion.hh:232
int64_t operator=(SignedBitfield< first, last > const &other)
Definition: bitunion.hh:163
bool operator==(Base const &base) const
Definition: bitunion.hh:245
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
Definition: bitfield.hh:67
uint64_t sext(uint64_t val)
Sign-extend an N-bit value to 64 bits.
Definition: bitfield.hh:108

Generated on Fri Jun 9 2017 13:03:40 for gem5 by doxygen 1.8.6