SPARC: Make PSTATE and HPSTATE a BitUnion.
authorGabe Black <gblack@eecs.umich.edu>
Sat, 11 Feb 2012 22:16:38 +0000 (14:16 -0800)
committerGabe Black <gblack@eecs.umich.edu>
Sat, 11 Feb 2012 22:16:38 +0000 (14:16 -0800)
This gets rid of cryptic bits of code with lots of bit manipulation, and makes
some comments redundant.

14 files changed:
src/arch/sparc/faults.cc
src/arch/sparc/interrupts.hh
src/arch/sparc/isa.cc
src/arch/sparc/isa.hh
src/arch/sparc/isa/base.isa
src/arch/sparc/isa/decoder.isa
src/arch/sparc/isa/formats/mem/util.isa
src/arch/sparc/isa/formats/priv.isa
src/arch/sparc/isa/operands.isa
src/arch/sparc/miscregs.hh
src/arch/sparc/process.cc
src/arch/sparc/remote_gdb.cc
src/arch/sparc/ua2005.cc
src/arch/sparc/utility.hh

index e67b8c50e16c54f1ff08e831ce68be3d026b86ba..c0f2701bd35cdc13f640bbc9f4ee18e09af6ba68 100644 (file)
@@ -276,17 +276,15 @@ enterREDState(ThreadContext *tc)
 {
     //@todo Disable the mmu?
     //@todo Disable watchpoints?
-    MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
-    // HPSTATE.red = 1
-    HPSTATE |= (1 << 5);
-    // HPSTATE.hpriv = 1
-    HPSTATE |= (1 << 2);
-    tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
+    HPSTATE hpstate= tc->readMiscRegNoEffect(MISCREG_HPSTATE);
+    hpstate.red = 1;
+    hpstate.hpriv = 1;
+    tc->setMiscReg(MISCREG_HPSTATE, hpstate);
     // PSTATE.priv is set to 1 here. The manual says it should be 0, but
     // Legion sets it to 1.
-    MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE);
-    PSTATE |= (1 << 2);
-    tc->setMiscReg(MISCREG_PSTATE, PSTATE);
+    PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
+    pstate.priv = 1;
+    tc->setMiscReg(MISCREG_PSTATE, pstate);
 }
 
 /**
@@ -299,8 +297,8 @@ doREDFault(ThreadContext *tc, TrapType tt)
 {
     MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL);
     MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE);
-    MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE);
-    MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
+    PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
+    HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
     MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
     MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
     MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
@@ -310,7 +308,7 @@ doREDFault(ThreadContext *tc, TrapType tt)
 
     TL++;
 
-    Addr pcMask = bits(PSTATE, 3) ? mask(32) : mask(64);
+    Addr pcMask = pstate.am ? mask(32) : mask(64);
 
     // set TSTATE.gl to gl
     replaceBits(TSTATE, 42, 40, GL);
@@ -319,7 +317,7 @@ doREDFault(ThreadContext *tc, TrapType tt)
     // set TSTATE.asi to asi
     replaceBits(TSTATE, 31, 24, ASI);
     // set TSTATE.pstate to pstate
-    replaceBits(TSTATE, 20, 8, PSTATE);
+    replaceBits(TSTATE, 20, 8, pstate);
     // set TSTATE.cwp to cwp
     replaceBits(TSTATE, 4, 0, CWP);
 
@@ -332,7 +330,7 @@ doREDFault(ThreadContext *tc, TrapType tt)
     tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask);
 
     // set HTSTATE.hpstate to hpstate
-    tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE);
+    tc->setMiscRegNoEffect(MISCREG_HTSTATE, hpstate);
 
     // TT = trap type;
     tc->setMiscRegNoEffect(MISCREG_TT, tt);
@@ -340,19 +338,17 @@ doREDFault(ThreadContext *tc, TrapType tt)
     // Update GL
     tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxGL));
 
-    PSTATE = mbits(PSTATE, 2, 2); // just save the priv bit
-    PSTATE |= (1 << 4); // set PSTATE.pef to 1
-    tc->setMiscRegNoEffect(MISCREG_PSTATE, PSTATE);
+    bool priv = pstate.priv; // just save the priv bit
+    pstate = 0;
+    pstate.priv = priv;
+    pstate.pef = 1;
+    tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate);
 
-    // set HPSTATE.red to 1
-    HPSTATE |= (1 << 5);
-    // set HPSTATE.hpriv to 1
-    HPSTATE |= (1 << 2);
-    // set HPSTATE.ibe to 0
-    HPSTATE &= ~(1 << 10);
-    // set HPSTATE.tlz to 0
-    HPSTATE &= ~(1 << 0);
-    tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE);
+    hpstate.red = 1;
+    hpstate.hpriv = 1;
+    hpstate.ibe = 0;
+    hpstate.tlz = 0;
+    tc->setMiscRegNoEffect(MISCREG_HPSTATE, hpstate);
 
     bool changedCWP = true;
     if (tt == 0x24)
@@ -380,8 +376,8 @@ doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
 {
     MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL);
     MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE);
-    MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE);
-    MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
+    PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
+    HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
     MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
     MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
     MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
@@ -393,7 +389,7 @@ doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
     TL++;
     tc->setMiscRegNoEffect(MISCREG_TL, TL);
 
-    Addr pcMask = bits(PSTATE, 3) ? mask(32) : mask(64);
+    Addr pcMask = pstate.am ? mask(32) : mask(64);
 
     // Save off state
 
@@ -404,7 +400,7 @@ doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
     // set TSTATE.asi to asi
     replaceBits(TSTATE, 31, 24, ASI);
     // set TSTATE.pstate to pstate
-    replaceBits(TSTATE, 20, 8, PSTATE);
+    replaceBits(TSTATE, 20, 8, pstate);
     // set TSTATE.cwp to cwp
     replaceBits(TSTATE, 4, 0, CWP);
 
@@ -417,7 +413,7 @@ doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
     tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask);
 
     // set HTSTATE.hpstate to hpstate
-    tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE);
+    tc->setMiscRegNoEffect(MISCREG_HTSTATE, hpstate);
 
     // TT = trap type;
     tc->setMiscRegNoEffect(MISCREG_TT, tt);
@@ -428,26 +424,26 @@ doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
     else
         tc->setMiscReg(MISCREG_GL, min<int>(GL + 1, MaxGL));
 
-    // PSTATE.mm is unchanged
-    PSTATE |= (1 << 4); // PSTATE.pef = whether or not an fpu is present
-    PSTATE &= ~(1 << 3); // PSTATE.am = 0
-    PSTATE &= ~(1 << 1); // PSTATE.ie = 0
-    // PSTATE.tle is unchanged
-    // PSTATE.tct = 0
+    // pstate.mm is unchanged
+    pstate.pef = 1; // PSTATE.pef = whether or not an fpu is present
+    pstate.am = 0;
+    pstate.ie = 0;
+    // pstate.tle is unchanged
+    // pstate.tct = 0
 
     if (gotoHpriv) {
-        PSTATE &= ~(1 << 9); // PSTATE.cle = 0
+        pstate.cle = 0;
         // The manual says PSTATE.priv should be 0, but Legion leaves it alone
-        HPSTATE &= ~(1 << 5); // HPSTATE.red = 0
-        HPSTATE |= (1 << 2); // HPSTATE.hpriv = 1
-        HPSTATE &= ~(1 << 10); // HPSTATE.ibe = 0
-        // HPSTATE.tlz is unchanged
-        tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE);
+        hpstate.red = 0;
+        hpstate.hpriv = 1;
+        hpstate.ibe = 0;
+        // hpstate.tlz is unchanged
+        tc->setMiscRegNoEffect(MISCREG_HPSTATE, hpstate);
     } else { // we are going to priv
-        PSTATE |= (1 << 2); // PSTATE.priv = 1
-        replaceBits(PSTATE, 9, 9, PSTATE >> 8); // PSTATE.cle = PSTATE.tle
+        pstate.priv = 1;
+        pstate.cle = pstate.tle;
     }
-    tc->setMiscRegNoEffect(MISCREG_PSTATE, PSTATE);
+    tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate);
 
 
     bool changedCWP = true;
@@ -506,22 +502,22 @@ SparcFaultBase::invoke(ThreadContext * tc, StaticInstPtr inst)
     // in the middle could change it in the regfile out from under us.
     MiscReg tl = tc->readMiscRegNoEffect(MISCREG_TL);
     MiscReg tt = tc->readMiscRegNoEffect(MISCREG_TT);
-    MiscReg pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
-    MiscReg hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
+    PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
+    HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
 
     Addr PC, NPC;
 
     PrivilegeLevel current;
-    if (hpstate & HPSTATE::hpriv)
+    if (hpstate.hpriv)
         current = Hyperprivileged;
-    else if (pstate & PSTATE::priv)
+    else if (pstate.priv)
         current = Privileged;
     else
         current = User;
 
     PrivilegeLevel level = getNextLevel(current);
 
-    if ((hpstate & HPSTATE::red) || (tl == MaxTL - 1)) {
+    if (hpstate.red || (tl == MaxTL - 1)) {
         getREDVector(5, PC, NPC);
         doREDFault(tc, tt);
         // This changes the hpstate and pstate, so we need to make sure we
@@ -565,20 +561,18 @@ PowerOnReset::invoke(ThreadContext *tc, StaticInstPtr inst)
     tc->setMiscRegNoEffect(MISCREG_TT, trapType());
     tc->setMiscReg(MISCREG_GL, MaxGL);
 
-    // Turn on pef and priv, set everything else to 0
-    tc->setMiscRegNoEffect(MISCREG_PSTATE, (1 << 4) | (1 << 2));
+    PSTATE pstate = 0;
+    pstate.pef = 1;
+    pstate.priv = 1;
+    tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate);
 
     // Turn on red and hpriv, set everything else to 0
-    MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
-    // HPSTATE.red = 1
-    HPSTATE |= (1 << 5);
-    // HPSTATE.hpriv = 1
-    HPSTATE |= (1 << 2);
-    // HPSTATE.ibe = 0
-    HPSTATE &= ~(1 << 10);
-    // HPSTATE.tlz = 0
-    HPSTATE &= ~(1 << 0);
-    tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE);
+    HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
+    hpstate.red = 1;
+    hpstate.hpriv = 1;
+    hpstate.ibe = 0;
+    hpstate.tlz = 0;
+    tc->setMiscRegNoEffect(MISCREG_HPSTATE, hpstate);
 
     // The tick register is unreadable by nonprivileged software
     tc->setMiscRegNoEffect(MISCREG_TICK, 1ULL << 63);
index b728e718827c73167f1582e5743ee122ebbe2057..6d5f30962e9cf03898df58ee5a8032fbcb40c868 100644 (file)
@@ -127,17 +127,16 @@ class Interrupts : public SimObject
     Fault
     getInterrupt(ThreadContext *tc)
     {
-        int hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
-        int pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
-        bool ie = pstate & PSTATE::ie;
+        HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
+        PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
 
         // THESE ARE IN ORDER OF PRIORITY
         // since there are early returns, and the highest
         // priority interrupts should get serviced,
         // it is v. important that new interrupts are inserted
         // in the right order of processing
-        if (hpstate & HPSTATE::hpriv) {
-            if (ie) {
+        if (hpstate.hpriv) {
+            if (pstate.ie) {
                 if (interrupts[IT_HINTP]) {
                     // This will be cleaned by a HINTP write
                     return new HstickMatch;
@@ -160,7 +159,7 @@ class Interrupts : public SimObject
                 // this will be cleared by an ASI read (or write)
                 return new InterruptVector;
             }
-            if (ie) {
+            if (pstate.ie) {
                 if (interrupts[IT_CPU_MONDO]) {
                     return new CpuMondo;
                 }
@@ -175,7 +174,7 @@ class Interrupts : public SimObject
                 if (interrupts[IT_RES_ERROR]) {
                     return new ResumableError;
                 }
-            } // !hpriv && ie
+            } // !hpriv && pstate.ie
         }  // !hpriv
         return NoFault;
     }
index 13f252e82e1b046206d0a52c0b498462e58def52..291e25cec854db6a38af74de8e0253fa3cde2152 100644 (file)
 namespace SparcISA
 {
 
-enum RegMask
+static PSTATE
+buildPstateMask()
 {
-    PSTATE_MASK = (((1 << 4) - 1) << 1) | (((1 << 4) - 1) << 6) | (1 << 12)
-};
+    PSTATE mask = 0;
+    mask.ie = 1;
+    mask.priv = 1;
+    mask.am = 1;
+    mask.pef = 1;
+    mask.mm = 3;
+    mask.tle = 1;
+    mask.cle = 1;
+    mask.pid1 = 1;
+    return mask;
+}
+
+static const PSTATE PstateMask = buildPstateMask();
 
 void
 ISA::reloadRegMap()
@@ -110,7 +122,8 @@ ISA::clear()
     // otherwin = 0;
     // wstate = 0;
     // In a T1, bit 11 is apparently always 1
-    hpstate = (1 << 11);
+    hpstate = 0;
+    hpstate.id = 1;
     memset(htstate, 0, sizeof(htstate));
     hintp = 0;
     htba = 0;
@@ -163,9 +176,10 @@ ISA::readMiscRegNoEffect(int miscReg)
      *                                                           |^lsuim
      *                                                           ^lsudm
      */
-    return bits((uint64_t)hpstate,2,2) |
-           bits((uint64_t)hpstate,5,5) << 1 |
-           bits((uint64_t)pstate,3,2) << 2 |
+    return      (uint64_t)hpstate.hpriv |
+                (uint64_t)hpstate.red << 1 |
+                (uint64_t)pstate.priv << 2 |
+                (uint64_t)pstate.am << 3 |
            bits((uint64_t)lsuCtrlReg,3,2) << 4 |
            bits((uint64_t)partId,7,0) << 8 |
            bits((uint64_t)tl,2,0) << 16 |
@@ -215,7 +229,7 @@ ISA::readMiscRegNoEffect(int miscReg)
       case MISCREG_TBA:
         return tba;
       case MISCREG_PSTATE:
-        return pstate;
+        return (MiscReg)pstate;
       case MISCREG_TL:
         return tl;
       case MISCREG_PIL:
@@ -238,7 +252,7 @@ ISA::readMiscRegNoEffect(int miscReg)
 
         /** Hyper privileged registers */
       case MISCREG_HPSTATE:
-        return hpstate;
+        return (MiscReg)hpstate;
       case MISCREG_HTSTATE:
         return htstate[tl-1];
       case MISCREG_HINTP:
@@ -408,7 +422,7 @@ ISA::setMiscRegNoEffect(int miscReg, MiscReg val)
         tba = val & ULL(~0x7FFF);
         break;
       case MISCREG_PSTATE:
-        pstate = (val & PSTATE_MASK);
+        pstate = (val & PstateMask);
         break;
       case MISCREG_TL:
         tl = val;
@@ -550,15 +564,17 @@ ISA::setMiscReg(int miscReg, MiscReg val, ThreadContext * tc)
         // Set up performance counting based on pcr value
         break;
       case MISCREG_PSTATE:
-        pstate = val & PSTATE_MASK;
+        pstate = val & PstateMask;
         return;
       case MISCREG_TL:
-        tl = val;
-        if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
-            tc->getCpuPtr()->postInterrupt(IT_TRAP_LEVEL_ZERO, 0);
-        else
-            tc->getCpuPtr()->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0);
-        return;
+        {
+            tl = val;
+            if (hpstate.tlz && tl == 0 && !hpstate.hpriv)
+                tc->getCpuPtr()->postInterrupt(IT_TRAP_LEVEL_ZERO, 0);
+            else
+                tc->getCpuPtr()->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0);
+            return;
+        }
       case MISCREG_CWP:
         new_val = val >= NWindows ? NWindows - 1 : val;
         if (val >= NWindows)
@@ -616,12 +632,12 @@ ISA::serialize(EventManager *em, std::ostream &os)
     SERIALIZE_ARRAY(tstate,MaxTL);
     SERIALIZE_ARRAY(tt,MaxTL);
     SERIALIZE_SCALAR(tba);
-    SERIALIZE_SCALAR(pstate);
+    SERIALIZE_SCALAR((uint16_t)pstate);
     SERIALIZE_SCALAR(tl);
     SERIALIZE_SCALAR(pil);
     SERIALIZE_SCALAR(cwp);
     SERIALIZE_SCALAR(gl);
-    SERIALIZE_SCALAR(hpstate);
+    SERIALIZE_SCALAR((uint64_t)hpstate);
     SERIALIZE_ARRAY(htstate,MaxTL);
     SERIALIZE_SCALAR(hintp);
     SERIALIZE_SCALAR(htba);
@@ -692,13 +708,21 @@ ISA::unserialize(EventManager *em, Checkpoint *cp, const std::string &section)
     UNSERIALIZE_ARRAY(tstate,MaxTL);
     UNSERIALIZE_ARRAY(tt,MaxTL);
     UNSERIALIZE_SCALAR(tba);
-    UNSERIALIZE_SCALAR(pstate);
+    {
+        uint16_t pstate;
+        UNSERIALIZE_SCALAR(pstate);
+        this->pstate = pstate;
+    }
     UNSERIALIZE_SCALAR(tl);
     UNSERIALIZE_SCALAR(pil);
     UNSERIALIZE_SCALAR(cwp);
     UNSERIALIZE_SCALAR(gl);
     reloadRegMap();
-    UNSERIALIZE_SCALAR(hpstate);
+    {
+        uint64_t hpstate;
+        UNSERIALIZE_SCALAR(hpstate);
+        this->hpstate = hpstate;
+    }
     UNSERIALIZE_ARRAY(htstate,MaxTL);
     UNSERIALIZE_SCALAR(hintp);
     UNSERIALIZE_SCALAR(htba);
index e5d2587863b3412dad42cd23eeda7ca3485c6d71..713f01fa5b5f86ca402cf59d609323dea6a6b494 100644 (file)
@@ -71,7 +71,7 @@ class ISA
                             // on the previous level)
     uint64_t tba;           // Trap Base Address
 
-    uint16_t pstate;        // Process State Register
+    PSTATE pstate;        // Process State Register
     uint8_t tl;             // Trap Level
     uint8_t pil;            // Process Interrupt Register
     uint8_t cwp;            // Current Window Pointer
@@ -83,7 +83,7 @@ class ISA
     uint8_t gl;             // Global level register
 
     /** Hyperprivileged Registers */
-    uint64_t hpstate;       // Hyperprivileged State Register
+    HPSTATE hpstate;       // Hyperprivileged State Register
     uint64_t htstate[MaxTL];// Hyperprivileged Trap State Register
     uint64_t hintp;
     uint64_t htba;          // Hyperprivileged Trap Base Address register
@@ -172,8 +172,8 @@ class ISA
 
   protected:
 
-    bool isHyperPriv() { return (hpstate & (1 << 2)); }
-    bool isPriv() { return (hpstate & (1 << 2)) || (pstate & (1 << 2)); }
+    bool isHyperPriv() { return hpstate.hpriv; }
+    bool isPriv() { return hpstate.hpriv || pstate.priv; }
     bool isNonPriv() { return !isPriv(); }
 
   public:
index d38df1c25714c0aa0f19eb7aa6daae527c350b06..3b3974cbf7a33040633c8fb0c48826c2fa184a67 100644 (file)
@@ -567,8 +567,8 @@ output exec {{
     checkFpEnableFault(%(CPU_exec_context)s *xc)
     {
         if (FullSystem) {
-            if (xc->readMiscReg(MISCREG_PSTATE) & PSTATE::pef &&
-                xc->readMiscReg(MISCREG_FPRS) & 0x4) {
+            PSTATE pstate = xc->readMiscReg(MISCREG_PSTATE);
+            if (pstate.pef && xc->readMiscReg(MISCREG_FPRS) & 0x4) {
                 return NoFault;
             } else {
                 return new FpDisabled;
index a05cb94f773c86428a05db3dcd99b76ee4114cab..44d2643c6e95f795df72d7f7672496819b1eab55 100644 (file)
@@ -139,7 +139,7 @@ decode OP default Unknown::unknown()
     }
     0x1: BranchN::call(30, {{
             IntReg midVal;
-            R15 = midVal = (Pstate<3:> ? (PC)<31:0> : PC);
+            R15 = midVal = (Pstate.am ? (PC)<31:0> : PC);
             NNPC = midVal + disp;
     }},None, None, IsIndirectControl, IsCall);
     0x2: decode OP3 {
@@ -327,7 +327,7 @@ decode OP default Unknown::unknown()
                 0x03: NoPriv::rdasi({{Rd = Asi;}});
                 0x04: Priv::rdtick({{Rd = Tick;}}, {{Tick<63:>}});
                 0x05: NoPriv::rdpc({{
-                    if (Pstate<3:>)
+                    if (Pstate.am)
                         Rd = (PC)<31:0>;
                     else
                         Rd = PC;
@@ -356,7 +356,7 @@ decode OP default Unknown::unknown()
                 0x18: Priv::rdstick({{Rd = Stick}}, {{Stick<63:>}});
                 0x19: Priv::rdstick_cmpr({{Rd = StickCmpr;}});
                 0x1A: Priv::rdstrand_sts_reg({{
-                    if (Pstate<2:> && !Hpstate<2:>)
+                    if (Pstate.am && !Hpstate.hpriv)
                         Rd = StrandStsReg<0:>;
                     else
                         Rd = StrandStsReg;
@@ -479,7 +479,7 @@ decode OP default Unknown::unknown()
                 0x11: Priv::wrpic({{Pic = Rs1 ^ Rs2_or_imm13;}}, {{Pcr<0:>}});
                 // 0x12 should cause an illegal instruction exception
                 0x13: NoPriv::wrgsr({{
-                    if (Fprs<2:> == 0 || Pstate<4:> == 0)
+                    if (Fprs<2:> == 0 || Pstate.pef == 0)
                         return new FpDisabled;
                     Gsr = Rs1 ^ Rs2_or_imm13;
                 }});
@@ -488,7 +488,7 @@ decode OP default Unknown::unknown()
                 0x16: Priv::wrsoftint({{Softint = Rs1 ^ Rs2_or_imm13;}});
                 0x17: Priv::wrtick_cmpr({{TickCmpr = Rs1 ^ Rs2_or_imm13;}});
                 0x18: NoPriv::wrstick({{
-                    if (!Hpstate<2:>)
+                    if (!Hpstate.hpriv)
                         return new IllegalInstruction;
                     Stick = Rs1 ^ Rs2_or_imm13;
                 }});
@@ -536,7 +536,7 @@ decode OP default Unknown::unknown()
                 0x05: Priv::wrprtba({{Tba = Rs1 ^ Rs2_or_imm13;}});
                 0x06: Priv::wrprpstate({{Pstate = Rs1 ^ Rs2_or_imm13;}});
                 0x07: Priv::wrprtl({{
-                    if (Pstate<2:> && !Hpstate<2:>)
+                    if (Pstate.priv && !Hpstate.hpriv)
                         Tl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxPTL);
                     else
                         Tl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxTL);
@@ -550,7 +550,7 @@ decode OP default Unknown::unknown()
                 0x0E: Priv::wrprwstate({{Wstate = Rs1 ^ Rs2_or_imm13;}});
                 // 0x0F should cause an illegal instruction exception
                 0x10: Priv::wrprgl({{
-                    if (Pstate<2:> && !Hpstate<2:>)
+                    if (Pstate.priv && !Hpstate.hpriv)
                         Gl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxPGL);
                     else
                         Gl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxGL);
@@ -997,7 +997,7 @@ decode OP default Unknown::unknown()
                 if (target & 0x3) {
                     fault = new MemAddressNotAligned;
                 } else {
-                    if (Pstate<3:>)
+                    if (Pstate.am)
                         Rd = (PC)<31:0>;
                     else
                         Rd = PC;
index a770591811e75c7bea55270f14a2717a29a3f709..ffce3063b295da84420c30f803ab91533e0a6db5 100644 (file)
@@ -317,17 +317,17 @@ let {{
     # are split into ones that are available in priv and hpriv, and
     # those that are only available in hpriv
     AlternateASIPrivFaultCheck = '''
-        if ((!bits(Pstate,2,2) && !bits(Hpstate,2,2) &&
+        if ((!Pstate.priv && !Hpstate.hpriv &&
              !asiIsUnPriv((ASI)EXT_ASI)) ||
-            (!bits(Hpstate,2,2) && asiIsHPriv((ASI)EXT_ASI)))
+            (!Hpstate.hpriv && asiIsHPriv((ASI)EXT_ASI)))
             fault = new PrivilegedAction;
-        else if (asiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2))
+        else if (asiIsAsIfUser((ASI)EXT_ASI) && !Pstate.priv)
             fault = new PrivilegedAction;
     '''
 
     TruncateEA = '''
         if (!FullSystem)
-            EA = Pstate<3:> ? EA<31:0> : EA;
+            EA = Pstate.am ? EA<31:0> : EA;
     '''
 }};
 
index 56f1cdbd937b78e0127269717c325bebdc88ea1e..e3242aab8d0fb1986ccd0166c14a3e80e04b4a64 100644 (file)
@@ -264,7 +264,7 @@ let {{
 }};
 
 def format Priv(code, extraCond=true, checkTl=false, *opt_flags) {{
-        checkCode = "(%s) && !(Pstate<2:> || Hpstate<2:>)" % extraCond
+        checkCode = "(%s) && !(Pstate.priv || Hpstate.hpriv)" % extraCond
         if checkTl != "false":
             tlCheck = "Tl == 0"
         else:
@@ -289,7 +289,7 @@ def format NoPriv(code, checkTl=false, *opt_flags) {{
 }};
 
 def format HPriv(code, checkTl=false, *opt_flags) {{
-        checkCode = "!Hpstate<2:2>"
+        checkCode = "!Hpstate.hpriv"
         if checkTl != "false":
             tlCheck = "Tl == 0"
         else:
index 425f6c317266ef6fdc18bd68405a8bf981dddff9..32a39bbee3dea17c4138838aa9df369050402a6e 100644 (file)
@@ -40,7 +40,10 @@ def operand_types {{
     'tudw' : 'Twin64_t',
     'tuw' : 'Twin32_t',
     'sf' : 'float',
-    'df' : 'double'
+    'df' : 'double',
+
+    'pstate' : 'PSTATE',
+    'hpstate' : 'HPSTATE'
 }};
 
 output header {{
@@ -167,7 +170,7 @@ def operands {{
     'Tt':               ('ControlReg', 'udw', 'MISCREG_TT', None, 56),
     'Tick':             ('ControlReg', 'udw', 'MISCREG_TICK', None, 57),
     'Tba':              ('ControlReg', 'udw', 'MISCREG_TBA', None, 58),
-    'Pstate':           ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 59),
+    '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),
@@ -183,7 +186,7 @@ def operands {{
     'Wstate':           ('IntReg', 'udw', 'NumIntArchRegs + 7', None, 67),
     'Gl':               ('ControlReg', 'udw', 'MISCREG_GL', None, 68),
 
-    'Hpstate':          ('ControlReg', 'udw', 'MISCREG_HPSTATE', None, 69),
+    'Hpstate':          ('ControlReg', 'hpstate', 'MISCREG_HPSTATE', None, 69),
     'Htstate':          ('ControlReg', 'udw', 'MISCREG_HTSTATE', None, 70),
     'Hintp':            ('ControlReg', 'udw', 'MISCREG_HINTP', None, 71),
     'Htba':             ('ControlReg', 'udw', 'MISCREG_HTBA', None, 72),
index 890013ec0db14349537326829eef74e5ccef25f6..7008b6b36d92e171d6629b62cd9cd5dc0d35f6ce 100644 (file)
@@ -32,6 +32,7 @@
 #ifndef __ARCH_SPARC_MISCREGS_HH__
 #define __ARCH_SPARC_MISCREGS_HH__
 
+#include "base/bitunion.hh"
 #include "base/types.hh"
 
 namespace SparcISA
@@ -115,26 +116,25 @@ enum MiscRegIndex
     MISCREG_NUMMISCREGS
 };
 
-struct HPSTATE
-{
-    const static uint64_t id = 0x800;   // this impl. dependent (id) field m
-    const static uint64_t ibe = 0x400;
-    const static uint64_t red = 0x20;
-    const static uint64_t hpriv = 0x4;
-    const static uint64_t tlz = 0x1;
-};
-
-
-struct PSTATE
-{
-    const static int cle = 0x200;
-    const static int tle = 0x100;
-    const static int mm = 0xC0;
-    const static int pef = 0x10;
-    const static int am = 0x8;
-    const static int priv = 0x4;
-    const static int ie = 0x2;
-};
+BitUnion64(HPSTATE)
+    Bitfield<0> tlz;
+    Bitfield<2> hpriv;
+    Bitfield<5> red;
+    Bitfield<10> ibe;
+    Bitfield<11> id;  // this impl. dependent (id) field m
+EndBitUnion(HPSTATE)
+
+BitUnion16(PSTATE)
+    Bitfield<1> ie;
+    Bitfield<2> priv;
+    Bitfield<3> am;
+    Bitfield<4> pef;
+    Bitfield<6, 7> mm;
+    Bitfield<8> tle;
+    Bitfield<9> cle;
+    Bitfield<10> pid0;
+    Bitfield<11> pid1;
+EndBitUnion(PSTATE)
 
 struct STS
 {
index cc39ecf31b1dd1f6843e13abdae4a5d67040b5bd..769f1549721ab815f2d7a2c43d0bc88031108d80 100644 (file)
@@ -161,7 +161,10 @@ Sparc32LiveProcess::initState()
 
     ThreadContext *tc = system->getThreadContext(contextIds[0]);
     // The process runs in user mode with 32 bit addresses
-    tc->setMiscReg(MISCREG_PSTATE, 0x0a);
+    PSTATE pstate = 0;
+    pstate.ie = 1;
+    pstate.am = 1;
+    tc->setMiscReg(MISCREG_PSTATE, pstate);
 
     argsInit(32 / 8, VMPageSize);
 }
@@ -173,7 +176,9 @@ Sparc64LiveProcess::initState()
 
     ThreadContext *tc = system->getThreadContext(contextIds[0]);
     // The process runs in user mode
-    tc->setMiscReg(MISCREG_PSTATE, 0x02);
+    PSTATE pstate = 0;
+    pstate.ie = 1;
+    tc->setMiscReg(MISCREG_PSTATE, pstate);
 
     argsInit(sizeof(IntReg), VMPageSize);
 }
@@ -533,27 +538,22 @@ SparcLiveProcess::setSyscallReturn(ThreadContext *tc,
     // 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 ().
+    PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
     if (return_value.successful()) {
         // no error, clear XCC.C
         tc->setIntReg(NumIntArchRegs + 2,
                 tc->readIntReg(NumIntArchRegs + 2) & 0xEE);
-        // tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) & 0xEE);
         IntReg val = return_value.value();
-        if (bits(tc->readMiscRegNoEffect(
-                        SparcISA::MISCREG_PSTATE), 3, 3)) {
+        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->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) | 0x11);
         IntReg val = -return_value.value();
-        if (bits(tc->readMiscRegNoEffect(
-                        SparcISA::MISCREG_PSTATE), 3, 3)) {
+        if (pstate.am)
             val = bits(val, 31, 0);
-        }
         tc->setIntReg(ReturnValueReg, val);
     }
 }
index ece6ec963a48accc571abfdec36614687c31634f..1298e327ee7070ddd487d62b9ced53a7527a7ef5 100644 (file)
@@ -181,9 +181,9 @@ RemoteGDB::getregs()
     memset(gdbregs.regs, 0, gdbregs.size);
 
     PCState pc = context->pcState();
+    PSTATE pstate = context->readMiscReg(MISCREG_PSTATE);
 
-    if (context->readMiscReg(MISCREG_PSTATE) &
-           PSTATE::am) {
+    if (pstate.am) {
         uint32_t *regs;
         regs = (uint32_t*)gdbregs.regs;
         regs[Reg32Pc] = htobe((uint32_t)pc.pc());
@@ -192,7 +192,7 @@ RemoteGDB::getregs()
             regs[x] = htobe((uint32_t)context->readIntReg(x - RegG0));
 
         regs[Reg32Y] = htobe((uint32_t)context->readIntReg(NumIntArchRegs + 1));
-        regs[Reg32Psr] = htobe((uint32_t)context->readMiscReg(MISCREG_PSTATE));
+        regs[Reg32Psr] = htobe((uint32_t)pstate);
         regs[Reg32Fsr] = htobe((uint32_t)context->readMiscReg(MISCREG_FSR));
         regs[Reg32Csr] = htobe((uint32_t)context->readIntReg(NumIntArchRegs + 2));
     } else {
@@ -206,7 +206,7 @@ RemoteGDB::getregs()
         gdbregs.regs[RegY] = htobe(context->readIntReg(NumIntArchRegs + 1));
         gdbregs.regs[RegState] = htobe(
             context->readMiscReg(MISCREG_CWP) |
-            context->readMiscReg(MISCREG_PSTATE) << 8 |
+            pstate << 8 |
             context->readMiscReg(MISCREG_ASI) << 24 |
             context->readIntReg(NumIntArchRegs + 2) << 32);
     }
index e6ab64de9c7e10fc14eeba5314b3507eee40c8b6..5948e0713aacd9748f60acc4a92af317b81f26e0 100644 (file)
@@ -206,13 +206,18 @@ ISA::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
         break;
 
       case MISCREG_HPSTATE:
-        // T1000 spec says impl. dependent val must always be 1
-        setMiscRegNoEffect(miscReg, val | HPSTATE::id);
-        if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
-            cpu->postInterrupt(IT_TRAP_LEVEL_ZERO, 0);
-        else
-            cpu->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0);
-        break;
+        {
+            HPSTATE newVal = val;
+            newVal.id = 1;
+            // T1000 spec says impl. dependent val must always be 1
+            setMiscRegNoEffect(miscReg, newVal);
+            newVal = hpstate;
+            if (newVal.tlz && tl == 0 && !newVal.hpriv)
+                cpu->postInterrupt(IT_TRAP_LEVEL_ZERO, 0);
+            else
+                cpu->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0);
+            break;
+        }
       case MISCREG_HTSTATE:
         setMiscRegNoEffect(miscReg, val);
         break;
index ee94ef29ac468f580624c633245a59565c9f79f5..b8e3b3f0efb108011d335ffe8974c0c54186a6bf 100644 (file)
@@ -58,8 +58,9 @@ uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp);
 static inline bool
 inUserMode(ThreadContext *tc)
 {
-    return !((tc->readMiscRegNoEffect(MISCREG_PSTATE) & (1 << 2)) ||
-             (tc->readMiscRegNoEffect(MISCREG_HPSTATE) & (1 << 2)));
+    PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
+    HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
+    return !(pstate.priv || hpstate.hpriv);
 }
 
 /**