misc,cpu: Make ThreadContext work with PCStateBase-s.
Change-Id: I92f1d79c697bb45f610604c9e84b24ea93d58776
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/52058
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
diff --git a/src/arch/arm/fastmodel/iris/thread_context.cc b/src/arch/arm/fastmodel/iris/thread_context.cc
index a6b8c2a..6d76eac 100644
--- a/src/arch/arm/fastmodel/iris/thread_context.cc
+++ b/src/arch/arm/fastmodel/iris/thread_context.cc
@@ -553,11 +553,10 @@
_status = new_status;
}
-ArmISA::PCState
+const PCStateBase &
ThreadContext::pcState() const
{
ArmISA::CPSR cpsr = readMiscRegNoEffect(ArmISA::MISCREG_CPSR);
- ArmISA::PCState pc;
pc.thumb(cpsr.t);
pc.nextThumb(pc.thumb());
@@ -579,9 +578,9 @@
return pc;
}
void
-ThreadContext::pcState(const ArmISA::PCState &val)
+ThreadContext::pcState(const PCStateBase &val)
{
- Addr pc = val.pc();
+ Addr pc = val.instAddr();
ArmISA::CPSR cpsr = readMiscRegNoEffect(ArmISA::MISCREG_CPSR);
if (cpsr.width && cpsr.t)
diff --git a/src/arch/arm/fastmodel/iris/thread_context.hh b/src/arch/arm/fastmodel/iris/thread_context.hh
index c5e4cc3..a343658 100644
--- a/src/arch/arm/fastmodel/iris/thread_context.hh
+++ b/src/arch/arm/fastmodel/iris/thread_context.hh
@@ -169,6 +169,8 @@
iris::IrisCppAdapter &call() const { return client.irisCall(); }
iris::IrisCppAdapter &noThrow() const { return client.irisCallNoThrow(); }
+ mutable ArmISA::PCState pc;
+
void readMem(iris::MemorySpaceId space,
Addr addr, void *p, size_t size);
void writeMem(iris::MemorySpaceId space,
@@ -345,11 +347,11 @@
setCCRegFlat(reg_idx, val);
}
- void pcStateNoRecord(const ArmISA::PCState &val) override { pcState(val); }
+ void pcStateNoRecord(const PCStateBase &val) override { pcState(val); }
MicroPC microPC() const override { return 0; }
- ArmISA::PCState pcState() const override;
- void pcState(const ArmISA::PCState &val) override;
+ const PCStateBase &pcState() const override;
+ void pcState(const PCStateBase &val) override;
Addr instAddr() const override;
RegVal readMiscRegNoEffect(RegIndex misc_reg) const override;
diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc
index b8ca6d2..64a07cb 100644
--- a/src/arch/arm/faults.cc
+++ b/src/arch/arm/faults.cc
@@ -534,8 +534,8 @@
saved_cpsr.v = tc->readCCReg(CCREG_V);
saved_cpsr.ge = tc->readCCReg(CCREG_GE);
- [[maybe_unused]] Addr cur_pc = tc->pcState().pc();
- ITSTATE it = tc->pcState().itstate();
+ [[maybe_unused]] Addr cur_pc = tc->pcState().as<PCState>().pc();
+ ITSTATE it = tc->pcState().as<PCState>().itstate();
saved_cpsr.it2 = it.top6;
saved_cpsr.it1 = it.bottom2;
@@ -688,7 +688,7 @@
spsr.t = 0;
} else {
spsr.ge = tc->readCCReg(CCREG_GE);
- ITSTATE it = tc->pcState().itstate();
+ ITSTATE it = tc->pcState().as<PCState>().itstate();
spsr.it2 = it.top6;
spsr.it1 = it.bottom2;
spsr.uao = 0;
@@ -696,7 +696,7 @@
tc->setMiscReg(spsr_idx, spsr);
// Save preferred return address into ELR_ELx
- Addr curr_pc = tc->pcState().pc();
+ Addr curr_pc = tc->pcState().instAddr();
Addr ret_addr = curr_pc;
if (from64)
ret_addr += armPcElrOffset();
@@ -887,7 +887,7 @@
tc->getSystemPtr()->workload->syscall(tc);
// Advance the PC since that won't happen automatically.
- PCState pc = tc->pcState();
+ PCState pc = tc->pcState().as<PCState>();
assert(inst);
inst->advancePC(pc);
tc->pcState(pc);
diff --git a/src/arch/arm/fs_workload.cc b/src/arch/arm/fs_workload.cc
index 6bbe664..6a79aa0 100644
--- a/src/arch/arm/fs_workload.cc
+++ b/src/arch/arm/fs_workload.cc
@@ -57,18 +57,18 @@
void
SkipFunc::returnFromFuncIn(ThreadContext *tc)
{
- PCState newPC = tc->pcState();
+ PCState new_pc = tc->pcState().as<PCState>();
if (inAArch64(tc)) {
- newPC.set(tc->readIntReg(INTREG_X30));
+ new_pc.set(tc->readIntReg(INTREG_X30));
} else {
- newPC.set(tc->readIntReg(ReturnAddressReg) & ~1ULL);
+ new_pc.set(tc->readIntReg(ReturnAddressReg) & ~1ULL);
}
CheckerCPU *checker = tc->getCheckerCpuPtr();
if (checker) {
- tc->pcStateNoRecord(newPC);
+ tc->pcStateNoRecord(new_pc);
} else {
- tc->pcState(newPC);
+ tc->pcState(new_pc);
}
}
diff --git a/src/arch/arm/htm.cc b/src/arch/arm/htm.cc
index e94e437..84ef4a1 100644
--- a/src/arch/arm/htm.cc
+++ b/src/arch/arm/htm.cc
@@ -90,7 +90,7 @@
}
fpcr = tc->readMiscReg(MISCREG_FPCR);
fpsr = tc->readMiscReg(MISCREG_FPSR);
- pcstateckpt = tc->pcState();
+ pcstateckpt = tc->pcState().as<PCState>();
BaseHTMCheckpoint::save(tc);
}
diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc
index 7e047f1..a2d9700 100644
--- a/src/arch/arm/isa.cc
+++ b/src/arch/arm/isa.cc
@@ -607,12 +607,11 @@
ISA::readMiscReg(int misc_reg)
{
CPSR cpsr = 0;
- PCState pc(0);
SCR scr = 0;
if (misc_reg == MISCREG_CPSR) {
cpsr = miscRegs[misc_reg];
- pc = tc->pcState();
+ auto pc = tc->pcState().as<PCState>();
cpsr.j = pc.jazelle() ? 1 : 0;
cpsr.t = pc.thumb() ? 1 : 0;
return cpsr;
@@ -959,7 +958,7 @@
DPRINTF(Arm, "Updating CPSR from %#x to %#x f:%d i:%d a:%d mode:%#x\n",
miscRegs[misc_reg], cpsr, cpsr.f, cpsr.i, cpsr.a, cpsr.mode);
- PCState pc = tc->pcState();
+ PCState pc = tc->pcState().as<PCState>();
pc.nextThumb(cpsr.t);
pc.nextJazelle(cpsr.j);
pc.illegalExec(cpsr.il == 1);
@@ -2602,7 +2601,7 @@
auto req = std::make_shared<Request>(
val, 0, flags, Request::funcRequestorId,
- tc->pcState().pc(), tc->contextId());
+ tc->pcState().instAddr(), tc->contextId());
Fault fault = getMMUPtr(tc)->translateFunctional(
req, tc, mode, tran_type);
@@ -2653,7 +2652,7 @@
auto req = std::make_shared<Request>(
val, 0, flags, Request::funcRequestorId,
- tc->pcState().pc(), tc->contextId());
+ tc->pcState().instAddr(), tc->contextId());
Fault fault = getMMUPtr(tc)->translateFunctional(
req, tc, mode, tran_type);
diff --git a/src/arch/arm/kvm/arm_cpu.cc b/src/arch/arm/kvm/arm_cpu.cc
index 4f47a15..e462e4f 100644
--- a/src/arch/arm/kvm/arm_cpu.cc
+++ b/src/arch/arm/kvm/arm_cpu.cc
@@ -820,7 +820,7 @@
// We update the PC state after we have updated the CPSR the
// contents of the CPSR affects how the npc is updated.
- PCState pc = tc->pcState();
+ PCState pc = tc->pcState().as<PCState>();
pc.set(getOneRegU32(REG_CORE32(usr_regs.ARM_pc)));
tc->pcState(pc);
diff --git a/src/arch/arm/nativetrace.cc b/src/arch/arm/nativetrace.cc
index 3cafcf7..8d0313a 100644
--- a/src/arch/arm/nativetrace.cc
+++ b/src/arch/arm/nativetrace.cc
@@ -114,7 +114,7 @@
}
//R15, aliased with the PC
- newState[STATE_PC] = tc->pcState().npc();
+ newState[STATE_PC] = tc->pcState().as<ArmISA::PCState>().npc();
changed[STATE_PC] = (newState[STATE_PC] != oldState[STATE_PC]);
//CPSR
@@ -142,7 +142,7 @@
ThreadContext *tc = record->getThread();
// This area is read only on the target. It can't stop there to tell us
// what's going on, so we should skip over anything there also.
- if (tc->pcState().npc() > 0xffff0000)
+ if (tc->pcState().as<ArmISA::PCState>().npc() > 0xffff0000)
return;
nState.update(this);
mState.update(tc);
diff --git a/src/arch/arm/remote_gdb.cc b/src/arch/arm/remote_gdb.cc
index 5382d51..2efa82f 100644
--- a/src/arch/arm/remote_gdb.cc
+++ b/src/arch/arm/remote_gdb.cc
@@ -223,7 +223,7 @@
for (int i = 0; i < 31; ++i)
r.x[i] = context->readIntReg(INTREG_X0 + i);
r.spx = context->readIntReg(INTREG_SPX);
- r.pc = context->pcState().pc();
+ r.pc = context->pcState().instAddr();
r.cpsr = context->readMiscRegNoEffect(MISCREG_CPSR);
size_t base = 0;
@@ -245,7 +245,7 @@
for (int i = 0; i < 31; ++i)
context->setIntReg(INTREG_X0 + i, r.x[i]);
- auto pc_state = context->pcState();
+ auto pc_state = context->pcState().as<PCState>();
pc_state.set(r.pc);
context->pcState(pc_state);
context->setMiscRegNoEffect(MISCREG_CPSR, r.cpsr);
@@ -287,7 +287,7 @@
r.gpr[12] = context->readIntReg(INTREG_R12);
r.gpr[13] = context->readIntReg(INTREG_SP);
r.gpr[14] = context->readIntReg(INTREG_LR);
- r.gpr[15] = context->pcState().pc();
+ r.gpr[15] = context->pcState().instAddr();
r.cpsr = context->readMiscRegNoEffect(MISCREG_CPSR);
// One day somebody will implement transfer of FPRs correctly.
@@ -317,7 +317,7 @@
context->setIntReg(INTREG_R12, r.gpr[12]);
context->setIntReg(INTREG_SP, r.gpr[13]);
context->setIntReg(INTREG_LR, r.gpr[14]);
- auto pc_state = context->pcState();
+ PCState pc_state = context->pcState().as<PCState>();
pc_state.set(r.gpr[15]);
context->pcState(pc_state);
diff --git a/src/arch/arm/self_debug.cc b/src/arch/arm/self_debug.cc
index 551abbb..2029bdc 100644
--- a/src/arch/arm/self_debug.cc
+++ b/src/arch/arm/self_debug.cc
@@ -89,7 +89,7 @@
ExceptionLevel el = (ExceptionLevel) currEL(tc);
for (auto &p: arBrkPoints){
- PCState pcst = tc->pcState();
+ PCState pcst = tc->pcState().as<PCState>();
Addr pc = vaddr;
if (pcst.itstate() != 0x0)
pc = pcst.pc();
@@ -676,8 +676,7 @@
bool
SoftwareStep::advanceSS(ThreadContext * tc)
{
-
- PCState pc = tc->pcState();
+ PCState pc = tc->pcState().as<PCState>();
bool res = false;
switch (stateSS) {
case INACTIVE_STATE:
diff --git a/src/arch/generic/debugfaults.hh b/src/arch/generic/debugfaults.hh
index f54bd7c..d5976cc 100644
--- a/src/arch/generic/debugfaults.hh
+++ b/src/arch/generic/debugfaults.hh
@@ -61,9 +61,9 @@
advancePC(ThreadContext *tc, const StaticInstPtr &inst)
{
if (inst) {
- auto pc = tc->pcState();
- inst->advancePC(pc);
- tc->pcState(pc);
+ std::unique_ptr<PCStateBase> pc(tc->pcState().clone());
+ inst->advancePC(*pc);
+ tc->pcState(*pc);
}
}
diff --git a/src/arch/mips/faults.cc b/src/arch/mips/faults.cc
index a9f5239..c1884ee 100644
--- a/src/arch/mips/faults.cc
+++ b/src/arch/mips/faults.cc
@@ -114,7 +114,7 @@
tc->setMiscRegNoEffect(MISCREG_STATUS, status);
// write EPC
- PCState pc = tc->pcState();
+ auto pc = tc->pcState().as<PCState>();
DPRINTF(MipsPRA, "PC: %s\n", pc);
bool delay_slot = pc.pc() + sizeof(MachInst) != pc.npc();
tc->setMiscRegNoEffect(MISCREG_EPC,
diff --git a/src/arch/mips/mt.hh b/src/arch/mips/mt.hh
index 91fcf50..adbbf52 100644
--- a/src/arch/mips/mt.hh
+++ b/src/arch/mips/mt.hh
@@ -39,6 +39,7 @@
#include "arch/mips/faults.hh"
#include "arch/mips/mt_constants.hh"
+#include "arch/mips/pcstate.hh"
#include "arch/mips/pra_constants.hh"
#include "arch/mips/regs/misc.hh"
#include "base/bitfield.hh"
@@ -140,7 +141,7 @@
// Save last known PC in TCRestart
// @TODO: Needs to check if this is a branch and if so,
// take previous instruction
- PCState pc = tc->pcState();
+ auto &pc = tc->pcState().template as<MipsISA::PCState>();
tc->setMiscReg(MISCREG_TC_RESTART, pc.npc());
warn("%i: Halting thread %i in %s @ PC %x, setting restart PC to %x",
diff --git a/src/arch/mips/remote_gdb.cc b/src/arch/mips/remote_gdb.cc
index bf845ba..ad39300 100644
--- a/src/arch/mips/remote_gdb.cc
+++ b/src/arch/mips/remote_gdb.cc
@@ -179,7 +179,7 @@
r.hi = context->readIntReg(INTREG_HI);
r.badvaddr = context->readMiscRegNoEffect(MISCREG_BADVADDR);
r.cause = context->readMiscRegNoEffect(MISCREG_CAUSE);
- r.pc = context->pcState().pc();
+ r.pc = context->pcState().instAddr();
for (int i = 0; i < 32; i++) r.fpr[i] = context->readFloatReg(i);
r.fsr = context->readFloatReg(FLOATREG_FCCR);
r.fir = context->readFloatReg(FLOATREG_FIR);
diff --git a/src/arch/power/faults.cc b/src/arch/power/faults.cc
index 3b8851e..be1796e 100644
--- a/src/arch/power/faults.cc
+++ b/src/arch/power/faults.cc
@@ -44,7 +44,7 @@
{
panic_if(tc->getSystemPtr()->trapToGdb(SIGILL, tc->contextId()),
"Unimplemented opcode encountered at virtual address %#x\n",
- tc->pcState().pc());
+ tc->pcState().instAddr());
}
void
@@ -59,7 +59,7 @@
{
panic_if(tc->getSystemPtr()->trapToGdb(SIGTRAP, tc->contextId()),
"Trap encountered at virtual address %#x\n",
- tc->pcState().pc());
+ tc->pcState().instAddr());
}
} // namespace PowerISA
diff --git a/src/arch/power/insts/branch.cc b/src/arch/power/insts/branch.cc
index 2cab370..8540cef 100644
--- a/src/arch/power/insts/branch.cc
+++ b/src/arch/power/insts/branch.cc
@@ -65,7 +65,7 @@
if (aa)
addr = li;
else
- addr = tc->pcState().pc() + li;
+ addr = tc->pcState().instAddr() + li;
return std::make_unique<PowerISA::PCState>(
msr.sf ? addr : addr & UINT32_MAX);
@@ -114,7 +114,7 @@
if (aa)
addr = bd;
else
- addr = tc->pcState().pc() + bd;
+ addr = tc->pcState().instAddr() + bd;
return std::make_unique<PowerISA::PCState>(
msr.sf ? addr : addr & UINT32_MAX);
diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc
index ca489d8..8ed4b75 100644
--- a/src/arch/power/process.cc
+++ b/src/arch/power/process.cc
@@ -103,7 +103,7 @@
initVirtMem->readBlob(getStartPC(), &entryPoint, sizeof(Addr));
// Update the PC state
- auto pc = tc->pcState();
+ auto pc = tc->pcState().as<PowerISA::PCState>();
pc.byteOrder(byteOrder);
pc.set(gtoh(entryPoint, byteOrder));
tc->pcState(pc);
@@ -356,7 +356,7 @@
msr.le = isLittleEndian;
tc->setIntReg(INTREG_MSR, msr);
- auto pc = tc->pcState();
+ auto pc = tc->pcState().as<PowerISA::PCState>();
pc.set(getStartPC());
pc.byteOrder(byteOrder);
tc->pcState(pc);
diff --git a/src/arch/power/remote_gdb.cc b/src/arch/power/remote_gdb.cc
index 0accb6a..702439d 100644
--- a/src/arch/power/remote_gdb.cc
+++ b/src/arch/power/remote_gdb.cc
@@ -192,7 +192,7 @@
for (int i = 0; i < NumFloatArchRegs; i++)
r.fpr[i] = context->readFloatReg(i);
- r.pc = htog((uint32_t)context->pcState().pc(), order);
+ r.pc = htog((uint32_t)context->pcState().instAddr(), order);
r.msr = 0; // MSR is privileged, hence not exposed here
r.cr = htog((uint32_t)context->readIntReg(INTREG_CR), order);
r.lr = htog((uint32_t)context->readIntReg(INTREG_LR), order);
@@ -215,7 +215,7 @@
for (int i = 0; i < NumFloatArchRegs; i++)
context->setFloatReg(i, r.fpr[i]);
- auto pc = context->pcState();
+ auto pc = context->pcState().as<PowerISA::PCState>();
pc.byteOrder(order);
pc.set(gtoh(r.pc, order));
context->pcState(pc);
@@ -246,7 +246,7 @@
for (int i = 0; i < NumFloatArchRegs; i++)
r.fpr[i] = context->readFloatReg(i);
- r.pc = htog(context->pcState().pc(), order);
+ r.pc = htog(context->pcState().instAddr(), order);
r.msr = 0; // MSR is privileged, hence not exposed here
r.cr = htog((uint32_t)context->readIntReg(INTREG_CR), order);
r.lr = htog(context->readIntReg(INTREG_LR), order);
@@ -269,7 +269,7 @@
for (int i = 0; i < NumFloatArchRegs; i++)
context->setFloatReg(i, r.fpr[i]);
- auto pc = context->pcState();
+ auto pc = context->pcState().as<PowerISA::PCState>();
pc.byteOrder(order);
pc.set(gtoh(r.pc, order));
context->pcState(pc);
diff --git a/src/arch/riscv/faults.cc b/src/arch/riscv/faults.cc
index 01f6827..703b0ee 100644
--- a/src/arch/riscv/faults.cc
+++ b/src/arch/riscv/faults.cc
@@ -51,16 +51,16 @@
void
RiscvFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
{
- panic("Fault %s encountered at pc 0x%016llx.", name(), tc->pcState().pc());
+ panic("Fault %s encountered at pc %s.", name(), tc->pcState());
}
void
RiscvFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
- PCState pcState = tc->pcState();
+ auto pc_state = tc->pcState().as<PCState>();
DPRINTFS(Fault, tc->getCpuPtr(), "Fault (%s) at PC: %s\n",
- name(), pcState);
+ name(), pc_state);
if (FullSystem) {
PrivilegeMode pp = (PrivilegeMode)tc->readMiscReg(MISCREG_PRV);
@@ -156,12 +156,12 @@
Addr addr = mbits(tc->readMiscReg(tvec), 63, 2);
if (isInterrupt() && bits(tc->readMiscReg(tvec), 1, 0) == 1)
addr += 4 * _code;
- pcState.set(addr);
+ pc_state.set(addr);
} else {
invokeSE(tc, inst);
- inst->advancePC(pcState);
+ inst->advancePC(pc_state);
}
- tc->pcState(pcState);
+ tc->pcState(pc_state);
}
void
@@ -184,31 +184,29 @@
UnknownInstFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
{
auto *rsi = static_cast<RiscvStaticInst *>(inst.get());
- panic("Unknown instruction 0x%08x at pc 0x%016llx", rsi->machInst,
- tc->pcState().pc());
+ panic("Unknown instruction 0x%08x at pc %s", rsi->machInst,
+ tc->pcState());
}
void
IllegalInstFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
{
auto *rsi = static_cast<RiscvStaticInst *>(inst.get());
- panic("Illegal instruction 0x%08x at pc 0x%016llx: %s", rsi->machInst,
- tc->pcState().pc(), reason.c_str());
+ panic("Illegal instruction 0x%08x at pc %s: %s", rsi->machInst,
+ tc->pcState(), reason.c_str());
}
void
-UnimplementedFault::invokeSE(ThreadContext *tc,
- const StaticInstPtr &inst)
+UnimplementedFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
{
- panic("Unimplemented instruction %s at pc 0x%016llx", instName,
- tc->pcState().pc());
+ panic("Unimplemented instruction %s at pc %s", instName, tc->pcState());
}
void
IllegalFrmFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
{
- panic("Illegal floating-point rounding mode 0x%x at pc 0x%016llx.",
- frm, tc->pcState().pc());
+ panic("Illegal floating-point rounding mode 0x%x at pc %s.",
+ frm, tc->pcState());
}
void
diff --git a/src/arch/riscv/isa.cc b/src/arch/riscv/isa.cc
index 0358889..c8b752c 100644
--- a/src/arch/riscv/isa.cc
+++ b/src/arch/riscv/isa.cc
@@ -466,8 +466,10 @@
// only allow to disable compressed instructions
// if the following instruction is 4-byte aligned
if ((val & ISA_EXT_C_MASK) == 0 &&
- bits(tc->pcState().npc(), 2, 0) != 0)
+ bits(tc->pcState().as<RiscvISA::PCState>().npc(),
+ 2, 0) != 0) {
val |= cur_val & ISA_EXT_C_MASK;
+ }
setMiscRegNoEffect(misc_reg, val);
}
break;
diff --git a/src/arch/riscv/isa/formats/standard.isa b/src/arch/riscv/isa/formats/standard.isa
index 3c16f60..9345c1f 100644
--- a/src/arch/riscv/isa/formats/standard.isa
+++ b/src/arch/riscv/isa/formats/standard.isa
@@ -255,9 +255,10 @@
std::unique_ptr<PCStateBase>
%(class_name)s::branchTarget(ThreadContext *tc) const
{
- PCState pc = tc->pcState();
- pc.set((tc->readIntReg(srcRegIdx(0).index()) + imm)&~0x1);
- return std::unique_ptr<PCStateBase>{pc.clone()};
+ PCStateBase *pc_ptr = tc->pcState().clone();
+ pc_ptr->as<PCState>().set(
+ (tc->readIntReg(srcRegIdx(0).index()) + imm) & ~0x1);
+ return std::unique_ptr<PCStateBase>{pc_ptr};
}
std::string
diff --git a/src/arch/riscv/process.cc b/src/arch/riscv/process.cc
index bdbb7cc..cbd13b0 100644
--- a/src/arch/riscv/process.cc
+++ b/src/arch/riscv/process.cc
@@ -114,7 +114,7 @@
for (ContextID ctx: contextIds) {
auto *tc = system->threads[ctx];
tc->setMiscRegNoEffect(MISCREG_PRV, PRV_U);
- PCState pc = tc->pcState();
+ PCState pc = tc->pcState().as<PCState>();
pc.rv32(true);
tc->pcState(pc);
}
diff --git a/src/arch/riscv/remote_gdb.cc b/src/arch/riscv/remote_gdb.cc
index ec3eb5a..50b0ba7 100644
--- a/src/arch/riscv/remote_gdb.cc
+++ b/src/arch/riscv/remote_gdb.cc
@@ -195,7 +195,7 @@
{
r.gpr[i] = context->readIntReg(i);
}
- r.pc = context->pcState().pc();
+ r.pc = context->pcState().instAddr();
// Floating point registers
for (int i = 0; i < NumFloatRegs; i++)
diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc
index 6ead79a..ec7386f 100644
--- a/src/arch/sparc/faults.cc
+++ b/src/arch/sparc/faults.cc
@@ -311,7 +311,7 @@
RegVal CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
RegVal CANSAVE = tc->readMiscRegNoEffect(INTREG_CANSAVE);
RegVal GL = tc->readMiscRegNoEffect(MISCREG_GL);
- PCState pc = tc->pcState();
+ auto &pc = tc->pcState().as<PCState>();
TL++;
@@ -390,7 +390,7 @@
RegVal CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
RegVal CANSAVE = tc->readIntReg(INTREG_CANSAVE);
RegVal GL = tc->readMiscRegNoEffect(MISCREG_GL);
- PCState pc = tc->pcState();
+ auto &pc = tc->pcState().as<PCState>();
// Increment the trap level
TL++;
@@ -825,7 +825,7 @@
// We need to explicitly advance the pc, since that's not done for us
// on a faulting instruction
- PCState pc = tc->pcState();
+ PCState pc = tc->pcState().as<PCState>();
pc.advance();
tc->pcState(pc);
}
diff --git a/src/arch/sparc/nativetrace.cc b/src/arch/sparc/nativetrace.cc
index 752e316..0179fe4 100644
--- a/src/arch/sparc/nativetrace.cc
+++ b/src/arch/sparc/nativetrace.cc
@@ -68,7 +68,7 @@
checkReg(*(regName++), regVal, realRegVal);
}
- SparcISA::PCState pc = tc->pcState();
+ auto &pc = tc->pcState().as<SparcISA::PCState>();
// PC
read(&realRegVal, sizeof(realRegVal));
realRegVal = betoh(realRegVal);
diff --git a/src/arch/sparc/remote_gdb.cc b/src/arch/sparc/remote_gdb.cc
index 83ef55b..9e1e06e 100644
--- a/src/arch/sparc/remote_gdb.cc
+++ b/src/arch/sparc/remote_gdb.cc
@@ -176,8 +176,9 @@
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));
- PCState pc = context->pcState();
+ for (int i = 0; i < 32; i++)
+ r.gpr[i] = htobe((uint32_t)context->readIntReg(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));
@@ -191,9 +192,11 @@
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));
- for (int i = 0; i < 32; i++) r.fpr[i] = 0;
- PCState pc = context->pcState();
+ for (int i = 0; i < 32; i++)
+ r.gpr[i] = htobe(context->readIntReg(i));
+ for (int i = 0; i < 32; i++)
+ r.fpr[i] = 0;
+ auto &pc = context->pcState().as<SparcISA::PCState>();
r.pc = htobe(pc.pc());
r.npc = htobe(pc.npc());
r.fsr = htobe(context->readMiscReg(MISCREG_FSR));
@@ -210,7 +213,8 @@
void
RemoteGDB::SPARCGdbRegCache::setRegs(ThreadContext *context) const
{
- for (int i = 0; i < 32; i++) context->setIntReg(i, r.gpr[i]);
+ for (int i = 0; i < 32; i++)
+ context->setIntReg(i, r.gpr[i]);
PCState pc;
pc.pc(r.pc);
pc.npc(r.npc);
@@ -226,7 +230,8 @@
void
RemoteGDB::SPARC64GdbRegCache::setRegs(ThreadContext *context) const
{
- for (int i = 0; i < 32; i++) context->setIntReg(i, r.gpr[i]);
+ for (int i = 0; i < 32; i++)
+ context->setIntReg(i, r.gpr[i]);
PCState pc;
pc.pc(r.pc);
pc.npc(r.npc);
diff --git a/src/arch/sparc/se_workload.cc b/src/arch/sparc/se_workload.cc
index 7c1e125..c87244f 100644
--- a/src/arch/sparc/se_workload.cc
+++ b/src/arch/sparc/se_workload.cc
@@ -54,7 +54,7 @@
void
SEWorkload::handleTrap(ThreadContext *tc, int trapNum)
{
- PCState pc = tc->pcState();
+ auto &pc = tc->pcState().as<PCState>();
switch (trapNum) {
case 0x01: // Software breakpoint
warn("Software breakpoint encountered at pc %#x.", pc.pc());
diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc
index d925bd7..ae9586b 100644
--- a/src/arch/x86/faults.cc
+++ b/src/arch/x86/faults.cc
@@ -64,9 +64,8 @@
return;
}
- PCState pcState = tc->pcState();
- Addr pc = pcState.pc();
- DPRINTF(Faults, "RIP %#x: vector %d: %s\n", pc, vector, describe());
+ PCState pc = tc->pcState().as<PCState>();
+ DPRINTF(Faults, "RIP %#x: vector %d: %s\n", pc.pc(), vector, describe());
using namespace X86ISAInst::rom_labels;
HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
MicroPC entry;
@@ -77,7 +76,7 @@
entry = extern_label_legacyModeInterrupt;
}
tc->setIntReg(INTREG_MICRO(1), vector);
- tc->setIntReg(INTREG_MICRO(7), pc);
+ tc->setIntReg(INTREG_MICRO(7), pc.pc());
if (errorCode != (uint64_t)(-1)) {
if (m5reg.mode == LongMode) {
entry = extern_label_longModeInterruptWithError;
@@ -90,9 +89,9 @@
assert(!isSoft());
tc->setIntReg(INTREG_MICRO(15), errorCode);
}
- pcState.upc(romMicroPC(entry));
- pcState.nupc(romMicroPC(entry) + 1);
- tc->pcState(pcState);
+ pc.upc(romMicroPC(entry));
+ pc.nupc(romMicroPC(entry) + 1);
+ tc->pcState(pc);
}
std::string
@@ -109,14 +108,9 @@
void
X86Trap::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
- X86FaultBase::invoke(tc);
- if (!FullSystem)
- return;
-
// This is the same as a fault, but it happens -after- the
// instruction.
- PCState pc = tc->pcState();
- pc.uEnd();
+ X86FaultBase::invoke(tc);
}
void
@@ -168,8 +162,8 @@
panic("Tried to %s unmapped address %#x.", modeStr, addr);
} else {
panic("Tried to %s unmapped address %#x.\nPC: %#x, Instr: %s",
- modeStr, addr, tc->pcState().pc(),
- inst->disassemble(tc->pcState().pc(),
+ modeStr, addr, tc->pcState(),
+ inst->disassemble(tc->pcState().instAddr(),
&loader::debugSymbolTable));
}
}
diff --git a/src/arch/x86/linux/se_workload.cc b/src/arch/x86/linux/se_workload.cc
index 46a6327..f5fa519 100644
--- a/src/arch/x86/linux/se_workload.cc
+++ b/src/arch/x86/linux/se_workload.cc
@@ -116,7 +116,7 @@
if (dynamic_cast<X86_64Process *>(process)) {
syscallDescs64.get(rax)->doSyscall(tc);
} else if (auto *proc32 = dynamic_cast<I386Process *>(process)) {
- PCState pc = tc->pcState();
+ PCState pc = tc->pcState().as<PCState>();
Addr eip = pc.pc();
const auto &vsyscall = proc32->getVSyscallPage();
if (eip >= vsyscall.base && eip < vsyscall.base + vsyscall.size) {
@@ -133,10 +133,10 @@
EmuLinux::event(ThreadContext *tc)
{
Process *process = tc->getProcessPtr();
- auto pcState = tc->pcState();
+ Addr pc = tc->pcState().instAddr();
if (process->kvmInSE) {
- Addr pc_page = mbits(pcState.pc(), 63, 12);
+ Addr pc_page = mbits(pc, 63, 12);
if (pc_page == syscallCodeVirtAddr) {
syscall(tc);
return;
@@ -145,7 +145,7 @@
return;
}
}
- warn("Unexpected workload event at pc %#x.", pcState.pc());
+ warn("Unexpected workload event at pc %#x.", pc);
}
void
diff --git a/src/arch/x86/nativetrace.cc b/src/arch/x86/nativetrace.cc
index 9e357a8..abb1a32 100644
--- a/src/arch/x86/nativetrace.cc
+++ b/src/arch/x86/nativetrace.cc
@@ -87,7 +87,7 @@
r13 = tc->readIntReg(X86ISA::INTREG_R13);
r14 = tc->readIntReg(X86ISA::INTREG_R14);
r15 = tc->readIntReg(X86ISA::INTREG_R15);
- rip = tc->pcState().npc();
+ rip = tc->pcState().as<X86ISA::PCState>().npc();
//This should be expanded if x87 registers are considered
for (int i = 0; i < 8; i++)
mmx[i] = tc->readFloatReg(X86ISA::FLOATREG_MMX(i));
diff --git a/src/arch/x86/remote_gdb.cc b/src/arch/x86/remote_gdb.cc
index 41b4525..abb2154 100644
--- a/src/arch/x86/remote_gdb.cc
+++ b/src/arch/x86/remote_gdb.cc
@@ -141,7 +141,7 @@
r.r13 = context->readIntReg(INTREG_R13);
r.r14 = context->readIntReg(INTREG_R14);
r.r15 = context->readIntReg(INTREG_R15);
- r.rip = context->pcState().pc();
+ r.rip = context->pcState().instAddr();
r.eflags = context->readMiscRegNoEffect(MISCREG_RFLAGS);
r.cs = context->readMiscRegNoEffect(MISCREG_CS);
r.ss = context->readMiscRegNoEffect(MISCREG_SS);
@@ -163,7 +163,7 @@
r.ebp = context->readIntReg(INTREG_RBP);
r.esi = context->readIntReg(INTREG_RSI);
r.edi = context->readIntReg(INTREG_RDI);
- r.eip = context->pcState().pc();
+ r.eip = context->pcState().instAddr();
r.eflags = context->readMiscRegNoEffect(MISCREG_RFLAGS);
r.cs = context->readMiscRegNoEffect(MISCREG_CS);
r.ss = context->readMiscRegNoEffect(MISCREG_SS);
diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh
index 2471bae..3d29d05 100644
--- a/src/cpu/checker/cpu.hh
+++ b/src/cpu/checker/cpu.hh
@@ -354,19 +354,17 @@
return (thread->htmTransactionStarts - thread->htmTransactionStops);
}
- mutable TheISA::PCState tempPCState;
const PCStateBase &
pcState() const override
{
- set(tempPCState, thread->pcState());
- return tempPCState;
+ return thread->pcState();
}
void
pcState(const PCStateBase &val) override
{
DPRINTF(Checker, "Changing PC to %s, old PC %s.\n",
val, thread->pcState());
- thread->pcState(val.as<TheISA::PCState>());
+ thread->pcState(val);
}
Addr instAddr() { return thread->instAddr(); }
MicroPC microPC() { return thread->microPC(); }
diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh
index 385ee2a..42b53cd 100644
--- a/src/cpu/checker/cpu_impl.hh
+++ b/src/cpu/checker/cpu_impl.hh
@@ -74,10 +74,10 @@
if (curStaticInst) {
if (curStaticInst->isLastMicroop())
curMacroStaticInst = nullStaticInstPtr;
- TheISA::PCState pcState = thread->pcState();
- curStaticInst->advancePC(pcState);
- thread->pcState(pcState);
- DPRINTF(Checker, "Advancing PC to %s.\n", thread->pcState());
+ std::unique_ptr<PCStateBase> pc_ptr(thread->pcState().clone());
+ curStaticInst->advancePC(*pc_ptr);
+ thread->pcState(*pc_ptr);
+ DPRINTF(Checker, "Advancing PC to %s.\n", *pc_ptr);
}
}
}
@@ -282,29 +282,32 @@
}
if (fault == NoFault) {
- TheISA::PCState pcState = thread->pcState();
+ std::unique_ptr<PCStateBase> pc_state(
+ thread->pcState().clone());
- if (isRomMicroPC(pcState.microPC())) {
+ if (isRomMicroPC(pc_state->microPC())) {
fetchDone = true;
curStaticInst = decoder.fetchRomMicroop(
- pcState.microPC(), nullptr);
+ pc_state->microPC(), nullptr);
} else if (!curMacroStaticInst) {
//We're not in the middle of a macro instruction
StaticInstPtr instPtr = nullptr;
//Predecode, ie bundle up an ExtMachInst
//If more fetch data is needed, pass it in.
- Addr fetchPC =
- (pcState.instAddr() & pc_mask) + fetchOffset;
- decoder.moreBytes(pcState, fetchPC);
+ Addr fetch_pc =
+ (pc_state->instAddr() & pc_mask) + fetchOffset;
+ decoder.moreBytes(pc_state->as<TheISA::PCState>(),
+ fetch_pc);
//If an instruction is ready, decode it.
//Otherwise, we'll have to fetch beyond the
//memory chunk at the current pc.
if (decoder.instReady()) {
fetchDone = true;
- instPtr = decoder.decode(pcState);
- thread->pcState(pcState);
+ instPtr = decoder.decode(
+ pc_state->as<TheISA::PCState>());
+ thread->pcState(*pc_state);
} else {
fetchDone = false;
fetchOffset += decoder.moreBytesSize();
@@ -315,14 +318,14 @@
if (instPtr && instPtr->isMacroop()) {
curMacroStaticInst = instPtr;
curStaticInst =
- instPtr->fetchMicroop(pcState.microPC());
+ instPtr->fetchMicroop(pc_state->microPC());
} else {
curStaticInst = instPtr;
}
} else {
// Read the next micro op from the macro-op
curStaticInst =
- curMacroStaticInst->fetchMicroop(pcState.microPC());
+ curMacroStaticInst->fetchMicroop(pc_state->microPC());
fetchDone = true;
}
}
diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh
index 62abb21..b210fea 100644
--- a/src/cpu/checker/thread_context.hh
+++ b/src/cpu/checker/thread_context.hh
@@ -321,11 +321,11 @@
}
/** Reads this thread's PC state. */
- TheISA::PCState pcState() const override { return actualTC->pcState(); }
+ const PCStateBase &pcState() const override { return actualTC->pcState(); }
/** Sets this thread's PC state. */
void
- pcState(const TheISA::PCState &val) override
+ pcState(const PCStateBase &val) override
{
DPRINTF(Checker, "Changing PC to %s, old PC %s\n",
val, checkerTC->pcState());
@@ -342,7 +342,7 @@
}
void
- pcStateNoRecord(const TheISA::PCState &val) override
+ pcStateNoRecord(const PCStateBase &val) override
{
return actualTC->pcState(val);
}
diff --git a/src/cpu/minor/exec_context.hh b/src/cpu/minor/exec_context.hh
index 2c5a4b2..2773f9e 100644
--- a/src/cpu/minor/exec_context.hh
+++ b/src/cpu/minor/exec_context.hh
@@ -299,18 +299,16 @@
return 0;
}
- mutable TheISA::PCState tempPCState;
const PCStateBase &
pcState() const override
{
- set(tempPCState, thread.pcState());
- return tempPCState;
+ return thread.pcState();
}
void
pcState(const PCStateBase &val) override
{
- thread.pcState(val.as<TheISA::PCState>());
+ thread.pcState(val);
}
RegVal
diff --git a/src/cpu/minor/execute.cc b/src/cpu/minor/execute.cc
index 39a3ba4..2b3cb8d 100644
--- a/src/cpu/minor/execute.cc
+++ b/src/cpu/minor/execute.cc
@@ -225,7 +225,7 @@
{
ThreadContext *thread = cpu.getContext(inst->id.threadId);
const std::unique_ptr<PCStateBase> pc_before(inst->pc->clone());
- TheISA::PCState target = thread->pcState();
+ std::unique_ptr<PCStateBase> target(thread->pcState().clone());
/* Force a branch for SerializeAfter/SquashAfter instructions
* at the end of micro-op sequence when we're not suspended */
@@ -236,10 +236,10 @@
inst->staticInst->isSquashAfter());
DPRINTF(Branch, "tryToBranch before: %s after: %s%s\n",
- *pc_before, target, (force_branch ? " (forcing)" : ""));
+ *pc_before, *target, (force_branch ? " (forcing)" : ""));
/* Will we change the PC to something other than the next instruction? */
- bool must_branch = *pc_before != target ||
+ bool must_branch = *pc_before != *target ||
fault != NoFault ||
force_branch;
@@ -247,11 +247,11 @@
BranchData::Reason reason = BranchData::NoBranch;
if (fault == NoFault) {
- inst->staticInst->advancePC(target);
- thread->pcState(target);
+ inst->staticInst->advancePC(*target);
+ thread->pcState(*target);
DPRINTF(Branch, "Advancing current PC from: %s to: %s\n",
- *pc_before, target);
+ *pc_before, *target);
}
if (inst->predictedTaken && !force_branch) {
@@ -265,7 +265,7 @@
*inst);
reason = BranchData::BadlyPredictedBranch;
- } else if (*inst->predictedTarget == target) {
+ } else if (*inst->predictedTarget == *target) {
/* Branch prediction got the right target, kill the branch and
* carry on.
* Note that this information to the branch predictor might get
@@ -281,14 +281,14 @@
DPRINTF(Branch, "Predicted a branch from 0x%x to 0x%x"
" but got the wrong target (actual: 0x%x) inst: %s\n",
inst->pc->instAddr(), inst->predictedTarget->instAddr(),
- target.instAddr(), *inst);
+ target->instAddr(), *inst);
reason = BranchData::BadlyPredictedBranchTarget;
}
} else if (must_branch) {
/* Unpredicted branch */
DPRINTF(Branch, "Unpredicted branch from 0x%x to 0x%x inst: %s\n",
- inst->pc->instAddr(), target.instAddr(), *inst);
+ inst->pc->instAddr(), target->instAddr(), *inst);
reason = BranchData::UnpredictedBranch;
} else {
@@ -296,14 +296,14 @@
reason = BranchData::NoBranch;
}
- updateBranchData(inst->id.threadId, reason, inst, target, branch);
+ updateBranchData(inst->id.threadId, reason, inst, target.get(), branch);
}
void
Execute::updateBranchData(
ThreadID tid,
BranchData::Reason reason,
- MinorDynInstPtr inst, const TheISA::PCState &target,
+ MinorDynInstPtr inst, const PCStateBase *target,
BranchData &branch)
{
if (reason != BranchData::NoBranch) {
@@ -443,7 +443,7 @@
/* Assume that an interrupt *must* cause a branch. Assert this? */
updateBranchData(thread_id, BranchData::Interrupt,
- MinorDynInst::bubble(), cpu.getContext(thread_id)->pcState(),
+ MinorDynInst::bubble(), &cpu.getContext(thread_id)->pcState(),
branch);
}
@@ -465,7 +465,7 @@
issued = false;
} else {
ThreadContext *thread = cpu.getContext(inst->id.threadId);
- TheISA::PCState old_pc = thread->pcState();
+ std::unique_ptr<PCStateBase> old_pc(thread->pcState().clone());
ExecContext context(cpu, *cpu.threads[inst->id.threadId],
*this, inst, zeroReg);
@@ -517,7 +517,7 @@
}
/* Restore thread PC */
- thread->pcState(old_pc);
+ thread->pcState(*old_pc);
issued = true;
}
@@ -1022,7 +1022,7 @@
!isInterrupted(thread_id)) /* Don't suspend if we have
interrupts */
{
- TheISA::PCState resume_pc = cpu.getContext(thread_id)->pcState();
+ auto &resume_pc = cpu.getContext(thread_id)->pcState();
assert(resume_pc.microPC() == 0);
@@ -1032,7 +1032,7 @@
cpu.stats.numFetchSuspends++;
updateBranchData(thread_id, BranchData::SuspendThread, inst,
- resume_pc, branch);
+ &resume_pc, branch);
}
}
@@ -1140,7 +1140,7 @@
/* Branch as there was a change in PC */
updateBranchData(thread_id, BranchData::UnpredictedBranch,
- MinorDynInst::bubble(), thread->pcState(), branch);
+ MinorDynInst::bubble(), &thread->pcState(), branch);
} else if (mem_response &&
num_mem_refs_committed < memoryCommitLimit)
{
@@ -1495,7 +1495,7 @@
* the bag */
if (commit_info.drainState == DrainHaltFetch) {
updateBranchData(commit_tid, BranchData::HaltFetch,
- MinorDynInst::bubble(), TheISA::PCState(0), branch);
+ MinorDynInst::bubble(), nullptr, branch);
cpu.wakeupOnEvent(Pipeline::ExecuteStageId);
setDrainState(commit_tid, DrainAllInsts);
diff --git a/src/cpu/minor/execute.hh b/src/cpu/minor/execute.hh
index 56966ba..21720bb 100644
--- a/src/cpu/minor/execute.hh
+++ b/src/cpu/minor/execute.hh
@@ -232,8 +232,7 @@
/** Actually create a branch to communicate to Fetch1/Fetch2 and,
* if that is a stream-changing branch update the streamSeqNum */
void updateBranchData(ThreadID tid, BranchData::Reason reason,
- MinorDynInstPtr inst, const TheISA::PCState &target,
- BranchData &branch);
+ MinorDynInstPtr inst, const PCStateBase *target, BranchData &branch);
/** Handle extracting mem ref responses from the memory queues and
* completing the associated instructions.
diff --git a/src/cpu/minor/fetch2.cc b/src/cpu/minor/fetch2.cc
index 58b68de..612b9e1 100644
--- a/src/cpu/minor/fetch2.cc
+++ b/src/cpu/minor/fetch2.cc
@@ -223,7 +223,7 @@
BranchData new_branch = BranchData(BranchData::BranchPrediction,
inst->id.threadId,
inst->id.streamSeqNum, thread.predictionSeqNum + 1,
- *inst->predictedTarget, inst);
+ inst->predictedTarget.get(), inst);
/* Mark with a new prediction number by the stream number of the
* instruction causing the prediction */
diff --git a/src/cpu/minor/lsq.cc b/src/cpu/minor/lsq.cc
index e4c97ea..e4c000b 100644
--- a/src/cpu/minor/lsq.cc
+++ b/src/cpu/minor/lsq.cc
@@ -80,7 +80,7 @@
LSQ::LSQRequest::tryToSuppressFault()
{
SimpleThread &thread = *port.cpu.threads[inst->id.threadId];
- TheISA::PCState old_pc = thread.pcState();
+ std::unique_ptr<PCStateBase> old_pc(thread.pcState().clone());
ExecContext context(port.cpu, thread, port.execute, inst, zeroReg);
[[maybe_unused]] Fault fault = inst->translationFault;
@@ -92,7 +92,7 @@
} else {
assert(inst->translationFault == fault);
}
- thread.pcState(old_pc);
+ thread.pcState(*old_pc);
}
void
@@ -102,14 +102,14 @@
*inst);
SimpleThread &thread = *port.cpu.threads[inst->id.threadId];
- TheISA::PCState old_pc = thread.pcState();
+ std::unique_ptr<PCStateBase> old_pc(thread.pcState().clone());
ExecContext context(port.cpu, thread, port.execute, inst, zeroReg);
context.setMemAccPredicate(false);
inst->staticInst->completeAcc(nullptr, &context, inst->traceData);
- thread.pcState(old_pc);
+ thread.pcState(*old_pc);
}
void
@@ -1131,7 +1131,7 @@
SimpleThread &thread = *cpu.threads[request->inst->id.threadId];
- TheISA::PCState old_pc = thread.pcState();
+ std::unique_ptr<PCStateBase> old_pc(thread.pcState().clone());
ExecContext context(cpu, thread, execute, request->inst, zeroReg);
/* Handle LLSC requests and tests */
@@ -1146,7 +1146,7 @@
"access for store conditional\n");
}
}
- thread.pcState(old_pc);
+ thread.pcState(*old_pc);
}
/* See the do_access comment above */
diff --git a/src/cpu/minor/pipe_data.hh b/src/cpu/minor/pipe_data.hh
index b85f9be..b736ea9 100644
--- a/src/cpu/minor/pipe_data.hh
+++ b/src/cpu/minor/pipe_data.hh
@@ -130,20 +130,23 @@
BranchData(Reason reason_, ThreadID thread_id,
InstSeqNum new_stream_seq_num, InstSeqNum new_prediction_seq_num,
- const PCStateBase &target, MinorDynInstPtr inst_) :
+ const PCStateBase *_target, MinorDynInstPtr inst_) :
reason(reason_), threadId(thread_id),
newStreamSeqNum(new_stream_seq_num),
newPredictionSeqNum(new_prediction_seq_num),
- target(target.clone()), inst(inst_)
- {}
+ inst(inst_)
+ {
+ set(target, _target);
+ }
BranchData(const BranchData &other) :
reason(other.reason), threadId(other.threadId),
newStreamSeqNum(other.newStreamSeqNum),
newPredictionSeqNum(other.newPredictionSeqNum),
- target(other.target->clone()),
inst(other.inst)
- {}
+ {
+ set(target, other.target);
+ }
BranchData &
operator=(const BranchData &other)
{
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index 69c6ed8..462c029 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -1307,14 +1307,14 @@
regFile.setCCReg(phys_reg, val);
}
-TheISA::PCState
+const PCStateBase &
CPU::pcState(ThreadID tid)
{
- return commit.pcState(tid).as<TheISA::PCState>();
+ return commit.pcState(tid);
}
void
-CPU::pcState(const TheISA::PCState &val, ThreadID tid)
+CPU::pcState(const PCStateBase &val, ThreadID tid)
{
commit.pcState(val, tid);
}
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index edb694e..e7dd065 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -385,10 +385,10 @@
void setArchCCReg(int reg_idx, RegVal val, ThreadID tid);
/** Sets the commit PC state of a specific thread. */
- void pcState(const TheISA::PCState &newPCState, ThreadID tid);
+ void pcState(const PCStateBase &new_pc_state, ThreadID tid);
/** Reads the commit PC state of a specific thread. */
- TheISA::PCState pcState(ThreadID tid);
+ const PCStateBase &pcState(ThreadID tid);
/** Reads the commit PC of a specific thread. */
Addr instAddr(ThreadID tid);
diff --git a/src/cpu/o3/thread_context.cc b/src/cpu/o3/thread_context.cc
index 0842062..9154012 100644
--- a/src/cpu/o3/thread_context.cc
+++ b/src/cpu/o3/thread_context.cc
@@ -248,7 +248,7 @@
}
void
-ThreadContext::pcState(const TheISA::PCState &val)
+ThreadContext::pcState(const PCStateBase &val)
{
cpu->pcState(val, thread->threadId());
@@ -256,7 +256,7 @@
}
void
-ThreadContext::pcStateNoRecord(const TheISA::PCState &val)
+ThreadContext::pcStateNoRecord(const PCStateBase &val)
{
cpu->pcState(val, thread->threadId());
diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh
index 9c38680..c50371e 100644
--- a/src/cpu/o3/thread_context.hh
+++ b/src/cpu/o3/thread_context.hh
@@ -277,16 +277,16 @@
}
/** Reads this thread's PC state. */
- TheISA::PCState
+ const PCStateBase &
pcState() const override
{
return cpu->pcState(thread->threadId());
}
/** Sets this thread's PC state. */
- void pcState(const TheISA::PCState &val) override;
+ void pcState(const PCStateBase &val) override;
- void pcStateNoRecord(const TheISA::PCState &val) override;
+ void pcStateNoRecord(const PCStateBase &val) override;
/** Reads this thread's PC. */
Addr
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index de1a733..8ee10b6 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -650,10 +650,9 @@
Fault fault = NoFault;
- TheISA::PCState pcState = thread->pcState();
+ const PCStateBase &pc = thread->pcState();
- bool needToFetch = !isRomMicroPC(pcState.microPC()) &&
- !curMacroStaticInst;
+ bool needToFetch = !isRomMicroPC(pc.microPC()) && !curMacroStaticInst;
if (needToFetch) {
ifetch_req->taskId(taskId());
setupFetchRequest(ifetch_req);
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index 7ddd100..549e745 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -112,7 +112,8 @@
checker->setSystem(p.system);
// Manipulate thread context
ThreadContext *cpu_tc = threadContexts[0];
- threadContexts[0] = new CheckerThreadContext<ThreadContext>(cpu_tc, this->checker);
+ threadContexts[0] = new CheckerThreadContext<ThreadContext>(
+ cpu_tc, this->checker);
} else {
checker = NULL;
}
@@ -312,31 +313,31 @@
t_info.setMemAccPredicate(true);
// decode the instruction
- TheISA::PCState pcState = thread->pcState();
+ std::unique_ptr<PCStateBase> pc_state(thread->pcState().clone());
auto &decoder = thread->decoder;
- if (isRomMicroPC(pcState.microPC())) {
+ if (isRomMicroPC(pc_state->microPC())) {
t_info.stayAtPC = false;
curStaticInst = decoder.fetchRomMicroop(
- pcState.microPC(), curMacroStaticInst);
+ pc_state->microPC(), curMacroStaticInst);
} else if (!curMacroStaticInst) {
//We're not in the middle of a macro instruction
StaticInstPtr instPtr = NULL;
//Predecode, ie bundle up an ExtMachInst
//If more fetch data is needed, pass it in.
- Addr fetchPC =
- (pcState.instAddr() & decoder.pcMask()) + t_info.fetchOffset;
+ Addr fetch_pc =
+ (pc_state->instAddr() & decoder.pcMask()) + t_info.fetchOffset;
- decoder.moreBytes(pcState, fetchPC);
+ decoder.moreBytes(pc_state->as<TheISA::PCState>(), fetch_pc);
//Decode an instruction if one is ready. Otherwise, we'll have to
//fetch beyond the MachInst at the current pc.
- instPtr = decoder.decode(pcState);
+ instPtr = decoder.decode(pc_state->as<TheISA::PCState>());
if (instPtr) {
t_info.stayAtPC = false;
- thread->pcState(pcState);
+ thread->pcState(*pc_state);
} else {
t_info.stayAtPC = true;
t_info.fetchOffset += decoder.moreBytesSize();
@@ -347,13 +348,13 @@
if (instPtr && instPtr->isMacroop()) {
curMacroStaticInst = instPtr;
curStaticInst =
- curMacroStaticInst->fetchMicroop(pcState.microPC());
+ curMacroStaticInst->fetchMicroop(pc_state->microPC());
} else {
curStaticInst = instPtr;
}
} else {
//Read the next micro op from the macro op
- curStaticInst = curMacroStaticInst->fetchMicroop(pcState.microPC());
+ curStaticInst = curMacroStaticInst->fetchMicroop(pc_state->microPC());
}
//If we decoded an instruction this "tick", record information about it.
@@ -460,7 +461,8 @@
SimpleExecContext &t_info = *threadInfo[curThread];
SimpleThread* thread = t_info.thread;
- const bool branching(thread->pcState().branching());
+ const bool branching =
+ thread->pcState().as<TheISA::PCState>().branching();
//Since we're moving to a new pc, zero out the offset
t_info.fetchOffset = 0;
@@ -472,9 +474,9 @@
if (curStaticInst) {
if (curStaticInst->isLastMicroop())
curMacroStaticInst = nullStaticInstPtr;
- TheISA::PCState pcState = thread->pcState();
- curStaticInst->advancePC(pcState);
- thread->pcState(pcState);
+ std::unique_ptr<PCStateBase> pc(thread->pcState().clone());
+ curStaticInst->advancePC(*pc);
+ thread->pcState(*pc);
}
}
@@ -483,7 +485,7 @@
// instruction in flight at the same time.
const InstSeqNum cur_sn(0);
- if (t_info.predPC->as<TheISA::PCState>() == thread->pcState()) {
+ if (*t_info.predPC == thread->pcState()) {
// Correctly predicted branch
branchPred->update(cur_sn, curThread);
} else {
diff --git a/src/cpu/simple/exec_context.hh b/src/cpu/simple/exec_context.hh
index 305f110..b0fe779 100644
--- a/src/cpu/simple/exec_context.hh
+++ b/src/cpu/simple/exec_context.hh
@@ -467,18 +467,16 @@
thread->setMiscReg(misc_reg, val);
}
- mutable TheISA::PCState tempPCState;
const PCStateBase &
pcState() const override
{
- set(tempPCState, thread->pcState());
- return tempPCState;
+ return thread->pcState();
}
void
pcState(const PCStateBase &val) override
{
- thread->pcState(val.as<TheISA::PCState>());
+ thread->pcState(val);
}
Fault
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index f05b7c4..9f1ce4a 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -693,9 +693,8 @@
if (_status == Idle)
return;
- TheISA::PCState pcState = thread->pcState();
- bool needToFetch = !isRomMicroPC(pcState.microPC()) &&
- !curMacroStaticInst;
+ MicroPC upc = thread->pcState().microPC();
+ bool needToFetch = !isRomMicroPC(upc) && !curMacroStaticInst;
if (needToFetch) {
_status = BaseSimpleCPU::Running;
diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh
index 258d376..31e02f7 100644
--- a/src/cpu/simple_thread.hh
+++ b/src/cpu/simple_thread.hh
@@ -105,7 +105,7 @@
std::vector<RegVal> ccRegs;
TheISA::ISA *const isa; // one "instance" of the current ISA.
- TheISA::PCState _pcState;
+ std::unique_ptr<PCStateBase> _pcState;
// hardware transactional memory
std::unique_ptr<BaseHTMCheckpoint> _htmCheckpoint;
@@ -249,7 +249,7 @@
void
clearArchRegs() override
{
- _pcState.set(0);
+ set(_pcState, isa->newPCState());
std::fill(intRegs.begin(), intRegs.end(), 0);
std::fill(floatRegs.begin(), floatRegs.end(), 0);
for (auto &vec_reg: vecRegs)
@@ -420,17 +420,17 @@
setCCRegFlat(flatIndex, val);
}
- TheISA::PCState pcState() const override { return _pcState; }
- void pcState(const TheISA::PCState &val) override { _pcState = val; }
+ const PCStateBase &pcState() const override { return *_pcState; }
+ void pcState(const PCStateBase &val) override { set(_pcState, val); }
void
- pcStateNoRecord(const TheISA::PCState &val) override
+ pcStateNoRecord(const PCStateBase &val) override
{
- _pcState = val;
+ set(_pcState, val);
}
- Addr instAddr() const override { return _pcState.instAddr(); }
- MicroPC microPC() const override { return _pcState.microPC(); }
+ Addr instAddr() const override { return _pcState->instAddr(); }
+ MicroPC microPC() const override { return _pcState->microPC(); }
bool readPredicate() const { return predicate; }
void setPredicate(bool val) { predicate = val; }
diff --git a/src/cpu/thread_context.cc b/src/cpu/thread_context.cc
index 4852111..40df84a 100644
--- a/src/cpu/thread_context.cc
+++ b/src/cpu/thread_context.cc
@@ -116,7 +116,7 @@
panic("CC reg idx %d doesn't match, one: %#x, two: %#x",
i, t1, t2);
}
- if (!(one->pcState() == two->pcState()))
+ if (one->pcState() != two->pcState())
panic("PC state doesn't match.");
int id1 = one->cpuId();
int id2 = two->cpuId();
@@ -243,9 +243,9 @@
tc.setCCRegFlat(i, ccRegs[i]);
}
- TheISA::PCState pcState;
- pcState.unserialize(cp);
- tc.pcState(pcState);
+ std::unique_ptr<PCStateBase> pc_state(tc.pcState().clone());
+ pc_state->unserialize(cp);
+ tc.pcState(*pc_state);
// thread_num and cpu_id are deterministic from the config
}
diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh
index 2fd22ff..9e4d495 100644
--- a/src/cpu/thread_context.hh
+++ b/src/cpu/thread_context.hh
@@ -223,24 +223,25 @@
virtual void setCCReg(RegIndex reg_idx, RegVal val) = 0;
- virtual TheISA::PCState pcState() const = 0;
+ virtual const PCStateBase &pcState() const = 0;
- virtual void pcState(const TheISA::PCState &val) = 0;
+ virtual void pcState(const PCStateBase &val) = 0;
void
pcState(Addr addr)
{
- pcState(getIsaPtr()->newPCState(addr)->as<TheISA::PCState>());
+ std::unique_ptr<PCStateBase> new_pc(getIsaPtr()->newPCState(addr));
+ pcState(*new_pc);
}
void
setNPC(Addr val)
{
- TheISA::PCState pc_state = pcState();
- pc_state.setNPC(val);
- pcState(pc_state);
+ std::unique_ptr<PCStateBase> pc_state(pcState().clone());
+ pc_state->as<TheISA::PCState>().setNPC(val);
+ pcState(*pc_state);
}
- virtual void pcStateNoRecord(const TheISA::PCState &val) = 0;
+ virtual void pcStateNoRecord(const PCStateBase &val) = 0;
virtual Addr instAddr() const = 0;
diff --git a/src/sim/faults.cc b/src/sim/faults.cc
index 77956d8..f7ca203 100644
--- a/src/sim/faults.cc
+++ b/src/sim/faults.cc
@@ -73,9 +73,9 @@
{
tc->getSystemPtr()->workload->syscall(tc);
// Move the PC forward since that doesn't happen automatically.
- TheISA::PCState pc = tc->pcState();
- inst->advancePC(pc);
- tc->pcState(pc);
+ std::unique_ptr<PCStateBase> pc(tc->pcState().clone());
+ inst->advancePC(*pc);
+ tc->pcState(*pc);
}
void
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index d78f4ac..54bd54b 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -1661,9 +1661,9 @@
desc->returnInto(ctc, 0);
- TheISA::PCState cpc = tc->pcState();
- cpc.advance();
- ctc->pcState(cpc);
+ std::unique_ptr<PCStateBase> cpc(tc->pcState().clone());
+ cpc->as<TheISA::PCState>().advance();
+ ctc->pcState(*cpc);
ctc->activate();
if (flags & OS::TGT_CLONE_VFORK) {
@@ -2225,8 +2225,9 @@
new_p->init();
new_p->initState();
tc->activate();
- TheISA::PCState pcState = tc->pcState();
- tc->setNPC(pcState.instAddr());
+ std::unique_ptr<PCStateBase> pc_state(tc->pcState().clone());
+ pc_state->as<TheISA::PCState>().advance();
+ tc->pcState(*pc_state);
return SyscallReturn();
}