diff --git a/src/cpu/reg_class.hh b/src/cpu/reg_class.hh index 177b6fadc5..080c758413 100644 --- a/src/cpu/reg_class.hh +++ b/src/cpu/reg_class.hh @@ -78,84 +78,9 @@ inline constexpr char VecPredRegClassName[] = "vector_predicate"; inline constexpr char CCRegClassName[] = "condition_code"; inline constexpr char MiscRegClassName[] = "miscellaneous"; -class RegId; - -class RegClassOps -{ - public: - /** Print the name of the register specified in id. */ - virtual std::string regName(const RegId &id) const; - /** Print the value of a register pointed to by val of size size. */ - virtual std::string valString(const void *val, size_t size) const; -}; - +class RegClass; class RegClassIterator; - -class RegClass -{ - private: - RegClassType _type; - const char *_name; - - size_t _numRegs; - size_t _regBytes = sizeof(RegVal); - // This is how much to shift an index by to get an offset of a register in - // a register file from the register index, which would otherwise need to - // be calculated with a multiply. - size_t _regShift = ceilLog2(sizeof(RegVal)); - - static inline RegClassOps defaultOps; - RegClassOps *_ops = &defaultOps; - const debug::Flag &debugFlag; - - public: - constexpr RegClass(RegClassType type, const char *new_name, - size_t num_regs, const debug::Flag &debug_flag) : - _type(type), _name(new_name), _numRegs(num_regs), debugFlag(debug_flag) - {} - - constexpr RegClass - ops(RegClassOps &new_ops) const - { - RegClass reg_class = *this; - reg_class._ops = &new_ops; - return reg_class; - } - - template - constexpr RegClass - regType() const - { - RegClass reg_class = *this; - reg_class._regBytes = sizeof(RegType); - reg_class._regShift = ceilLog2(reg_class._regBytes); - return reg_class; - } - - constexpr RegClassType type() const { return _type; } - constexpr const char *name() const { return _name; } - constexpr size_t numRegs() const { return _numRegs; } - constexpr size_t regBytes() const { return _regBytes; } - constexpr size_t regShift() const { return _regShift; } - constexpr const debug::Flag &debug() const { return debugFlag; } - - std::string regName(const RegId &id) const { return _ops->regName(id); } - std::string - valString(const void *val) const - { - return _ops->valString(val, regBytes()); - } - - using iterator = RegClassIterator; - - inline iterator begin() const; - inline iterator end() const; - - inline constexpr RegId operator[](RegIndex idx) const; -}; - -inline constexpr RegClass - invalidRegClass(InvalidRegClass, "invalid", 0, debug::InvalidReg); +class BaseISA; /** Register ID: describe an architectural register with its class and index. * This structure is used instead of just the register index to disambiguate @@ -173,7 +98,7 @@ class RegId friend class RegClassIterator; public: - constexpr RegId() : RegId(invalidRegClass, 0) {} + inline constexpr RegId(); constexpr RegId(const RegClass ®_class, RegIndex reg_idx) : _regClass(®_class), regIdx(reg_idx), numPinnedWrites(0) @@ -216,11 +141,7 @@ class RegId } /** @return true if it is of the specified class. */ - constexpr bool - is(RegClassType reg_class) const - { - return _regClass->type() == reg_class; - } + inline constexpr bool is(RegClassType reg_class) const; /** Index accessors */ /** @{ */ @@ -228,24 +149,142 @@ class RegId /** Class accessor */ constexpr const RegClass ®Class() const { return *_regClass; } - constexpr RegClassType classValue() const { return _regClass->type(); } + inline constexpr RegClassType classValue() const; /** Return a const char* with the register class name. */ - constexpr const char* - className() const - { - return _regClass->name(); - } + inline constexpr const char* className() const; + + inline constexpr bool isFlat() const; + inline RegId flatten(const BaseISA &isa) const; int getNumPinnedWrites() const { return numPinnedWrites; } void setNumPinnedWrites(int num_writes) { numPinnedWrites = num_writes; } - friend std::ostream& - operator<<(std::ostream& os, const RegId& rid) + friend inline std::ostream& operator<<(std::ostream& os, const RegId& rid); +}; + +class RegClassOps +{ + public: + /** Print the name of the register specified in id. */ + virtual std::string regName(const RegId &id) const; + /** Print the value of a register pointed to by val of size size. */ + virtual std::string valString(const void *val, size_t size) const; + /** Flatten register id id using information in the ISA object isa. */ + virtual RegId + flatten(const BaseISA &isa, const RegId &id) const { - return os << rid.regClass().regName(rid); + return id; } }; +class RegClassIterator; + +class RegClass +{ + private: + RegClassType _type; + const char *_name; + + size_t _numRegs; + size_t _regBytes = sizeof(RegVal); + // This is how much to shift an index by to get an offset of a register in + // a register file from the register index, which would otherwise need to + // be calculated with a multiply. + size_t _regShift = ceilLog2(sizeof(RegVal)); + + static inline RegClassOps defaultOps; + const RegClassOps *_ops = &defaultOps; + const debug::Flag &debugFlag; + + bool _flat = true; + + public: + constexpr RegClass(RegClassType type, const char *new_name, + size_t num_regs, const debug::Flag &debug_flag) : + _type(type), _name(new_name), _numRegs(num_regs), debugFlag(debug_flag) + {} + + constexpr RegClass + needsFlattening() const + { + RegClass reg_class = *this; + reg_class._flat = false; + return reg_class; + } + + constexpr RegClass + ops(const RegClassOps &new_ops) const + { + RegClass reg_class = *this; + reg_class._ops = &new_ops; + return reg_class; + } + + template + constexpr RegClass + regType() const + { + RegClass reg_class = *this; + reg_class._regBytes = sizeof(RegType); + reg_class._regShift = ceilLog2(reg_class._regBytes); + return reg_class; + } + + constexpr RegClassType type() const { return _type; } + constexpr const char *name() const { return _name; } + constexpr size_t numRegs() const { return _numRegs; } + constexpr size_t regBytes() const { return _regBytes; } + constexpr size_t regShift() const { return _regShift; } + constexpr const debug::Flag &debug() const { return debugFlag; } + constexpr bool isFlat() const { return _flat; } + + std::string regName(const RegId &id) const { return _ops->regName(id); } + std::string + valString(const void *val) const + { + return _ops->valString(val, regBytes()); + } + RegId + flatten(const BaseISA &isa, const RegId &id) const + { + return isFlat() ? id : _ops->flatten(isa, id); + } + + using iterator = RegClassIterator; + + inline iterator begin() const; + inline iterator end() const; + + inline constexpr RegId operator[](RegIndex idx) const; +}; + +inline constexpr RegClass + invalidRegClass(InvalidRegClass, "invalid", 0, debug::InvalidReg); + +constexpr RegId::RegId() : RegId(invalidRegClass, 0) {} + +constexpr bool +RegId::is(RegClassType reg_class) const +{ + return _regClass->type() == reg_class; +} + +constexpr RegClassType RegId::classValue() const { return _regClass->type(); } +constexpr const char* RegId::className() const { return _regClass->name(); } + +constexpr bool RegId::isFlat() const { return _regClass->isFlat(); } +RegId +RegId::flatten(const BaseISA &isa) const +{ + return _regClass->flatten(isa, *this); +} + +std::ostream& +operator<<(std::ostream& os, const RegId& rid) +{ + return os << rid.regClass().regName(rid); +} + class RegClassIterator { private: