cpu-minor: Use PCStateBase in the minor CPU DynInst class.
Change-Id: I43d538568d473e27cdbfe6ea77c317b18cfdf18f
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/52047
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: ZHENGRONG WANG <seanyukigeek@gmail.com>
Maintainer: ZHENGRONG WANG <seanyukigeek@gmail.com>
diff --git a/src/cpu/minor/decode.cc b/src/cpu/minor/decode.cc
index ab908e0..e82811f 100644
--- a/src/cpu/minor/decode.cc
+++ b/src/cpu/minor/decode.cc
@@ -115,7 +115,7 @@
{
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 @@
/* 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 @@
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 5a4ef37..8a07647 100644
--- a/src/cpu/minor/dyn_inst.cc
+++ b/src/cpu/minor/dyn_inst.cc
@@ -120,7 +120,7 @@
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 @@
{
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 @@
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 d71ccec..96a1649 100644
--- a/src/cpu/minor/dyn_inst.hh
+++ b/src/cpu/minor/dyn_inst.hh
@@ -173,64 +173,64 @@
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<PCStateBase> 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<PCStateBase> 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 @@
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 6d94e47..ba0be03 100644
--- a/src/cpu/minor/exec_context.hh
+++ b/src/cpu/minor/exec_context.hh
@@ -93,8 +93,8 @@
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<TheISA::PCState>());
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 3234de5..39a3ba4 100644
--- a/src/cpu/minor/execute.cc
+++ b/src/cpu/minor/execute.cc
@@ -224,7 +224,7 @@
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<PCStateBase> pc_before(inst->pc->clone());
TheISA::PCState target = thread->pcState();
/* Force a branch for SerializeAfter/SquashAfter instructions
@@ -236,10 +236,10 @@
inst->staticInst->isSquashAfter());
DPRINTF(Branch, "tryToBranch before: %s after: %s%s\n",
- pc_before, target, (force_branch ? " (forcing)" : ""));
+ *pc_before, target, (force_branch ? " (forcing)" : ""));
/* Will we change the PC to something other than the next instruction? */
- bool must_branch = pc_before != target ||
+ bool must_branch = *pc_before != target ||
fault != NoFault ||
force_branch;
@@ -251,7 +251,7 @@
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 @@
* 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 @@
} 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 @@
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 68c1371..3988132 100644
--- a/src/cpu/minor/fetch2.cc
+++ b/src/cpu/minor/fetch2.cc
@@ -192,26 +192,24 @@
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<PCStateBase> 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<TheISA::PCState>(),
+ 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 @@
BranchData new_branch = BranchData(BranchData::BranchPrediction,
inst->id.threadId,
inst->id.streamSeqNum, thread.predictionSeqNum + 1,
- inst->predictedTarget, inst);
+ inst->predictedTarget->as<TheISA::PCState>(), inst);
/* Mark with a new prediction number by the stream number of the
* instruction causing the prediction */
@@ -235,7 +233,7 @@
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 @@
* 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 @@
* 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 6c606a6..e4c97ea 100644
--- a/src/cpu/minor/lsq.cc
+++ b/src/cpu/minor/lsq.cc
@@ -1648,7 +1648,7 @@
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);