bitfield.hh revision 4661:44458219add1
1/*
2 * Copyright (c) 2003-2005 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: Steve Reinhardt
29 *          Nathan Binkert
30 */
31
32#ifndef __BASE_BITFIELD_HH__
33#define __BASE_BITFIELD_HH__
34
35#include <inttypes.h>
36
37/**
38 * Generate a 64-bit mask of 'nbits' 1s, right justified.
39 */
40inline uint64_t
41mask(int nbits)
42{
43    return (nbits == 64) ? (uint64_t)-1LL : (1ULL << nbits) - 1;
44}
45
46
47
48/**
49 * Extract the bitfield from position 'first' to 'last' (inclusive)
50 * from 'val' and right justify it.  MSB is numbered 63, LSB is 0.
51 */
52template <class T>
53inline
54T
55bits(T val, int first, int last)
56{
57    int nbits = first - last + 1;
58    return (val >> last) & mask(nbits);
59}
60
61/**
62 * Extract the bit from this position from 'val' and right justify it.
63 */
64template <class T>
65inline
66T
67bits(T val, int bit)
68{
69    return bits(val, bit, bit);
70}
71
72/**
73 * Mask off the given bits in place like bits() but without shifting.
74 * msb = 63, lsb = 0
75 */
76template <class T>
77inline
78T
79mbits(T val, int first, int last)
80{
81    return val & (mask(first+1) & ~mask(last));
82}
83
84inline uint64_t
85mask(int first, int last)
86{
87    return mbits((uint64_t)-1LL, first, last);
88}
89
90/**
91 * Sign-extend an N-bit value to 64 bits.
92 */
93template <int N>
94inline
95int64_t
96sext(uint64_t val)
97{
98    int sign_bit = bits(val, N-1, N-1);
99    return sign_bit ? (val | ~mask(N)) : val;
100}
101
102/**
103 * Return val with bits first to last set to bit_val
104 */
105template <class T, class B>
106inline
107T
108insertBits(T val, int first, int last, B bit_val)
109{
110    T t_bit_val = bit_val;
111    T bmask = mask(first - last + 1) << last;
112    return ((t_bit_val << last) & bmask) | (val & ~bmask);
113}
114
115/**
116 * Overloaded for access to only one bit in value
117 */
118template <class T, class B>
119inline
120T
121insertBits(T val, int bit, B bit_val)
122{
123    return insertBits(val, bit, bit, bit_val);
124}
125
126/**
127 * A convenience function to replace bits first to last of val with bit_val
128 * in place.
129 */
130template <class T, class B>
131inline
132void
133replaceBits(T& val, int first, int last, B bit_val)
134{
135    val = insertBits(val, first, last, bit_val);
136}
137
138/** Overloaded function to allow to access only 1 bit*/
139template <class T, class B>
140inline
141void
142replaceBits(T& val, int bit, B bit_val)
143{
144    val = insertBits(val, bit, bit, bit_val);
145}
146/**
147 * Returns the bit position of the MSB that is set in the input
148 */
149inline
150int
151findMsbSet(uint64_t val) {
152    int msb = 0;
153    if (!val)
154        return 0;
155    if (bits(val, 63,32)) { msb += 32; val >>= 32; }
156    if (bits(val, 31,16)) { msb += 16; val >>= 16; }
157    if (bits(val, 15,8))  { msb += 8;  val >>= 8;  }
158    if (bits(val, 7,4))   { msb += 4;  val >>= 4;  }
159    if (bits(val, 3,2))   { msb += 2;  val >>= 2;  }
160    if (bits(val, 1,1))   { msb += 1; }
161    return msb;
162}
163
164//	The following implements the BitUnion system of defining bitfields
165//on top of an underlying class. This is done through the pervasive use of
166//both named and unnamed unions which all contain the same actual storage.
167//Since they're unioned with each other, all of these storage locations
168//overlap. This allows all of the bitfields to manipulate the same data
169//without having to have access to each other. More details are provided with the
170//individual components.
171
172//This namespace is for classes which implement the backend of the BitUnion
173//stuff. Don't use any of these directly, except for the Bitfield classes in
174//the *BitfieldTypes class(es).
175namespace BitfieldBackend
176{
177    //A base class for all bitfields. It instantiates the actual storage,
178    //and provides getBits and setBits functions for manipulating it. The
179    //Data template parameter is type of the underlying storage.
180    template<class Data>
181    class BitfieldBase
182    {
183      protected:
184        Data __data;
185
186        //This function returns a range of bits from the underlying storage.
187        //It relies on the "bits" function above. It's the user's
188        //responsibility to make sure that there is a properly overloaded
189        //version of this function for whatever type they want to overlay.
190        inline uint64_t
191        getBits(int first, int last) const
192        {
193            return bits(__data, first, last);
194        }
195
196        //Similar to the above, but for settings bits with replaceBits.
197        inline void
198        setBits(int first, int last, uint64_t val)
199        {
200            replaceBits(__data, first, last, val);
201        }
202    };
203
204    //This class contains all the "regular" bitfield classes. It is inherited
205    //by all BitUnions which give them access to those types.
206    template<class Type>
207    class RegularBitfieldTypes
208    {
209      protected:
210        //This class implements ordinary bitfields, that is a span of bits
211        //who's msb is "first", and who's lsb is "last".
212        template<int first, int last=first>
213        class Bitfield : public BitfieldBase<Type>
214        {
215          public:
216            operator uint64_t () const
217            {
218                return this->getBits(first, last);
219            }
220
221            uint64_t
222            operator=(const uint64_t _data)
223            {
224                this->setBits(first, last, _data);
225                return _data;
226            }
227        };
228
229        //A class which specializes the above so that it can only be read
230        //from. This is accomplished explicitly making sure the assignment
231        //operator is blocked. The conversion operator is carried through
232        //inheritance. This will unfortunately need to be copied into each
233        //bitfield type due to limitations with how templates work
234        template<int first, int last=first>
235        class BitfieldRO : public Bitfield<first, last>
236        {
237          private:
238            uint64_t
239            operator=(const uint64_t _data);
240        };
241
242        //Similar to the above, but only allows writing.
243        template<int first, int last=first>
244        class BitfieldWO : public Bitfield<first, last>
245        {
246          private:
247            operator uint64_t () const;
248
249          public:
250            using Bitfield<first, last>::operator=;
251        };
252    };
253
254    //This class contains all the "regular" bitfield classes. It is inherited
255    //by all BitUnions which give them access to those types.
256    template<class Type>
257    class SignedBitfieldTypes
258    {
259      protected:
260        //This class implements ordinary bitfields, that is a span of bits
261        //who's msb is "first", and who's lsb is "last".
262        template<int first, int last=first>
263        class SignedBitfield : public BitfieldBase<Type>
264        {
265          public:
266            operator int64_t () const
267            {
268                return sext<first - last + 1>(this->getBits(first, last));
269            }
270
271            int64_t
272            operator=(const int64_t _data)
273            {
274                this->setBits(first, last, _data);
275                return _data;
276            }
277        };
278
279        //A class which specializes the above so that it can only be read
280        //from. This is accomplished explicitly making sure the assignment
281        //operator is blocked. The conversion operator is carried through
282        //inheritance. This will unfortunately need to be copied into each
283        //bitfield type due to limitations with how templates work
284        template<int first, int last=first>
285        class SignedBitfieldRO : public SignedBitfield<first, last>
286        {
287          private:
288            int64_t
289            operator=(const int64_t _data);
290        };
291
292        //Similar to the above, but only allows writing.
293        template<int first, int last=first>
294        class SignedBitfieldWO : public SignedBitfield<first, last>
295        {
296          private:
297            operator int64_t () const;
298
299          public:
300            int64_t operator=(const int64_t _data)
301            {
302                *((SignedBitfield<first, last> *)this) = _data;
303                return _data;
304            }
305        };
306    };
307
308    template<class Type>
309    class BitfieldTypes : public RegularBitfieldTypes<Type>,
310                          public SignedBitfieldTypes<Type>
311    {};
312
313    //When a BitUnion is set up, an underlying class is created which holds
314    //the actual union. This class then inherits from it, and provids the
315    //implementations for various operators. Setting things up this way
316    //prevents having to redefine these functions in every different BitUnion
317    //type. More operators could be implemented in the future, as the need
318    //arises.
319    template <class Type, class Base>
320    class BitUnionOperators : public Base
321    {
322      public:
323        operator Type () const
324        {
325            return Base::__data;
326        }
327
328        Type
329        operator=(const Type & _data)
330        {
331            Base::__data = _data;
332            return _data;
333        }
334
335        bool
336        operator<(const Base & base) const
337        {
338            return Base::__data < base.__data;
339        }
340
341        bool
342        operator==(const Base & base) const
343        {
344            return Base::__data == base.__data;
345        }
346    };
347}
348
349//This macro is a backend for other macros that specialize it slightly.
350//First, it creates/extends a namespace "BitfieldUnderlyingClasses" and
351//sticks the class which has the actual union in it, which
352//BitfieldOperators above inherits from. Putting these classes in a special
353//namespace ensures that there will be no collisions with other names as long
354//as the BitUnion names themselves are all distinct and nothing else uses
355//the BitfieldUnderlyingClasses namespace, which is unlikely. The class itself
356//creates a typedef of the "type" parameter called __DataType. This allows
357//the type to propagate outside of the macro itself in a controlled way.
358//Finally, the base storage is defined which BitfieldOperators will refer to
359//in the operators it defines. This macro is intended to be followed by
360//bitfield definitions which will end up inside it's union. As explained
361//above, these is overlayed the __data member in its entirety by each of the
362//bitfields which are defined in the union, creating shared storage with no
363//overhead.
364#define __BitUnion(type, name) \
365    namespace BitfieldUnderlyingClasses \
366    { \
367        class name; \
368    } \
369    class BitfieldUnderlyingClasses::name : \
370        public BitfieldBackend::BitfieldTypes<type> \
371    { \
372      public: \
373        typedef type __DataType; \
374        union { \
375            type __data;\
376
377//This closes off the class and union started by the above macro. It is
378//followed by a typedef which makes "name" refer to a BitfieldOperator
379//class inheriting from the class and union just defined, which completes
380//building up the type for the user.
381#define EndBitUnion(name) \
382        }; \
383    }; \
384    typedef BitfieldBackend::BitUnionOperators< \
385        BitfieldUnderlyingClasses::name::__DataType, \
386        BitfieldUnderlyingClasses::name> name;
387
388//This sets up a bitfield which has other bitfields nested inside of it. The
389//__data member functions like the "underlying storage" of the top level
390//BitUnion. Like everything else, it overlays with the top level storage, so
391//making it a regular bitfield type makes the entire thing function as a
392//regular bitfield when referred to by itself.
393#define __SubBitUnion(fieldType, first, last, name) \
394    class : public BitfieldBackend::BitfieldTypes<__DataType> \
395    { \
396      public: \
397        union { \
398            fieldType<first, last> __data;
399
400//This closes off the union created above and gives it a name. Unlike the top
401//level BitUnion, we're interested in creating an object instead of a type.
402//The operators are defined in the macro itself instead of a class for
403//technical reasons. If someone determines a way to move them to one, please
404//do so.
405#define EndSubBitUnion(name) \
406        }; \
407        inline operator const __DataType () \
408        { return __data; } \
409        \
410        inline const __DataType operator = (const __DataType & _data) \
411        { __data = _data; } \
412    } name;
413
414//Regular bitfields
415//These define macros for read/write regular bitfield based subbitfields.
416#define SubBitUnion(name, first, last) \
417    __SubBitUnion(Bitfield, first, last, name)
418
419//Regular bitfields
420//These define macros for read/write regular bitfield based subbitfields.
421#define SignedSubBitUnion(name, first, last) \
422    __SubBitUnion(SignedBitfield, first, last, name)
423
424//Use this to define an arbitrary type overlayed with bitfields.
425#define BitUnion(type, name) __BitUnion(type, name)
426
427//Use this to define conveniently sized values overlayed with bitfields.
428#define BitUnion64(name) __BitUnion(uint64_t, name)
429#define BitUnion32(name) __BitUnion(uint32_t, name)
430#define BitUnion16(name) __BitUnion(uint16_t, name)
431#define BitUnion8(name) __BitUnion(uint8_t, name)
432
433#endif // __BASE_BITFIELD_HH__
434