diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index 32103514cf..ed4cf24d83 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -80,7 +80,7 @@ class MiscRegClassOps : public RegClassOps } } miscRegClassOps; -VecElemRegClassOps vecRegElemClassOps(NumVecElemPerVecReg); +VecElemRegClassOps vecRegElemClassOps(NumVecElemPerVecReg); ISA::ISA(const Params &p) : BaseISA(p), system(NULL), _decoderFlavor(p.decoderFlavor), pmu(p.pmu), impdefAsNop(p.impdef_nop), diff --git a/src/cpu/reg_class.cc b/src/cpu/reg_class.cc index b6678383bf..51b607af63 100644 --- a/src/cpu/reg_class.cc +++ b/src/cpu/reg_class.cc @@ -39,23 +39,61 @@ */ #include "cpu/reg_class.hh" + +#include + #include "base/cprintf.hh" namespace gem5 { std::string -DefaultRegClassOps::regName(const RegId &id) const +RegClassOps::regName(const RegId &id) const { return csprintf("r%d", id.index()); } std::string -VecElemRegClassOps::regName(const RegId &id) const +RegClassOps::valString(const void *val, size_t size) const { - RegIndex reg_idx = id.index() / elemsPerVec; - RegIndex elem_idx = id.index() % elemsPerVec; - return csprintf("v%d[%d]", reg_idx, elem_idx); + // If this is just a RegVal, or could be interpreted as one, print it + // that way. + if (size == sizeof(uint64_t)) + return csprintf("0x%016x", *(const uint64_t *)val); + else if (size == sizeof(uint32_t)) + return csprintf("0x%08x", *(const uint32_t *)val); + else if (size == sizeof(uint16_t)) + return csprintf("0x%04x", *(const uint16_t *)val); + else if (size == sizeof(uint8_t)) + return csprintf("0x%02x", *(const uint8_t *)val); + + // Otherwise, print it as a sequence of bytes, 4 in a chunk, separated by + // spaces, and all surrounded by []s. + + std::stringstream out; + ccprintf(out, "["); + + constexpr size_t chunk_size = 4; + const uint8_t *bytes = (const uint8_t *)val; + + while (size >= chunk_size) { + size -= chunk_size; + if (size) { + ccprintf(out, "%02x%02x%02x%02x ", bytes[0], bytes[1], bytes[2], + bytes[3]); + } else { + ccprintf(out, "%02x%02x%02x%02x", bytes[0], bytes[1], bytes[2], + bytes[3]); + } + bytes += chunk_size; + } + + while (size--) + ccprintf(out, "%02x", *bytes++); + + ccprintf(out, "]"); + + return out.str(); } const char *RegId::regClassStrings[] = { diff --git a/src/cpu/reg_class.hh b/src/cpu/reg_class.hh index 5664bc31be..e9e54da379 100644 --- a/src/cpu/reg_class.hh +++ b/src/cpu/reg_class.hh @@ -44,6 +44,7 @@ #include #include +#include "base/cprintf.hh" #include "base/intmath.hh" #include "base/types.hh" @@ -69,26 +70,10 @@ class RegId; class RegClassOps { public: - virtual std::string regName(const RegId &id) const = 0; -}; - -class DefaultRegClassOps : public RegClassOps -{ - public: - std::string regName(const RegId &id) const override; -}; - -class VecElemRegClassOps : public RegClassOps -{ - protected: - size_t elemsPerVec; - - public: - explicit VecElemRegClassOps(size_t elems_per_vec) : - elemsPerVec(elems_per_vec) - {} - - std::string regName(const RegId &id) const override; + /** 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 @@ -102,7 +87,7 @@ class RegClass // be calculated with a multiply. size_t _regShift; - static inline DefaultRegClassOps defaultOps; + static inline RegClassOps defaultOps; RegClassOps *_ops = &defaultOps; public: @@ -124,6 +109,11 @@ class RegClass size_t regShift() const { return _regShift; } std::string regName(const RegId &id) const { return _ops->regName(id); } + std::string + valString(const void *val) const + { + return _ops->valString(val, regBytes()); + } }; /** Register ID: describe an architectural register with its class and index. @@ -197,6 +187,38 @@ class RegId } }; +template +class TypedRegClassOps : public RegClassOps +{ + public: + std::string + valString(const void *val, size_t size) const override + { + assert(size == sizeof(ValueType)); + return csprintf("%s", *(const ValueType *)val); + } +}; + +template +class VecElemRegClassOps : public TypedRegClassOps +{ + protected: + size_t elemsPerVec; + + public: + explicit VecElemRegClassOps(size_t elems_per_vec) : + elemsPerVec(elems_per_vec) + {} + + std::string + regName(const RegId &id) const override + { + RegIndex reg_idx = id.index() / elemsPerVec; + RegIndex elem_idx = id.index() % elemsPerVec; + return csprintf("v%d[%d]", reg_idx, elem_idx); + } +}; + /** Physical register ID. * Like a register ID but physical. The inheritance is private because the * only relationship between this types is functional, and it is done to