summaryrefslogtreecommitdiff
path: root/src/arch/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/sparc')
-rw-r--r--src/arch/sparc/faults.cc65
-rw-r--r--src/arch/sparc/isa/base.isa8
-rw-r--r--src/arch/sparc/isa/decoder.isa89
-rw-r--r--src/arch/sparc/isa/formats/branch.isa17
-rw-r--r--src/arch/sparc/isa/formats/micro.isa16
-rw-r--r--src/arch/sparc/isa/operands.isa3
-rw-r--r--src/arch/sparc/nativetrace.cc5
-rw-r--r--src/arch/sparc/predecoder.hh4
-rw-r--r--src/arch/sparc/process.cc25
-rw-r--r--src/arch/sparc/remote_gdb.cc21
-rw-r--r--src/arch/sparc/types.hh3
-rw-r--r--src/arch/sparc/utility.cc12
-rw-r--r--src/arch/sparc/utility.hh17
13 files changed, 177 insertions, 108 deletions
diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc
index df0a283b9..28ee64321 100644
--- a/src/arch/sparc/faults.cc
+++ b/src/arch/sparc/faults.cc
@@ -307,15 +307,11 @@ void doREDFault(ThreadContext *tc, TrapType tt)
//MiscReg CANSAVE = tc->readMiscRegNoEffect(MISCREG_CANSAVE);
MiscReg CANSAVE = tc->readMiscRegNoEffect(NumIntArchRegs + 3);
MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL);
- MiscReg PC = tc->readPC();
- MiscReg NPC = tc->readNextPC();
+ PCState pc = tc->pcState();
TL++;
- if (bits(PSTATE, 3,3)) {
- PC &= mask(32);
- NPC &= mask(32);
- }
+ Addr pcMask = bits(PSTATE, 3) ? mask(32) : mask(64);
//set TSTATE.gl to gl
replaceBits(TSTATE, 42, 40, GL);
@@ -332,9 +328,9 @@ void doREDFault(ThreadContext *tc, TrapType tt)
tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE);
//set TPC to PC
- tc->setMiscRegNoEffect(MISCREG_TPC, PC);
+ tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask);
//set TNPC to NPC
- tc->setMiscRegNoEffect(MISCREG_TNPC, NPC);
+ tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask);
//set HTSTATE.hpstate to hpstate
tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE);
@@ -394,18 +390,14 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
//MiscReg CANSAVE = tc->readMiscRegNoEffect(MISCREG_CANSAVE);
MiscReg CANSAVE = tc->readIntReg(NumIntArchRegs + 3);
MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL);
- MiscReg PC = tc->readPC();
- MiscReg NPC = tc->readNextPC();
-
- if (bits(PSTATE, 3,3)) {
- PC &= mask(32);
- NPC &= mask(32);
- }
+ PCState pc = tc->pcState();
//Increment the trap level
TL++;
tc->setMiscRegNoEffect(MISCREG_TL, TL);
+ Addr pcMask = bits(PSTATE, 3) ? mask(32) : mask(64);
+
//Save off state
//set TSTATE.gl to gl
@@ -423,9 +415,9 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE);
//set TPC to PC
- tc->setMiscRegNoEffect(MISCREG_TPC, PC);
+ tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask);
//set TNPC to NPC
- tc->setMiscRegNoEffect(MISCREG_TNPC, NPC);
+ tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask);
//set HTSTATE.hpstate to hpstate
tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE);
@@ -479,7 +471,7 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
}
}
-void getREDVector(MiscReg TT, Addr & PC, Addr & NPC)
+void getREDVector(MiscReg TT, Addr &PC, Addr &NPC)
{
//XXX The following constant might belong in a header file.
const Addr RSTVAddr = 0xFFF0000000ULL;
@@ -554,9 +546,13 @@ void SparcFaultBase::invoke(ThreadContext * tc, StaticInstPtr inst)
getPrivVector(tc, PC, NPC, trapType(), tl+1);
}
- tc->setPC(PC);
- tc->setNextPC(NPC);
- tc->setNextNPC(NPC + sizeof(MachInst));
+ PCState pc;
+ pc.pc(PC);
+ pc.npc(NPC);
+ pc.nnpc(NPC + sizeof(MachInst));
+ pc.upc(0);
+ pc.nupc(1);
+ tc->pcState(pc);
}
void PowerOnReset::invoke(ThreadContext * tc, StaticInstPtr inst)
@@ -593,9 +589,14 @@ void PowerOnReset::invoke(ThreadContext * tc, StaticInstPtr inst)
Addr PC, NPC;
getREDVector(trapType(), PC, NPC);
- tc->setPC(PC);
- tc->setNextPC(NPC);
- tc->setNextNPC(NPC + sizeof(MachInst));
+
+ PCState pc;
+ pc.pc(PC);
+ pc.npc(NPC);
+ pc.nnpc(NPC + sizeof(MachInst));
+ pc.upc(0);
+ pc.nupc(1);
+ tc->pcState(pc);
//These registers are specified as "undefined" after a POR, and they
//should have reasonable values after the miscregfile is reset
@@ -664,10 +665,7 @@ void SpillNNormal::invoke(ThreadContext *tc, StaticInstPtr inst)
assert(lp);
//Then adjust the PC and NPC
- Addr spillStart = lp->readSpillStart();
- tc->setPC(spillStart);
- tc->setNextPC(spillStart + sizeof(MachInst));
- tc->setNextNPC(spillStart + 2*sizeof(MachInst));
+ tc->pcState(lp->readSpillStart());
}
void FillNNormal::invoke(ThreadContext *tc, StaticInstPtr inst)
@@ -681,10 +679,7 @@ void FillNNormal::invoke(ThreadContext *tc, StaticInstPtr inst)
assert(lp);
//Then adjust the PC and NPC
- Addr fillStart = lp->readFillStart();
- tc->setPC(fillStart);
- tc->setNextPC(fillStart + sizeof(MachInst));
- tc->setNextNPC(fillStart + 2*sizeof(MachInst));
+ tc->pcState(lp->readFillStart());
}
void TrapInstruction::invoke(ThreadContext *tc, StaticInstPtr inst)
@@ -702,9 +697,9 @@ void TrapInstruction::invoke(ThreadContext *tc, StaticInstPtr inst)
//We need to explicitly advance the pc, since that's not done for us
//on a faulting instruction
- tc->setPC(tc->readNextPC());
- tc->setNextPC(tc->readNextNPC());
- tc->setNextNPC(tc->readNextNPC() + sizeof(MachInst));
+ PCState pc = tc->pcState();
+ pc.advance();
+ tc->pcState(pc);
}
#endif
diff --git a/src/arch/sparc/isa/base.isa b/src/arch/sparc/isa/base.isa
index ce063bcdc..c6055b3a3 100644
--- a/src/arch/sparc/isa/base.isa
+++ b/src/arch/sparc/isa/base.isa
@@ -111,6 +111,8 @@ output header {{
void printRegArray(std::ostream &os,
const RegIndex indexArray[], int num) const;
+
+ void advancePC(SparcISA::PCState &pcState) const;
};
bool passesFpCondition(uint32_t fcc, uint32_t condition);
@@ -261,6 +263,12 @@ output decoder {{
}
void
+ SparcStaticInst::advancePC(SparcISA::PCState &pcState) const
+ {
+ pcState.advance();
+ }
+
+ void
SparcStaticInst::printSrcReg(std::ostream &os, int reg) const
{
if(_numSrcRegs > reg)
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa
index b9b38b569..80b29398c 100644
--- a/src/arch/sparc/isa/decoder.isa
+++ b/src/arch/sparc/isa/decoder.isa
@@ -46,14 +46,18 @@ decode OP default Unknown::unknown()
{
//Branch Always
0x8: bpa(19, annul_code={{
- NPC = xc->readPC() + disp;
- NNPC = NPC + 4;
+ SparcISA::PCState pc = PCS;
+ pc.npc(pc.pc() + disp);
+ pc.nnpc(pc.npc() + 4);
+ PCS = pc;
}});
//Branch Never
0x0: bpn(19, {{;}},
annul_code={{
- NNPC = NPC + 8;
- NPC = NPC + 4;
+ SparcISA::PCState pc = PCS;
+ pc.nnpc(pc.npc() + 8);
+ pc.npc(pc.npc() + 4);
+ PCS = pc;
}});
default: decode BPCC
{
@@ -66,14 +70,18 @@ decode OP default Unknown::unknown()
{
//Branch Always
0x8: ba(22, annul_code={{
- NPC = xc->readPC() + disp;
- NNPC = NPC + 4;
+ SparcISA::PCState pc = PCS;
+ pc.npc(pc.pc() + disp);
+ pc.nnpc(pc.npc() + 4);
+ PCS = pc;
}});
//Branch Never
0x0: bn(22, {{;}},
annul_code={{
- NNPC = NPC + 8;
- NPC = NPC + 4;
+ SparcISA::PCState pc = PCS;
+ pc.nnpc(pc.npc() + 8);
+ pc.npc(pc.npc() + 4);
+ PCS = pc;
}});
default: bicc(22, test={{passesCondition(Ccr<3:0>, COND2)}});
}
@@ -97,14 +105,18 @@ decode OP default Unknown::unknown()
format BranchN {
//Branch Always
0x8: fbpa(22, annul_code={{
- NPC = xc->readPC() + disp;
- NNPC = NPC + 4;
+ SparcISA::PCState pc = PCS;
+ pc.npc(pc.pc() + disp);
+ pc.nnpc(pc.npc() + 4);
+ PCS = pc;
}});
//Branch Never
0x0: fbpn(22, {{;}},
annul_code={{
- NNPC = NPC + 8;
- NPC = NPC + 4;
+ SparcISA::PCState pc = PCS;
+ pc.nnpc(pc.npc() + 8);
+ pc.npc(pc.npc() + 4);
+ PCS = pc;
}});
default: decode BPCC {
0x0: fbpfcc0(19, test=
@@ -123,14 +135,18 @@ decode OP default Unknown::unknown()
format BranchN {
//Branch Always
0x8: fba(22, annul_code={{
- NPC = xc->readPC() + disp;
- NNPC = NPC + 4;
+ SparcISA::PCState pc = PCS;
+ pc.npc(pc.pc() + disp);
+ pc.nnpc(pc.npc() + 4);
+ PCS = pc;
}});
//Branch Never
0x0: fbn(22, {{;}},
annul_code={{
- NNPC = NPC + 8;
- NPC = NPC + 4;
+ SparcISA::PCState pc = PCS;
+ pc.nnpc(pc.npc() + 8);
+ pc.npc(pc.npc() + 4);
+ PCS = pc;
}});
default: fbfcc(22, test=
{{passesFpCondition(Fsr<11:10>, COND2)}});
@@ -138,11 +154,13 @@ decode OP default Unknown::unknown()
}
}
0x1: BranchN::call(30, {{
+ SparcISA::PCState pc = PCS;
if (Pstate<3:>)
- R15 = (xc->readPC())<31:0>;
+ R15 = (pc.pc())<31:0>;
else
- R15 = xc->readPC();
- NNPC = R15 + disp;
+ R15 = pc.pc();
+ pc.nnpc(R15 + disp);
+ PCS = pc;
}});
0x2: decode OP3 {
format IntOp {
@@ -316,10 +334,12 @@ decode OP default Unknown::unknown()
0x03: NoPriv::rdasi({{Rd = Asi;}});
0x04: Priv::rdtick({{Rd = Tick;}}, {{Tick<63:>}});
0x05: NoPriv::rdpc({{
+ SparcISA::PCState pc = PCS;
if(Pstate<3:>)
- Rd = (xc->readPC())<31:0>;
+ Rd = (pc.pc())<31:0>;
else
- Rd = xc->readPC();}});
+ Rd = pc.pc();
+ }});
0x06: NoPriv::rdfprs({{
//Wait for all fpops to finish.
Rd = Fprs;
@@ -973,7 +993,8 @@ decode OP default Unknown::unknown()
0x51: m5break({{PseudoInst::debugbreak(xc->tcBase());
}}, IsNonSpeculative);
0x54: m5panic({{
- panic("M5 panic instruction called at pc=%#x.", xc->readPC());
+ SparcISA::PCState pc = PCS;
+ panic("M5 panic instruction called at pc=%#x.", pc.pc());
}}, No_OpClass, IsNonSpeculative);
}
#endif
@@ -985,11 +1006,13 @@ decode OP default Unknown::unknown()
fault = new MemAddressNotAligned;
else
{
+ SparcISA::PCState pc = PCS;
if (Pstate<3:>)
- Rd = (xc->readPC())<31:0>;
+ Rd = (pc.pc())<31:0>;
else
- Rd = xc->readPC();
- NNPC = target;
+ Rd = pc.pc();
+ pc.nnpc(target);
+ PCS = pc;
}
}});
0x39: Branch::return({{
@@ -1010,7 +1033,9 @@ decode OP default Unknown::unknown()
fault = new MemAddressNotAligned;
else
{
- NNPC = target;
+ SparcISA::PCState pc = PCS;
+ pc.nnpc(target);
+ PCS = pc;
Cwp = (Cwp - 1 + NWindows) % NWindows;
Cansave = Cansave + 1;
Canrestore = Canrestore - 1;
@@ -1082,8 +1107,10 @@ decode OP default Unknown::unknown()
Ccr = Tstate<39:32>;
Gl = Tstate<42:40>;
Hpstate = Htstate;
- NPC = Tnpc;
- NNPC = Tnpc + 4;
+ SparcISA::PCState pc = PCS;
+ pc.npc(Tnpc);
+ pc.nnpc(Tnpc + 4);
+ PCS = pc;
Tl = Tl - 1;
}}, checkTl=true);
0x1: Priv::retry({{
@@ -1093,8 +1120,10 @@ decode OP default Unknown::unknown()
Ccr = Tstate<39:32>;
Gl = Tstate<42:40>;
Hpstate = Htstate;
- NPC = Tpc;
- NNPC = Tnpc;
+ SparcISA::PCState pc = PCS;
+ pc.npc(Tpc);
+ pc.nnpc(Tnpc);
+ PCS = pc;
Tl = Tl - 1;
}}, checkTl=true);
}
diff --git a/src/arch/sparc/isa/formats/branch.isa b/src/arch/sparc/isa/formats/branch.isa
index faaee8842..e62e0035a 100644
--- a/src/arch/sparc/isa/formats/branch.isa
+++ b/src/arch/sparc/isa/formats/branch.isa
@@ -193,7 +193,7 @@ def template JumpExecute {{
%(op_decl)s;
%(op_rd)s;
- NNPC = xc->readNextNPC();
+ PCS = PCS;
%(code)s;
if(fault == NoFault)
@@ -289,15 +289,24 @@ let {{
def doCondBranch(name, Name, base, cond, code, opt_flags):
return doBranch(name, Name, base, cond, code, code,
- 'NPC = NPC; NNPC = NNPC;',
- 'NNPC = NPC + 8; NPC = NPC + 4',
+ 'PCS = PCS;',
+ '''
+ SparcISA::PCState pc = PCS;
+ pc.nnpc(pc.npc() + 8);
+ pc.npc(pc.npc() + 4);
+ PCS = pc;
+ ''',
opt_flags)
def doUncondBranch(name, Name, base, code, annul_code, opt_flags):
return doBranch(name, Name, base, "true", code, annul_code,
";", ";", opt_flags)
- default_branch_code = "NNPC = xc->readPC() + disp;"
+ default_branch_code = '''
+ SparcISA::PCState pc = PCS;
+ pc.nnpc(pc.pc() + disp);
+ PCS = pc;
+ '''
}};
// Format for branch instructions with n bit displacements:
diff --git a/src/arch/sparc/isa/formats/micro.isa b/src/arch/sparc/isa/formats/micro.isa
index c1d0c4f36..b5a53a68b 100644
--- a/src/arch/sparc/isa/formats/micro.isa
+++ b/src/arch/sparc/isa/formats/micro.isa
@@ -81,10 +81,11 @@ output header {{
StaticInstPtr * microops;
- StaticInstPtr fetchMicroop(MicroPC microPC)
+ StaticInstPtr
+ fetchMicroop(MicroPC upc) const
{
- assert(microPC < numMicroops);
- return microops[microPC];
+ assert(upc < numMicroops);
+ return microops[upc];
}
%(MacroExecute)s
@@ -102,6 +103,15 @@ output header {{
{
flags[IsMicroop] = true;
}
+
+ void
+ advancePC(SparcISA::PCState &pcState) const
+ {
+ if (flags[IsLastMicroop])
+ pcState.uEnd();
+ else
+ pcState.uAdvance();
+ }
};
class SparcDelayedMicroInst : public SparcMicroInst
diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa
index a627a2e6f..8bf6450be 100644
--- a/src/arch/sparc/isa/operands.isa
+++ b/src/arch/sparc/isa/operands.isa
@@ -126,8 +126,7 @@ def operands {{
#'Frs2': ('FloatReg', 'df', 'dfpr(RS2)', 'IsFloating', 12),
'Frs2_low': ('FloatReg', 'uw', 'dfprl(RS2)', 'IsFloating', 12),
'Frs2_high': ('FloatReg', 'uw', 'dfprh(RS2)', 'IsFloating', 12),
- 'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 31),
- 'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 32),
+ 'PCS': ('PCState', 'udw', None, (None, None, 'IsControl'), 30),
# Registers which are used explicitly in instructions
'R0': ('IntReg', 'udw', '0', None, 6),
'R1': ('IntReg', 'udw', '1', None, 7),
diff --git a/src/arch/sparc/nativetrace.cc b/src/arch/sparc/nativetrace.cc
index 8a1eb7a58..9bccaaf7d 100644
--- a/src/arch/sparc/nativetrace.cc
+++ b/src/arch/sparc/nativetrace.cc
@@ -67,16 +67,17 @@ Trace::SparcNativeTrace::check(NativeTraceRecord *record)
checkReg(*(regName++), regVal, realRegVal);
}
+ SparcISA::PCState pc = tc->pcState();
// PC
read(&realRegVal, sizeof(realRegVal));
realRegVal = SparcISA::gtoh(realRegVal);
- regVal = tc->readNextPC();
+ regVal = pc.npc();
checkReg("pc", regVal, realRegVal);
// NPC
read(&realRegVal, sizeof(realRegVal));
realRegVal = SparcISA::gtoh(realRegVal);
- regVal = tc->readNextNPC();
+ pc.nnpc();
checkReg("npc", regVal, realRegVal);
// CCR
diff --git a/src/arch/sparc/predecoder.hh b/src/arch/sparc/predecoder.hh
index c4ab4fe79..8a2587929 100644
--- a/src/arch/sparc/predecoder.hh
+++ b/src/arch/sparc/predecoder.hh
@@ -72,7 +72,7 @@ namespace SparcISA
//Use this to give data to the predecoder. This should be used
//when there is control flow.
- void moreBytes(Addr pc, Addr fetchPC, MachInst inst)
+ void moreBytes(const PCState &pc, Addr fetchPC, MachInst inst)
{
emi = inst;
//The I bit, bit 13, is used to figure out where the ASI
@@ -99,7 +99,7 @@ namespace SparcISA
}
//This returns a constant reference to the ExtMachInst to avoid a copy
- const ExtMachInst & getExtMachInst()
+ const ExtMachInst & getExtMachInst(PCState &pcState)
{
return emi;
}
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc
index 0cd8889a9..a6e21977a 100644
--- a/src/arch/sparc/process.cc
+++ b/src/arch/sparc/process.cc
@@ -69,41 +69,39 @@ SparcLiveProcess::SparcLiveProcess(LiveProcessParams * params,
void SparcLiveProcess::handleTrap(int trapNum, ThreadContext *tc)
{
+ PCState pc = tc->pcState();
switch(trapNum)
{
case 0x01: //Software breakpoint
- warn("Software breakpoint encountered at pc %#x.\n", tc->readPC());
+ warn("Software breakpoint encountered at pc %#x.\n", pc.pc());
break;
case 0x02: //Division by zero
- warn("Software signaled a division by zero at pc %#x.\n",
- tc->readPC());
+ warn("Software signaled a division by zero at pc %#x.\n", pc.pc());
break;
case 0x03: //Flush window trap
flushWindows(tc);
break;
case 0x04: //Clean windows
warn("Ignoring process request for clean register "
- "windows at pc %#x.\n", tc->readPC());
+ "windows at pc %#x.\n", pc.pc());
break;
case 0x05: //Range check
- warn("Software signaled a range check at pc %#x.\n",
- tc->readPC());
+ warn("Software signaled a range check at pc %#x.\n", pc.pc());
break;
case 0x06: //Fix alignment
warn("Ignoring process request for os assisted unaligned accesses "
- "at pc %#x.\n", tc->readPC());
+ "at pc %#x.\n", pc.pc());
break;
case 0x07: //Integer overflow
- warn("Software signaled an integer overflow at pc %#x.\n",
- tc->readPC());
+ warn("Software signaled an integer overflow at pc %#x.\n", pc.pc());
break;
case 0x32: //Get integer condition codes
warn("Ignoring process request to get the integer condition codes "
- "at pc %#x.\n", tc->readPC());
+ "at pc %#x.\n", pc.pc());
break;
case 0x33: //Set integer condition codes
warn("Ignoring process request to set the integer condition codes "
- "at pc %#x.\n", tc->readPC());
+ "at pc %#x.\n", pc.pc());
break;
default:
panic("Unimplemented trap to operating system: trap number %#x.\n", trapNum);
@@ -402,10 +400,7 @@ SparcLiveProcess::argsInit(int pageSize)
// don't have anything like that, it should be set to 0.
tc->setIntReg(1, 0);
- Addr prog_entry = objFile->entryPoint();
- tc->setPC(prog_entry);
- tc->setNextPC(prog_entry + sizeof(MachInst));
- tc->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
+ tc->pcState(objFile->entryPoint());
//Align the "stack_min" to a page boundary.
stack_min = roundDown(stack_min, pageSize);
diff --git a/src/arch/sparc/remote_gdb.cc b/src/arch/sparc/remote_gdb.cc
index 4eea0c077..aea40ea22 100644
--- a/src/arch/sparc/remote_gdb.cc
+++ b/src/arch/sparc/remote_gdb.cc
@@ -179,12 +179,14 @@ RemoteGDB::getregs()
{
memset(gdbregs.regs, 0, gdbregs.size);
+ PCState pc = context->pcState();
+
if (context->readMiscReg(MISCREG_PSTATE) &
PSTATE::am) {
uint32_t *regs;
regs = (uint32_t*)gdbregs.regs;
- regs[Reg32Pc] = htobe((uint32_t)context->readPC());
- regs[Reg32Npc] = htobe((uint32_t)context->readNextPC());
+ regs[Reg32Pc] = htobe((uint32_t)pc.pc());
+ regs[Reg32Npc] = htobe((uint32_t)pc.npc());
for(int x = RegG0; x <= RegI0 + 7; x++)
regs[x] = htobe((uint32_t)context->readIntReg(x - RegG0));
@@ -193,8 +195,8 @@ RemoteGDB::getregs()
regs[Reg32Fsr] = htobe((uint32_t)context->readMiscReg(MISCREG_FSR));
regs[Reg32Csr] = htobe((uint32_t)context->readIntReg(NumIntArchRegs + 2));
} else {
- gdbregs.regs[RegPc] = htobe(context->readPC());
- gdbregs.regs[RegNpc] = htobe(context->readNextPC());
+ gdbregs.regs[RegPc] = htobe(pc.pc());
+ gdbregs.regs[RegNpc] = htobe(pc.npc());
for(int x = RegG0; x <= RegI0 + 7; x++)
gdbregs.regs[x] = htobe(context->readIntReg(x - RegG0));
@@ -224,8 +226,13 @@ RemoteGDB::getregs()
void
RemoteGDB::setregs()
{
- context->setPC(gdbregs.regs[RegPc]);
- context->setNextPC(gdbregs.regs[RegNpc]);
+ PCState pc;
+ pc.pc(gdbregs.regs[RegPc]);
+ pc.npc(gdbregs.regs[RegNpc]);
+ pc.nnpc(pc.npc() + sizeof(MachInst));
+ pc.upc(0);
+ pc.nupc(1);
+ context->pcState(pc);
for(int x = RegG0; x <= RegI0 + 7; x++)
context->setIntReg(x - RegG0, gdbregs.regs[x]);
//Only the integer registers, pc and npc are set in netbsd
@@ -241,6 +248,6 @@ RemoteGDB::clearSingleStep()
void
RemoteGDB::setSingleStep()
{
- nextBkpt = context->readNextPC();
+ nextBkpt = context->pcState().npc();
setTempBreakpoint(nextBkpt);
}
diff --git a/src/arch/sparc/types.hh b/src/arch/sparc/types.hh
index 70558ec6d..122fd808f 100644
--- a/src/arch/sparc/types.hh
+++ b/src/arch/sparc/types.hh
@@ -33,12 +33,15 @@
#include "base/bigint.hh"
#include "base/types.hh"
+#include "arch/generic/types.hh"
namespace SparcISA
{
typedef uint32_t MachInst;
typedef uint64_t ExtMachInst;
+ typedef GenericISA::DelaySlotUPCState<MachInst> PCState;
+
typedef Twin64_t LargestRead;
struct CoreSpecific {
diff --git a/src/arch/sparc/utility.cc b/src/arch/sparc/utility.cc
index be4dfac84..6de44d8a3 100644
--- a/src/arch/sparc/utility.cc
+++ b/src/arch/sparc/utility.cc
@@ -213,20 +213,16 @@ copyRegs(ThreadContext *src, ThreadContext *dest)
// Copy misc. registers
copyMiscRegs(src, dest);
-
// Lastly copy PC/NPC
- dest->setPC(src->readPC());
- dest->setNextPC(src->readNextPC());
- dest->setNextNPC(src->readNextNPC());
+ dest->pcState(src->pcState());
}
void
skipFunction(ThreadContext *tc)
{
- Addr newpc = tc->readIntReg(ReturnAddressReg);
- tc->setPC(newpc);
- tc->setNextPC(tc->readPC() + sizeof(TheISA::MachInst));
- tc->setNextPC(tc->readNextPC() + sizeof(TheISA::MachInst));
+ TheISA::PCState newPC = tc->pcState();
+ newPC.set(tc->readIntReg(ReturnAddressReg));
+ tc->pcState(newPC);
}
diff --git a/src/arch/sparc/utility.hh b/src/arch/sparc/utility.hh
index f6a585e23..0d5a4bb93 100644
--- a/src/arch/sparc/utility.hh
+++ b/src/arch/sparc/utility.hh
@@ -36,11 +36,22 @@
#include "arch/sparc/tlb.hh"
#include "base/misc.hh"
#include "base/bitfield.hh"
+#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
#include "sim/fault.hh"
namespace SparcISA
{
+
+ inline PCState
+ buildRetPC(const PCState &curPC, const PCState &callPC)
+ {
+ PCState ret = callPC;
+ ret.uEnd();
+ ret.pc(curPC.npc());
+ return ret;
+ }
+
uint64_t
getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp);
@@ -78,6 +89,12 @@ namespace SparcISA
void skipFunction(ThreadContext *tc);
+ inline void
+ advancePC(PCState &pc, const StaticInstPtr inst)
+ {
+ inst->advancePC(pc);
+ }
+
} // namespace SparcISA
#endif