summaryrefslogtreecommitdiff
path: root/src/arch/sparc
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2009-07-10 01:01:47 -0700
committerGabe Black <gblack@eecs.umich.edu>2009-07-10 01:01:47 -0700
commit64fe7af51a4cfd01886bf524f4f37d7e1a31fa9f (patch)
tree14d8f641c0f42da7f9e2a2dc93af9f719d3af740 /src/arch/sparc
parent9993ca8280b03a390d860b9dfb6597c7ecc98a27 (diff)
downloadgem5-64fe7af51a4cfd01886bf524f4f37d7e1a31fa9f.tar.xz
SPARC: Set up a lookup table for integer register flattening.
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
Diffstat (limited to 'src/arch/sparc')
-rw-r--r--src/arch/sparc/isa.cc116
-rw-r--r--src/arch/sparc/isa.hh34
-rw-r--r--src/arch/sparc/process.cc2
-rw-r--r--src/arch/sparc/utility.cc16
4 files changed, 88 insertions, 80 deletions
diff --git a/src/arch/sparc/isa.cc b/src/arch/sparc/isa.cc
index 61366937f..3226b4e42 100644
--- a/src/arch/sparc/isa.cc
+++ b/src/arch/sparc/isa.cc
@@ -45,8 +45,46 @@ enum RegMask
};
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;
-}
-
}
diff --git a/src/arch/sparc/isa.hh b/src/arch/sparc/isa.hh
index c953be01b..9b4fd50d0 100644
--- a/src/arch/sparc/isa.hh
+++ b/src/arch/sparc/isa.hh
@@ -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)
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc
index 2ec483bab..89e853573 100644
--- a/src/arch/sparc/process.cc
+++ b/src/arch/sparc/process.cc
@@ -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);
diff --git a/src/arch/sparc/utility.cc b/src/arch/sparc/utility.cc
index 9c9b833fe..84e700f6d 100644
--- a/src/arch/sparc/utility.cc
+++ b/src/arch/sparc/utility.cc
@@ -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.