cpu: constexpr most of RegId's methods, and add a RegIndex operator.

That will let a RegId be used where a RegId is required, but also let it
be downconverted into a scalar RegIndex if using an older API. Note that
this does *not* let you automatically upconvert from a RegIndex into a
RegId, since there would be no way to know what class of register to
use.

Change-Id: I5fff224dce5e02959d5fc3e717014bf7eaa9c022
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49753
Tested-by: kokoro <noreply+kokoro@google.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
diff --git a/src/cpu/reg_class.hh b/src/cpu/reg_class.hh
index a4b65d0..3372fce 100644
--- a/src/cpu/reg_class.hh
+++ b/src/cpu/reg_class.hh
@@ -93,22 +93,22 @@
     const debug::Flag &debugFlag;
 
   public:
-    RegClass(size_t num_regs, const debug::Flag &debug_flag,
+    constexpr RegClass(size_t num_regs, const debug::Flag &debug_flag,
             size_t reg_bytes=sizeof(RegVal)) :
         _numRegs(num_regs), _regBytes(reg_bytes),
         _regShift(ceilLog2(reg_bytes)), debugFlag(debug_flag)
     {}
-    RegClass(size_t num_regs, RegClassOps &new_ops,
+    constexpr RegClass(size_t num_regs, RegClassOps &new_ops,
             const debug::Flag &debug_flag, size_t reg_bytes=sizeof(RegVal)) :
         RegClass(num_regs, debug_flag, reg_bytes)
     {
         _ops = &new_ops;
     }
 
-    size_t numRegs() const { return _numRegs; }
-    size_t regBytes() const { return _regBytes; }
-    size_t regShift() const { return _regShift; }
-    const debug::Flag &debug() const { return debugFlag; }
+    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
@@ -134,24 +134,33 @@
     friend struct std::hash<RegId>;
 
   public:
-    RegId() : RegId(InvalidRegClass, 0) {}
+    constexpr RegId() : RegId(InvalidRegClass, 0) {}
 
-    explicit RegId(RegClassType reg_class, RegIndex reg_idx)
+    constexpr RegId(RegClassType reg_class, RegIndex reg_idx)
         : regClass(reg_class), regIdx(reg_idx), numPinnedWrites(0)
     {}
 
-    bool
+    constexpr operator RegIndex() const
+    {
+        return index();
+    }
+
+    constexpr bool
     operator==(const RegId& that) const
     {
         return regClass == that.classValue() && regIdx == that.index();
     }
 
-    bool operator!=(const RegId& that) const { return !(*this==that); }
+    constexpr bool
+    operator!=(const RegId& that) const
+    {
+        return !(*this==that);
+    }
 
     /** Order operator.
      * The order is required to implement maps with key type RegId
      */
-    bool
+    constexpr bool
     operator<(const RegId& that) const
     {
         return regClass < that.classValue() ||
@@ -161,23 +170,31 @@
     /**
      * Return true if this register can be renamed
      */
-    bool
+    constexpr bool
     isRenameable() const
     {
         return regClass != MiscRegClass && regClass != InvalidRegClass;
     }
 
     /** @return true if it is of the specified class. */
-    bool is(RegClassType reg_class) const { return regClass == reg_class; }
+    constexpr bool
+    is(RegClassType reg_class) const
+    {
+        return regClass == reg_class;
+    }
 
     /** Index accessors */
     /** @{ */
-    RegIndex index() const { return regIdx; }
+    constexpr RegIndex index() const { return regIdx; }
 
     /** Class accessor */
-    RegClassType classValue() const { return regClass; }
+    constexpr RegClassType classValue() const { return regClass; }
     /** Return a const char* with the register class name. */
-    const char* className() const { return regClassStrings[regClass]; }
+    constexpr const char*
+    className() const
+    {
+        return regClassStrings[regClass];
+    }
 
     int getNumPinnedWrites() const { return numPinnedWrites; }
     void setNumPinnedWrites(int num_writes) { numPinnedWrites = num_writes; }