arch-power: Refactor special purpose registers
authorSandipan Das <sandipan@linux.ibm.com>
Sat, 6 Feb 2021 11:42:50 +0000 (17:12 +0530)
committerSandipan Das <sandipan@linux.ibm.com>
Mon, 15 Feb 2021 08:32:37 +0000 (14:02 +0530)
This converts the definitions of all the currently defined
Special Purpose Registers (SPRs) to miscellaneous registers
which allows us to print the corresponding SPR name in the
debug logs rather than an ambiguous register number making
things much easier to correlate.

Change-Id: I03f10e3a44a8437beec453dfae2207d71ce43c1e
Signed-off-by: Sandipan Das <sandipan@linux.ibm.com>
src/arch/power/insts/integer.cc
src/arch/power/isa.hh
src/arch/power/isa/operands.isa
src/arch/power/miscregs.hh
src/arch/power/registers.hh
src/arch/power/remote_gdb.cc
src/arch/power/se_workload.hh

index febd469c4814db127cbf46cb885d16e55723cf7d..9355198c7a2405152f30f8ad8e4b9849947b5c86 100644 (file)
@@ -45,9 +45,16 @@ IntOp::generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const
     if (!myMnemonic.compare("or") && srcRegIdx(0) == srcRegIdx(1)) {
         myMnemonic = "mr";
         printSecondSrc = false;
-    } else if (!myMnemonic.compare("mtlr") || !myMnemonic.compare("cmpi")) {
+    } else if (!myMnemonic.compare("mtcrf") ||
+               !myMnemonic.compare("mtxer") ||
+               !myMnemonic.compare("mtlr")  ||
+               !myMnemonic.compare("mtctr") ||
+               !myMnemonic.compare("cmpi")) {
         printDest = false;
-    } else if (!myMnemonic.compare("mflr")) {
+    } else if (!myMnemonic.compare("mfcr")  ||
+               !myMnemonic.compare("mfxer") ||
+               !myMnemonic.compare("mflr")  ||
+               !myMnemonic.compare("mfctr")) {
         printSrcs = false;
     }
 
index 1fbbddfaada65612184a6421c143d650f4070197..557858f0a10c8a577567d3c2da5b8bd07f211ac5 100644 (file)
@@ -35,6 +35,7 @@
 #include "arch/power/types.hh"
 #include "base/logging.hh"
 #include "cpu/reg_class.hh"
+#include "debug/MiscRegs.hh"
 #include "sim/sim_object.hh"
 
 struct PowerISAParams;
@@ -60,30 +61,60 @@ class ISA : public BaseISA
     RegVal
     readMiscRegNoEffect(int misc_reg) const
     {
-        fatal("Power does not currently have any misc regs defined\n");
-        return dummy;
+        assert(misc_reg < NumMiscRegs);
+        int flatIndex = flattenMiscIndex(misc_reg);
+        auto val = miscRegs[flatIndex];
+        DPRINTF(MiscRegs, "Reading misc reg %d (%s) as %#x.\n", misc_reg,
+                miscRegName[flatIndex], val);
+        return val;
     }
 
     RegVal
     readMiscReg(int misc_reg)
     {
-        fatal("Power does not currently have any misc regs defined\n");
-        return dummy;
+        return readMiscRegNoEffect(misc_reg);
     }
 
     void
     setMiscRegNoEffect(int misc_reg, RegVal val)
     {
-        fatal("Power does not currently have any misc regs defined\n");
+        assert(misc_reg < NumMiscRegs);
+        int flatIndex = flattenMiscIndex(misc_reg);
+        DPRINTF(MiscRegs, "Setting misc reg %d (%s) to %#x.\n", misc_reg,
+                miscRegName[flatIndex], val);
+        miscRegs[flatIndex] = val;
     }
 
     void
     setMiscReg(int misc_reg, RegVal val)
     {
-        fatal("Power does not currently have any misc regs defined\n");
+        return setMiscRegNoEffect(misc_reg, val);
     }
 
-    RegId flattenRegId(const RegId& regId) const { return regId; }
+    RegId
+    flattenRegId(const RegId& regId) const
+    {
+        switch (regId.classValue()) {
+            case IntRegClass:
+                return RegId(IntRegClass, flattenIntIndex(regId.index()));
+            case FloatRegClass:
+                return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
+            case VecRegClass:
+                return RegId(VecRegClass, flattenVecIndex(regId.index()));
+            case VecElemClass:
+                return RegId(VecElemClass, flattenVecElemIndex(regId.index()),
+                             regId.elemIndex());
+            case VecPredRegClass:
+                return RegId(VecPredRegClass,
+                             flattenVecPredIndex(regId.index()));
+            case CCRegClass:
+                return RegId(CCRegClass, flattenCCIndex(regId.index()));
+            case MiscRegClass:
+                return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
+        }
+
+        return RegId();
+    }
 
     int
     flattenIntIndex(int reg) const
index 07415babd86c1ac42bc3a1e079a4e30c7e50472f..4ca4d2433e1e2581f56a498bf63407deb14324b1 100644 (file)
@@ -61,13 +61,13 @@ def operands {{
     'NIA': ('PCState', 'ud', 'npc', (None, None, 'IsControl'), 9),
 
     # Control registers
-    'CR': ('IntReg', 'uw', 'INTREG_CR', 'IsInteger', 9),
-    'LR': ('IntReg', 'ud', 'INTREG_LR', 'IsInteger', 9),
-    'CTR': ('IntReg', 'ud', 'INTREG_CTR', 'IsInteger', 9),
-    'XER': ('IntReg', 'uw', 'INTREG_XER', 'IsInteger', 9),
+    'CR': ('ControlReg', 'uw', 'MISCREG_CR', 'IsInteger', 9),
+    'XER': ('ControlReg', 'uw', 'MISCREG_XER', 'IsInteger', 9),
+    'LR': ('ControlReg', 'ud', 'MISCREG_LR', 'IsInteger', 9),
+    'CTR': ('ControlReg', 'ud', 'MISCREG_CTR', 'IsInteger', 9),
 
-    # Setting as IntReg so things are stored as an integer, not double
-    'FPSCR': ('IntReg', 'uw', 'INTREG_FPSCR', 'IsFloating', 9),
+    # Setting as ControlReg so things are stored as an integer, not double
+    'FPSCR': ('ControlReg', 'uw', 'MISCREG_FPSCR', 'IsFloating', 9),
 
     # Registers for linked loads and stores
     'Rsv': ('IntReg', 'uw', 'INTREG_RSV', 'IsInteger', 9),
index f7d9e3b07daa07253cc89e4ba97c5ba9d6cc146f..9d366b206e5d555f4d4c552b52f5c82064afed4d 100644 (file)
@@ -35,10 +35,20 @@ namespace PowerISA
 {
 
 enum MiscRegIndex {
-    NUM_MISCREGS = 0
+    MISCREG_CR,
+    MISCREG_FPSCR,
+    MISCREG_XER,
+    MISCREG_LR,
+    MISCREG_CTR,
+    NUM_MISCREGS
 };
 
 const char * const miscRegName[NUM_MISCREGS] = {
+    "CR",
+    "FPSCR",
+    "XER",
+    "LR",
+    "CTR",
 };
 
 BitUnion32(Cr)
index def55e30845a42b375bd02db55fd1fec7887dfb4..ad1b60814daf2702c227f85d2a75736bc19d9abb 100644 (file)
@@ -62,9 +62,9 @@ constexpr bool VecPredRegHasPackedRepr = ::DummyVecPredRegHasPackedRepr;
 // Constants Related to the number of registers
 const int NumIntArchRegs = 32;
 
-// CR, XER, LR, CTR, FPSCR, RSV, RSV-LEN, RSV-ADDR
+// RSV, RSV-LEN, RSV-ADDR
 // and zero register, which doesn't actually exist but needs a number
-const int NumIntSpecialRegs = 9;
+const int NumIntSpecialRegs = 4;
 const int NumFloatArchRegs = 32;
 
 const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs;
@@ -84,12 +84,7 @@ const int StackPointerReg = 1;
 const int ZeroReg = NumIntRegs - 1;
 
 enum MiscIntRegNums {
-    INTREG_CR = NumIntArchRegs,
-    INTREG_XER,
-    INTREG_LR,
-    INTREG_CTR,
-    INTREG_FPSCR,
-    INTREG_RSV,
+    INTREG_RSV = NumIntArchRegs,
     INTREG_RSV_LEN,
     INTREG_RSV_ADDR
 };
index ce9976fac6e7bb22a25ae79d47360aab36349baf..d2e292e42e38c1891e8159980b57e09319598af1 100644 (file)
@@ -182,10 +182,10 @@ RemoteGDB::PowerGdbRegCache::getRegs(ThreadContext *context)
 
     r.pc = htobe((uint32_t)context->pcState().pc());
     r.msr = 0; // Is MSR modeled?
-    r.cr = htobe((uint32_t)context->readIntReg(INTREG_CR));
-    r.lr = htobe((uint32_t)context->readIntReg(INTREG_LR));
-    r.ctr = htobe((uint32_t)context->readIntReg(INTREG_CTR));
-    r.xer = htobe((uint32_t)context->readIntReg(INTREG_XER));
+    r.cr = htobe((uint32_t)context->readMiscReg(MISCREG_CR));
+    r.lr = htobe((uint32_t)context->readMiscReg(MISCREG_LR));
+    r.ctr = htobe((uint32_t)context->readMiscReg(MISCREG_CTR));
+    r.xer = htobe((uint32_t)context->readMiscReg(MISCREG_XER));
 }
 
 void
@@ -201,10 +201,10 @@ RemoteGDB::PowerGdbRegCache::setRegs(ThreadContext *context) const
 
     context->pcState(betoh(r.pc));
     // Is MSR modeled?
-    context->setIntReg(INTREG_CR, betoh(r.cr));
-    context->setIntReg(INTREG_LR, betoh(r.lr));
-    context->setIntReg(INTREG_CTR, betoh(r.ctr));
-    context->setIntReg(INTREG_XER, betoh(r.xer));
+    context->setMiscReg(MISCREG_CR, betoh(r.cr));
+    context->setMiscReg(MISCREG_LR, betoh(r.lr));
+    context->setMiscReg(MISCREG_CTR, betoh(r.ctr));
+    context->setMiscReg(MISCREG_XER, betoh(r.xer));
 }
 
 BaseGdbRegCache*
index 5f3630cfde69cd9301777588e75040990d68f8b4..cb89aa30764bf0e385c69e11064856c11bed2aba 100644 (file)
@@ -72,13 +72,13 @@ struct Result<PowerISA::SEWorkload::SyscallABI, SyscallReturn>
         if (ret.suppressed() || ret.needsRetry())
             return;
 
-        PowerISA::Cr cr = tc->readIntReg(PowerISA::INTREG_CR);
+        PowerISA::Cr cr = tc->readIntReg(PowerISA::MISCREG_CR);
         if (ret.successful()) {
             cr.cr0.so = 0;
         } else {
             cr.cr0.so = 1;
         }
-        tc->setIntReg(PowerISA::INTREG_CR, cr);
+        tc->setIntReg(PowerISA::MISCREG_CR, cr);
         tc->setIntReg(PowerISA::ReturnValueReg, ret.encodedValue());
     }
 };