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
This commit is contained in:
parent
9993ca8280
commit
64fe7af51a
5 changed files with 89 additions and 81 deletions
|
@ -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 §ion)
|
|||
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 §ion)
|
|||
#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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue