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>
This commit is contained in:
Gabe Black
2021-10-15 20:22:03 -07:00
parent aa949dba0f
commit 8279191cd9
53 changed files with 226 additions and 225 deletions

View File

@@ -553,11 +553,10 @@ ThreadContext::setStatus(Status new_status)
_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 @@ ThreadContext::pcState() const
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)

View File

@@ -169,6 +169,8 @@ class ThreadContext : public gem5::ThreadContext
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 @@ class ThreadContext : public gem5::ThreadContext
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;

View File

@@ -534,8 +534,8 @@ ArmFault::invoke32(ThreadContext *tc, const StaticInstPtr &inst)
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 @@ ArmFault::invoke64(ThreadContext *tc, const StaticInstPtr &inst)
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 @@ ArmFault::invoke64(ThreadContext *tc, const StaticInstPtr &inst)
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 @@ SupervisorCall::invoke(ThreadContext *tc, const StaticInstPtr &inst)
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);

View File

@@ -57,18 +57,18 @@ namespace ArmISA
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);
}
}

View File

@@ -90,7 +90,7 @@ ArmISA::HTMCheckpoint::save(ThreadContext *tc)
}
fpcr = tc->readMiscReg(MISCREG_FPCR);
fpsr = tc->readMiscReg(MISCREG_FPSR);
pcstateckpt = tc->pcState();
pcstateckpt = tc->pcState().as<PCState>();
BaseHTMCheckpoint::save(tc);
}

View File

@@ -607,12 +607,11 @@ RegVal
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 @@ ISA::setMiscReg(int misc_reg, RegVal val)
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 @@ ISA::addressTranslation64(MMU::ArmTranslationType tran_type,
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 @@ ISA::addressTranslation(MMU::ArmTranslationType tran_type,
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);

View File

@@ -820,7 +820,7 @@ ArmKvmCPU::updateTCStateCore()
// 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);

View File

@@ -114,7 +114,7 @@ Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc)
}
//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 @@ Trace::ArmNativeTrace::check(NativeTraceRecord *record)
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);

View File

@@ -223,7 +223,7 @@ RemoteGDB::AArch64GdbRegCache::getRegs(ThreadContext *context)
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 @@ RemoteGDB::AArch64GdbRegCache::setRegs(ThreadContext *context) const
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 @@ RemoteGDB::AArch32GdbRegCache::getRegs(ThreadContext *context)
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 @@ RemoteGDB::AArch32GdbRegCache::setRegs(ThreadContext *context) const
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);

View File

@@ -89,7 +89,7 @@ SelfDebug::testBreakPoints(ThreadContext *tc, Addr vaddr)
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 @@ SoftwareStep::debugExceptionReturnSS(ThreadContext *tc, CPSR spsr,
bool
SoftwareStep::advanceSS(ThreadContext * tc)
{
PCState pc = tc->pcState();
PCState pc = tc->pcState().as<PCState>();
bool res = false;
switch (stateSS) {
case INACTIVE_STATE:

View File

@@ -61,9 +61,9 @@ class M5DebugFault : public FaultBase
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);
}
}

View File

@@ -114,7 +114,7 @@ MipsFaultBase::setExceptionState(ThreadContext *tc, uint8_t excCode)
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,

View File

@@ -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 @@ haltThread(TC *tc)
// 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",

View File

@@ -179,7 +179,7 @@ RemoteGDB::MipsGdbRegCache::getRegs(ThreadContext *context)
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);

View File

@@ -44,7 +44,7 @@ UnimplementedOpcodeFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
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 @@ TrapFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
panic_if(tc->getSystemPtr()->trapToGdb(SIGTRAP, tc->contextId()),
"Trap encountered at virtual address %#x\n",
tc->pcState().pc());
tc->pcState().instAddr());
}
} // namespace PowerISA

View File

@@ -65,7 +65,7 @@ BranchOp::branchTarget(ThreadContext *tc) const
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 @@ BranchDispCondOp::branchTarget(ThreadContext *tc) const
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);

View File

@@ -103,7 +103,7 @@ PowerProcess::initState()
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 @@ PowerProcess::argsInit(int pageSize)
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);

View File

@@ -192,7 +192,7 @@ RemoteGDB::PowerGdbRegCache::getRegs(ThreadContext *context)
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 @@ RemoteGDB::PowerGdbRegCache::setRegs(ThreadContext *context) const
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 @@ RemoteGDB::Power64GdbRegCache::getRegs(ThreadContext *context)
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 @@ RemoteGDB::Power64GdbRegCache::setRegs(ThreadContext *context) const
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);

View File

@@ -51,16 +51,16 @@ namespace RiscvISA
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 @@ RiscvFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
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 @@ void
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

View File

@@ -466,8 +466,10 @@ ISA::setMiscReg(int misc_reg, RegVal val)
// 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;

View File

@@ -255,9 +255,10 @@ def template JumpExecute {{
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

View File

@@ -114,7 +114,7 @@ RiscvProcess32::initState()
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);
}

View File

@@ -195,7 +195,7 @@ RemoteGDB::RiscvGdbRegCache::getRegs(ThreadContext *context)
{
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++)

View File

@@ -311,7 +311,7 @@ doREDFault(ThreadContext *tc, TrapType tt)
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 @@ doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
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 @@ TrapInstruction::invoke(ThreadContext *tc, const StaticInstPtr &inst)
// 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);
}

View File

@@ -68,7 +68,7 @@ Trace::SparcNativeTrace::check(NativeTraceRecord *record)
checkReg(*(regName++), regVal, realRegVal);
}
SparcISA::PCState pc = tc->pcState();
auto &pc = tc->pcState().as<SparcISA::PCState>();
// PC
read(&realRegVal, sizeof(realRegVal));
realRegVal = betoh(realRegVal);

View File

@@ -176,8 +176,9 @@ void
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 @@ void
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 @@ RemoteGDB::SPARC64GdbRegCache::getRegs(ThreadContext *context)
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 @@ RemoteGDB::SPARCGdbRegCache::setRegs(ThreadContext *context) const
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);

View File

@@ -54,7 +54,7 @@ SEWorkload::is64(ThreadContext *tc)
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());

View File

@@ -64,9 +64,8 @@ X86FaultBase::invoke(ThreadContext *tc, const StaticInstPtr &inst)
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 @@ X86FaultBase::invoke(ThreadContext *tc, const StaticInstPtr &inst)
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 @@ X86FaultBase::invoke(ThreadContext *tc, const StaticInstPtr &inst)
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 @@ X86FaultBase::describe() const
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 @@ PageFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
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));
}
}

View File

@@ -116,7 +116,7 @@ EmuLinux::syscall(ThreadContext *tc)
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 @@ void
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 @@ EmuLinux::event(ThreadContext *tc)
return;
}
}
warn("Unexpected workload event at pc %#x.", pcState.pc());
warn("Unexpected workload event at pc %#x.", pc);
}
void

View File

@@ -87,7 +87,7 @@ X86NativeTrace::ThreadState::update(ThreadContext *tc)
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));

View File

@@ -141,7 +141,7 @@ RemoteGDB::AMD64GdbRegCache::getRegs(ThreadContext *context)
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 @@ RemoteGDB::X86GdbRegCache::getRegs(ThreadContext *context)
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);

View File

@@ -354,19 +354,17 @@ class CheckerCPU : public BaseCPU, public ExecContext
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(); }

View File

@@ -74,10 +74,10 @@ Checker<DynInstPtr>::advancePC(const Fault &fault)
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 @@ Checker<DynInstPtr>::verify(const DynInstPtr &completed_inst)
}
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 @@ Checker<DynInstPtr>::verify(const DynInstPtr &completed_inst)
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;
}
}

View File

@@ -321,11 +321,11 @@ class CheckerThreadContext : public ThreadContext
}
/** 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 @@ class CheckerThreadContext : public ThreadContext
}
void
pcStateNoRecord(const TheISA::PCState &val) override
pcStateNoRecord(const PCStateBase &val) override
{
return actualTC->pcState(val);
}

View File

@@ -299,18 +299,16 @@ class ExecContext : public gem5::ExecContext
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

View File

@@ -225,7 +225,7 @@ Execute::tryToBranch(MinorDynInstPtr inst, Fault fault, BranchData &branch)
{
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 @@ Execute::tryToBranch(MinorDynInstPtr inst, Fault fault, BranchData &branch)
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 @@ Execute::tryToBranch(MinorDynInstPtr inst, Fault fault, BranchData &branch)
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 @@ Execute::tryToBranch(MinorDynInstPtr inst, Fault fault, BranchData &branch)
*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 @@ Execute::tryToBranch(MinorDynInstPtr inst, Fault fault, BranchData &branch)
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 @@ Execute::tryToBranch(MinorDynInstPtr inst, Fault fault, BranchData &branch)
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 @@ Execute::takeInterrupt(ThreadID thread_id, BranchData &branch)
/* 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 @@ Execute::executeMemRefInst(MinorDynInstPtr inst, BranchData &branch,
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 @@ Execute::executeMemRefInst(MinorDynInstPtr inst, BranchData &branch,
}
/* Restore thread PC */
thread->pcState(old_pc);
thread->pcState(*old_pc);
issued = true;
}
@@ -1022,7 +1022,7 @@ Execute::commitInst(MinorDynInstPtr inst, bool early_memory_issue,
!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 @@ Execute::commitInst(MinorDynInstPtr inst, bool early_memory_issue,
cpu.stats.numFetchSuspends++;
updateBranchData(thread_id, BranchData::SuspendThread, inst,
resume_pc, branch);
&resume_pc, branch);
}
}
@@ -1140,7 +1140,7 @@ Execute::commit(ThreadID thread_id, bool only_commit_microops, bool discard,
/* 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 @@ Execute::evaluate()
* 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);

View File

@@ -232,8 +232,7 @@ class Execute : public Named
/** 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.

View File

@@ -223,7 +223,7 @@ Fetch2::predictBranch(MinorDynInstPtr inst, BranchData &branch)
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 */

View File

@@ -80,7 +80,7 @@ void
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 @@ LSQ::LSQRequest::tryToSuppressFault()
} else {
assert(inst->translationFault == fault);
}
thread.pcState(old_pc);
thread.pcState(*old_pc);
}
void
@@ -102,14 +102,14 @@ LSQ::LSQRequest::completeDisabledMemAccess()
*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 @@ LSQ::tryToSendToTransfers(LSQRequestPtr request)
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 @@ LSQ::tryToSendToTransfers(LSQRequestPtr request)
"access for store conditional\n");
}
}
thread.pcState(old_pc);
thread.pcState(*old_pc);
}
/* See the do_access comment above */

View File

@@ -130,20 +130,23 @@ class BranchData /* : public ReportIF, public BubbleIF */
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)
{

View File

@@ -1307,14 +1307,14 @@ CPU::setArchCCReg(int reg_idx, RegVal val, ThreadID tid)
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);
}

View File

@@ -385,10 +385,10 @@ class CPU : public BaseCPU
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);

View File

@@ -248,7 +248,7 @@ ThreadContext::setCCRegFlat(RegIndex reg_idx, RegVal val)
}
void
ThreadContext::pcState(const TheISA::PCState &val)
ThreadContext::pcState(const PCStateBase &val)
{
cpu->pcState(val, thread->threadId());
@@ -256,7 +256,7 @@ ThreadContext::pcState(const TheISA::PCState &val)
}
void
ThreadContext::pcStateNoRecord(const TheISA::PCState &val)
ThreadContext::pcStateNoRecord(const PCStateBase &val)
{
cpu->pcState(val, thread->threadId());

View File

@@ -277,16 +277,16 @@ class ThreadContext : public gem5::ThreadContext
}
/** 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

View File

@@ -650,10 +650,9 @@ AtomicSimpleCPU::tick()
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);

View File

@@ -112,7 +112,8 @@ BaseSimpleCPU::BaseSimpleCPU(const BaseSimpleCPUParams &p)
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 @@ BaseSimpleCPU::preExecute()
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 @@ BaseSimpleCPU::preExecute()
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 @@ BaseSimpleCPU::advancePC(const Fault &fault)
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 @@ BaseSimpleCPU::advancePC(const Fault &fault)
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 @@ BaseSimpleCPU::advancePC(const Fault &fault)
// 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 {

View File

@@ -467,18 +467,16 @@ class SimpleExecContext : public ExecContext
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

View File

@@ -693,9 +693,8 @@ TimingSimpleCPU::fetch()
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;

View File

@@ -105,7 +105,7 @@ class SimpleThread : public ThreadState, public ThreadContext
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 @@ class SimpleThread : public ThreadState, public ThreadContext
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 @@ class SimpleThread : public ThreadState, public ThreadContext
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; }

View File

@@ -116,7 +116,7 @@ ThreadContext::compare(ThreadContext *one, ThreadContext *two)
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 @@ unserialize(ThreadContext &tc, CheckpointIn &cp)
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
}

View File

@@ -223,24 +223,25 @@ class ThreadContext : public PCEventScope
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;

View File

@@ -73,9 +73,9 @@ SESyscallFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
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

View File

@@ -1661,9 +1661,9 @@ cloneFunc(SyscallDesc *desc, ThreadContext *tc, RegVal flags, RegVal newStack,
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 @@ execveFunc(SyscallDesc *desc, ThreadContext *tc,
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();
}