diff --git a/src/cpu/minor/decode.cc b/src/cpu/minor/decode.cc index ab908e0660..e82811f1c5 100644 --- a/src/cpu/minor/decode.cc +++ b/src/cpu/minor/decode.cc @@ -115,7 +115,7 @@ dynInstAddTracing(MinorDynInstPtr inst, StaticInstPtr static_inst, { inst->traceData = cpu.getTracer()->getInstRecord(curTick(), cpu.getContext(inst->id.threadId), - inst->staticInst, inst->pc, static_inst); + inst->staticInst, *inst->pc, static_inst); /* Use the execSeqNum as the fetch sequence number as this most closely * matches the other processor models' idea of fetch sequence */ @@ -176,7 +176,7 @@ Decode::evaluate() /* Set up PC for the next micro-op emitted */ if (!decode_info.inMacroop) { - decode_info.microopPC = inst->pc; + set(decode_info.microopPC, *inst->pc); decode_info.inMacroop = true; } @@ -188,14 +188,15 @@ Decode::evaluate() output_inst = new MinorDynInst(static_micro_inst, inst->id); - output_inst->pc = decode_info.microopPC; + set(output_inst->pc, decode_info.microopPC); output_inst->fault = NoFault; /* Allow a predicted next address only on the last * microop */ if (static_micro_inst->isLastMicroop()) { output_inst->predictedTaken = inst->predictedTaken; - output_inst->predictedTarget = inst->predictedTarget; + set(output_inst->predictedTarget, + inst->predictedTarget); } DPRINTF(Decode, "Microop decomposition inputIndex:" diff --git a/src/cpu/minor/dyn_inst.cc b/src/cpu/minor/dyn_inst.cc index 5a4ef37c96..8a076474c5 100644 --- a/src/cpu/minor/dyn_inst.cc +++ b/src/cpu/minor/dyn_inst.cc @@ -120,7 +120,7 @@ std::ostream & operator <<(std::ostream &os, const MinorDynInst &inst) { os << inst.id << " pc: 0x" - << std::hex << inst.pc.instAddr() << std::dec << " ("; + << std::hex << inst.pc->instAddr() << std::dec << " ("; if (inst.isFault()) os << "fault: \"" << inst.fault->name() << '"'; @@ -180,7 +180,7 @@ MinorDynInst::minorTraceInst(const Named &named_object, { if (isFault()) { minorInst(named_object, "id=F;%s addr=0x%x fault=\"%s\"\n", - id, pc.instAddr(), fault->name()); + id, pc->instAddr(), fault->name()); } else { unsigned int num_src_regs = staticInst->numSrcRegs(); unsigned int num_dest_regs = staticInst->numDestRegs(); @@ -222,7 +222,7 @@ MinorDynInst::minorTraceInst(const Named &named_object, minorInst(named_object, "id=%s addr=0x%x inst=\"%s\" class=%s" " flags=\"%s\"%s%s\n", - id, pc.instAddr(), + id, pc->instAddr(), (staticInst->opClass() == No_OpClass ? "(invalid)" : staticInst->disassemble(0,NULL)), enums::OpClassStrings[staticInst->opClass()], diff --git a/src/cpu/minor/dyn_inst.hh b/src/cpu/minor/dyn_inst.hh index d71ccec409..96a1649a73 100644 --- a/src/cpu/minor/dyn_inst.hh +++ b/src/cpu/minor/dyn_inst.hh @@ -173,64 +173,64 @@ class MinorDynInst : public RefCounted InstId id; /** Trace information for this instruction's execution */ - Trace::InstRecord *traceData; + Trace::InstRecord *traceData = nullptr; /** The fetch address of this instruction */ - TheISA::PCState pc; + std::unique_ptr pc; /** This is actually a fault masquerading as an instruction */ Fault fault; /** Tried to predict the destination of this inst (if a control * instruction or a sys call) */ - bool triedToPredict; + bool triedToPredict = false; /** This instruction was predicted to change control flow and * the following instructions will have a newer predictionSeqNum */ - bool predictedTaken; + bool predictedTaken = false; /** Predicted branch target */ - TheISA::PCState predictedTarget; + std::unique_ptr predictedTarget; /** Fields only set during execution */ /** FU this instruction is issued to */ - unsigned int fuIndex; + unsigned int fuIndex = 0; /** This instruction is in the LSQ, not a functional unit */ - bool inLSQ; + bool inLSQ = false; /** Translation fault in case of a mem ref */ Fault translationFault; /** The instruction has been sent to the store buffer */ - bool inStoreBuffer; + bool inStoreBuffer = false; /** Can this instruction be executed out of order. In this model, * this only happens with mem refs that need to be issued early * to allow other instructions to fill the fetch delay */ - bool canEarlyIssue; + bool canEarlyIssue = false; /** Flag controlling conditional execution of the instruction */ - bool predicate; + bool predicate = true; /** Flag controlling conditional execution of the memory access associated * with the instruction (only meaningful for loads/stores) */ - bool memAccPredicate; + bool memAccPredicate = true; /** execSeqNum of the latest inst on which this inst depends. * This can be used as a sanity check for dependency ordering * where slightly out of order execution is required (notably * initiateAcc for memory ops) */ - InstSeqNum instToWaitFor; + InstSeqNum instToWaitFor = 0; /** Extra delay at the end of the pipeline */ - Cycles extraCommitDelay; - TimingExpr *extraCommitDelayExpr; + Cycles extraCommitDelay{0}; + TimingExpr *extraCommitDelayExpr = nullptr; /** Once issued, extraCommitDelay becomes minimumCommitCycle * to account for delay in absolute time */ - Cycles minimumCommitCycle; + Cycles minimumCommitCycle{0}; /** Flat register indices so that, when clearing the scoreboard, we * have the same register indices as when the instruction was marked @@ -239,13 +239,7 @@ class MinorDynInst : public RefCounted public: MinorDynInst(StaticInstPtr si, InstId id_=InstId(), Fault fault_=NoFault) : - staticInst(si), id(id_), traceData(NULL), - pc(TheISA::PCState(0)), fault(fault_), - triedToPredict(false), predictedTaken(false), - fuIndex(0), inLSQ(false), translationFault(NoFault), - inStoreBuffer(false), canEarlyIssue(false), predicate(true), - memAccPredicate(true), instToWaitFor(0), extraCommitDelay(Cycles(0)), - extraCommitDelayExpr(NULL), minimumCommitCycle(Cycles(0)), + staticInst(si), id(id_), fault(fault_), translationFault(NoFault), flatDestRegIdx(si ? si->numDestRegs() : 0) { } diff --git a/src/cpu/minor/exec_context.hh b/src/cpu/minor/exec_context.hh index 6d94e47ded..ba0be03f69 100644 --- a/src/cpu/minor/exec_context.hh +++ b/src/cpu/minor/exec_context.hh @@ -93,8 +93,8 @@ class ExecContext : public gem5::ExecContext execute(execute_), inst(inst_) { - DPRINTF(MinorExecute, "ExecContext setting PC: %s\n", inst->pc); - pcState(inst->pc); + DPRINTF(MinorExecute, "ExecContext setting PC: %s\n", *inst->pc); + pcState(inst->pc->as()); setPredicate(inst->readPredicate()); setMemAccPredicate(inst->readMemAccPredicate()); thread.setIntReg(zeroReg, 0); diff --git a/src/cpu/minor/execute.cc b/src/cpu/minor/execute.cc index 3234de5467..39a3ba426b 100644 --- a/src/cpu/minor/execute.cc +++ b/src/cpu/minor/execute.cc @@ -224,7 +224,7 @@ void Execute::tryToBranch(MinorDynInstPtr inst, Fault fault, BranchData &branch) { ThreadContext *thread = cpu.getContext(inst->id.threadId); - const TheISA::PCState &pc_before = inst->pc; + const std::unique_ptr pc_before(inst->pc->clone()); TheISA::PCState target = thread->pcState(); /* Force a branch for SerializeAfter/SquashAfter instructions @@ -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; @@ -251,7 +251,7 @@ Execute::tryToBranch(MinorDynInstPtr inst, Fault fault, BranchData &branch) thread->pcState(target); DPRINTF(Branch, "Advancing current PC from: %s to: %s\n", - pc_before, target); + *pc_before, target); } if (inst->predictedTaken && !force_branch) { @@ -261,24 +261,26 @@ Execute::tryToBranch(MinorDynInstPtr inst, Fault fault, BranchData &branch) * intended PC value */ DPRINTF(Branch, "Predicted a branch from 0x%x to 0x%x but" " none happened inst: %s\n", - inst->pc.instAddr(), inst->predictedTarget.instAddr(), *inst); + inst->pc->instAddr(), inst->predictedTarget->instAddr(), + *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 * overwritten by a "real" branch during this cycle */ DPRINTF(Branch, "Predicted a branch from 0x%x to 0x%x correctly" " inst: %s\n", - inst->pc.instAddr(), inst->predictedTarget.instAddr(), *inst); + inst->pc->instAddr(), inst->predictedTarget->instAddr(), + *inst); reason = BranchData::CorrectlyPredictedBranch; } else { /* Branch prediction got the wrong target */ 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(), + inst->pc->instAddr(), inst->predictedTarget->instAddr(), target.instAddr(), *inst); reason = BranchData::BadlyPredictedBranchTarget; @@ -286,7 +288,7 @@ Execute::tryToBranch(MinorDynInstPtr inst, Fault fault, BranchData &branch) } 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 { @@ -890,7 +892,7 @@ Execute::doInstCommitAccounting(MinorDynInstPtr inst) if (inst->traceData) inst->traceData->setCPSeq(thread->numOp); - cpu.probeInstCommit(inst->staticInst, inst->pc.instAddr()); + cpu.probeInstCommit(inst->staticInst, inst->pc->instAddr()); } bool diff --git a/src/cpu/minor/fetch2.cc b/src/cpu/minor/fetch2.cc index 68c137143b..39881322ec 100644 --- a/src/cpu/minor/fetch2.cc +++ b/src/cpu/minor/fetch2.cc @@ -192,26 +192,24 @@ void Fetch2::predictBranch(MinorDynInstPtr inst, BranchData &branch) { Fetch2ThreadInfo &thread = fetchInfo[inst->id.threadId]; - TheISA::PCState inst_pc = inst->pc; assert(!inst->predictedTaken); /* Skip non-control/sys call instructions */ - if (inst->staticInst->isControl() || - inst->staticInst->isSyscall()) - { + if (inst->staticInst->isControl() || inst->staticInst->isSyscall()){ + std::unique_ptr inst_pc(inst->pc->clone()); + /* Tried to predict */ inst->triedToPredict = true; DPRINTF(Branch, "Trying to predict for inst: %s\n", *inst); if (branchPredictor.predict(inst->staticInst, - inst->id.fetchSeqNum, inst_pc, - inst->id.threadId)) - { + inst->id.fetchSeqNum, inst_pc->as(), + inst->id.threadId)) { + set(branch.target, *inst_pc); inst->predictedTaken = true; - inst->predictedTarget = inst_pc; - branch.target = inst_pc; + set(inst->predictedTarget, inst_pc); } } else { DPRINTF(Branch, "Not attempting prediction for inst: %s\n", *inst); @@ -226,7 +224,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->as(), inst); /* Mark with a new prediction number by the stream number of the * instruction causing the prediction */ @@ -235,7 +233,7 @@ Fetch2::predictBranch(MinorDynInstPtr inst, BranchData &branch) DPRINTF(Branch, "Branch predicted taken inst: %s target: %s" " new predictionSeqNum: %d\n", - *inst, inst->predictedTarget, thread.predictionSeqNum); + *inst, *inst->predictedTarget, thread.predictionSeqNum); } } @@ -369,7 +367,7 @@ Fetch2::evaluate() * not been set */ assert(dyn_inst->id.execSeqNum == 0); - dyn_inst->pc = fetch_info.pc; + set(dyn_inst->pc, fetch_info.pc); /* Pack a faulting instruction but allow other * instructions to be generated. (Fetch2 makes no @@ -412,7 +410,7 @@ Fetch2::evaluate() * has not been set */ assert(dyn_inst->id.execSeqNum == 0); - dyn_inst->pc = fetch_info.pc; + set(dyn_inst->pc, fetch_info.pc); DPRINTF(Fetch, "decoder inst %s\n", *dyn_inst); // Collect some basic inst class stats diff --git a/src/cpu/minor/lsq.cc b/src/cpu/minor/lsq.cc index 6c606a62ca..e4c97ea4e6 100644 --- a/src/cpu/minor/lsq.cc +++ b/src/cpu/minor/lsq.cc @@ -1648,7 +1648,7 @@ LSQ::pushRequest(MinorDynInstPtr inst, bool isLoad, uint8_t *data, request->request->setVirt( addr, size, flags, cpu.dataRequestorId(), /* I've no idea why we need the PC, but give it */ - inst->pc.instAddr(), std::move(amo_op)); + inst->pc->instAddr(), std::move(amo_op)); request->request->setByteEnable(byte_enable); requests.push(request);