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:
Gabe Black
2021-08-28 22:34:51 -07:00
parent a0e278863f
commit 0de5b1f173
13 changed files with 196 additions and 109 deletions

View File

@@ -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>();

View File

@@ -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++)

View File

@@ -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;
}

View File

@@ -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),

View File

@@ -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);
}
};

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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());

View File

@@ -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++));
}
};

View File

@@ -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

View File

@@ -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);

View File

@@ -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, &regVal, reg_bytes);
} else {
uint32_t regVal = htobe<uint32_t>(tc->readIntReg(index));
uint32_t regVal = htobe<uint32_t>(tc->getReg(reg));
memcpy(bytes, &regVal, 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);
}

View File

@@ -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());
}
};