cpu-minor: Convert the rest of the CPU to use PCStateBase *|&.
Change-Id: I528622cd5ad82dbcefe1462401841c6e28359ed3 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/52049 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:
@@ -184,7 +184,7 @@ Decode::evaluate()
|
||||
* static_inst. */
|
||||
static_micro_inst =
|
||||
static_inst->fetchMicroop(
|
||||
decode_info.microopPC.microPC());
|
||||
decode_info.microopPC->microPC());
|
||||
|
||||
output_inst =
|
||||
new MinorDynInst(static_micro_inst, inst->id);
|
||||
@@ -201,19 +201,18 @@ Decode::evaluate()
|
||||
|
||||
DPRINTF(Decode, "Microop decomposition inputIndex:"
|
||||
" %d output_index: %d lastMicroop: %s microopPC:"
|
||||
" %d.%d inst: %d\n",
|
||||
" %s inst: %d\n",
|
||||
decode_info.inputIndex, output_index,
|
||||
(static_micro_inst->isLastMicroop() ?
|
||||
"true" : "false"),
|
||||
decode_info.microopPC.instAddr(),
|
||||
decode_info.microopPC.microPC(),
|
||||
*decode_info.microopPC,
|
||||
*output_inst);
|
||||
|
||||
/* Acknowledge that the static_inst isn't mine, it's my
|
||||
* parent macro-op's */
|
||||
parent_static_inst = static_inst;
|
||||
|
||||
static_micro_inst->advancePC(decode_info.microopPC);
|
||||
static_micro_inst->advancePC(*decode_info.microopPC);
|
||||
|
||||
/* Step input if this is the last micro-op */
|
||||
if (static_micro_inst->isLastMicroop()) {
|
||||
|
||||
@@ -94,40 +94,35 @@ class Decode : public Named
|
||||
|
||||
struct DecodeThreadInfo
|
||||
{
|
||||
|
||||
/** Default Constructor */
|
||||
DecodeThreadInfo() :
|
||||
inputIndex(0),
|
||||
inMacroop(false),
|
||||
execSeqNum(InstId::firstExecSeqNum),
|
||||
blocked(false)
|
||||
{ }
|
||||
DecodeThreadInfo() {}
|
||||
|
||||
DecodeThreadInfo(const DecodeThreadInfo& other) :
|
||||
inputIndex(other.inputIndex),
|
||||
inMacroop(other.inMacroop),
|
||||
execSeqNum(other.execSeqNum),
|
||||
blocked(other.blocked)
|
||||
{ }
|
||||
{
|
||||
set(microopPC, other.microopPC);
|
||||
}
|
||||
|
||||
|
||||
/** Index into the inputBuffer's head marking the start of unhandled
|
||||
* instructions */
|
||||
unsigned int inputIndex;
|
||||
unsigned int inputIndex = 0;
|
||||
|
||||
/** True when we're in the process of decomposing a micro-op and
|
||||
* microopPC will be valid. This is only the case when there isn't
|
||||
* sufficient space in Executes input buffer to take the whole of a
|
||||
* decomposed instruction and some of that instructions micro-ops must
|
||||
* be generated in a later cycle */
|
||||
bool inMacroop;
|
||||
TheISA::PCState microopPC;
|
||||
bool inMacroop = false;
|
||||
std::unique_ptr<PCStateBase> microopPC;
|
||||
|
||||
/** Source of execSeqNums to number instructions. */
|
||||
InstSeqNum execSeqNum;
|
||||
InstSeqNum execSeqNum = InstId::firstExecSeqNum;
|
||||
|
||||
/** Blocked indication for report */
|
||||
bool blocked;
|
||||
bool blocked = false;
|
||||
};
|
||||
|
||||
std::vector<DecodeThreadInfo> decodeInfo;
|
||||
|
||||
@@ -83,6 +83,9 @@ Fetch1::Fetch1(const std::string &name_,
|
||||
numFetchesInMemorySystem(0),
|
||||
numFetchesInITLB(0)
|
||||
{
|
||||
for (auto &info: fetchInfo)
|
||||
info.pc.reset(params.isa[0]->newPCState());
|
||||
|
||||
if (lineSnap == 0) {
|
||||
lineSnap = cpu.cacheLineSize();
|
||||
DPRINTF(Fetch, "lineSnap set to cache line size of: %d\n",
|
||||
@@ -511,8 +514,8 @@ Fetch1::changeStream(const BranchData &branch)
|
||||
thread.state = FetchRunning;
|
||||
break;
|
||||
}
|
||||
thread.pc = branch.target;
|
||||
thread.fetchAddr = thread.pc.instAddr();
|
||||
set(thread.pc, branch.target);
|
||||
thread.fetchAddr = thread.pc->instAddr();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -546,7 +549,7 @@ Fetch1::processResponse(Fetch1::FetchRequestPtr response,
|
||||
/* Make sequence numbers valid in return */
|
||||
line.id = response->id;
|
||||
/* Set the PC in case there was a sequence change */
|
||||
line.pc = thread.pc;
|
||||
set(line.pc, thread.pc);
|
||||
/* Set fetch address to virtual address */
|
||||
line.fetchAddr = response->pc;
|
||||
/* Set the lineBase, which is a sizeof(MachInst) aligned address <=
|
||||
@@ -715,12 +718,11 @@ Fetch1::wakeupFetch(ThreadID tid)
|
||||
{
|
||||
ThreadContext *thread_ctx = cpu.getContext(tid);
|
||||
Fetch1ThreadInfo &thread = fetchInfo[tid];
|
||||
thread.pc = thread_ctx->pcState();
|
||||
thread.fetchAddr = thread.pc.instAddr();
|
||||
set(thread.pc, thread_ctx->pcState());
|
||||
thread.fetchAddr = thread.pc->instAddr();
|
||||
thread.state = FetchRunning;
|
||||
thread.wakeupGuard = true;
|
||||
DPRINTF(Fetch, "[tid:%d]: Changing stream wakeup %s\n",
|
||||
tid, thread_ctx->pcState());
|
||||
DPRINTF(Fetch, "[tid:%d]: Changing stream wakeup %s\n", tid, *thread.pc);
|
||||
|
||||
cpu.wakeupOnEvent(Pipeline::Fetch1StageId);
|
||||
}
|
||||
|
||||
@@ -243,52 +243,43 @@ class Fetch1 : public Named
|
||||
|
||||
struct Fetch1ThreadInfo
|
||||
{
|
||||
|
||||
/** Consturctor to initialize all fields. */
|
||||
Fetch1ThreadInfo() :
|
||||
state(FetchWaitingForPC),
|
||||
pc(TheISA::PCState(0)),
|
||||
fetchAddr(0),
|
||||
streamSeqNum(InstId::firstStreamSeqNum),
|
||||
predictionSeqNum(InstId::firstPredictionSeqNum),
|
||||
blocked(false),
|
||||
wakeupGuard(false)
|
||||
{ }
|
||||
// All fields have default initializers.
|
||||
Fetch1ThreadInfo() {}
|
||||
|
||||
Fetch1ThreadInfo(const Fetch1ThreadInfo& other) :
|
||||
state(other.state),
|
||||
pc(other.pc),
|
||||
pc(other.pc->clone()),
|
||||
streamSeqNum(other.streamSeqNum),
|
||||
predictionSeqNum(other.predictionSeqNum),
|
||||
blocked(other.blocked)
|
||||
{ }
|
||||
|
||||
FetchState state;
|
||||
FetchState state = FetchWaitingForPC;
|
||||
|
||||
/** Fetch PC value. This is updated by branches from Execute, branch
|
||||
* prediction targets from Fetch2. This is only valid immediately
|
||||
* following a redirect from one of those two sources. */
|
||||
TheISA::PCState pc;
|
||||
std::unique_ptr<PCStateBase> pc;
|
||||
|
||||
/** The address we're currently fetching lines from. */
|
||||
Addr fetchAddr;
|
||||
Addr fetchAddr = 0;
|
||||
|
||||
/** Stream sequence number. This changes on request from Execute and is
|
||||
* used to tag instructions by the fetch stream to which they belong.
|
||||
* Execute originates new prediction sequence numbers. */
|
||||
InstSeqNum streamSeqNum;
|
||||
InstSeqNum streamSeqNum = InstId::firstStreamSeqNum;
|
||||
|
||||
/** Prediction sequence number. This changes when requests from Execute
|
||||
* or Fetch2 ask for a change of fetch address and is used to tag lines
|
||||
* by the prediction to which they belong. Fetch2 originates
|
||||
* prediction sequence numbers. */
|
||||
InstSeqNum predictionSeqNum;
|
||||
InstSeqNum predictionSeqNum = InstId::firstPredictionSeqNum;
|
||||
|
||||
/** Blocked indication for report */
|
||||
bool blocked;
|
||||
bool blocked = false;
|
||||
|
||||
/** Signal to guard against sleeping first cycle of wakeup */
|
||||
bool wakeupGuard;
|
||||
bool wakeupGuard = false;
|
||||
};
|
||||
|
||||
std::vector<Fetch1ThreadInfo> fetchInfo;
|
||||
|
||||
@@ -156,7 +156,7 @@ Fetch2::updateBranchPrediction(const BranchData &branch)
|
||||
/* Unpredicted branch or barrier */
|
||||
DPRINTF(Branch, "Unpredicted branch seen inst: %s\n", *inst);
|
||||
branchPredictor.squash(inst->id.fetchSeqNum,
|
||||
branch.target, true, inst->id.threadId);
|
||||
branch.target->as<TheISA::PCState>(), true, inst->id.threadId);
|
||||
// Update after squashing to accomodate O3CPU
|
||||
// using the branch prediction code.
|
||||
branchPredictor.update(inst->id.fetchSeqNum,
|
||||
@@ -172,7 +172,8 @@ Fetch2::updateBranchPrediction(const BranchData &branch)
|
||||
/* Predicted taken, not taken */
|
||||
DPRINTF(Branch, "Branch mis-predicted inst: %s\n", *inst);
|
||||
branchPredictor.squash(inst->id.fetchSeqNum,
|
||||
branch.target /* Not used */, false, inst->id.threadId);
|
||||
branch.target->as<TheISA::PCState>() /* Not used */,
|
||||
false, inst->id.threadId);
|
||||
// Update after squashing to accomodate O3CPU
|
||||
// using the branch prediction code.
|
||||
branchPredictor.update(inst->id.fetchSeqNum,
|
||||
@@ -181,9 +182,9 @@ Fetch2::updateBranchPrediction(const BranchData &branch)
|
||||
case BranchData::BadlyPredictedBranchTarget:
|
||||
/* Predicted taken, was taken but to a different target */
|
||||
DPRINTF(Branch, "Branch mis-predicted target inst: %s target: %s\n",
|
||||
*inst, branch.target);
|
||||
*inst, *branch.target);
|
||||
branchPredictor.squash(inst->id.fetchSeqNum,
|
||||
branch.target, true, inst->id.threadId);
|
||||
branch.target->as<TheISA::PCState>(), true, inst->id.threadId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -224,7 +225,7 @@ Fetch2::predictBranch(MinorDynInstPtr inst, BranchData &branch)
|
||||
BranchData new_branch = BranchData(BranchData::BranchPrediction,
|
||||
inst->id.threadId,
|
||||
inst->id.streamSeqNum, thread.predictionSeqNum + 1,
|
||||
inst->predictedTarget->as<TheISA::PCState>(), inst);
|
||||
*inst->predictedTarget, inst);
|
||||
|
||||
/* Mark with a new prediction number by the stream number of the
|
||||
* instruction causing the prediction */
|
||||
@@ -331,13 +332,13 @@ Fetch2::evaluate()
|
||||
/* Set the inputIndex to be the MachInst-aligned offset
|
||||
* from lineBaseAddr of the new PC value */
|
||||
fetch_info.inputIndex =
|
||||
(line_in->pc.instAddr() & decoder->pcMask()) -
|
||||
(line_in->pc->instAddr() & decoder->pcMask()) -
|
||||
line_in->lineBaseAddr;
|
||||
DPRINTF(Fetch, "Setting new PC value: %s inputIndex: 0x%x"
|
||||
" lineBaseAddr: 0x%x lineWidth: 0x%x\n",
|
||||
line_in->pc, fetch_info.inputIndex, line_in->lineBaseAddr,
|
||||
*line_in->pc, fetch_info.inputIndex, line_in->lineBaseAddr,
|
||||
line_in->lineWidth);
|
||||
fetch_info.pc = line_in->pc;
|
||||
set(fetch_info.pc, line_in->pc);
|
||||
fetch_info.havePC = true;
|
||||
decoder->reset();
|
||||
}
|
||||
@@ -383,7 +384,7 @@ Fetch2::evaluate()
|
||||
decoder->moreBytesSize());
|
||||
|
||||
if (!decoder->instReady()) {
|
||||
decoder->moreBytes(fetch_info.pc,
|
||||
decoder->moreBytes(fetch_info.pc->as<TheISA::PCState>(),
|
||||
line_in->lineBaseAddr + fetch_info.inputIndex);
|
||||
DPRINTF(Fetch, "Offering MachInst to decoder addr: 0x%x\n",
|
||||
line_in->lineBaseAddr + fetch_info.inputIndex);
|
||||
@@ -397,7 +398,7 @@ Fetch2::evaluate()
|
||||
* Remember not to assign it until *after* calling
|
||||
* decode */
|
||||
StaticInstPtr decoded_inst =
|
||||
decoder->decode(fetch_info.pc);
|
||||
decoder->decode(fetch_info.pc->as<TheISA::PCState>());
|
||||
|
||||
/* Make a new instruction and pick up the line, stream,
|
||||
* prediction, thread ids from the incoming line */
|
||||
@@ -432,7 +433,7 @@ Fetch2::evaluate()
|
||||
" pc: %s inst: %s\n",
|
||||
line_in->id,
|
||||
line_in->lineWidth, output_index, fetch_info.inputIndex,
|
||||
fetch_info.pc, *dyn_inst);
|
||||
*fetch_info.pc, *dyn_inst);
|
||||
|
||||
/*
|
||||
* In SE mode, it's possible to branch to a microop when
|
||||
@@ -448,10 +449,10 @@ Fetch2::evaluate()
|
||||
* may be pointing to a microop other than 0. Once
|
||||
* advanced, however, the microop number *must* be 0
|
||||
*/
|
||||
fetch_info.pc.uReset();
|
||||
fetch_info.pc->as<TheISA::PCState>().uReset();
|
||||
|
||||
/* Advance PC for the next instruction */
|
||||
decoded_inst->advancePC(fetch_info.pc);
|
||||
decoded_inst->advancePC(*fetch_info.pc);
|
||||
|
||||
/* Predict any branches and issue a branch if
|
||||
* necessary */
|
||||
@@ -467,7 +468,7 @@ Fetch2::evaluate()
|
||||
|
||||
DPRINTF(Fetch, "Updated inputIndex value PC: %s"
|
||||
" inputIndex: 0x%x lineBaseAddr: 0x%x lineWidth: 0x%x\n",
|
||||
line_in->pc, fetch_info.inputIndex, line_in->lineBaseAddr,
|
||||
*line_in->pc, fetch_info.inputIndex, line_in->lineBaseAddr,
|
||||
line_in->lineWidth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,32 +104,22 @@ class Fetch2 : public Named
|
||||
|
||||
struct Fetch2ThreadInfo
|
||||
{
|
||||
|
||||
/** Default constructor */
|
||||
Fetch2ThreadInfo() :
|
||||
inputIndex(0),
|
||||
pc(TheISA::PCState(0)),
|
||||
havePC(false),
|
||||
lastStreamSeqNum(InstId::firstStreamSeqNum),
|
||||
fetchSeqNum(InstId::firstFetchSeqNum),
|
||||
expectedStreamSeqNum(InstId::firstStreamSeqNum),
|
||||
predictionSeqNum(InstId::firstPredictionSeqNum),
|
||||
blocked(false)
|
||||
{ }
|
||||
Fetch2ThreadInfo() {}
|
||||
|
||||
Fetch2ThreadInfo(const Fetch2ThreadInfo& other) :
|
||||
inputIndex(other.inputIndex),
|
||||
pc(other.pc),
|
||||
havePC(other.havePC),
|
||||
lastStreamSeqNum(other.lastStreamSeqNum),
|
||||
expectedStreamSeqNum(other.expectedStreamSeqNum),
|
||||
predictionSeqNum(other.predictionSeqNum),
|
||||
blocked(other.blocked)
|
||||
{ }
|
||||
{
|
||||
set(pc, other.pc);
|
||||
}
|
||||
|
||||
/** Index into an incompletely processed input line that instructions
|
||||
* are to be extracted from */
|
||||
unsigned int inputIndex;
|
||||
unsigned int inputIndex = 0;
|
||||
|
||||
|
||||
/** Remembered program counter value. Between contiguous lines, this
|
||||
@@ -138,34 +128,34 @@ class Fetch2 : public Named
|
||||
* havePC is needed to accomodate instructions which span across
|
||||
* lines meaning that Fetch2 and the decoder need to remember a PC
|
||||
* value and a partially-offered instruction from the previous line */
|
||||
TheISA::PCState pc;
|
||||
std::unique_ptr<PCStateBase> pc;
|
||||
|
||||
/** PC is currently valid. Initially false, gets set to true when a
|
||||
* change-of-stream line is received and false again when lines are
|
||||
* discarded for any reason */
|
||||
bool havePC;
|
||||
bool havePC = false;
|
||||
|
||||
/** Stream sequence number of the last seen line used to identify
|
||||
* changes of instruction stream */
|
||||
InstSeqNum lastStreamSeqNum;
|
||||
InstSeqNum lastStreamSeqNum = InstId::firstStreamSeqNum;
|
||||
|
||||
/** Fetch2 is the source of fetch sequence numbers. These represent the
|
||||
* sequence that instructions were extracted from fetched lines. */
|
||||
InstSeqNum fetchSeqNum;
|
||||
InstSeqNum fetchSeqNum = InstId::firstFetchSeqNum;
|
||||
|
||||
/** Stream sequence number remembered from last time the
|
||||
* predictionSeqNum changed. Lines should only be discarded when their
|
||||
* predictionSeqNums disagree with Fetch2::predictionSeqNum *and* they
|
||||
* are from the same stream that bore that prediction number */
|
||||
InstSeqNum expectedStreamSeqNum;
|
||||
InstSeqNum expectedStreamSeqNum = InstId::firstStreamSeqNum;
|
||||
|
||||
/** Fetch2 is the source of prediction sequence numbers. These
|
||||
* represent predicted changes of control flow sources from branch
|
||||
* prediction in Fetch2. */
|
||||
InstSeqNum predictionSeqNum;
|
||||
InstSeqNum predictionSeqNum = InstId::firstPredictionSeqNum;
|
||||
|
||||
/** Blocked indication for report */
|
||||
bool blocked;
|
||||
bool blocked = false;
|
||||
};
|
||||
|
||||
std::vector<Fetch2ThreadInfo> fetchInfo;
|
||||
|
||||
@@ -145,7 +145,7 @@ BranchData::reportData(std::ostream &os) const
|
||||
} else {
|
||||
os << reason
|
||||
<< ';' << newStreamSeqNum << '.' << newPredictionSeqNum
|
||||
<< ";0x" << std::hex << target.instAddr() << std::dec
|
||||
<< ";0x" << std::hex << target->instAddr() << std::dec
|
||||
<< ';';
|
||||
inst->reportData(os);
|
||||
}
|
||||
@@ -155,7 +155,7 @@ std::ostream &
|
||||
operator <<(std::ostream &os, const BranchData &branch)
|
||||
{
|
||||
os << branch.reason << " target: 0x"
|
||||
<< std::hex << branch.target.instAddr() << std::dec
|
||||
<< std::hex << branch.target->instAddr() << std::dec
|
||||
<< ' ' << *branch.inst
|
||||
<< ' ' << branch.newStreamSeqNum << "(stream)."
|
||||
<< branch.newPredictionSeqNum << "(pred)";
|
||||
|
||||
@@ -110,42 +110,51 @@ class BranchData /* : public ReportIF, public BubbleIF */
|
||||
|
||||
public:
|
||||
/** Explanation for this branch */
|
||||
Reason reason;
|
||||
Reason reason = NoBranch;
|
||||
|
||||
/** ThreadID associated with branch */
|
||||
ThreadID threadId;
|
||||
ThreadID threadId = InvalidThreadID;
|
||||
|
||||
/** Sequence number of new stream/prediction to be adopted */
|
||||
InstSeqNum newStreamSeqNum;
|
||||
InstSeqNum newPredictionSeqNum;
|
||||
InstSeqNum newStreamSeqNum = 0;
|
||||
InstSeqNum newPredictionSeqNum = 0;
|
||||
|
||||
/** Starting PC of that stream */
|
||||
TheISA::PCState target;
|
||||
std::unique_ptr<PCStateBase> target;
|
||||
|
||||
/** Instruction which caused this branch */
|
||||
MinorDynInstPtr inst;
|
||||
MinorDynInstPtr inst = MinorDynInst::bubble();
|
||||
|
||||
public:
|
||||
BranchData() :
|
||||
reason(NoBranch), threadId(InvalidThreadID), newStreamSeqNum(0),
|
||||
newPredictionSeqNum(0), target(TheISA::PCState(0)),
|
||||
inst(MinorDynInst::bubble())
|
||||
{ }
|
||||
BranchData() {}
|
||||
|
||||
BranchData(
|
||||
Reason reason_,
|
||||
ThreadID thread_id,
|
||||
InstSeqNum new_stream_seq_num,
|
||||
InstSeqNum new_prediction_seq_num,
|
||||
TheISA::PCState target,
|
||||
MinorDynInstPtr inst_) :
|
||||
reason(reason_),
|
||||
threadId(thread_id),
|
||||
BranchData(Reason reason_, ThreadID thread_id,
|
||||
InstSeqNum new_stream_seq_num, InstSeqNum new_prediction_seq_num,
|
||||
const PCStateBase &target, MinorDynInstPtr inst_) :
|
||||
reason(reason_), threadId(thread_id),
|
||||
newStreamSeqNum(new_stream_seq_num),
|
||||
newPredictionSeqNum(new_prediction_seq_num),
|
||||
target(target),
|
||||
inst(inst_)
|
||||
{ }
|
||||
target(target.clone()), inst(inst_)
|
||||
{}
|
||||
|
||||
BranchData(const BranchData &other) :
|
||||
reason(other.reason), threadId(other.threadId),
|
||||
newStreamSeqNum(other.newStreamSeqNum),
|
||||
newPredictionSeqNum(other.newPredictionSeqNum),
|
||||
target(other.target->clone()),
|
||||
inst(other.inst)
|
||||
{}
|
||||
BranchData &
|
||||
operator=(const BranchData &other)
|
||||
{
|
||||
reason = other.reason;
|
||||
threadId = other.threadId;
|
||||
newStreamSeqNum = other.newStreamSeqNum;
|
||||
newPredictionSeqNum = other.newPredictionSeqNum;
|
||||
set(target, other.target);
|
||||
inst = other.inst;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** BubbleIF interface */
|
||||
static BranchData bubble() { return BranchData(); }
|
||||
@@ -176,48 +185,60 @@ class ForwardLineData /* : public ReportIF, public BubbleIF */
|
||||
{
|
||||
private:
|
||||
/** This line is a bubble. No other data member is required to be valid
|
||||
* if this is true */
|
||||
bool bubbleFlag;
|
||||
* if this is true
|
||||
* Make lines bubbles by default */
|
||||
bool bubbleFlag = true;
|
||||
|
||||
public:
|
||||
/** First byte address in the line. This is allowed to be
|
||||
* <= pc.instAddr() */
|
||||
Addr lineBaseAddr;
|
||||
Addr lineBaseAddr = 0;
|
||||
|
||||
/** PC of the first inst within this sequence */
|
||||
TheISA::PCState pc;
|
||||
std::unique_ptr<PCStateBase> pc;
|
||||
|
||||
/** Address of this line of data */
|
||||
Addr fetchAddr;
|
||||
|
||||
/** Explicit line width, don't rely on data.size */
|
||||
unsigned int lineWidth;
|
||||
unsigned int lineWidth = 0;
|
||||
|
||||
public:
|
||||
/** This line has a fault. The bubble flag will be false and seqNums
|
||||
* will be valid but no data will */
|
||||
Fault fault;
|
||||
Fault fault = NoFault;
|
||||
|
||||
/** Thread, stream, prediction ... id of this line */
|
||||
InstId id;
|
||||
|
||||
/** Line data. line[0] is the byte at address pc.instAddr(). Data is
|
||||
* only valid upto lineWidth - 1. */
|
||||
uint8_t *line;
|
||||
uint8_t *line = nullptr;
|
||||
|
||||
/** Packet from which the line is taken */
|
||||
Packet *packet;
|
||||
Packet *packet = nullptr;
|
||||
|
||||
public:
|
||||
ForwardLineData() :
|
||||
bubbleFlag(true),
|
||||
lineBaseAddr(0),
|
||||
lineWidth(0),
|
||||
fault(NoFault),
|
||||
line(NULL),
|
||||
packet(NULL)
|
||||
ForwardLineData() {}
|
||||
ForwardLineData(const ForwardLineData &other) :
|
||||
bubbleFlag(other.bubbleFlag), lineBaseAddr(other.lineBaseAddr),
|
||||
pc(other.pc->clone()), fetchAddr(other.fetchAddr),
|
||||
lineWidth(other.lineWidth), fault(other.fault), id(other.id),
|
||||
line(other.line), packet(other.packet)
|
||||
{}
|
||||
ForwardLineData &
|
||||
operator=(const ForwardLineData &other)
|
||||
{
|
||||
/* Make lines bubbles by default */
|
||||
bubbleFlag = other.bubbleFlag;
|
||||
lineBaseAddr = other.lineBaseAddr;
|
||||
set(pc, other.pc);
|
||||
fetchAddr = other.fetchAddr;
|
||||
lineWidth = other.lineWidth;
|
||||
fault = other.fault;
|
||||
id = other.id;
|
||||
line = other.line;
|
||||
packet = other.packet;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~ForwardLineData() { line = NULL; }
|
||||
|
||||
Reference in New Issue
Block a user