diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2007-07-14 17:28:26 -0700 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2007-07-14 17:28:26 -0700 |
commit | 873b762d4b7ced232782c937e6927d1f007e82eb (patch) | |
tree | 1349b290fa2c07af3c3ffdf06f81c784b43d4e99 /src/base/bitfield.hh | |
parent | 4f7809d5e674384f58d3be6f4591afc0ceb2c37e (diff) | |
download | gem5-873b762d4b7ced232782c937e6927d1f007e82eb.tar.xz |
Move bitunion code into it's own file.
--HG--
extra : convert_revision : 8d55ca9645ee4e357b7f4595435542eb72490331
Diffstat (limited to 'src/base/bitfield.hh')
-rw-r--r-- | src/base/bitfield.hh | 269 |
1 files changed, 0 insertions, 269 deletions
diff --git a/src/base/bitfield.hh b/src/base/bitfield.hh index 70a46386e..664093fa2 100644 --- a/src/base/bitfield.hh +++ b/src/base/bitfield.hh @@ -161,273 +161,4 @@ findMsbSet(uint64_t val) { return msb; } -// The following implements the BitUnion system of defining bitfields -//on top of an underlying class. This is done through the pervasive use of -//both named and unnamed unions which all contain the same actual storage. -//Since they're unioned with each other, all of these storage locations -//overlap. This allows all of the bitfields to manipulate the same data -//without having to have access to each other. More details are provided with the -//individual components. - -//This namespace is for classes which implement the backend of the BitUnion -//stuff. Don't use any of these directly, except for the Bitfield classes in -//the *BitfieldTypes class(es). -namespace BitfieldBackend -{ - //A base class for all bitfields. It instantiates the actual storage, - //and provides getBits and setBits functions for manipulating it. The - //Data template parameter is type of the underlying storage. - template<class Data> - class BitfieldBase - { - protected: - Data __data; - - //This function returns a range of bits from the underlying storage. - //It relies on the "bits" function above. It's the user's - //responsibility to make sure that there is a properly overloaded - //version of this function for whatever type they want to overlay. - inline uint64_t - getBits(int first, int last) const - { - return bits(__data, first, last); - } - - //Similar to the above, but for settings bits with replaceBits. - inline void - setBits(int first, int last, uint64_t val) - { - replaceBits(__data, first, last, val); - } - }; - - //This class contains all the "regular" bitfield classes. It is inherited - //by all BitUnions which give them access to those types. - template<class Type> - class RegularBitfieldTypes - { - protected: - //This class implements ordinary bitfields, that is a span of bits - //who's msb is "first", and who's lsb is "last". - template<int first, int last=first> - class Bitfield : public BitfieldBase<Type> - { - public: - operator uint64_t () const - { - return this->getBits(first, last); - } - - uint64_t - operator=(const uint64_t _data) - { - this->setBits(first, last, _data); - return _data; - } - }; - - //A class which specializes the above so that it can only be read - //from. This is accomplished explicitly making sure the assignment - //operator is blocked. The conversion operator is carried through - //inheritance. This will unfortunately need to be copied into each - //bitfield type due to limitations with how templates work - template<int first, int last=first> - class BitfieldRO : public Bitfield<first, last> - { - private: - uint64_t - operator=(const uint64_t _data); - }; - - //Similar to the above, but only allows writing. - template<int first, int last=first> - class BitfieldWO : public Bitfield<first, last> - { - private: - operator uint64_t () const; - - public: - using Bitfield<first, last>::operator=; - }; - }; - - //This class contains all the "regular" bitfield classes. It is inherited - //by all BitUnions which give them access to those types. - template<class Type> - class SignedBitfieldTypes - { - protected: - //This class implements ordinary bitfields, that is a span of bits - //who's msb is "first", and who's lsb is "last". - template<int first, int last=first> - class SignedBitfield : public BitfieldBase<Type> - { - public: - operator int64_t () const - { - return sext<first - last + 1>(this->getBits(first, last)); - } - - int64_t - operator=(const int64_t _data) - { - this->setBits(first, last, _data); - return _data; - } - }; - - //A class which specializes the above so that it can only be read - //from. This is accomplished explicitly making sure the assignment - //operator is blocked. The conversion operator is carried through - //inheritance. This will unfortunately need to be copied into each - //bitfield type due to limitations with how templates work - template<int first, int last=first> - class SignedBitfieldRO : public SignedBitfield<first, last> - { - private: - int64_t - operator=(const int64_t _data); - }; - - //Similar to the above, but only allows writing. - template<int first, int last=first> - class SignedBitfieldWO : public SignedBitfield<first, last> - { - private: - operator int64_t () const; - - public: - int64_t operator=(const int64_t _data) - { - *((SignedBitfield<first, last> *)this) = _data; - return _data; - } - }; - }; - - template<class Type> - class BitfieldTypes : public RegularBitfieldTypes<Type>, - public SignedBitfieldTypes<Type> - {}; - - //When a BitUnion is set up, an underlying class is created which holds - //the actual union. This class then inherits from it, and provids the - //implementations for various operators. Setting things up this way - //prevents having to redefine these functions in every different BitUnion - //type. More operators could be implemented in the future, as the need - //arises. - template <class Type, class Base> - class BitUnionOperators : public Base - { - public: - operator Type () const - { - return Base::__data; - } - - Type - operator=(const Type & _data) - { - Base::__data = _data; - return _data; - } - - bool - operator<(const Base & base) const - { - return Base::__data < base.__data; - } - - bool - operator==(const Base & base) const - { - return Base::__data == base.__data; - } - }; -} - -//This macro is a backend for other macros that specialize it slightly. -//First, it creates/extends a namespace "BitfieldUnderlyingClasses" and -//sticks the class which has the actual union in it, which -//BitfieldOperators above inherits from. Putting these classes in a special -//namespace ensures that there will be no collisions with other names as long -//as the BitUnion names themselves are all distinct and nothing else uses -//the BitfieldUnderlyingClasses namespace, which is unlikely. The class itself -//creates a typedef of the "type" parameter called __DataType. This allows -//the type to propagate outside of the macro itself in a controlled way. -//Finally, the base storage is defined which BitfieldOperators will refer to -//in the operators it defines. This macro is intended to be followed by -//bitfield definitions which will end up inside it's union. As explained -//above, these is overlayed the __data member in its entirety by each of the -//bitfields which are defined in the union, creating shared storage with no -//overhead. -#define __BitUnion(type, name) \ - namespace BitfieldUnderlyingClasses \ - { \ - class name; \ - } \ - class BitfieldUnderlyingClasses::name : \ - public BitfieldBackend::BitfieldTypes<type> \ - { \ - public: \ - typedef type __DataType; \ - union { \ - type __data;\ - -//This closes off the class and union started by the above macro. It is -//followed by a typedef which makes "name" refer to a BitfieldOperator -//class inheriting from the class and union just defined, which completes -//building up the type for the user. -#define EndBitUnion(name) \ - }; \ - }; \ - typedef BitfieldBackend::BitUnionOperators< \ - BitfieldUnderlyingClasses::name::__DataType, \ - BitfieldUnderlyingClasses::name> name; - -//This sets up a bitfield which has other bitfields nested inside of it. The -//__data member functions like the "underlying storage" of the top level -//BitUnion. Like everything else, it overlays with the top level storage, so -//making it a regular bitfield type makes the entire thing function as a -//regular bitfield when referred to by itself. -#define __SubBitUnion(fieldType, first, last, name) \ - class : public BitfieldBackend::BitfieldTypes<__DataType> \ - { \ - public: \ - union { \ - fieldType<first, last> __data; - -//This closes off the union created above and gives it a name. Unlike the top -//level BitUnion, we're interested in creating an object instead of a type. -//The operators are defined in the macro itself instead of a class for -//technical reasons. If someone determines a way to move them to one, please -//do so. -#define EndSubBitUnion(name) \ - }; \ - inline operator const __DataType () \ - { return __data; } \ - \ - inline const __DataType operator = (const __DataType & _data) \ - { __data = _data; } \ - } name; - -//Regular bitfields -//These define macros for read/write regular bitfield based subbitfields. -#define SubBitUnion(name, first, last) \ - __SubBitUnion(Bitfield, first, last, name) - -//Regular bitfields -//These define macros for read/write regular bitfield based subbitfields. -#define SignedSubBitUnion(name, first, last) \ - __SubBitUnion(SignedBitfield, first, last, name) - -//Use this to define an arbitrary type overlayed with bitfields. -#define BitUnion(type, name) __BitUnion(type, name) - -//Use this to define conveniently sized values overlayed with bitfields. -#define BitUnion64(name) __BitUnion(uint64_t, name) -#define BitUnion32(name) __BitUnion(uint32_t, name) -#define BitUnion16(name) __BitUnion(uint16_t, name) -#define BitUnion8(name) __BitUnion(uint8_t, name) - #endif // __BASE_BITFIELD_HH__ |