From 64fe7af51a4cfd01886bf524f4f37d7e1a31fa9f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 10 Jul 2009 01:01:47 -0700 Subject: [PATCH] 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 --- src/arch/sparc/isa.cc | 116 +++++++++++++++----------------------- src/arch/sparc/isa.hh | 34 ++++++++++- src/arch/sparc/process.cc | 2 +- src/arch/sparc/utility.cc | 16 +++--- src/sim/syscall_emul.cc | 2 +- 5 files changed, 89 insertions(+), 81 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 @@ -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; -} - } 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. diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index 941c56530..811bdb73a 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -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);