Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/49105 )

Change subject: cpu: Store raw byte vectors for register files.
......................................................................

cpu: Store raw byte vectors for register files.

Individual register files, like the ones for scalar integer, floating
point, or condition code registers, are now declared as vectors of their
actual type. Accessing them is simple, since the register you want can
be accessed simply by indexing into the vector.

Unfortunately, that means the code that sets up that storage has to know
what that underlying type is, and that means knowing (and hard coding)
information about the ISA being built.

Instead, this change makes the SimpleThread and O3 PhysRegFile classes
store registers as vectors of bytes, and offsets into those vectors
using computed offsets. Because the elements of the register files are
forced to be offset by powers of 2, computing the offsets can be done
with a shift rather than a multiplication.

The accessors which actually pull values in and out of these vectors are
still specific to each register type and need to know what the
underlying type is, but this change pulls that one level out of the CPUs
towards their peripheral APIs. Later changes will factor these uses out
as well.

Change-Id: I5e19d359a0e83e5827ae263d369999f90c7aa63d
---
M src/cpu/o3/regfile.cc
M src/cpu/o3/regfile.hh
M src/cpu/simple_thread.cc
M src/cpu/simple_thread.hh
4 files changed, 149 insertions(+), 67 deletions(-)



diff --git a/src/cpu/o3/regfile.cc b/src/cpu/o3/regfile.cc
index 746c256..d104564 100644
--- a/src/cpu/o3/regfile.cc
+++ b/src/cpu/o3/regfile.cc
@@ -54,13 +54,13 @@
                          unsigned _numPhysicalVecRegs,
                          unsigned _numPhysicalVecPredRegs,
                          unsigned _numPhysicalCCRegs,
-                         const BaseISA::RegClasses &regClasses,
+                         const BaseISA::RegClasses &reg_classes,
                          VecMode vmode)
-    : intRegFile(_numPhysicalIntRegs),
-      floatRegFile(_numPhysicalFloatRegs),
-      vectorRegFile(_numPhysicalVecRegs),
-      vecPredRegFile(_numPhysicalVecPredRegs),
-      ccRegFile(_numPhysicalCCRegs),
+    : intRegFile(reg_classes.at(IntRegClass), _numPhysicalIntRegs),
+      floatRegFile(reg_classes.at(FloatRegClass), _numPhysicalFloatRegs),
+      vectorRegFile(reg_classes.at(VecRegClass), _numPhysicalVecRegs),
+ vecPredRegFile(reg_classes.at(VecPredRegClass), _numPhysicalVecPredRegs),
+      ccRegFile(reg_classes.at(CCRegClass), _numPhysicalCCRegs),
       numPhysicalIntRegs(_numPhysicalIntRegs),
       numPhysicalFloatRegs(_numPhysicalFloatRegs),
       numPhysicalVecRegs(_numPhysicalVecRegs),
@@ -84,7 +84,7 @@
         intRegIds.emplace_back(IntRegClass, phys_reg, flat_reg_idx++);
     }

-    zeroReg = RegId(IntRegClass, regClasses.at(IntRegClass).zeroReg());
+    zeroReg = RegId(IntRegClass, reg_classes.at(IntRegClass).zeroReg());

     // The next batch of the registers are the floating-point physical
     // registers; put them onto the floating-point free list.
@@ -95,7 +95,6 @@
     // The next batch of the registers are the vector physical
     // registers; put them onto the vector free list.
     for (phys_reg = 0; phys_reg < numPhysicalVecRegs; phys_reg++) {
-        vectorRegFile[phys_reg].zero();
         vecRegIds.emplace_back(VecRegClass, phys_reg, flat_reg_idx++);
     }
     // The next batch of the registers are the vector element physical
@@ -122,7 +121,7 @@
     }

     // Misc regs have a fixed mapping but still need PhysRegIds.
-    for (phys_reg = 0; phys_reg < regClasses.at(MiscRegClass).size();
+    for (phys_reg = 0; phys_reg < reg_classes.at(MiscRegClass).size();
             phys_reg++) {
         miscRegIds.emplace_back(MiscRegClass, phys_reg, 0);
     }
diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh
index 8101d53..3c8ebdb 100644
--- a/src/cpu/o3/regfile.hh
+++ b/src/cpu/o3/regfile.hh
@@ -73,26 +73,61 @@
     using IdRange = std::pair<PhysIds::iterator,
                               PhysIds::iterator>;
   private:
+    class RegFile
+    {
+      private:
+        std::vector<uint8_t> data;
+        const size_t _size;
+        const size_t _regShift;
+        const size_t _regBytes;
+
+      public:
+        RegFile(const RegClass &info, unsigned num_phys) :
+            data(num_phys << info.regShift()), _size(num_phys),
+            _regShift(info.regShift()), _regBytes(info.regBytes())
+        {}
+
+        size_t size() const { return _size; }
+        size_t regShift() const { return _regShift; }
+        size_t regBytes() const { return _regBytes; }
+
+        template <typename Reg=RegVal>
+        Reg &
+        reg(size_t idx)
+        {
+ return *reinterpret_cast<Reg *>(data.data() + (idx << _regShift));
+        }
+        template <typename Reg=RegVal>
+        const Reg &
+        reg(size_t idx) const
+        {
+            return *reinterpret_cast<const Reg *>(
+                    data.data() + (idx << _regShift));
+        }
+
+        void clear() { std::fill(data.begin(), data.end(), 0); }
+    };
+
     /** Integer register file. */
-    std::vector<RegVal> intRegFile;
+    RegFile intRegFile;
     std::vector<PhysRegId> intRegIds;
     RegId zeroReg;

     /** Floating point register file. */
-    std::vector<RegVal> floatRegFile;
+    RegFile floatRegFile;
     std::vector<PhysRegId> floatRegIds;

     /** Vector register file. */
-    std::vector<TheISA::VecRegContainer> vectorRegFile;
+    RegFile vectorRegFile;
     std::vector<PhysRegId> vecRegIds;
     std::vector<PhysRegId> vecElemIds;

     /** Predicate register file. */
-    std::vector<TheISA::VecPredRegContainer> vecPredRegFile;
+    RegFile vecPredRegFile;
     std::vector<PhysRegId> vecPredRegIds;

     /** Condition-code register file. */
-    std::vector<RegVal> ccRegFile;
+    RegFile ccRegFile;
     std::vector<PhysRegId> ccRegIds;

     /** Misc Reg Ids */
@@ -144,9 +179,8 @@
                 unsigned _numPhysicalVecRegs,
                 unsigned _numPhysicalVecPredRegs,
                 unsigned _numPhysicalCCRegs,
-                const BaseISA::RegClasses &regClasses,
-                VecMode vmode
-                );
+                const BaseISA::RegClasses &,
+                VecMode vmode);

     /**
      * Destructor to free resources
@@ -187,8 +221,8 @@
         assert(phys_reg->is(IntRegClass));

         DPRINTF(IEW, "RegFile: Access to int register %i, has data "
-                "%#x\n", phys_reg->index(), intRegFile[phys_reg->index()]);
-        return intRegFile[phys_reg->index()];
+ "%#x\n", phys_reg->index(), intRegFile.reg(phys_reg->index()));
+        return intRegFile.reg(phys_reg->index());
     }

     RegVal
@@ -196,7 +230,7 @@
     {
         assert(phys_reg->is(FloatRegClass));

-        RegVal floatRegBits = floatRegFile[phys_reg->index()];
+        RegVal floatRegBits = floatRegFile.reg(phys_reg->index());

         DPRINTF(IEW, "RegFile: Access to float register %i as int, "
                 "has data %#x\n", phys_reg->index(), floatRegBits);
@@ -212,9 +246,9 @@

         DPRINTF(IEW, "RegFile: Access to vector register %i, has "
                 "data %s\n", int(phys_reg->index()),
-                vectorRegFile[phys_reg->index()]);
+ vectorRegFile.reg<TheISA::VecRegContainer>(phys_reg->index()));

-        return vectorRegFile[phys_reg->index()];
+ return vectorRegFile.reg<TheISA::VecRegContainer>(phys_reg->index());
     }

     /** Reads a vector register for modification. */
@@ -230,7 +264,8 @@
     readVecElem(PhysRegIdPtr phys_reg) const
     {
         assert(phys_reg->is(VecElemClass));
-        auto ret = vectorRegFile[phys_reg->index()].as<TheISA::VecElem>();
+        auto ret = vectorRegFile.reg<TheISA::VecRegContainer>(
+                phys_reg->index()).as<TheISA::VecElem>();
         const TheISA::VecElem& val = ret[phys_reg->elemIndex()];
         DPRINTF(IEW, "RegFile: Access to element %d of vector register %i,"
                 " has data %#x\n", phys_reg->elemIndex(),
@@ -247,9 +282,11 @@

         DPRINTF(IEW, "RegFile: Access to predicate register %i, has "
                 "data %s\n", int(phys_reg->index()),
-                vecPredRegFile[phys_reg->index()]);
+                vecPredRegFile.reg<TheISA::VecPredRegContainer>(
+                    phys_reg->index()));

-        return vecPredRegFile[phys_reg->index()];
+        return vecPredRegFile.reg<TheISA::VecPredRegContainer>(
+                phys_reg->index());
     }

     TheISA::VecPredRegContainer&
@@ -268,9 +305,9 @@

         DPRINTF(IEW, "RegFile: Access to cc register %i, has "
                 "data %#x\n", phys_reg->index(),
-                ccRegFile[phys_reg->index()]);
+                ccRegFile.reg(phys_reg->index()));

-        return ccRegFile[phys_reg->index()];
+        return ccRegFile.reg(phys_reg->index());
     }

     /** Sets an integer register to the given value. */
@@ -283,7 +320,7 @@
                 phys_reg->index(), val);

         if (phys_reg->index() != zeroReg.index())
-            intRegFile[phys_reg->index()] = val;
+            intRegFile.reg(phys_reg->index()) = val;
     }

     void
@@ -294,7 +331,7 @@
         DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
                 phys_reg->index(), (uint64_t)val);

-        floatRegFile[phys_reg->index()] = val;
+        floatRegFile.reg(phys_reg->index()) = val;
     }

     /** Sets a vector register to the given value. */
@@ -306,7 +343,7 @@
         DPRINTF(IEW, "RegFile: Setting vector register %i to %s\n",
                 int(phys_reg->index()), val);

-        vectorRegFile[phys_reg->index()] = val;
+ vectorRegFile.reg<TheISA::VecRegContainer>(phys_reg->index()) = val;
     }

     /** Sets a vector register to the given value. */
@@ -318,8 +355,8 @@
         DPRINTF(IEW, "RegFile: Setting element %d of vector register %i to"
" %#x\n", phys_reg->elemIndex(), int(phys_reg->index()), val);

-        vectorRegFile[phys_reg->index()].as<TheISA::VecElem>()[
-            phys_reg->elemIndex()] = val;
+        vectorRegFile.reg<TheISA::VecRegContainer>(phys_reg->index()).
+            as<TheISA::VecElem>()[phys_reg->elemIndex()] = val;
     }

     /** Sets a predicate register to the given value. */
@@ -332,7 +369,8 @@
         DPRINTF(IEW, "RegFile: Setting predicate register %i to %s\n",
                 int(phys_reg->index()), val);

-        vecPredRegFile[phys_reg->index()] = val;
+        vecPredRegFile.reg<TheISA::VecPredRegContainer>(
+                phys_reg->index()) = val;
     }

     /** Sets a condition-code register to the given value. */
@@ -344,7 +382,7 @@
         DPRINTF(IEW, "RegFile: Setting cc register %i to %#x\n",
                 phys_reg->index(), (uint64_t)val);

-        ccRegFile[phys_reg->index()] = val;
+        ccRegFile.reg(phys_reg->index()) = val;
     }

     /** Get the PhysRegIds of the elems of a vector register.
diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc
index 67756b4..cd28b8c 100644
--- a/src/cpu/simple_thread.cc
+++ b/src/cpu/simple_thread.cc
@@ -69,19 +69,17 @@
                            Process *_process, BaseMMU *_mmu,
                            BaseISA *_isa)
     : ThreadState(_cpu, _thread_num, _process),
+      floatRegs(_isa->regClasses().at(FloatRegClass)),
+      intRegs(_isa->regClasses().at(IntRegClass)),
+      vecRegs(_isa->regClasses().at(VecRegClass)),
+      vecPredRegs(_isa->regClasses().at(VecPredRegClass)),
+      ccRegs(_isa->regClasses().at(CCRegClass)),
       isa(dynamic_cast<TheISA::ISA *>(_isa)),
       predicate(true), memAccPredicate(true),
       comInstEventQueue("instruction-based event queue"),
       system(_sys), mmu(_mmu), decoder(isa),
       htmTransactionStarts(0), htmTransactionStops(0)
 {
-    assert(isa);
-    const auto &regClasses = isa->regClasses();
-    intRegs.resize(regClasses.at(IntRegClass).size());
-    floatRegs.resize(regClasses.at(FloatRegClass).size());
-    vecRegs.resize(regClasses.at(VecRegClass).size());
-    vecPredRegs.resize(regClasses.at(VecPredRegClass).size());
-    ccRegs.resize(regClasses.at(CCRegClass).size());
     clearArchRegs();
 }

diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh
index 37f666c..97bd21a 100644
--- a/src/cpu/simple_thread.hh
+++ b/src/cpu/simple_thread.hh
@@ -97,11 +97,46 @@
     typedef ThreadContext::Status Status;

   protected:
-    std::vector<RegVal> floatRegs;
-    std::vector<RegVal> intRegs;
-    std::vector<TheISA::VecRegContainer> vecRegs;
-    std::vector<TheISA::VecPredRegContainer> vecPredRegs;
-    std::vector<RegVal> ccRegs;
+    class RegFile
+    {
+      private:
+        std::vector<uint8_t> data;
+        const size_t _size;
+        const size_t _regShift;
+        const size_t _regBytes;
+
+      public:
+        RegFile(const RegClass &info) :
+            data(info.size() << info.regShift()), _size(info.size()),
+            _regShift(info.regShift()), _regBytes(info.regBytes())
+        {}
+
+        size_t size() const { return _size; }
+        size_t regShift() const { return _regShift; }
+        size_t regBytes() const { return _regBytes; }
+
+        template <typename Reg=RegVal>
+        Reg &
+        reg(size_t idx)
+        {
+ return *reinterpret_cast<Reg *>(data.data() + (idx << _regShift));
+        }
+        template <typename Reg=RegVal>
+        const Reg &
+        reg(size_t idx) const
+        {
+            return *reinterpret_cast<const Reg *>(
+                    data.data() + (idx << _regShift));
+        }
+
+        void clear() { std::fill(data.begin(), data.end(), 0); }
+    };
+
+    RegFile floatRegs;
+    RegFile intRegs;
+    RegFile vecRegs;
+    RegFile vecPredRegs;
+    RegFile ccRegs;
     TheISA::ISA *const isa;    // one "instance" of the current ISA.

     TheISA::PCState _pcState;
@@ -249,13 +284,11 @@
     clearArchRegs() override
     {
         _pcState = 0;
-        std::fill(intRegs.begin(), intRegs.end(), 0);
-        std::fill(floatRegs.begin(), floatRegs.end(), 0);
-        for (auto &vec_reg: vecRegs)
-            vec_reg.zero();
-        for (auto &pred_reg: vecPredRegs)
-            pred_reg.reset();
-        std::fill(ccRegs.begin(), ccRegs.end(), 0);
+        intRegs.clear();
+        floatRegs.clear();
+        vecRegs.clear();
+        vecPredRegs.clear();
+        ccRegs.clear();
         isa->clear();
     }

@@ -484,76 +517,90 @@
         storeCondFailures = sc_failures;
     }

- RegVal readIntRegFlat(RegIndex idx) const override { return intRegs[idx]; }
+    RegVal
+    readIntRegFlat(RegIndex idx) const override
+    {
+        return intRegs.reg(idx);
+    }
     void
     setIntRegFlat(RegIndex idx, RegVal val) override
     {
-        intRegs[idx] = val;
+        intRegs.reg(idx) = val;
     }

     RegVal
     readFloatRegFlat(RegIndex idx) const override
     {
-        return floatRegs[idx];
+        return floatRegs.reg(idx);
     }
     void
     setFloatRegFlat(RegIndex idx, RegVal val) override
     {
-        floatRegs[idx] = val;
+        floatRegs.reg(idx) = val;
     }

     const TheISA::VecRegContainer &
     readVecRegFlat(RegIndex reg) const override
     {
-        return vecRegs[reg];
+        return vecRegs.reg<TheISA::VecRegContainer>(reg);
     }

     TheISA::VecRegContainer &
     getWritableVecRegFlat(RegIndex reg) override
     {
-        return vecRegs[reg];
+        return vecRegs.reg<TheISA::VecRegContainer>(reg);
     }

     void
setVecRegFlat(RegIndex reg, const TheISA::VecRegContainer &val) override
     {
-        vecRegs[reg] = val;
+        vecRegs.reg<TheISA::VecRegContainer>(reg) = val;
     }

     const TheISA::VecElem &
readVecElemFlat(RegIndex reg, const ElemIndex &elemIndex) const override
     {
-        return vecRegs[reg].as<TheISA::VecElem>()[elemIndex];
+        return vecRegs.reg<TheISA::VecRegContainer>(reg).
+            as<TheISA::VecElem>()[elemIndex];
     }

     void
     setVecElemFlat(RegIndex reg, const ElemIndex &elemIndex,
                    const TheISA::VecElem &val) override
     {
-        vecRegs[reg].as<TheISA::VecElem>()[elemIndex] = val;
+        vecRegs.reg<TheISA::VecRegContainer>(reg).
+            as<TheISA::VecElem>()[elemIndex] = val;
     }

     const TheISA::VecPredRegContainer &
     readVecPredRegFlat(RegIndex reg) const override
     {
-        return vecPredRegs[reg];
+        return vecPredRegs.reg<TheISA::VecPredRegContainer>(reg);
     }

     TheISA::VecPredRegContainer &
     getWritableVecPredRegFlat(RegIndex reg) override
     {
-        return vecPredRegs[reg];
+        return vecPredRegs.reg<TheISA::VecPredRegContainer>(reg);
     }

     void
     setVecPredRegFlat(RegIndex reg,
             const TheISA::VecPredRegContainer &val) override
     {
-        vecPredRegs[reg] = val;
+        vecPredRegs.reg<TheISA::VecPredRegContainer>(reg) = val;
     }

- RegVal readCCRegFlat(RegIndex idx) const override { return ccRegs[idx]; } - void setCCRegFlat(RegIndex idx, RegVal val) override { ccRegs[idx] = val; }
+    RegVal
+    readCCRegFlat(RegIndex idx) const override
+    {
+        return ccRegs.reg(idx);
+    }
+    void
+    setCCRegFlat(RegIndex idx, RegVal val) override
+    {
+        ccRegs.reg(idx) = val;
+    }

     // hardware transactional memory
     void htmAbortTransaction(uint64_t htm_uid,

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/49105
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I5e19d359a0e83e5827ae263d369999f90c7aa63d
Gerrit-Change-Number: 49105
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to