diff --git a/src/arch/arm/fastmodel/iris/thread_context.cc b/src/arch/arm/fastmodel/iris/thread_context.cc index a6b8c2a372..6d76eac7e2 100644 --- a/src/arch/arm/fastmodel/iris/thread_context.cc +++ b/src/arch/arm/fastmodel/iris/thread_context.cc @@ -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) diff --git a/src/arch/arm/fastmodel/iris/thread_context.hh b/src/arch/arm/fastmodel/iris/thread_context.hh index c5e4cc3f07..a343658bea 100644 --- a/src/arch/arm/fastmodel/iris/thread_context.hh +++ b/src/arch/arm/fastmodel/iris/thread_context.hh @@ -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; diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc index b8ca6d289c..64a07cbb1f 100644 --- a/src/arch/arm/faults.cc +++ b/src/arch/arm/faults.cc @@ -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().pc(); + ITSTATE it = tc->pcState().as().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().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(); 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 6bbe6644e4..6a79aa0fef 100644 --- a/src/arch/arm/fs_workload.cc +++ b/src/arch/arm/fs_workload.cc @@ -57,18 +57,18 @@ namespace ArmISA void SkipFunc::returnFromFuncIn(ThreadContext *tc) { - PCState newPC = tc->pcState(); + PCState new_pc = tc->pcState().as(); 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 e94e4379ce..84ef4a1238 100644 --- a/src/arch/arm/htm.cc +++ b/src/arch/arm/htm.cc @@ -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(); BaseHTMCheckpoint::save(tc); } diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index 7e047f1715..a2d970026f 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -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(); 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(); 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( 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( 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 4f47a156b7..e462e4fb7f 100644 --- a/src/arch/arm/kvm/arm_cpu.cc +++ b/src/arch/arm/kvm/arm_cpu.cc @@ -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(); 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 3cafcf7fe3..8d0313a0b5 100644 --- a/src/arch/arm/nativetrace.cc +++ b/src/arch/arm/nativetrace.cc @@ -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().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().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 5382d51ebb..2efa82fa33 100644 --- a/src/arch/arm/remote_gdb.cc +++ b/src/arch/arm/remote_gdb.cc @@ -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(); 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(); 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 551abbb3cb..2029bdc7ca 100644 --- a/src/arch/arm/self_debug.cc +++ b/src/arch/arm/self_debug.cc @@ -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(); 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(); bool res = false; switch (stateSS) { case INACTIVE_STATE: diff --git a/src/arch/generic/debugfaults.hh b/src/arch/generic/debugfaults.hh index f54bd7ca23..d5976cc8c4 100644 --- a/src/arch/generic/debugfaults.hh +++ b/src/arch/generic/debugfaults.hh @@ -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 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 a9f5239213..c1884ee3ee 100644 --- a/src/arch/mips/faults.cc +++ b/src/arch/mips/faults.cc @@ -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(); 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 91fcf503a4..adbbf526f2 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 @@ 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(); 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 bf845baf76..ad393002f1 100644 --- a/src/arch/mips/remote_gdb.cc +++ b/src/arch/mips/remote_gdb.cc @@ -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); diff --git a/src/arch/power/faults.cc b/src/arch/power/faults.cc index 3b8851e3b3..be1796e14a 100644 --- a/src/arch/power/faults.cc +++ b/src/arch/power/faults.cc @@ -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 diff --git a/src/arch/power/insts/branch.cc b/src/arch/power/insts/branch.cc index 2cab370acd..8540cefbae 100644 --- a/src/arch/power/insts/branch.cc +++ b/src/arch/power/insts/branch.cc @@ -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( 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( msr.sf ? addr : addr & UINT32_MAX); diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc index ca489d8e40..8ed4b75353 100644 --- a/src/arch/power/process.cc +++ b/src/arch/power/process.cc @@ -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(); 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(); 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 0accb6ad97..702439d7ac 100644 --- a/src/arch/power/remote_gdb.cc +++ b/src/arch/power/remote_gdb.cc @@ -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(); 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(); 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 01f68275b9..703b0ee894 100644 --- a/src/arch/riscv/faults.cc +++ b/src/arch/riscv/faults.cc @@ -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(); 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(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(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 0358889c71..c8b752c914 100644 --- a/src/arch/riscv/isa.cc +++ b/src/arch/riscv/isa.cc @@ -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().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 3c16f60e50..9345c1ff54 100644 --- a/src/arch/riscv/isa/formats/standard.isa +++ b/src/arch/riscv/isa/formats/standard.isa @@ -255,9 +255,10 @@ def template JumpExecute {{ std::unique_ptr %(class_name)s::branchTarget(ThreadContext *tc) const { - PCState pc = tc->pcState(); - pc.set((tc->readIntReg(srcRegIdx(0).index()) + imm)&~0x1); - return std::unique_ptr{pc.clone()}; + PCStateBase *pc_ptr = tc->pcState().clone(); + pc_ptr->as().set( + (tc->readIntReg(srcRegIdx(0).index()) + imm) & ~0x1); + return std::unique_ptr{pc_ptr}; } std::string diff --git a/src/arch/riscv/process.cc b/src/arch/riscv/process.cc index bdbb7cc995..cbd13b00e7 100644 --- a/src/arch/riscv/process.cc +++ b/src/arch/riscv/process.cc @@ -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(); pc.rv32(true); tc->pcState(pc); } diff --git a/src/arch/riscv/remote_gdb.cc b/src/arch/riscv/remote_gdb.cc index ec3eb5a0a5..50b0ba7d9c 100644 --- a/src/arch/riscv/remote_gdb.cc +++ b/src/arch/riscv/remote_gdb.cc @@ -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++) diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 6ead79affd..ec7386f159 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -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(); 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(); // 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(); pc.advance(); tc->pcState(pc); } diff --git a/src/arch/sparc/nativetrace.cc b/src/arch/sparc/nativetrace.cc index 752e316ba7..0179fe4890 100644 --- a/src/arch/sparc/nativetrace.cc +++ b/src/arch/sparc/nativetrace.cc @@ -68,7 +68,7 @@ Trace::SparcNativeTrace::check(NativeTraceRecord *record) checkReg(*(regName++), regVal, realRegVal); } - SparcISA::PCState pc = tc->pcState(); + auto &pc = tc->pcState().as(); // 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 83ef55bbfe..9e1e06e5b0 100644 --- a/src/arch/sparc/remote_gdb.cc +++ b/src/arch/sparc/remote_gdb.cc @@ -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(); 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(); 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); diff --git a/src/arch/sparc/se_workload.cc b/src/arch/sparc/se_workload.cc index 7c1e1259b2..c87244fa93 100644 --- a/src/arch/sparc/se_workload.cc +++ b/src/arch/sparc/se_workload.cc @@ -54,7 +54,7 @@ SEWorkload::is64(ThreadContext *tc) void SEWorkload::handleTrap(ThreadContext *tc, int trapNum) { - PCState pc = tc->pcState(); + auto &pc = tc->pcState().as(); 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 d925bd7ee2..ae9586bb51 100644 --- a/src/arch/x86/faults.cc +++ b/src/arch/x86/faults.cc @@ -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(); + 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)); } } diff --git a/src/arch/x86/linux/se_workload.cc b/src/arch/x86/linux/se_workload.cc index 46a6327d77..f5fa51976d 100644 --- a/src/arch/x86/linux/se_workload.cc +++ b/src/arch/x86/linux/se_workload.cc @@ -116,7 +116,7 @@ EmuLinux::syscall(ThreadContext *tc) if (dynamic_cast(process)) { syscallDescs64.get(rax)->doSyscall(tc); } else if (auto *proc32 = dynamic_cast(process)) { - PCState pc = tc->pcState(); + PCState pc = tc->pcState().as(); 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 diff --git a/src/arch/x86/nativetrace.cc b/src/arch/x86/nativetrace.cc index 9e357a8044..abb1a32c9d 100644 --- a/src/arch/x86/nativetrace.cc +++ b/src/arch/x86/nativetrace.cc @@ -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().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 41b4525854..abb215488c 100644 --- a/src/arch/x86/remote_gdb.cc +++ b/src/arch/x86/remote_gdb.cc @@ -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); diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh index 2471bae111..3d29d05eb7 100644 --- a/src/cpu/checker/cpu.hh +++ b/src/cpu/checker/cpu.hh @@ -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()); + 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 385ee2aa53..42b53cdcdb 100644 --- a/src/cpu/checker/cpu_impl.hh +++ b/src/cpu/checker/cpu_impl.hh @@ -74,10 +74,10 @@ Checker::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 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::verify(const DynInstPtr &completed_inst) } if (fault == NoFault) { - TheISA::PCState pcState = thread->pcState(); + std::unique_ptr 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(), + 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()); + thread->pcState(*pc_state); } else { fetchDone = false; fetchOffset += decoder.moreBytesSize(); @@ -315,14 +318,14 @@ Checker::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; } } diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh index 62abb2156d..b210feaad9 100644 --- a/src/cpu/checker/thread_context.hh +++ b/src/cpu/checker/thread_context.hh @@ -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); } diff --git a/src/cpu/minor/exec_context.hh b/src/cpu/minor/exec_context.hh index 2c5a4b22a9..2773f9e547 100644 --- a/src/cpu/minor/exec_context.hh +++ b/src/cpu/minor/exec_context.hh @@ -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()); + thread.pcState(val); } RegVal diff --git a/src/cpu/minor/execute.cc b/src/cpu/minor/execute.cc index 39a3ba426b..2b3cb8def6 100644 --- a/src/cpu/minor/execute.cc +++ b/src/cpu/minor/execute.cc @@ -225,7 +225,7 @@ Execute::tryToBranch(MinorDynInstPtr inst, Fault fault, BranchData &branch) { ThreadContext *thread = cpu.getContext(inst->id.threadId); const std::unique_ptr pc_before(inst->pc->clone()); - TheISA::PCState target = thread->pcState(); + std::unique_ptr 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 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); diff --git a/src/cpu/minor/execute.hh b/src/cpu/minor/execute.hh index 56966ba3db..21720bbb46 100644 --- a/src/cpu/minor/execute.hh +++ b/src/cpu/minor/execute.hh @@ -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. diff --git a/src/cpu/minor/fetch2.cc b/src/cpu/minor/fetch2.cc index 58b68de92f..612b9e1f3a 100644 --- a/src/cpu/minor/fetch2.cc +++ b/src/cpu/minor/fetch2.cc @@ -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 */ diff --git a/src/cpu/minor/lsq.cc b/src/cpu/minor/lsq.cc index e4c97ea4e6..e4c000baed 100644 --- a/src/cpu/minor/lsq.cc +++ b/src/cpu/minor/lsq.cc @@ -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 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 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 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 */ diff --git a/src/cpu/minor/pipe_data.hh b/src/cpu/minor/pipe_data.hh index b85f9bef70..b736ea9762 100644 --- a/src/cpu/minor/pipe_data.hh +++ b/src/cpu/minor/pipe_data.hh @@ -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) { diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 69c6ed8aad..462c0291ec 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -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(); + 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 edb694ebf2..e7dd06547a 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -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); diff --git a/src/cpu/o3/thread_context.cc b/src/cpu/o3/thread_context.cc index 0842062ca8..915401235b 100644 --- a/src/cpu/o3/thread_context.cc +++ b/src/cpu/o3/thread_context.cc @@ -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()); diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh index 9c3868015c..c50371efac 100644 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@ -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 diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index de1a7335d3..8ee10b6b87 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -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); diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 7ddd10074a..549e745754 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -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(cpu_tc, this->checker); + threadContexts[0] = new CheckerThreadContext( + 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 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(), 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()); 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().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 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() == 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 305f1108f2..b0fe779258 100644 --- a/src/cpu/simple/exec_context.hh +++ b/src/cpu/simple/exec_context.hh @@ -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()); + thread->pcState(val); } Fault diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index f05b7c4edf..9f1ce4a5e6 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -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; diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index 258d376408..31e02f763f 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -105,7 +105,7 @@ class SimpleThread : public ThreadState, public ThreadContext std::vector ccRegs; TheISA::ISA *const isa; // one "instance" of the current ISA. - TheISA::PCState _pcState; + std::unique_ptr _pcState; // hardware transactional memory std::unique_ptr _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; } diff --git a/src/cpu/thread_context.cc b/src/cpu/thread_context.cc index 48521117f5..40df84aa0a 100644 --- a/src/cpu/thread_context.cc +++ b/src/cpu/thread_context.cc @@ -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 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 2fd22ffe83..9e4d4956b6 100644 --- a/src/cpu/thread_context.hh +++ b/src/cpu/thread_context.hh @@ -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()); + std::unique_ptr 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 pc_state(pcState().clone()); + pc_state->as().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 77956d89cf..f7ca203ec8 100644 --- a/src/sim/faults.cc +++ b/src/sim/faults.cc @@ -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 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 d78f4acebe..54bd54b5d2 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -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 cpc(tc->pcState().clone()); + cpc->as().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 pc_state(tc->pcState().clone()); + pc_state->as().advance(); + tc->pcState(*pc_state); return SyscallReturn(); }