sparc: Introduce constants for pseudo integer registers.
authorGabe Black <gabeblack@google.com>
Sat, 7 Dec 2019 10:12:53 +0000 (02:12 -0800)
committerGabe Black <gabeblack@google.com>
Thu, 12 Mar 2020 01:35:34 +0000 (01:35 +0000)
These are "integer" registers which are renamed, but which aren't
normally considered integer registers by the ISA. They had been indexed
by adding an opaque constant to the number of official integer
registers which obscured what they were, and was also fragile and
invited mistakes.

Change-Id: Idab8cf4d889682b98c7c81a00d9a92d8e3bb3a05
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/23445
Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/sparc/faults.cc
src/arch/sparc/isa/operands.isa
src/arch/sparc/linux/linux.hh
src/arch/sparc/nativetrace.cc
src/arch/sparc/process.cc
src/arch/sparc/registers.hh
src/arch/sparc/remote_gdb.cc
src/arch/sparc/sparc_traits.hh

index d134fb50f5392ab69d020e1d6e1a55d81eeb9cae..c1b49e108f68b900c27ceafa0471371f15a227cc 100644 (file)
@@ -303,10 +303,10 @@ doREDFault(ThreadContext *tc, TrapType tt)
     RegVal TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE);
     PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
     HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
-    RegVal CCR = tc->readIntReg(NumIntArchRegs + 2);
+    RegVal CCR = tc->readIntReg(INTREG_CCR);
     RegVal ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
     RegVal CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
-    RegVal CANSAVE = tc->readMiscRegNoEffect(NumIntArchRegs + 3);
+    RegVal CANSAVE = tc->readMiscRegNoEffect(INTREG_CANSAVE);
     RegVal GL = tc->readMiscRegNoEffect(MISCREG_GL);
     PCState pc = tc->pcState();
 
@@ -382,10 +382,10 @@ doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
     RegVal TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE);
     PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
     HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
-    RegVal CCR = tc->readIntReg(NumIntArchRegs + 2);
+    RegVal CCR = tc->readIntReg(INTREG_CCR);
     RegVal ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
     RegVal CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
-    RegVal CANSAVE = tc->readIntReg(NumIntArchRegs + 3);
+    RegVal CANSAVE = tc->readIntReg(INTREG_CANSAVE);
     RegVal GL = tc->readMiscRegNoEffect(MISCREG_GL);
     PCState pc = tc->pcState();
 
index c408c422ffe4b75fd7770ae749ba1d5ae02bb586..2c1eec6b1984f7dd8087baa4b46e59fbf16caafc 100644 (file)
@@ -85,7 +85,7 @@ def operands {{
     'Rs1':              ('IntReg', 'udw', 'RS1', 'IsInteger', 6),
     'Rs2':              ('IntReg', 'udw', 'RS2', 'IsInteger', 7),
     # A microcode register. Right now, this is the only one.
-    'uReg0':            ('IntReg', 'udw', 'NumIntArchRegs', 'IsInteger', 8),
+    'uReg0':            ('IntReg', 'udw', 'INTREG_UREG0', 'IsInteger', 8),
     # Because double and quad precision register numbers are decoded
     # differently, they get different operands. The single precision versions
     # have an s post pended to their name.
@@ -135,24 +135,21 @@ def operands {{
     'R1':               ('IntReg', 'udw', '1', None, 7),
     'R15':              ('IntReg', 'udw', '15', 'IsInteger', 8),
     'R16':              ('IntReg', 'udw', '16', None, 9),
-    'O0':               ('IntReg', 'udw', '8', 'IsInteger', 10),
-    'O1':               ('IntReg', 'udw', '9', 'IsInteger', 11),
-    'O2':               ('IntReg', 'udw', '10', 'IsInteger', 12),
-    'O3':               ('IntReg', 'udw', '11', 'IsInteger', 13),
-    'O4':               ('IntReg', 'udw', '12', 'IsInteger', 14),
-    'O5':               ('IntReg', 'udw', '13', 'IsInteger', 15),
+    'O0':               ('IntReg', 'udw', 'INTREG_O0', 'IsInteger', 10),
+    'O1':               ('IntReg', 'udw', 'INTREG_O1', 'IsInteger', 11),
+    'O2':               ('IntReg', 'udw', 'INTREG_O2', 'IsInteger', 12),
+    'O3':               ('IntReg', 'udw', 'INTREG_O3', 'IsInteger', 13),
+    'O4':               ('IntReg', 'udw', 'INTREG_O4', 'IsInteger', 14),
+    'O5':               ('IntReg', 'udw', 'INTREG_O5', 'IsInteger', 15),
 
     # Control registers
-#   'Y':                ('ControlReg', 'udw', 'MISCREG_Y', None, 40),
-#   'Ccr':              ('ControlReg', 'udw', 'MISCREG_CCR', None, 41),
-    'Y':                ('IntReg', 'udw', 'NumIntArchRegs + 1', None, 40),
-    'Ccr':              ('IntReg', 'udw', 'NumIntArchRegs + 2', None, 41),
+    'Y':                ('IntReg', 'udw', 'INTREG_Y', None, 40),
+    'Ccr':              ('IntReg', 'udw', 'INTREG_CCR', None, 41),
     'Asi':              ('ControlReg', 'udw', 'MISCREG_ASI', None, 42),
     'Fprs':             ('ControlReg', 'udw', 'MISCREG_FPRS', None, 43),
     'Pcr':              ('ControlReg', 'udw', 'MISCREG_PCR', None, 44),
     'Pic':              ('ControlReg', 'udw', 'MISCREG_PIC', None, 45),
-#   'Gsr':              ('ControlReg', 'udw', 'MISCREG_GSR', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 46),
-    'Gsr':              ('IntReg', 'udw', 'NumIntArchRegs + 8', None, 46),
+    'Gsr':              ('IntReg', 'udw', 'INTREG_GSR', None, 46),
     'Softint':          ('ControlReg', 'udw', 'MISCREG_SOFTINT', None, 47),
     'SoftintSet':       ('ControlReg', 'udw', 'MISCREG_SOFTINT_SET', None, 48),
     'SoftintClr':       ('ControlReg', 'udw', 'MISCREG_SOFTINT_CLR', None, 49),
@@ -169,17 +166,15 @@ def operands {{
     'Pstate':           ('ControlReg', 'pstate', 'MISCREG_PSTATE', None, 59),
     'Tl':               ('ControlReg', 'udw', 'MISCREG_TL', None, 60),
     'Pil':              ('ControlReg', 'udw', 'MISCREG_PIL', None, 61),
-    'Cwp':              ('ControlReg', 'udw', 'MISCREG_CWP', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 62),
-#   'Cansave':          ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 63),
-#   'Canrestore':       ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 64),
-#   'Cleanwin':         ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 65),
-#   'Otherwin':         ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 66),
-#   'Wstate':           ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 67),
-    'Cansave':          ('IntReg', 'udw', 'NumIntArchRegs + 3', None, 63),
-    'Canrestore':       ('IntReg', 'udw', 'NumIntArchRegs + 4', None, 64),
-    'Cleanwin':         ('IntReg', 'udw', 'NumIntArchRegs + 5', None, 65),
-    'Otherwin':         ('IntReg', 'udw', 'NumIntArchRegs + 6', None, 66),
-    'Wstate':           ('IntReg', 'udw', 'NumIntArchRegs + 7', None, 67),
+    'Cwp':              ('ControlReg', 'udw', 'MISCREG_CWP',
+            (None, None, ['IsSerializeAfter',
+                          'IsSerializing',
+                          'IsNonSpeculative']), 62),
+    'Cansave':          ('IntReg', 'udw', 'INTREG_CANSAVE', None, 63),
+    'Canrestore':       ('IntReg', 'udw', 'INTREG_CANRESTORE', None, 64),
+    'Cleanwin':         ('IntReg', 'udw', 'INTREG_CLEANWIN', None, 65),
+    'Otherwin':         ('IntReg', 'udw', 'INTREG_OTHERWIN', None, 66),
+    'Wstate':           ('IntReg', 'udw', 'INTREG_WSTATE', None, 67),
     'Gl':               ('ControlReg', 'udw', 'MISCREG_GL', None, 68),
 
     'Hpstate':          ('ControlReg', 'hpstate', 'MISCREG_HPSTATE', None, 69),
index 26cb1f866f040fa549fa59c7fed2979be1fc925e..1d45407ef5dbdd0df414870afdc4ed4d9e7887d4 100644 (file)
@@ -191,12 +191,12 @@ class SparcLinux : public Linux
               uint64_t stack, uint64_t tls)
     {
         SparcISA::copyRegs(ptc, ctc);
-        ctc->setIntReg(SparcISA::NumIntArchRegs + 6, 0);
-        ctc->setIntReg(SparcISA::NumIntArchRegs + 4, 0);
-        ctc->setIntReg(SparcISA::NumIntArchRegs + 3, SparcISA::NWindows - 2);
-        ctc->setIntReg(SparcISA::NumIntArchRegs + 5, SparcISA::NWindows);
+        ctc->setIntReg(SparcISA::INTREG_OTHERWIN, 0);
+        ctc->setIntReg(SparcISA::INTREG_CANRESTORE, 0);
+        ctc->setIntReg(SparcISA::INTREG_CANSAVE, SparcISA::NWindows - 2);
+        ctc->setIntReg(SparcISA::INTREG_CLEANWIN, SparcISA::NWindows);
         ctc->setMiscReg(SparcISA::MISCREG_CWP, 0);
-        ctc->setIntReg(SparcISA::NumIntArchRegs + 7, 0);
+        ctc->setIntReg(SparcISA::INTREG_WSTATE, 0);
         ctc->setMiscRegNoEffect(SparcISA::MISCREG_TL, 0);
         ctc->setMiscReg(SparcISA::MISCREG_ASI, SparcISA::ASI_PRIMARY);
         for (int y = 8; y < 32; y++)
index 2a62d433061cb3c9b2fc3763d5db3e8a82433d86..6e9e206ed48a4ef88d54b0f530ed97ecb62d7a8f 100644 (file)
@@ -82,7 +82,7 @@ Trace::SparcNativeTrace::check(NativeTraceRecord *record)
     // CCR
     read(&realRegVal, sizeof(realRegVal));
     realRegVal = betoh(realRegVal);
-    regVal = tc->readIntReg(SparcISA::NumIntArchRegs + 2);
+    regVal = tc->readIntReg(SparcISA::INTREG_CCR);
     checkReg("ccr", regVal, realRegVal);
 }
 
index 884deb44f5d76e20a576457d4151e5517c95c967..4c055a9b101fc8a7f843b23e8e5103fd452a6a6d 100644 (file)
@@ -123,22 +123,17 @@ SparcProcess::initState()
      */
 
     // No windows contain info from other programs
-    // tc->setMiscRegNoEffect(MISCREG_OTHERWIN, 0);
-    tc->setIntReg(NumIntArchRegs + 6, 0);
+    tc->setIntReg(INTREG_OTHERWIN, 0);
     // There are no windows to pop
-    // tc->setMiscRegNoEffect(MISCREG_CANRESTORE, 0);
-    tc->setIntReg(NumIntArchRegs + 4, 0);
+    tc->setIntReg(INTREG_CANRESTORE, 0);
     // All windows are available to save into
-    // tc->setMiscRegNoEffect(MISCREG_CANSAVE, NWindows - 2);
-    tc->setIntReg(NumIntArchRegs + 3, NWindows - 2);
+    tc->setIntReg(INTREG_CANSAVE, NWindows - 2);
     // All windows are "clean"
-    // tc->setMiscRegNoEffect(MISCREG_CLEANWIN, NWindows);
-    tc->setIntReg(NumIntArchRegs + 5, NWindows);
+    tc->setIntReg(INTREG_CLEANWIN, NWindows);
     // Start with register window 0
     tc->setMiscReg(MISCREG_CWP, 0);
     // Always use spill and fill traps 0
-    // tc->setMiscRegNoEffect(MISCREG_WSTATE, 0);
-    tc->setIntReg(NumIntArchRegs + 7, 0);
+    tc->setIntReg(INTREG_WSTATE, 0);
     // Set the trap level to 0
     tc->setMiscRegNoEffect(MISCREG_TL, 0);
     // Set the ASI register to something fixed
@@ -428,9 +423,9 @@ Sparc32Process::argsInit(int intSize, int pageSize)
 
 void Sparc32Process::flushWindows(ThreadContext *tc)
 {
-    RegVal Cansave = tc->readIntReg(NumIntArchRegs + 3);
-    RegVal Canrestore = tc->readIntReg(NumIntArchRegs + 4);
-    RegVal Otherwin = tc->readIntReg(NumIntArchRegs + 6);
+    RegVal Cansave = tc->readIntReg(INTREG_CANSAVE);
+    RegVal Canrestore = tc->readIntReg(INTREG_CANRESTORE);
+    RegVal Otherwin = tc->readIntReg(INTREG_OTHERWIN);
     RegVal CWP = tc->readMiscReg(MISCREG_CWP);
     RegVal origCWP = CWP;
     CWP = (CWP + Cansave + 2) % NWindows;
@@ -455,17 +450,17 @@ void Sparc32Process::flushWindows(ThreadContext *tc)
             CWP = (CWP + 1) % NWindows;
         }
     }
-    tc->setIntReg(NumIntArchRegs + 3, Cansave);
-    tc->setIntReg(NumIntArchRegs + 4, Canrestore);
+    tc->setIntReg(INTREG_CANSAVE, Cansave);
+    tc->setIntReg(INTREG_CANRESTORE, Canrestore);
     tc->setMiscReg(MISCREG_CWP, origCWP);
 }
 
 void
 Sparc64Process::flushWindows(ThreadContext *tc)
 {
-    RegVal Cansave = tc->readIntReg(NumIntArchRegs + 3);
-    RegVal Canrestore = tc->readIntReg(NumIntArchRegs + 4);
-    RegVal Otherwin = tc->readIntReg(NumIntArchRegs + 6);
+    RegVal Cansave = tc->readIntReg(INTREG_CANSAVE);
+    RegVal Canrestore = tc->readIntReg(INTREG_CANRESTORE);
+    RegVal Otherwin = tc->readIntReg(INTREG_OTHERWIN);
     RegVal CWP = tc->readMiscReg(MISCREG_CWP);
     RegVal origCWP = CWP;
     CWP = (CWP + Cansave + 2) % NWindows;
@@ -490,8 +485,8 @@ Sparc64Process::flushWindows(ThreadContext *tc)
             CWP = (CWP + 1) % NWindows;
         }
     }
-    tc->setIntReg(NumIntArchRegs + 3, Cansave);
-    tc->setIntReg(NumIntArchRegs + 4, Canrestore);
+    tc->setIntReg(INTREG_CANSAVE, Cansave);
+    tc->setIntReg(INTREG_CANRESTORE, Canrestore);
     tc->setMiscReg(MISCREG_CWP, origCWP);
 }
 
@@ -518,16 +513,14 @@ SparcProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn sysret)
     PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
     if (sysret.successful()) {
         // no error, clear XCC.C
-        tc->setIntReg(NumIntArchRegs + 2,
-                      tc->readIntReg(NumIntArchRegs + 2) & 0xEE);
+        tc->setIntReg(INTREG_CCR, tc->readIntReg(INTREG_CCR) & 0xEE);
         RegVal val = sysret.returnValue();
         if (pstate.am)
             val = bits(val, 31, 0);
         tc->setIntReg(ReturnValueReg, val);
     } else {
         // got an error, set XCC.C
-        tc->setIntReg(NumIntArchRegs + 2,
-                      tc->readIntReg(NumIntArchRegs + 2) | 0x11);
+        tc->setIntReg(INTREG_CCR, tc->readIntReg(INTREG_CCR) | 0x11);
         RegVal val = sysret.errnoValue();
         if (pstate.am)
             val = bits(val, 31, 0);
index b8b09995115ec383d8ca5b55a7cce26ed2b99c84..6fd6577d1158161f90e98d0035af0f45498381a9 100644 (file)
@@ -59,17 +59,45 @@ constexpr size_t VecPredRegSizeBits = ::DummyVecPredRegSizeBits;
 constexpr bool VecPredRegHasPackedRepr = ::DummyVecPredRegHasPackedRepr;
 
 // semantically meaningful register indices
+enum {
+    // Globals
+    INTREG_G0, INTREG_G1, INTREG_G2, INTREG_G3,
+    INTREG_G4, INTREG_G5, INTREG_G6, INTREG_G7,
+    // Outputs
+    INTREG_O0, INTREG_O1, INTREG_O2, INTREG_O3,
+    INTREG_O4, INTREG_O5, INTREG_O6, INTREG_O7,
+    // Locals
+    INTREG_L0, INTREG_L1, INTREG_L2, INTREG_L3,
+    INTREG_L4, INTREG_L5, INTREG_L6, INTREG_L7,
+    // Inputs
+    INTREG_I0, INTREG_I1, INTREG_I2, INTREG_I3,
+    INTREG_I4, INTREG_I5, INTREG_I6, INTREG_I7,
+
+    NumIntArchRegs,
+
+    INTREG_UREG0 = NumIntArchRegs,
+    INTREG_Y,
+    INTREG_CCR,
+    INTREG_CANSAVE,
+    INTREG_CANRESTORE,
+    INTREG_CLEANWIN,
+    INTREG_OTHERWIN,
+    INTREG_WSTATE,
+    INTREG_GSR,
+
+    NumMicroIntRegs = INTREG_GSR - INTREG_UREG0 + 1
+};
 const int ZeroReg = 0;      // architecturally meaningful
+
 // the rest of these depend on the ABI
-const int ReturnAddressReg = 31; // post call, precall is 15
-const int ReturnValueReg = 8;  // Post return, 24 is pre-return.
-const int StackPointerReg = 14;
-const int FramePointerReg = 30;
+const int ReturnAddressReg = INTREG_I7; // post call, precall is 15
+const int ReturnValueReg = INTREG_O0;  // Post return, 24 is pre-return.
+const int StackPointerReg = INTREG_O6;
+const int FramePointerReg = INTREG_I6;
 
-// Some OS syscall use a second register (o1) to return a second value
-const int SyscallPseudoReturnReg = 9;
+// Some OS syscall use a second register to return a second value
+const int SyscallPseudoReturnReg = INTREG_O1;
 
-const int NumIntArchRegs = 32;
 const int NumIntRegs = (MaxGL + 1) * 8 + NWindows * 16 + NumMicroIntRegs;
 const int NumVecRegs = 1;  // Not applicable to SPARC
                            // (1 to prevent warnings)
@@ -77,6 +105,9 @@ const int NumVecPredRegs = 1;  // Not applicable to SPARC
                                // (1 to prevent warnings)
 const int NumCCRegs = 0;
 
+const int NumFloatRegs = 64;
+const int NumFloatArchRegs = NumFloatRegs;
+
 const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs;
 
 } // namespace SparcISA
index 349f28cacb1e1e2e902ba5bdc587739342ad76a3..d0f3cd802a67edf3b1832b57be4cc4c3314dc115 100644 (file)
@@ -176,11 +176,11 @@ RemoteGDB::SPARCGdbRegCache::getRegs(ThreadContext *context)
     PCState pc = context->pcState();
     r.pc = htobe((uint32_t)pc.pc());
     r.npc = htobe((uint32_t)pc.npc());
-    r.y = htobe((uint32_t)context->readIntReg(NumIntArchRegs + 1));
+    r.y = htobe((uint32_t)context->readIntReg(INTREG_Y));
     PSTATE pstate = context->readMiscReg(MISCREG_PSTATE);
     r.psr = htobe((uint32_t)pstate);
     r.fsr = htobe((uint32_t)context->readMiscReg(MISCREG_FSR));
-    r.csr = htobe((uint32_t)context->readIntReg(NumIntArchRegs + 2));
+    r.csr = htobe((uint32_t)context->readIntReg(INTREG_CCR));
 }
 
 void
@@ -194,13 +194,13 @@ RemoteGDB::SPARC64GdbRegCache::getRegs(ThreadContext *context)
     r.npc = htobe(pc.npc());
     r.fsr = htobe(context->readMiscReg(MISCREG_FSR));
     r.fprs = htobe(context->readMiscReg(MISCREG_FPRS));
-    r.y = htobe(context->readIntReg(NumIntArchRegs + 1));
+    r.y = htobe(context->readIntReg(INTREG_Y));
     PSTATE pstate = context->readMiscReg(MISCREG_PSTATE);
     r.state = htobe(
         context->readMiscReg(MISCREG_CWP) |
         pstate << 8 |
         context->readMiscReg(MISCREG_ASI) << 24 |
-        context->readIntReg(NumIntArchRegs + 2) << 32);
+        context->readIntReg(INTREG_CCR) << 32);
 }
 
 void
index e92b9822e91d54a5180c828a6e8c175ae4a84a32..e53f514b593349f26c01797be790cb86aeefac40 100644 (file)
@@ -39,10 +39,6 @@ const int MaxPGL = 2;
 
 // Number of register windows, can legally be 3 to 32
 const int NWindows = 8;
-const int NumMicroIntRegs = 9;
-
-const int NumFloatRegs = 64;
-const int NumFloatArchRegs = NumFloatRegs;
 }
 
 #endif // __ARCH_SPARC_SPARC_TRAITS_HH__