SPARC: Set up a lookup table for integer register flattening.
authorGabe Black <gblack@eecs.umich.edu>
Fri, 10 Jul 2009 08:01:47 +0000 (01:01 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Fri, 10 Jul 2009 08:01:47 +0000 (01:01 -0700)
Using a look up table changed the run time of the SPARC_FS solaris boot
regression from:

real    14m45.951s
user    13m57.528s
sys     0m3.452s

to:

real    12m19.777s
user    12m2.685s
sys     0m2.420s

src/arch/sparc/isa.cc
src/arch/sparc/isa.hh
src/arch/sparc/process.cc
src/arch/sparc/utility.cc
src/sim/syscall_emul.cc

index 61366937fa017e6836ad9b7e8c3c927f01df4b10..3226b4e4290a030dde25c23ef20391bdbad942a2 100644 (file)
@@ -44,9 +44,47 @@ enum RegMask
         PSTATE_MASK = (((1 << 4) - 1) << 1) | (((1 << 4) - 1) << 6) | (1 << 12)
 };
 
+void
+ISA::reloadRegMap()
+{
+    installGlobals(gl, CurrentGlobalsOffset);
+    installWindow(cwp, CurrentWindowOffset);
+    // Microcode registers.
+    for (int i = 0; i < NumMicroIntRegs; i++)
+        intRegMap[MicroIntOffset + i] = i + TotalGlobals + NWindows * 16;
+    installGlobals(gl, NextGlobalsOffset);
+    installWindow(cwp - 1, NextWindowOffset);
+    installGlobals(gl, PreviousGlobalsOffset);
+    installWindow(cwp + 1, PreviousWindowOffset);
+}
+
+void
+ISA::installWindow(int cwp, int offset)
+{
+    assert(offset >= 0 && offset + NumWindowedRegs <= NumIntRegs);
+    RegIndex *mapChunk = intRegMap + offset;
+    for (int i = 0; i < NumWindowedRegs; i++)
+        mapChunk[i] = TotalGlobals +
+            ((i - cwp * RegsPerWindow + TotalWindowed) % (TotalWindowed));
+}
+
+void
+ISA::installGlobals(int gl, int offset)
+{
+    assert(offset >= 0 && offset + NumGlobalRegs <= NumIntRegs);
+    RegIndex *mapChunk = intRegMap + offset;
+    mapChunk[0] = 0;
+    for (int i = 1; i < NumGlobalRegs; i++)
+        mapChunk[i] = i + gl * NumGlobalRegs;
+}
+
 void
 ISA::clear()
 {
+    cwp = 0;
+    gl = 0;
+    reloadRegMap();
+
     //y = 0;
     //ccr = 0;
     asi = 0;
@@ -64,13 +102,11 @@ ISA::clear()
     pstate = 0;
     tl = 0;
     pil = 0;
-    cwp = 0;
     //cansave = 0;
     //canrestore = 0;
     //cleanwin = 0;
     //otherwin = 0;
     //wstate = 0;
-    gl = 0;
     //In a T1, bit 11 is apparently always 1
     hpstate = (1 << 11);
     memset(htstate, 0, sizeof(htstate));
@@ -530,8 +566,15 @@ ISA::setMiscReg(int miscReg, MiscReg val, ThreadContext * tc)
         new_val = val >= NWindows ? NWindows - 1 : val;
         if (val >= NWindows)
             new_val = NWindows - 1;
+
+        installWindow(new_val, CurrentWindowOffset);
+        installWindow(new_val - 1, NextWindowOffset);
+        installWindow(new_val + 1, PreviousWindowOffset);
         break;
       case MISCREG_GL:
+        installGlobals(val, CurrentGlobalsOffset);
+        installGlobals(val, NextGlobalsOffset);
+        installGlobals(val, PreviousGlobalsOffset);
         break;
       case MISCREG_PIL:
       case MISCREG_SOFTINT:
@@ -668,6 +711,7 @@ ISA::unserialize(EventManager *em, Checkpoint *cp, const std::string &section)
     UNSERIALIZE_SCALAR(pil);
     UNSERIALIZE_SCALAR(cwp);
     UNSERIALIZE_SCALAR(gl);
+    reloadRegMap();
     UNSERIALIZE_SCALAR(hpstate);
     UNSERIALIZE_ARRAY(htstate,MaxTL);
     UNSERIALIZE_SCALAR(hintp);
@@ -723,72 +767,4 @@ ISA::unserialize(EventManager *em, Checkpoint *cp, const std::string &section)
  #endif
 }
 
-int
-ISA::flattenIntIndex(int reg)
-{
-    int gl = readMiscRegNoEffect(MISCREG_GL);
-    int cwp = readMiscRegNoEffect(MISCREG_CWP);
-    //DPRINTF(RegisterWindows, "Global Level = %d, Current Window Pointer = %d\n", gl, cwp);
-    int newReg;
-    //The total number of global registers
-    int numGlobals = (MaxGL + 1) * 8;
-    if(reg < 8)
-    {
-        //Global register
-        //Put it in the appropriate set of globals
-        newReg = reg + gl * 8;
-    }
-    else if(reg < NumIntArchRegs)
-    {
-        //Regular windowed register
-        //Put it in the window pointed to by cwp
-        newReg = numGlobals +
-            ((reg - 8 - cwp * 16 + NWindows * 16) % (NWindows * 16));
-    }
-    else if(reg < NumIntArchRegs + NumMicroIntRegs)
-    {
-        //Microcode register
-        //Displace from the end of the regular registers
-        newReg = reg - NumIntArchRegs + numGlobals + NWindows * 16;
-    }
-    else if(reg < 2 * NumIntArchRegs + NumMicroIntRegs)
-    {
-        reg -= (NumIntArchRegs + NumMicroIntRegs);
-        if(reg < 8)
-        {
-            //Global register from the next window
-            //Put it in the appropriate set of globals
-            newReg = reg + gl * 8;
-        }
-        else
-        {
-            //Windowed register from the previous window
-            //Put it in the window before the one pointed to by cwp
-            newReg = numGlobals +
-                ((reg - 8 - (cwp - 1) * 16 + NWindows * 16) % (NWindows * 16));
-        }
-    }
-    else if(reg < 3 * NumIntArchRegs + NumMicroIntRegs)
-    {
-        reg -= (2 * NumIntArchRegs + NumMicroIntRegs);
-        if(reg < 8)
-        {
-            //Global register from the previous window
-            //Put it in the appropriate set of globals
-            newReg = reg + gl * 8;
-        }
-        else
-        {
-            //Windowed register from the next window
-            //Put it in the window after the one pointed to by cwp
-            newReg = numGlobals +
-                ((reg - 8 - (cwp + 1) * 16 + NWindows * 16) % (NWindows * 16));
-        }
-    }
-    else
-        panic("Tried to flatten invalid register index %d!\n", reg);
-    DPRINTF(RegisterWindows, "Flattened register %d to %d.\n", reg, newReg);
-    return newReg;
-}
-
 }
index c953be01b9ff0b123a2ddec25bdf5b84f0e1b128..9b4fd50d058691bd31c3366aa5d7ccfecb8548b8 100644 (file)
@@ -139,6 +139,31 @@ namespace SparcISA
                 &ISA::processHSTickCompare> HSTickCompareEvent;
         HSTickCompareEvent *hSTickCompare;
 #endif
+
+        static const int NumGlobalRegs = 8;
+        static const int NumWindowedRegs = 24;
+        static const int WindowOverlap = 8;
+
+        static const int TotalGlobals = (MaxGL + 1) * NumGlobalRegs;
+        static const int RegsPerWindow = NumWindowedRegs - WindowOverlap;
+        static const int TotalWindowed = NWindows * RegsPerWindow;
+
+        enum InstIntRegOffsets {
+            CurrentGlobalsOffset = 0,
+            CurrentWindowOffset = CurrentGlobalsOffset + NumGlobalRegs,
+            MicroIntOffset = CurrentWindowOffset + NumWindowedRegs,
+            NextGlobalsOffset = MicroIntOffset + NumMicroIntRegs,
+            NextWindowOffset = NextGlobalsOffset + NumGlobalRegs,
+            PreviousGlobalsOffset = NextWindowOffset + NumWindowedRegs,
+            PreviousWindowOffset = PreviousGlobalsOffset + NumGlobalRegs,
+            TotalInstIntRegs = PreviousWindowOffset + NumWindowedRegs
+        };
+
+        RegIndex intRegMap[TotalInstIntRegs];
+        void installWindow(int cwp, int offset);
+        void installGlobals(int gl, int offset);
+        void reloadRegMap();
+
       public:
 
         void clear();
@@ -163,7 +188,14 @@ namespace SparcISA
         void setMiscReg(int miscReg, const MiscReg val,
                 ThreadContext *tc);
 
-        int flattenIntIndex(int reg);
+        int
+        flattenIntIndex(int reg)
+        {
+            assert(reg < TotalInstIntRegs);
+            RegIndex flatIndex = intRegMap[reg];
+            assert(flatIndex < NumIntRegs);
+            return flatIndex;
+        }
 
         int
         flattenFloatIndex(int reg)
index 2ec483babb970e75c445b761a593069ea11d5779..89e8535737761d62a09fb62ba2074c7190323ad6 100644 (file)
@@ -140,7 +140,7 @@ SparcLiveProcess::startup()
     //tc->setMiscRegNoEffect(MISCREG_CLEANWIN, NWindows);
     tc->setIntReg(NumIntArchRegs + 5, NWindows);
     //Start with register window 0
-    tc->setMiscRegNoEffect(MISCREG_CWP, 0);
+    tc->setMiscReg(MISCREG_CWP, 0);
     //Always use spill and fill traps 0
     //tc->setMiscRegNoEffect(MISCREG_WSTATE, 0);
     tc->setIntReg(NumIntArchRegs + 7, 0);
index 9c9b833fe1d8cf89270de6bf90f6a8d90655a455..84e700f6d177b62a20c084e2fb63fef09b8f1f3c 100644 (file)
@@ -101,13 +101,13 @@ copyMiscRegs(ThreadContext *src, ThreadContext *dest)
     dest->setMiscRegNoEffect(MISCREG_TBA, src->readMiscRegNoEffect(MISCREG_TBA));
     dest->setMiscRegNoEffect(MISCREG_PSTATE, src->readMiscRegNoEffect(MISCREG_PSTATE));
     dest->setMiscRegNoEffect(MISCREG_PIL, src->readMiscRegNoEffect(MISCREG_PIL));
-    dest->setMiscRegNoEffect(MISCREG_CWP, src->readMiscRegNoEffect(MISCREG_CWP));
+    dest->setMiscReg(MISCREG_CWP, src->readMiscRegNoEffect(MISCREG_CWP));
 //    dest->setMiscRegNoEffect(MISCREG_CANSAVE, src->readMiscRegNoEffect(MISCREG_CANSAVE));
 //    dest->setMiscRegNoEffect(MISCREG_CANRESTORE, src->readMiscRegNoEffect(MISCREG_CANRESTORE));
 //    dest->setMiscRegNoEffect(MISCREG_OTHERWIN, src->readMiscRegNoEffect(MISCREG_OTHERWIN));
 //    dest->setMiscRegNoEffect(MISCREG_CLEANWIN, src->readMiscRegNoEffect(MISCREG_CLEANWIN));
 //    dest->setMiscRegNoEffect(MISCREG_WSTATE, src->readMiscRegNoEffect(MISCREG_WSTATE));
-    dest->setMiscRegNoEffect(MISCREG_GL, src->readMiscRegNoEffect(MISCREG_GL));
+    dest->setMiscReg(MISCREG_GL, src->readMiscRegNoEffect(MISCREG_GL));
 
     // Hyperprivilged registers
     dest->setMiscRegNoEffect(MISCREG_HPSTATE, src->readMiscRegNoEffect(MISCREG_HPSTATE));
@@ -180,16 +180,16 @@ copyRegs(ThreadContext *src, ThreadContext *dest)
     int old_cwp = src->readMiscRegNoEffect(MISCREG_CWP);
     //Globals
     for (int x = 0; x < MaxGL; ++x) {
-        src->setMiscRegNoEffect(MISCREG_GL, x);
-        dest->setMiscRegNoEffect(MISCREG_GL, x);
+        src->setMiscReg(MISCREG_GL, x);
+        dest->setMiscReg(MISCREG_GL, x);
         // Skip %g0 which is always zero.
         for (int y = 1; y < 8; y++)
             dest->setIntReg(y, src->readIntReg(y));
     }
     //Locals and ins. Outs are all also ins.
     for (int x = 0; x < NWindows; ++x) {
-         src->setMiscRegNoEffect(MISCREG_CWP, x);
-         dest->setMiscRegNoEffect(MISCREG_CWP, x);
+         src->setMiscReg(MISCREG_CWP, x);
+         dest->setMiscReg(MISCREG_CWP, x);
          for (int y = 16; y < 32; y++)
              dest->setIntReg(y, src->readIntReg(y));
     }
@@ -198,8 +198,8 @@ copyRegs(ThreadContext *src, ThreadContext *dest)
         dest->setIntReg(y, src->readIntReg(y));
 
     //Restore src's GL, CWP
-    src->setMiscRegNoEffect(MISCREG_GL, old_gl);
-    src->setMiscRegNoEffect(MISCREG_CWP, old_cwp);
+    src->setMiscReg(MISCREG_GL, old_gl);
+    src->setMiscReg(MISCREG_CWP, old_cwp);
 
 
     // Then loop through the floating point registers.
index 941c56530706494afed242132b70b7bebbf2e30f..811bdb73a8766018bafaddb5f7fad35484b541b7 100644 (file)
@@ -692,7 +692,7 @@ cloneFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
             ctc->setIntReg(NumIntArchRegs + 4, 0);
             ctc->setIntReg(NumIntArchRegs + 3, NWindows - 2);
             ctc->setIntReg(NumIntArchRegs + 5, NWindows);
-            ctc->setMiscRegNoEffect(MISCREG_CWP, 0);
+            ctc->setMiscReg(MISCREG_CWP, 0);
             ctc->setIntReg(NumIntArchRegs + 7, 0);
             ctc->setMiscRegNoEffect(MISCREG_TL, 0);
             ctc->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY);