From 2edca021e0ca486c82df797d0fb693ebb8306ebd Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 7 Dec 2019 02:12:53 -0800 Subject: [PATCH] sparc: Introduce constants for pseudo integer registers. These are "integer" registers which are renamed, but which aren't normally considered integer registers by the ISA. They had been indexed by adding an opaque constant to the number of official integer registers which obscured what they were, and was also fragile and invited mistakes. Change-Id: Idab8cf4d889682b98c7c81a00d9a92d8e3bb3a05 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/23445 Reviewed-by: Bobby R. Bruce Maintainer: Gabe Black Tested-by: kokoro --- src/arch/sparc/faults.cc | 8 +++--- src/arch/sparc/isa/operands.isa | 43 ++++++++++++++----------------- src/arch/sparc/linux/linux.hh | 10 ++++---- src/arch/sparc/nativetrace.cc | 2 +- src/arch/sparc/process.cc | 41 +++++++++++++----------------- src/arch/sparc/registers.hh | 45 ++++++++++++++++++++++++++++----- src/arch/sparc/remote_gdb.cc | 8 +++--- src/arch/sparc/sparc_traits.hh | 4 --- 8 files changed, 88 insertions(+), 73 deletions(-) diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index d134fb50f..c1b49e108 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -303,10 +303,10 @@ doREDFault(ThreadContext *tc, TrapType tt) RegVal TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE); PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); - RegVal CCR = tc->readIntReg(NumIntArchRegs + 2); + RegVal CCR = tc->readIntReg(INTREG_CCR); RegVal ASI = tc->readMiscRegNoEffect(MISCREG_ASI); RegVal CWP = tc->readMiscRegNoEffect(MISCREG_CWP); - RegVal CANSAVE = tc->readMiscRegNoEffect(NumIntArchRegs + 3); + RegVal CANSAVE = tc->readMiscRegNoEffect(INTREG_CANSAVE); RegVal GL = tc->readMiscRegNoEffect(MISCREG_GL); PCState pc = tc->pcState(); @@ -382,10 +382,10 @@ doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) RegVal TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE); PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); - RegVal CCR = tc->readIntReg(NumIntArchRegs + 2); + RegVal CCR = tc->readIntReg(INTREG_CCR); RegVal ASI = tc->readMiscRegNoEffect(MISCREG_ASI); RegVal CWP = tc->readMiscRegNoEffect(MISCREG_CWP); - RegVal CANSAVE = tc->readIntReg(NumIntArchRegs + 3); + RegVal CANSAVE = tc->readIntReg(INTREG_CANSAVE); RegVal GL = tc->readMiscRegNoEffect(MISCREG_GL); PCState pc = tc->pcState(); diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa index c408c422f..2c1eec6b1 100644 --- a/src/arch/sparc/isa/operands.isa +++ b/src/arch/sparc/isa/operands.isa @@ -85,7 +85,7 @@ def operands {{ 'Rs1': ('IntReg', 'udw', 'RS1', 'IsInteger', 6), 'Rs2': ('IntReg', 'udw', 'RS2', 'IsInteger', 7), # A microcode register. Right now, this is the only one. - 'uReg0': ('IntReg', 'udw', 'NumIntArchRegs', 'IsInteger', 8), + 'uReg0': ('IntReg', 'udw', 'INTREG_UREG0', 'IsInteger', 8), # Because double and quad precision register numbers are decoded # differently, they get different operands. The single precision versions # have an s post pended to their name. @@ -135,24 +135,21 @@ def operands {{ 'R1': ('IntReg', 'udw', '1', None, 7), 'R15': ('IntReg', 'udw', '15', 'IsInteger', 8), 'R16': ('IntReg', 'udw', '16', None, 9), - 'O0': ('IntReg', 'udw', '8', 'IsInteger', 10), - 'O1': ('IntReg', 'udw', '9', 'IsInteger', 11), - 'O2': ('IntReg', 'udw', '10', 'IsInteger', 12), - 'O3': ('IntReg', 'udw', '11', 'IsInteger', 13), - 'O4': ('IntReg', 'udw', '12', 'IsInteger', 14), - 'O5': ('IntReg', 'udw', '13', 'IsInteger', 15), + 'O0': ('IntReg', 'udw', 'INTREG_O0', 'IsInteger', 10), + 'O1': ('IntReg', 'udw', 'INTREG_O1', 'IsInteger', 11), + 'O2': ('IntReg', 'udw', 'INTREG_O2', 'IsInteger', 12), + 'O3': ('IntReg', 'udw', 'INTREG_O3', 'IsInteger', 13), + 'O4': ('IntReg', 'udw', 'INTREG_O4', 'IsInteger', 14), + 'O5': ('IntReg', 'udw', 'INTREG_O5', 'IsInteger', 15), # Control registers -# 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40), -# 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 41), - 'Y': ('IntReg', 'udw', 'NumIntArchRegs + 1', None, 40), - 'Ccr': ('IntReg', 'udw', 'NumIntArchRegs + 2', None, 41), + 'Y': ('IntReg', 'udw', 'INTREG_Y', None, 40), + 'Ccr': ('IntReg', 'udw', 'INTREG_CCR', None, 41), 'Asi': ('ControlReg', 'udw', 'MISCREG_ASI', None, 42), 'Fprs': ('ControlReg', 'udw', 'MISCREG_FPRS', None, 43), 'Pcr': ('ControlReg', 'udw', 'MISCREG_PCR', None, 44), 'Pic': ('ControlReg', 'udw', 'MISCREG_PIC', None, 45), -# 'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 46), - 'Gsr': ('IntReg', 'udw', 'NumIntArchRegs + 8', None, 46), + 'Gsr': ('IntReg', 'udw', 'INTREG_GSR', None, 46), 'Softint': ('ControlReg', 'udw', 'MISCREG_SOFTINT', None, 47), 'SoftintSet': ('ControlReg', 'udw', 'MISCREG_SOFTINT_SET', None, 48), 'SoftintClr': ('ControlReg', 'udw', 'MISCREG_SOFTINT_CLR', None, 49), @@ -169,17 +166,15 @@ def operands {{ '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), -# 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 63), -# 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 64), -# 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 65), -# 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 66), -# 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 67), - 'Cansave': ('IntReg', 'udw', 'NumIntArchRegs + 3', None, 63), - 'Canrestore': ('IntReg', 'udw', 'NumIntArchRegs + 4', None, 64), - 'Cleanwin': ('IntReg', 'udw', 'NumIntArchRegs + 5', None, 65), - 'Otherwin': ('IntReg', 'udw', 'NumIntArchRegs + 6', None, 66), - 'Wstate': ('IntReg', 'udw', 'NumIntArchRegs + 7', None, 67), + 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', + (None, None, ['IsSerializeAfter', + 'IsSerializing', + 'IsNonSpeculative']), 62), + 'Cansave': ('IntReg', 'udw', 'INTREG_CANSAVE', None, 63), + 'Canrestore': ('IntReg', 'udw', 'INTREG_CANRESTORE', None, 64), + 'Cleanwin': ('IntReg', 'udw', 'INTREG_CLEANWIN', None, 65), + 'Otherwin': ('IntReg', 'udw', 'INTREG_OTHERWIN', None, 66), + 'Wstate': ('IntReg', 'udw', 'INTREG_WSTATE', None, 67), 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 68), 'Hpstate': ('ControlReg', 'hpstate', 'MISCREG_HPSTATE', None, 69), diff --git a/src/arch/sparc/linux/linux.hh b/src/arch/sparc/linux/linux.hh index 26cb1f866..1d45407ef 100644 --- a/src/arch/sparc/linux/linux.hh +++ b/src/arch/sparc/linux/linux.hh @@ -191,12 +191,12 @@ class SparcLinux : public Linux uint64_t stack, uint64_t tls) { SparcISA::copyRegs(ptc, ctc); - ctc->setIntReg(SparcISA::NumIntArchRegs + 6, 0); - ctc->setIntReg(SparcISA::NumIntArchRegs + 4, 0); - ctc->setIntReg(SparcISA::NumIntArchRegs + 3, SparcISA::NWindows - 2); - ctc->setIntReg(SparcISA::NumIntArchRegs + 5, SparcISA::NWindows); + ctc->setIntReg(SparcISA::INTREG_OTHERWIN, 0); + ctc->setIntReg(SparcISA::INTREG_CANRESTORE, 0); + ctc->setIntReg(SparcISA::INTREG_CANSAVE, SparcISA::NWindows - 2); + ctc->setIntReg(SparcISA::INTREG_CLEANWIN, SparcISA::NWindows); ctc->setMiscReg(SparcISA::MISCREG_CWP, 0); - ctc->setIntReg(SparcISA::NumIntArchRegs + 7, 0); + ctc->setIntReg(SparcISA::INTREG_WSTATE, 0); ctc->setMiscRegNoEffect(SparcISA::MISCREG_TL, 0); ctc->setMiscReg(SparcISA::MISCREG_ASI, SparcISA::ASI_PRIMARY); for (int y = 8; y < 32; y++) diff --git a/src/arch/sparc/nativetrace.cc b/src/arch/sparc/nativetrace.cc index 2a62d4330..6e9e206ed 100644 --- a/src/arch/sparc/nativetrace.cc +++ b/src/arch/sparc/nativetrace.cc @@ -82,7 +82,7 @@ Trace::SparcNativeTrace::check(NativeTraceRecord *record) // CCR read(&realRegVal, sizeof(realRegVal)); realRegVal = betoh(realRegVal); - regVal = tc->readIntReg(SparcISA::NumIntArchRegs + 2); + regVal = tc->readIntReg(SparcISA::INTREG_CCR); checkReg("ccr", regVal, realRegVal); } diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 884deb44f..4c055a9b1 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -123,22 +123,17 @@ SparcProcess::initState() */ // No windows contain info from other programs - // tc->setMiscRegNoEffect(MISCREG_OTHERWIN, 0); - tc->setIntReg(NumIntArchRegs + 6, 0); + tc->setIntReg(INTREG_OTHERWIN, 0); // There are no windows to pop - // tc->setMiscRegNoEffect(MISCREG_CANRESTORE, 0); - tc->setIntReg(NumIntArchRegs + 4, 0); + tc->setIntReg(INTREG_CANRESTORE, 0); // All windows are available to save into - // tc->setMiscRegNoEffect(MISCREG_CANSAVE, NWindows - 2); - tc->setIntReg(NumIntArchRegs + 3, NWindows - 2); + tc->setIntReg(INTREG_CANSAVE, NWindows - 2); // All windows are "clean" - // tc->setMiscRegNoEffect(MISCREG_CLEANWIN, NWindows); - tc->setIntReg(NumIntArchRegs + 5, NWindows); + tc->setIntReg(INTREG_CLEANWIN, NWindows); // Start with register window 0 tc->setMiscReg(MISCREG_CWP, 0); // Always use spill and fill traps 0 - // tc->setMiscRegNoEffect(MISCREG_WSTATE, 0); - tc->setIntReg(NumIntArchRegs + 7, 0); + tc->setIntReg(INTREG_WSTATE, 0); // Set the trap level to 0 tc->setMiscRegNoEffect(MISCREG_TL, 0); // Set the ASI register to something fixed @@ -428,9 +423,9 @@ Sparc32Process::argsInit(int intSize, int pageSize) void Sparc32Process::flushWindows(ThreadContext *tc) { - RegVal Cansave = tc->readIntReg(NumIntArchRegs + 3); - RegVal Canrestore = tc->readIntReg(NumIntArchRegs + 4); - RegVal Otherwin = tc->readIntReg(NumIntArchRegs + 6); + RegVal Cansave = tc->readIntReg(INTREG_CANSAVE); + RegVal Canrestore = tc->readIntReg(INTREG_CANRESTORE); + RegVal Otherwin = tc->readIntReg(INTREG_OTHERWIN); RegVal CWP = tc->readMiscReg(MISCREG_CWP); RegVal origCWP = CWP; CWP = (CWP + Cansave + 2) % NWindows; @@ -455,17 +450,17 @@ void Sparc32Process::flushWindows(ThreadContext *tc) CWP = (CWP + 1) % NWindows; } } - tc->setIntReg(NumIntArchRegs + 3, Cansave); - tc->setIntReg(NumIntArchRegs + 4, Canrestore); + tc->setIntReg(INTREG_CANSAVE, Cansave); + tc->setIntReg(INTREG_CANRESTORE, Canrestore); tc->setMiscReg(MISCREG_CWP, origCWP); } void Sparc64Process::flushWindows(ThreadContext *tc) { - RegVal Cansave = tc->readIntReg(NumIntArchRegs + 3); - RegVal Canrestore = tc->readIntReg(NumIntArchRegs + 4); - RegVal Otherwin = tc->readIntReg(NumIntArchRegs + 6); + RegVal Cansave = tc->readIntReg(INTREG_CANSAVE); + RegVal Canrestore = tc->readIntReg(INTREG_CANRESTORE); + RegVal Otherwin = tc->readIntReg(INTREG_OTHERWIN); RegVal CWP = tc->readMiscReg(MISCREG_CWP); RegVal origCWP = CWP; CWP = (CWP + Cansave + 2) % NWindows; @@ -490,8 +485,8 @@ Sparc64Process::flushWindows(ThreadContext *tc) CWP = (CWP + 1) % NWindows; } } - tc->setIntReg(NumIntArchRegs + 3, Cansave); - tc->setIntReg(NumIntArchRegs + 4, Canrestore); + tc->setIntReg(INTREG_CANSAVE, Cansave); + tc->setIntReg(INTREG_CANRESTORE, Canrestore); tc->setMiscReg(MISCREG_CWP, origCWP); } @@ -518,16 +513,14 @@ SparcProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn sysret) PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); if (sysret.successful()) { // no error, clear XCC.C - tc->setIntReg(NumIntArchRegs + 2, - tc->readIntReg(NumIntArchRegs + 2) & 0xEE); + tc->setIntReg(INTREG_CCR, tc->readIntReg(INTREG_CCR) & 0xEE); RegVal val = sysret.returnValue(); 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->setIntReg(INTREG_CCR, tc->readIntReg(INTREG_CCR) | 0x11); RegVal val = sysret.errnoValue(); if (pstate.am) val = bits(val, 31, 0); diff --git a/src/arch/sparc/registers.hh b/src/arch/sparc/registers.hh index b8b099951..6fd6577d1 100644 --- a/src/arch/sparc/registers.hh +++ b/src/arch/sparc/registers.hh @@ -59,17 +59,45 @@ constexpr size_t VecPredRegSizeBits = ::DummyVecPredRegSizeBits; constexpr bool VecPredRegHasPackedRepr = ::DummyVecPredRegHasPackedRepr; // semantically meaningful register indices +enum { + // Globals + INTREG_G0, INTREG_G1, INTREG_G2, INTREG_G3, + INTREG_G4, INTREG_G5, INTREG_G6, INTREG_G7, + // Outputs + INTREG_O0, INTREG_O1, INTREG_O2, INTREG_O3, + INTREG_O4, INTREG_O5, INTREG_O6, INTREG_O7, + // Locals + INTREG_L0, INTREG_L1, INTREG_L2, INTREG_L3, + INTREG_L4, INTREG_L5, INTREG_L6, INTREG_L7, + // Inputs + INTREG_I0, INTREG_I1, INTREG_I2, INTREG_I3, + INTREG_I4, INTREG_I5, INTREG_I6, INTREG_I7, + + NumIntArchRegs, + + INTREG_UREG0 = NumIntArchRegs, + INTREG_Y, + INTREG_CCR, + INTREG_CANSAVE, + INTREG_CANRESTORE, + INTREG_CLEANWIN, + INTREG_OTHERWIN, + INTREG_WSTATE, + INTREG_GSR, + + NumMicroIntRegs = INTREG_GSR - INTREG_UREG0 + 1 +}; const int ZeroReg = 0; // architecturally meaningful + // the rest of these depend on the ABI -const int ReturnAddressReg = 31; // post call, precall is 15 -const int ReturnValueReg = 8; // Post return, 24 is pre-return. -const int StackPointerReg = 14; -const int FramePointerReg = 30; +const int ReturnAddressReg = INTREG_I7; // post call, precall is 15 +const int ReturnValueReg = INTREG_O0; // Post return, 24 is pre-return. +const int StackPointerReg = INTREG_O6; +const int FramePointerReg = INTREG_I6; -// Some OS syscall use a second register (o1) to return a second value -const int SyscallPseudoReturnReg = 9; +// Some OS syscall use a second register to return a second value +const int SyscallPseudoReturnReg = INTREG_O1; -const int NumIntArchRegs = 32; const int NumIntRegs = (MaxGL + 1) * 8 + NWindows * 16 + NumMicroIntRegs; const int NumVecRegs = 1; // Not applicable to SPARC // (1 to prevent warnings) @@ -77,6 +105,9 @@ const int NumVecPredRegs = 1; // Not applicable to SPARC // (1 to prevent warnings) const int NumCCRegs = 0; +const int NumFloatRegs = 64; +const int NumFloatArchRegs = NumFloatRegs; + const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs; } // namespace SparcISA diff --git a/src/arch/sparc/remote_gdb.cc b/src/arch/sparc/remote_gdb.cc index 349f28cac..d0f3cd802 100644 --- a/src/arch/sparc/remote_gdb.cc +++ b/src/arch/sparc/remote_gdb.cc @@ -176,11 +176,11 @@ RemoteGDB::SPARCGdbRegCache::getRegs(ThreadContext *context) PCState pc = context->pcState(); r.pc = htobe((uint32_t)pc.pc()); r.npc = htobe((uint32_t)pc.npc()); - r.y = htobe((uint32_t)context->readIntReg(NumIntArchRegs + 1)); + r.y = htobe((uint32_t)context->readIntReg(INTREG_Y)); PSTATE pstate = context->readMiscReg(MISCREG_PSTATE); r.psr = htobe((uint32_t)pstate); r.fsr = htobe((uint32_t)context->readMiscReg(MISCREG_FSR)); - r.csr = htobe((uint32_t)context->readIntReg(NumIntArchRegs + 2)); + r.csr = htobe((uint32_t)context->readIntReg(INTREG_CCR)); } void @@ -194,13 +194,13 @@ RemoteGDB::SPARC64GdbRegCache::getRegs(ThreadContext *context) r.npc = htobe(pc.npc()); r.fsr = htobe(context->readMiscReg(MISCREG_FSR)); r.fprs = htobe(context->readMiscReg(MISCREG_FPRS)); - r.y = htobe(context->readIntReg(NumIntArchRegs + 1)); + r.y = htobe(context->readIntReg(INTREG_Y)); PSTATE pstate = context->readMiscReg(MISCREG_PSTATE); r.state = htobe( context->readMiscReg(MISCREG_CWP) | pstate << 8 | context->readMiscReg(MISCREG_ASI) << 24 | - context->readIntReg(NumIntArchRegs + 2) << 32); + context->readIntReg(INTREG_CCR) << 32); } void diff --git a/src/arch/sparc/sparc_traits.hh b/src/arch/sparc/sparc_traits.hh index e92b9822e..e53f514b5 100644 --- a/src/arch/sparc/sparc_traits.hh +++ b/src/arch/sparc/sparc_traits.hh @@ -39,10 +39,6 @@ const int MaxPGL = 2; // Number of register windows, can legally be 3 to 32 const int NWindows = 8; -const int NumMicroIntRegs = 9; - -const int NumFloatRegs = 64; -const int NumFloatArchRegs = NumFloatRegs; } #endif // __ARCH_SPARC_SPARC_TRAITS_HH__ -- 2.30.2