arch-sparc: Revamp the int regs.
Change-Id: Ifa968e42e55f78cea9eb92e9fc6fc906e0784594 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49768 Maintainer: Gabe Black <gabe.black@gmail.com> Reviewed-by: Boris Shingarov <shingarov@labware.com> Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -306,10 +306,10 @@ doREDFault(ThreadContext *tc, TrapType tt)
|
||||
RegVal TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE);
|
||||
PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
|
||||
HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
|
||||
CCR ccr = tc->readIntReg(INTREG_CCR);
|
||||
CCR ccr = tc->getReg(int_reg::Ccr);
|
||||
RegVal ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
|
||||
RegVal CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
|
||||
RegVal CANSAVE = tc->readMiscRegNoEffect(INTREG_CANSAVE);
|
||||
RegVal CANSAVE = tc->getReg(int_reg::Cansave);
|
||||
RegVal GL = tc->readMiscRegNoEffect(MISCREG_GL);
|
||||
auto &pc = tc->pcState().as<PCState>();
|
||||
|
||||
@@ -385,10 +385,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);
|
||||
CCR ccr = tc->readIntReg(INTREG_CCR);
|
||||
CCR ccr = tc->getReg(int_reg::Ccr);
|
||||
RegVal ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
|
||||
RegVal CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
|
||||
RegVal CANSAVE = tc->readIntReg(INTREG_CANSAVE);
|
||||
RegVal CANSAVE = tc->getReg(int_reg::Cansave);
|
||||
RegVal GL = tc->readMiscRegNoEffect(MISCREG_GL);
|
||||
auto &pc = tc->pcState().as<PCState>();
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ static const PSTATE PstateMask = buildPstateMask();
|
||||
|
||||
ISA::ISA(const Params &p) : BaseISA(p)
|
||||
{
|
||||
_regClasses.emplace_back(NumIntRegs, debug::IntRegs);
|
||||
_regClasses.emplace_back(int_reg::NumRegs, debug::IntRegs);
|
||||
_regClasses.emplace_back(NumFloatRegs, debug::FloatRegs);
|
||||
_regClasses.emplace_back(1, debug::IntRegs); // Not applicable for SPARC
|
||||
_regClasses.emplace_back(2, debug::IntRegs); // Not applicable for SPARC
|
||||
@@ -226,19 +226,26 @@ ISA::copyRegsFrom(ThreadContext *src)
|
||||
src->setMiscReg(MISCREG_GL, x);
|
||||
tc->setMiscReg(MISCREG_GL, x);
|
||||
// Skip %g0 which is always zero.
|
||||
for (int y = 1; y < 8; y++)
|
||||
tc->setIntReg(y, src->readIntReg(y));
|
||||
for (int y = 1; y < 8; y++) {
|
||||
RegId reg(IntRegClass, y);
|
||||
tc->setReg(reg, src->getReg(reg));
|
||||
}
|
||||
}
|
||||
// Locals and ins. Outs are all also ins.
|
||||
for (int x = 0; x < NWindows; ++x) {
|
||||
src->setMiscReg(MISCREG_CWP, x);
|
||||
tc->setMiscReg(MISCREG_CWP, x);
|
||||
for (int y = 16; y < 32; y++)
|
||||
tc->setIntReg(y, src->readIntReg(y));
|
||||
for (int y = 16; y < 32; y++) {
|
||||
RegId reg(IntRegClass, y);
|
||||
tc->setReg(reg, src->getReg(reg));
|
||||
}
|
||||
}
|
||||
// Microcode reg and pseudo int regs (misc regs in the integer regfile).
|
||||
for (int y = NumIntArchRegs; y < NumIntArchRegs + NumMicroIntRegs; ++y)
|
||||
tc->setIntReg(y, src->readIntReg(y));
|
||||
for (int y = int_reg::NumArchRegs;
|
||||
y < int_reg::NumArchRegs + int_reg::NumMicroRegs; ++y) {
|
||||
RegId reg(IntRegClass, y);
|
||||
tc->setReg(reg, src->getReg(reg));
|
||||
}
|
||||
|
||||
// Restore src's GL, CWP
|
||||
src->setMiscReg(MISCREG_GL, old_gl);
|
||||
@@ -263,7 +270,7 @@ ISA::reloadRegMap()
|
||||
installGlobals(gl, CurrentGlobalsOffset);
|
||||
installWindow(cwp, CurrentWindowOffset);
|
||||
// Microcode registers.
|
||||
for (int i = 0; i < NumMicroIntRegs; i++)
|
||||
for (int i = 0; i < int_reg::NumMicroRegs; i++)
|
||||
intRegMap[MicroIntOffset + i] = i + TotalGlobals + NWindows * 16;
|
||||
installGlobals(gl, NextGlobalsOffset);
|
||||
installWindow(cwp - 1, NextWindowOffset);
|
||||
@@ -274,7 +281,7 @@ ISA::reloadRegMap()
|
||||
void
|
||||
ISA::installWindow(int cwp, int offset)
|
||||
{
|
||||
assert(offset >= 0 && offset + NumWindowedRegs <= NumIntRegs);
|
||||
assert(offset >= 0 && offset + NumWindowedRegs <= int_reg::NumRegs);
|
||||
RegIndex *mapChunk = intRegMap + offset;
|
||||
for (int i = 0; i < NumWindowedRegs; i++)
|
||||
mapChunk[i] = TotalGlobals +
|
||||
@@ -284,7 +291,7 @@ ISA::installWindow(int cwp, int offset)
|
||||
void
|
||||
ISA::installGlobals(int gl, int offset)
|
||||
{
|
||||
assert(offset >= 0 && offset + NumGlobalRegs <= NumIntRegs);
|
||||
assert(offset >= 0 && offset + NumGlobalRegs <= int_reg::NumRegs);
|
||||
RegIndex *mapChunk = intRegMap + offset;
|
||||
mapChunk[0] = 0;
|
||||
for (int i = 1; i < NumGlobalRegs; i++)
|
||||
|
||||
@@ -154,7 +154,7 @@ class ISA : public BaseISA
|
||||
CurrentGlobalsOffset = 0,
|
||||
CurrentWindowOffset = CurrentGlobalsOffset + NumGlobalRegs,
|
||||
MicroIntOffset = CurrentWindowOffset + NumWindowedRegs,
|
||||
NextGlobalsOffset = MicroIntOffset + NumMicroIntRegs,
|
||||
NextGlobalsOffset = MicroIntOffset + int_reg::NumMicroRegs,
|
||||
NextWindowOffset = NextGlobalsOffset + NumGlobalRegs,
|
||||
PreviousGlobalsOffset = NextWindowOffset + NumWindowedRegs,
|
||||
PreviousWindowOffset = PreviousGlobalsOffset + NumGlobalRegs,
|
||||
@@ -214,7 +214,7 @@ class ISA : public BaseISA
|
||||
{
|
||||
assert(reg < TotalInstIntRegs);
|
||||
RegIndex flatIndex = intRegMap[reg];
|
||||
assert(flatIndex < NumIntRegs);
|
||||
assert(flatIndex < int_reg::NumRegs);
|
||||
return flatIndex;
|
||||
}
|
||||
|
||||
|
||||
@@ -81,10 +81,12 @@ def operands {{
|
||||
'Rd': IntReg('udw', 'RD', 'IsInteger', 1),
|
||||
# The Rd from the previous window
|
||||
'Rd_prev': IntReg('udw',
|
||||
'RD + NumIntArchRegs + NumMicroIntRegs', 'IsInteger', 2),
|
||||
'RD + int_reg::NumArchRegs + int_reg::NumMicroRegs',
|
||||
'IsInteger', 2),
|
||||
# The Rd from the next window
|
||||
'Rd_next': IntReg('udw',
|
||||
'RD + 2 * NumIntArchRegs + NumMicroIntRegs', 'IsInteger', 3),
|
||||
'RD + 2 * int_reg::NumArchRegs + int_reg::NumMicroRegs',
|
||||
'IsInteger', 3),
|
||||
# For microcoded twin load instructions, RdTwin appears in the "code"
|
||||
# for the instruction is replaced by RdLow or RdHigh by the format
|
||||
# before it's processed by the iop.
|
||||
@@ -95,7 +97,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', 'INTREG_UREG0', 'IsInteger', 8),
|
||||
'uReg0': IntReg('udw', 'int_reg::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.
|
||||
@@ -145,13 +147,13 @@ def operands {{
|
||||
'R15': IntReg('udw', '15', 'IsInteger', 8),
|
||||
|
||||
# Control registers
|
||||
'Y': IntReg('udw', 'INTREG_Y', None, 40),
|
||||
'Ccr': IntReg('udw', 'INTREG_CCR', None, 41),
|
||||
'Y': IntReg('udw', 'int_reg::Y', None, 40),
|
||||
'Ccr': IntReg('udw', 'int_reg::Ccr', None, 41),
|
||||
'Asi': ControlRegOp('udw', 'MISCREG_ASI', None, 42),
|
||||
'Fprs': ControlRegOp('udw', 'MISCREG_FPRS', None, 43),
|
||||
'Pcr': ControlRegOp('udw', 'MISCREG_PCR', None, 44),
|
||||
'Pic': ControlRegOp('udw', 'MISCREG_PIC', None, 45),
|
||||
'Gsr': IntReg('udw', 'INTREG_GSR', None, 46),
|
||||
'Gsr': IntReg('udw', 'int_reg::Gsr', None, 46),
|
||||
'Softint': ControlRegOp('udw', 'MISCREG_SOFTINT', None, 47),
|
||||
'SoftintSet': ControlRegOp('udw', 'MISCREG_SOFTINT_SET', None, 48),
|
||||
'SoftintClr': ControlRegOp('udw', 'MISCREG_SOFTINT_CLR', None, 49),
|
||||
@@ -172,11 +174,11 @@ def operands {{
|
||||
(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),
|
||||
'Cansave': IntReg('udw', 'int_reg::Cansave', None, 63),
|
||||
'Canrestore': IntReg('udw', 'int_reg::Canrestore', None, 64),
|
||||
'Cleanwin': IntReg('udw', 'int_reg::Cleanwin', None, 65),
|
||||
'Otherwin': IntReg('udw', 'int_reg::Otherwin', None, 66),
|
||||
'Wstate': IntReg('udw', 'int_reg::Wstate', None, 67),
|
||||
'Gl': ControlRegOp('udw', 'MISCREG_GL', None, 68),
|
||||
|
||||
'Hpstate': ControlRegOp('hpstate', 'MISCREG_HPSTATE', None, 69),
|
||||
|
||||
@@ -221,24 +221,26 @@ class SparcLinux : public Linux, public OpenFlagTable<SparcLinux>
|
||||
uint64_t stack, uint64_t tls)
|
||||
{
|
||||
ctc->getIsaPtr()->copyRegsFrom(ptc);
|
||||
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::INTREG_WSTATE, 0);
|
||||
ctc->setMiscRegNoEffect(SparcISA::MISCREG_TL, 0);
|
||||
ctc->setReg(SparcISA::int_reg::Otherwin, (RegVal)0);
|
||||
ctc->setReg(SparcISA::int_reg::Canrestore, (RegVal)0);
|
||||
ctc->setReg(SparcISA::int_reg::Cansave, SparcISA::NWindows - 2);
|
||||
ctc->setReg(SparcISA::int_reg::Cleanwin, SparcISA::NWindows);
|
||||
ctc->setMiscReg(SparcISA::MISCREG_CWP, (RegVal)0);
|
||||
ctc->setReg(SparcISA::int_reg::Wstate, (RegVal)0);
|
||||
ctc->setMiscRegNoEffect(SparcISA::MISCREG_TL, (RegVal)0);
|
||||
ctc->setMiscReg(SparcISA::MISCREG_ASI, SparcISA::ASI_PRIMARY);
|
||||
for (int y = 8; y < 32; y++)
|
||||
ctc->setIntReg(y, ptc->readIntReg(y));
|
||||
for (int y = 8; y < 32; y++) {
|
||||
RegId reg(IntRegClass, y);
|
||||
ctc->setReg(reg, ptc->getReg(reg));
|
||||
}
|
||||
|
||||
if (stack)
|
||||
ctc->setIntReg(SparcISA::StackPointerReg, stack);
|
||||
ctc->setReg(SparcISA::StackPointerReg, stack);
|
||||
|
||||
// Set these extra values. Since "clone" doesn't return two values,
|
||||
// we can set these and they won't be clobbered by the syscall ABI.
|
||||
ptc->setIntReg(SparcISA::SyscallPseudoReturnReg, 0);
|
||||
ctc->setIntReg(SparcISA::SyscallPseudoReturnReg, 1);
|
||||
ptc->setReg(SparcISA::SyscallPseudoReturnReg, (RegVal)0);
|
||||
ctc->setReg(SparcISA::SyscallPseudoReturnReg, 1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ EmuLinux::syscall32(ThreadContext *tc)
|
||||
// This will move into the base SEWorkload function at some point.
|
||||
process->Process::syscall(tc);
|
||||
|
||||
syscall32Descs.get(tc->readIntReg(1))->doSyscall(tc);
|
||||
syscall32Descs.get(tc->getReg(RegId(IntRegClass, 1)))->doSyscall(tc);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -128,7 +128,7 @@ EmuLinux::syscall64(ThreadContext *tc)
|
||||
// This will move into the base SEWorkload function at some point.
|
||||
process->Process::syscall(tc);
|
||||
|
||||
syscallDescs.get(tc->readIntReg(1))->doSyscall(tc);
|
||||
syscallDescs.get(tc->getReg(RegId(IntRegClass, 1)))->doSyscall(tc);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace gem5
|
||||
|
||||
namespace Trace {
|
||||
|
||||
static const char *intRegNames[SparcISA::NumIntArchRegs] = {
|
||||
static const char *intRegNames[SparcISA::int_reg::NumArchRegs] = {
|
||||
// Global registers
|
||||
"g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
|
||||
// Output registers
|
||||
@@ -60,10 +60,10 @@ Trace::SparcNativeTrace::check(NativeTraceRecord *record)
|
||||
// Integer registers
|
||||
|
||||
// I doubt a real SPARC will describe more integer registers than this.
|
||||
assert(SparcISA::NumIntArchRegs == 32);
|
||||
assert(SparcISA::int_reg::NumArchRegs == 32);
|
||||
const char **regName = intRegNames;
|
||||
for (int i = 0; i < SparcISA::NumIntArchRegs; i++) {
|
||||
regVal = tc->readIntReg(i);
|
||||
for (int i = 0; i < SparcISA::int_reg::NumArchRegs; i++) {
|
||||
regVal = tc->getReg(RegId(IntRegClass, i));
|
||||
read(&realRegVal, sizeof(realRegVal));
|
||||
realRegVal = betoh(realRegVal);
|
||||
checkReg(*(regName++), regVal, realRegVal);
|
||||
@@ -85,7 +85,7 @@ Trace::SparcNativeTrace::check(NativeTraceRecord *record)
|
||||
// CCR
|
||||
read(&realRegVal, sizeof(realRegVal));
|
||||
realRegVal = betoh(realRegVal);
|
||||
regVal = tc->readIntReg(SparcISA::INTREG_CCR);
|
||||
regVal = tc->getReg(SparcISA::int_reg::Ccr);
|
||||
checkReg("ccr", regVal, realRegVal);
|
||||
}
|
||||
|
||||
|
||||
@@ -83,17 +83,17 @@ SparcProcess::initState()
|
||||
*/
|
||||
|
||||
// No windows contain info from other programs
|
||||
tc->setIntReg(INTREG_OTHERWIN, 0);
|
||||
tc->setReg(int_reg::Otherwin, (RegVal)0);
|
||||
// There are no windows to pop
|
||||
tc->setIntReg(INTREG_CANRESTORE, 0);
|
||||
tc->setReg(int_reg::Canrestore, (RegVal)0);
|
||||
// All windows are available to save into
|
||||
tc->setIntReg(INTREG_CANSAVE, NWindows - 2);
|
||||
tc->setReg(int_reg::Cansave, NWindows - 2);
|
||||
// All windows are "clean"
|
||||
tc->setIntReg(INTREG_CLEANWIN, NWindows);
|
||||
tc->setReg(int_reg::Cleanwin, NWindows);
|
||||
// Start with register window 0
|
||||
tc->setMiscReg(MISCREG_CWP, 0);
|
||||
// Always use spill and fill traps 0
|
||||
tc->setIntReg(INTREG_WSTATE, 0);
|
||||
tc->setReg(int_reg::Wstate, (RegVal)0);
|
||||
// Set the trap level to 0
|
||||
tc->setMiscRegNoEffect(MISCREG_TL, 0);
|
||||
// Set the ASI register to something fixed
|
||||
@@ -358,13 +358,13 @@ SparcProcess::argsInit(int pageSize)
|
||||
ThreadContext *tc = system->threads[contextIds[0]];
|
||||
// Set up the thread context to start running the process
|
||||
// assert(NumArgumentRegs >= 2);
|
||||
// tc->setIntReg(ArgumentReg[0], argc);
|
||||
// tc->setIntReg(ArgumentReg[1], argv_array_base);
|
||||
tc->setIntReg(StackPointerReg, memState->getStackMin() - StackBias);
|
||||
// tc->setReg(ArgumentReg[0], argc);
|
||||
// tc->setReg(ArgumentReg[1], argv_array_base);
|
||||
tc->setReg(StackPointerReg, memState->getStackMin() - StackBias);
|
||||
|
||||
// %g1 is a pointer to a function that should be run at exit. Since we
|
||||
// don't have anything like that, it should be set to 0.
|
||||
tc->setIntReg(1, 0);
|
||||
tc->setReg(int_reg::G1, (RegVal)0);
|
||||
|
||||
tc->pcState(getStartPC());
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ struct Result<SparcPseudoInstABI, T>
|
||||
// This assumes that all pseudo ops have their return value set
|
||||
// by the pseudo op instruction. This may need to be revisited if we
|
||||
// modify the pseudo op ABI in util/m5/m5op_x86.S
|
||||
tc->setIntReg(SparcISA::INTREG_O0, ret);
|
||||
tc->setReg(SparcISA::int_reg::O0, ret);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -64,7 +64,7 @@ struct Argument<SparcPseudoInstABI, uint64_t>
|
||||
get(ThreadContext *tc, SparcPseudoInstABI::State &state)
|
||||
{
|
||||
panic_if(state >= 6, "Too many psuedo inst arguments.");
|
||||
return tc->readIntReg(SparcISA::INTREG_O0 + state++);
|
||||
return tc->getReg(SparcISA::int_reg::o(state++));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#define __ARCH_SPARC_REGS_INT_HH__
|
||||
|
||||
#include "arch/sparc/sparc_traits.hh"
|
||||
#include "cpu/reg_class.hh"
|
||||
|
||||
namespace gem5
|
||||
{
|
||||
@@ -37,46 +38,119 @@ namespace gem5
|
||||
namespace SparcISA
|
||||
{
|
||||
|
||||
namespace int_reg
|
||||
{
|
||||
|
||||
// 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,
|
||||
_G0Idx, _G1Idx, _G2Idx, _G3Idx, _G4Idx, _G5Idx, _G6Idx, _G7Idx,
|
||||
_O0Idx, _O1Idx, _O2Idx, _O3Idx, _O4Idx, _O5Idx, _O6Idx, _O7Idx,
|
||||
_L0Idx, _L1Idx, _L2Idx, _L3Idx, _L4Idx, _L5Idx, _L6Idx, _L7Idx,
|
||||
_I0Idx, _I1Idx, _I2Idx, _I3Idx, _I4Idx, _I5Idx, _I6Idx, _I7Idx,
|
||||
|
||||
NumIntArchRegs,
|
||||
NumArchRegs,
|
||||
|
||||
INTREG_UREG0 = NumIntArchRegs,
|
||||
INTREG_Y,
|
||||
INTREG_CCR,
|
||||
INTREG_CANSAVE,
|
||||
INTREG_CANRESTORE,
|
||||
INTREG_CLEANWIN,
|
||||
INTREG_OTHERWIN,
|
||||
INTREG_WSTATE,
|
||||
INTREG_GSR,
|
||||
_Ureg0Idx = NumArchRegs,
|
||||
_YIdx,
|
||||
_CcrIdx,
|
||||
_CansaveIdx,
|
||||
_CanrestoreIdx,
|
||||
_CleanwinIdx,
|
||||
_OtherwinIdx,
|
||||
_WstateIdx,
|
||||
_GsrIdx,
|
||||
|
||||
NumMicroIntRegs = INTREG_GSR - INTREG_UREG0 + 1
|
||||
NumMicroRegs = _GsrIdx - _Ureg0Idx + 1
|
||||
};
|
||||
|
||||
inline constexpr RegId
|
||||
// Globals
|
||||
G0(IntRegClass, _G0Idx),
|
||||
G1(IntRegClass, _G1Idx),
|
||||
G2(IntRegClass, _G2Idx),
|
||||
G3(IntRegClass, _G3Idx),
|
||||
G4(IntRegClass, _G4Idx),
|
||||
G5(IntRegClass, _G5Idx),
|
||||
G6(IntRegClass, _G6Idx),
|
||||
G7(IntRegClass, _G7Idx),
|
||||
|
||||
// Outputs
|
||||
O0(IntRegClass, _O0Idx),
|
||||
O1(IntRegClass, _O1Idx),
|
||||
O2(IntRegClass, _O2Idx),
|
||||
O3(IntRegClass, _O3Idx),
|
||||
O4(IntRegClass, _O4Idx),
|
||||
O5(IntRegClass, _O5Idx),
|
||||
O6(IntRegClass, _O6Idx),
|
||||
O7(IntRegClass, _O7Idx),
|
||||
|
||||
// Locals
|
||||
L0(IntRegClass, _L0Idx),
|
||||
L1(IntRegClass, _L1Idx),
|
||||
L2(IntRegClass, _L2Idx),
|
||||
L3(IntRegClass, _L3Idx),
|
||||
L4(IntRegClass, _L4Idx),
|
||||
L5(IntRegClass, _L5Idx),
|
||||
L6(IntRegClass, _L6Idx),
|
||||
L7(IntRegClass, _L7Idx),
|
||||
|
||||
// Inputs
|
||||
I0(IntRegClass, _I0Idx),
|
||||
I1(IntRegClass, _I1Idx),
|
||||
I2(IntRegClass, _I2Idx),
|
||||
I3(IntRegClass, _I3Idx),
|
||||
I4(IntRegClass, _I4Idx),
|
||||
I5(IntRegClass, _I5Idx),
|
||||
I6(IntRegClass, _I6Idx),
|
||||
I7(IntRegClass, _I7Idx),
|
||||
|
||||
Ureg0(IntRegClass, _Ureg0Idx),
|
||||
Y(IntRegClass, _YIdx),
|
||||
Ccr(IntRegClass, _CcrIdx),
|
||||
Cansave(IntRegClass, _CansaveIdx),
|
||||
Canrestore(IntRegClass, _CanrestoreIdx),
|
||||
Cleanwin(IntRegClass, _CleanwinIdx),
|
||||
Otherwin(IntRegClass, _OtherwinIdx),
|
||||
Wstate(IntRegClass, _WstateIdx),
|
||||
Gsr(IntRegClass, _GsrIdx);
|
||||
|
||||
inline constexpr RegId
|
||||
g(int index)
|
||||
{
|
||||
return RegId(IntRegClass, G0 + index);
|
||||
}
|
||||
|
||||
inline constexpr RegId
|
||||
o(int index)
|
||||
{
|
||||
return RegId(IntRegClass, O0 + index);
|
||||
}
|
||||
|
||||
inline constexpr RegId
|
||||
l(int index)
|
||||
{
|
||||
return RegId(IntRegClass, L0 + index);
|
||||
}
|
||||
|
||||
inline constexpr RegId
|
||||
i(int index)
|
||||
{
|
||||
return RegId(IntRegClass, I0 + index);
|
||||
}
|
||||
|
||||
const int NumRegs = (MaxGL + 1) * 8 + NWindows * 16 + NumMicroRegs;
|
||||
|
||||
} // namespace int_reg
|
||||
|
||||
// the rest of these depend on the ABI
|
||||
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;
|
||||
inline constexpr auto
|
||||
&ReturnAddressReg = int_reg::I7, // post call, precall is 15
|
||||
&ReturnValueReg = int_reg::O0, // Post return, 24 is pre-return.
|
||||
&StackPointerReg = int_reg::O6,
|
||||
&FramePointerReg = int_reg::I6,
|
||||
|
||||
// Some OS syscall use a second register to return a second value
|
||||
const int SyscallPseudoReturnReg = INTREG_O1;
|
||||
|
||||
const int NumIntRegs = (MaxGL + 1) * 8 + NWindows * 16 + NumMicroIntRegs;
|
||||
// Some OS syscall use a second register to return a second value
|
||||
&SyscallPseudoReturnReg = int_reg::O1;
|
||||
|
||||
} // namespace SparcISA
|
||||
} // namespace gem5
|
||||
|
||||
@@ -177,15 +177,15 @@ RemoteGDB::SPARCGdbRegCache::getRegs(ThreadContext *context)
|
||||
{
|
||||
DPRINTF(GDBAcc, "getRegs in remotegdb \n");
|
||||
for (int i = 0; i < 32; i++)
|
||||
r.gpr[i] = htobe((uint32_t)context->readIntReg(i));
|
||||
r.gpr[i] = htobe((uint32_t)context->getReg(RegId(IntRegClass, i)));
|
||||
auto &pc = context->pcState().as<SparcISA::PCState>();
|
||||
r.pc = htobe((uint32_t)pc.pc());
|
||||
r.npc = htobe((uint32_t)pc.npc());
|
||||
r.y = htobe((uint32_t)context->readIntReg(INTREG_Y));
|
||||
r.y = htobe((uint32_t)context->getReg(int_reg::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(INTREG_CCR));
|
||||
r.csr = htobe((uint32_t)context->getReg(int_reg::Ccr));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -193,7 +193,7 @@ RemoteGDB::SPARC64GdbRegCache::getRegs(ThreadContext *context)
|
||||
{
|
||||
DPRINTF(GDBAcc, "getRegs in remotegdb \n");
|
||||
for (int i = 0; i < 32; i++)
|
||||
r.gpr[i] = htobe(context->readIntReg(i));
|
||||
r.gpr[i] = htobe(context->getReg(RegId(IntRegClass, i)));
|
||||
for (int i = 0; i < 32; i++)
|
||||
r.fpr[i] = 0;
|
||||
auto &pc = context->pcState().as<SparcISA::PCState>();
|
||||
@@ -201,20 +201,20 @@ 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(INTREG_Y));
|
||||
r.y = htobe(context->getReg(int_reg::Y));
|
||||
PSTATE pstate = context->readMiscReg(MISCREG_PSTATE);
|
||||
r.state = htobe(
|
||||
context->readMiscReg(MISCREG_CWP) |
|
||||
pstate << 8 |
|
||||
context->readMiscReg(MISCREG_ASI) << 24 |
|
||||
context->readIntReg(INTREG_CCR) << 32);
|
||||
context->getReg(int_reg::Ccr) << 32);
|
||||
}
|
||||
|
||||
void
|
||||
RemoteGDB::SPARCGdbRegCache::setRegs(ThreadContext *context) const
|
||||
{
|
||||
for (int i = 0; i < 32; i++)
|
||||
context->setIntReg(i, r.gpr[i]);
|
||||
context->setReg(RegId(IntRegClass, i), r.gpr[i]);
|
||||
PCState pc;
|
||||
pc.pc(r.pc);
|
||||
pc.npc(r.npc);
|
||||
@@ -231,7 +231,7 @@ void
|
||||
RemoteGDB::SPARC64GdbRegCache::setRegs(ThreadContext *context) const
|
||||
{
|
||||
for (int i = 0; i < 32; i++)
|
||||
context->setIntReg(i, r.gpr[i]);
|
||||
context->setReg(RegId(IntRegClass, i), r.gpr[i]);
|
||||
PCState pc;
|
||||
pc.pc(r.pc);
|
||||
pc.npc(r.npc);
|
||||
|
||||
@@ -42,7 +42,8 @@ namespace SparcISA
|
||||
{
|
||||
|
||||
const std::vector<int> SEWorkload::BaseSyscallABI::ArgumentRegs = {
|
||||
INTREG_O0, INTREG_O1, INTREG_O2, INTREG_O3, INTREG_O4, INTREG_O5
|
||||
int_reg::O0, int_reg::O1, int_reg::O2,
|
||||
int_reg::O3, int_reg::O4, int_reg::O5
|
||||
};
|
||||
|
||||
bool
|
||||
@@ -96,9 +97,9 @@ SEWorkload::handleTrap(ThreadContext *tc, int trapNum)
|
||||
void
|
||||
SEWorkload::flushWindows(ThreadContext *tc)
|
||||
{
|
||||
RegVal Cansave = tc->readIntReg(INTREG_CANSAVE);
|
||||
RegVal Canrestore = tc->readIntReg(INTREG_CANRESTORE);
|
||||
RegVal Otherwin = tc->readIntReg(INTREG_OTHERWIN);
|
||||
RegVal Cansave = tc->getReg(int_reg::Cansave);
|
||||
RegVal Canrestore = tc->getReg(int_reg::Canrestore);
|
||||
RegVal Otherwin = tc->getReg(int_reg::Otherwin);
|
||||
RegVal CWP = tc->readMiscReg(MISCREG_CWP);
|
||||
RegVal origCWP = CWP;
|
||||
|
||||
@@ -114,15 +115,16 @@ SEWorkload::flushWindows(ThreadContext *tc)
|
||||
|
||||
tc->setMiscReg(MISCREG_CWP, CWP);
|
||||
// Do the stores
|
||||
RegVal sp = tc->readIntReg(StackPointerReg);
|
||||
RegVal sp = tc->getReg(StackPointerReg);
|
||||
|
||||
Addr addr = is_64 ? sp + 2047 : sp;
|
||||
for (int index = 16; index < 32; index++) {
|
||||
RegId reg(IntRegClass, index);
|
||||
if (is_64) {
|
||||
uint64_t regVal = htobe<uint64_t>(tc->readIntReg(index));
|
||||
uint64_t regVal = htobe<uint64_t>(tc->getReg(reg));
|
||||
memcpy(bytes, ®Val, reg_bytes);
|
||||
} else {
|
||||
uint32_t regVal = htobe<uint32_t>(tc->readIntReg(index));
|
||||
uint32_t regVal = htobe<uint32_t>(tc->getReg(reg));
|
||||
memcpy(bytes, ®Val, reg_bytes);
|
||||
}
|
||||
if (!proxy.tryWriteBlob(addr, bytes, reg_bytes)) {
|
||||
@@ -136,8 +138,8 @@ SEWorkload::flushWindows(ThreadContext *tc)
|
||||
CWP = (CWP + 1) % NWindows;
|
||||
}
|
||||
|
||||
tc->setIntReg(INTREG_CANSAVE, Cansave);
|
||||
tc->setIntReg(INTREG_CANRESTORE, Canrestore);
|
||||
tc->setReg(int_reg::Cansave, Cansave);
|
||||
tc->setReg(int_reg::Canrestore, Canrestore);
|
||||
tc->setMiscReg(MISCREG_CWP, origCWP);
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ struct Result<ABI, SyscallReturn,
|
||||
// and put the return value itself in the standard return value reg.
|
||||
SparcISA::PSTATE pstate =
|
||||
tc->readMiscRegNoEffect(SparcISA::MISCREG_PSTATE);
|
||||
SparcISA::CCR ccr = tc->readIntReg(SparcISA::INTREG_CCR);
|
||||
SparcISA::CCR ccr = tc->getReg(SparcISA::int_reg::Ccr);
|
||||
RegVal val;
|
||||
if (ret.successful()) {
|
||||
ccr.xcc.c = ccr.icc.c = 0;
|
||||
@@ -103,12 +103,12 @@ struct Result<ABI, SyscallReturn,
|
||||
ccr.xcc.c = ccr.icc.c = 1;
|
||||
val = ret.errnoValue();
|
||||
}
|
||||
tc->setIntReg(SparcISA::INTREG_CCR, ccr);
|
||||
tc->setReg(SparcISA::int_reg::Ccr, ccr);
|
||||
if (pstate.am)
|
||||
val = bits(val, 31, 0);
|
||||
tc->setIntReg(SparcISA::ReturnValueReg, val);
|
||||
tc->setReg(SparcISA::ReturnValueReg, val);
|
||||
if (ret.count() == 2)
|
||||
tc->setIntReg(SparcISA::SyscallPseudoReturnReg, ret.value2());
|
||||
tc->setReg(SparcISA::SyscallPseudoReturnReg, ret.value2());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user