sparc: Introduce a BitUnion for the CCR register.
authorGabe Black <gabeblack@google.com>
Sat, 7 Dec 2019 10:37:50 +0000 (02:37 -0800)
committerGabe Black <gabeblack@google.com>
Thu, 12 Mar 2020 01:35:34 +0000 (01:35 +0000)
This avoids opaque masks when accessing fields of this register.

Change-Id: If20d82c7c6401e6b1b35bb6d2c69542a56e2fb45
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/23446
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/miscregs.hh
src/arch/sparc/process.cc

index c1b49e108f68b900c27ceafa0471371f15a227cc..dc68c01bfa06a21692f12f97ce8853460d23585e 100644 (file)
@@ -303,7 +303,7 @@ 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(INTREG_CCR);
+    CCR ccr = tc->readIntReg(INTREG_CCR);
     RegVal ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
     RegVal CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
     RegVal CANSAVE = tc->readMiscRegNoEffect(INTREG_CANSAVE);
@@ -317,7 +317,7 @@ doREDFault(ThreadContext *tc, TrapType tt)
     // set TSTATE.gl to gl
     replaceBits(TSTATE, 42, 40, GL);
     // set TSTATE.ccr to ccr
-    replaceBits(TSTATE, 39, 32, CCR);
+    replaceBits(TSTATE, 39, 32, ccr);
     // set TSTATE.asi to asi
     replaceBits(TSTATE, 31, 24, ASI);
     // set TSTATE.pstate to pstate
@@ -382,7 +382,7 @@ 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(INTREG_CCR);
+    CCR ccr = tc->readIntReg(INTREG_CCR);
     RegVal ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
     RegVal CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
     RegVal CANSAVE = tc->readIntReg(INTREG_CANSAVE);
@@ -400,7 +400,7 @@ doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
     // set TSTATE.gl to gl
     replaceBits(TSTATE, 42, 40, GL);
     // set TSTATE.ccr to ccr
-    replaceBits(TSTATE, 39, 32, CCR);
+    replaceBits(TSTATE, 39, 32, ccr);
     // set TSTATE.asi to asi
     replaceBits(TSTATE, 31, 24, ASI);
     // set TSTATE.pstate to pstate
index b0679b9639b844aa136989fc981e599d00894a67..3602c8e508c53a3945d79146e4cc14336b143ea4 100644 (file)
@@ -133,6 +133,21 @@ BitUnion16(PSTATE)
     Bitfield<11> pid1;
 EndBitUnion(PSTATE)
 
+BitUnion8(CCR)
+    SubBitUnion(xcc, 7, 4)
+        Bitfield<7> n;
+        Bitfield<6> z;
+        Bitfield<5> v;
+        Bitfield<4> c;
+    EndSubBitUnion(xcc)
+    SubBitUnion(icc, 3, 0)
+        Bitfield<3> n;
+        Bitfield<2> z;
+        Bitfield<1> v;
+        Bitfield<0> c;
+    EndSubBitUnion(icc)
+EndBitUnion(CCR)
+
 struct STS
 {
     const static int st_idle     = 0x00;
index 4c055a9b101fc8a7f843b23e8e5103fd452a6a6d..ce201d0b4924c79dc0eb644a268b61b435a1da66 100644 (file)
@@ -509,23 +509,21 @@ SparcProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn sysret)
 {
     // check for error condition.  SPARC syscall convention is to
     // indicate success/failure in reg the carry bit of the ccr
-    // and put the return value itself in the standard return value reg ().
+    // and put the return value itself in the standard return value reg.
     PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
+    CCR ccr = tc->readIntReg(INTREG_CCR);
+    RegVal val;
     if (sysret.successful()) {
-        // no error, clear XCC.C
-        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);
+        ccr.xcc.c = ccr.icc.c = 0;
+        val = sysret.returnValue();
     } else {
-        // got an error, set XCC.C
-        tc->setIntReg(INTREG_CCR, tc->readIntReg(INTREG_CCR) | 0x11);
-        RegVal val = sysret.errnoValue();
-        if (pstate.am)
-            val = bits(val, 31, 0);
-        tc->setIntReg(ReturnValueReg, val);
+        ccr.xcc.c = ccr.icc.c = 1;
+        val = sysret.errnoValue();
     }
+    tc->setIntReg(INTREG_CCR, ccr);
+    if (pstate.am)
+        val = bits(val, 31, 0);
+    tc->setIntReg(ReturnValueReg, val);
     if (sysret.count() > 1)
         tc->setIntReg(SyscallPseudoReturnReg, sysret.value2());
 }