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>
This commit is contained in:
Gabe Black
2021-10-08 17:57:18 -07:00
parent f7bfa30e77
commit dc8ac3b6ad
7 changed files with 50 additions and 55 deletions

View File

@@ -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:"

View File

@@ -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()],

View File

@@ -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<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 @@ 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)
{ }

View File

@@ -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<TheISA::PCState>());
setPredicate(inst->readPredicate());
setMemAccPredicate(inst->readMemAccPredicate());
thread.setIntReg(zeroReg, 0);

View File

@@ -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<PCStateBase> 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

View File

@@ -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<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 @@ 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<TheISA::PCState>(), 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

View File

@@ -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);