diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/alpha/predecoder.hh | 1 | ||||
-rw-r--r-- | src/arch/sparc/predecoder.hh | 1 | ||||
-rw-r--r-- | src/base/bitfield.hh | 210 | ||||
-rw-r--r-- | src/cpu/exetrace.cc | 10 |
4 files changed, 220 insertions, 2 deletions
diff --git a/src/arch/alpha/predecoder.hh b/src/arch/alpha/predecoder.hh index 4e89f53a6..650f2bfa2 100644 --- a/src/arch/alpha/predecoder.hh +++ b/src/arch/alpha/predecoder.hh @@ -33,6 +33,7 @@ #include "arch/alpha/types.hh" #include "base/misc.hh" +#include "config/full_system.hh" #include "sim/host.hh" class ThreadContext; diff --git a/src/arch/sparc/predecoder.hh b/src/arch/sparc/predecoder.hh index 71b14b020..4a8c9dc4a 100644 --- a/src/arch/sparc/predecoder.hh +++ b/src/arch/sparc/predecoder.hh @@ -33,6 +33,7 @@ #include "arch/sparc/types.hh" #include "base/misc.hh" +#include "cpu/thread_context.hh" #include "sim/host.hh" class ThreadContext; diff --git a/src/base/bitfield.hh b/src/base/bitfield.hh index 79dbcc86c..ff816286f 100644 --- a/src/base/bitfield.hh +++ b/src/base/bitfield.hh @@ -130,6 +130,216 @@ 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) + { + 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 const Type () + { + return this->getBits(first, last); + } + + const Type + operator=(const Type & _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: + const Type + operator=(const Type & _data); + }; + + //Similar to the above, but only allows writing. + template<int first, int last=first> + class BitfieldWO : public Bitfield<first, last> + { + private: + operator const Type (); + + public: + const Type operator=(const Type & _data) + { + *((Bitfield<first, last> *)this) = _data; + return _data; + } + }; + }; + + template<class Type> + class BitfieldTypes : public RegularBitfieldTypes<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 const Type () + { + return Base::__data; + } + + const Type + operator=(const Type & _data) + { + Base::__data = _data; + } + + bool + operator<(const Base & base) + { + return Base::__data < base.__data; + } + + bool + operator==(const Base & base) + { + 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) + +//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__ diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index 1799b46c5..c568b1439 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -37,6 +37,7 @@ #include <sys/ipc.h> #include <sys/shm.h> +#include "arch/predecoder.hh" #include "arch/regfile.hh" #include "arch/utility.hh" #include "base/loader/symtab.hh" @@ -393,6 +394,7 @@ Trace::InstRecord::dump() outs << endl; } #if THE_ISA == SPARC_ISA && FULL_SYSTEM + static TheISA::Predecoder predecoder(NULL); // Compare if (IsOn(ExecLegion)) { @@ -647,9 +649,13 @@ Trace::InstRecord::dump() << staticInst->disassemble(m5Pc, debugSymbolTable) << endl; + predecoder.setTC(thread); + predecoder.moreBytes(m5Pc, 0, shared_data->instruction); + + assert(predecoder.extMachInstRead()); + StaticInstPtr legionInst = - StaticInst::decode(makeExtMI(shared_data->instruction, - thread)); + StaticInst::decode(predecoder.getExtMachInst()); outs << setfill(' ') << setw(15) << " Legion Inst: " << "0x" << setw(8) << setfill('0') << hex |