inorder: update support for branch delay slots
This commit is contained in:
@@ -1433,9 +1433,7 @@ InOrderCPU::cleanUpRemovedInsts()
|
||||
ThreadID tid = inst->threadNumber;
|
||||
|
||||
// Remove From Register Dependency Map, If Necessary
|
||||
archRegDepMap[(*removeList.front())->threadNumber].
|
||||
remove((*removeList.front()));
|
||||
|
||||
archRegDepMap[tid].remove(inst);
|
||||
|
||||
// Clear if Non-Speculative
|
||||
if (inst->staticInst &&
|
||||
@@ -1444,6 +1442,8 @@ InOrderCPU::cleanUpRemovedInsts()
|
||||
nonSpecInstActive[tid] = false;
|
||||
}
|
||||
|
||||
inst->onInstList = false;
|
||||
|
||||
instList[tid].erase(removeList.front());
|
||||
|
||||
removeList.pop();
|
||||
|
||||
@@ -66,7 +66,7 @@ InOrderDynInst::InOrderDynInst(InOrderCPU *cpu,
|
||||
inFrontEnd(true), frontSked(NULL), backSked(NULL),
|
||||
squashingStage(0), predictTaken(false), procDelaySlotOnMispred(false),
|
||||
fetchMemReq(NULL), dataMemReq(NULL), instEffAddr(0), eaCalcDone(false),
|
||||
lqIdx(0), sqIdx(0), instListIt(NULL)
|
||||
lqIdx(0), sqIdx(0), instListIt(NULL), onInstList(false)
|
||||
{
|
||||
for(int i = 0; i < MaxInstSrcRegs; i++) {
|
||||
instSrc[i].integer = 0;
|
||||
|
||||
@@ -988,11 +988,13 @@ class InOrderDynInst : public FastAlloc, public RefCounted
|
||||
/** Iterator pointing to this BaseDynInst in the list of all insts. */
|
||||
ListIt instListIt;
|
||||
|
||||
bool onInstList;
|
||||
|
||||
/** Returns iterator to this instruction in the list of all insts. */
|
||||
ListIt getInstListIt() { return instListIt; }
|
||||
|
||||
/** Sets iterator for this instruction in the list of all insts. */
|
||||
void setInstListIt(ListIt _instListIt) { instListIt = _instListIt; }
|
||||
void setInstListIt(ListIt _instListIt) { onInstList = true; instListIt = _instListIt; }
|
||||
|
||||
/** Count of total number of dynamic instructions. */
|
||||
static int instcount;
|
||||
|
||||
@@ -153,7 +153,7 @@ BranchPredictor::squash(DynInstPtr inst, int squash_stage,
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
// We need to squash the actual branch , NOT the delay slot
|
||||
// in the branch predictor
|
||||
squash_seq_num = squash_seq_num - 1;
|
||||
//squash_seq_num = squash_seq_num - 1;
|
||||
#endif
|
||||
|
||||
if (squash_stage >= ThePipeline::BackEndStartStage) {
|
||||
|
||||
@@ -177,11 +177,8 @@ ExecutionUnit::execute(int slot_num)
|
||||
"predicted as not taken.\n", tid,
|
||||
seq_num, inst->pcState());
|
||||
} else {
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
inst->bdelaySeqNum = seq_num + 1;
|
||||
#else
|
||||
inst->bdelaySeqNum = seq_num;
|
||||
#endif
|
||||
|
||||
DPRINTF(InOrderExecute, "[tid:%i]: "
|
||||
"Misprediction detected at "
|
||||
"[sn:%i] PC %s,\n\t squashing after "
|
||||
@@ -203,11 +200,7 @@ ExecutionUnit::execute(int slot_num)
|
||||
inst->seqNum = seq_num;
|
||||
inst->setPredTarg(pc);
|
||||
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
inst->bdelaySeqNum = seq_num + 1;
|
||||
#else
|
||||
inst->bdelaySeqNum = seq_num;
|
||||
#endif
|
||||
|
||||
DPRINTF(InOrderExecute, "[tid:%i] Redirecting"
|
||||
" fetch to %s.\n", tid,
|
||||
|
||||
@@ -143,15 +143,7 @@ FetchSeqUnit::execute(int slot_num)
|
||||
inst->readPredTarg());
|
||||
} else if (inst->predTaken()) {
|
||||
// Taken Control
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
DPRINTF(InOrderFetchSeq, "[tid:%i]: [sn:%i] Updating delay"
|
||||
" slot target to PC %s\n", tid, inst->seqNum,
|
||||
inst->readPredTarg());
|
||||
inst->bdelaySeqNum = seq_num + 1;
|
||||
#else
|
||||
inst->bdelaySeqNum = seq_num;
|
||||
#endif
|
||||
|
||||
inst->squashingStage = stage_num;
|
||||
DPRINTF(InOrderFetchSeq, "[tid:%i] Setting up squash to "
|
||||
"start from stage %i, after [sn:%i].\n",
|
||||
@@ -190,59 +182,41 @@ void
|
||||
FetchSeqUnit::squash(DynInstPtr inst, int squash_stage,
|
||||
InstSeqNum squash_seq_num, ThreadID tid)
|
||||
{
|
||||
DPRINTF(InOrderFetchSeq, "[tid:%i]: Updating due to squash from stage %i."
|
||||
"\n", tid, squash_stage);
|
||||
DPRINTF(InOrderFetchSeq, "[tid:%i]: Updating due to squash from %s (%s) "
|
||||
"stage %i.\n", tid, inst->instName(), inst->pcState(),
|
||||
squash_stage);
|
||||
assert(squash_seq_num == inst->seqNum);
|
||||
|
||||
InstSeqNum done_seq_num = inst->bdelaySeqNum;
|
||||
TheISA::PCState nextPC = inst->pcState();
|
||||
assert(inst->staticInst);
|
||||
advancePC(nextPC, inst->staticInst);
|
||||
|
||||
// Handles the case where we are squashing because of something that is
|
||||
// not a branch...like a memory stall
|
||||
TheISA::PCState newPC;
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
if (inst->isControl()) {
|
||||
newPC = inst->readPredTarg();
|
||||
} else {
|
||||
TheISA::PCState thisPC = inst->pcState();
|
||||
assert(inst->staticInst);
|
||||
advancePC(thisPC, inst->staticInst);
|
||||
newPC = thisPC;
|
||||
if (inst->onInstList) {
|
||||
ListIt inst_it = inst->getInstListIt();
|
||||
inst_it++;
|
||||
if (inst_it != cpu->instList[tid].end()) {
|
||||
DynInstPtr delaySlotInst = (*inst_it);
|
||||
if (delaySlotInst->pcState() != nextPC)
|
||||
squash_seq_num = delaySlotInst->seqNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (squashSeqNum[tid] <= done_seq_num &&
|
||||
if (squashSeqNum[tid] <= squash_seq_num &&
|
||||
lastSquashCycle[tid] == curTick()) {
|
||||
DPRINTF(InOrderFetchSeq, "[tid:%i]: Ignoring squash from stage %i, "
|
||||
"since there is an outstanding squash that is older.\n",
|
||||
tid, squash_stage);
|
||||
} else {
|
||||
squashSeqNum[tid] = done_seq_num;
|
||||
squashSeqNum[tid] = squash_seq_num;
|
||||
lastSquashCycle[tid] = curTick();
|
||||
|
||||
if (inst->isControl()) {
|
||||
// If the next inst. num is greater than done seq num,
|
||||
// then that means we have seen the delay slot
|
||||
assert(cpu->nextInstSeqNum(tid) >= done_seq_num);
|
||||
if (cpu->nextInstSeqNum(tid) > done_seq_num) {
|
||||
// Reset PC
|
||||
pc[tid] = newPC;
|
||||
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
// The Pred. Target will be (NPC, NNPC, NNPC+4)
|
||||
// so since we already saw the NPC (i.e. delay slot)
|
||||
// advance one more to get (NNPC, NNPC+4, NNPC+8)
|
||||
TheISA::advancePC(pc[tid], inst->staticInst);
|
||||
#endif
|
||||
|
||||
DPRINTF(InOrderFetchSeq, "[tid:%i]: Setting PC to %s.\n",
|
||||
tid, newPC);
|
||||
} else {
|
||||
// If The very next instruction number that needs to be given
|
||||
// out by the CPU is the done seq. num, then we haven't seen
|
||||
// the delay slot instruction yet.
|
||||
assert(ISA_HAS_DELAY_SLOT);
|
||||
pc[tid] = newPC;
|
||||
}
|
||||
} else {
|
||||
pc[tid] = newPC;
|
||||
}
|
||||
DPRINTF(InOrderFetchSeq, "[tid:%i]: Setting PC to %s.\n",
|
||||
tid, nextPC);
|
||||
pc[tid] = nextPC;
|
||||
|
||||
// Unblock Any Stages Waiting for this information to be updated ...
|
||||
if (!pcValid[tid]) {
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
class FetchSeqUnit : public Resource {
|
||||
public:
|
||||
typedef ThePipeline::DynInstPtr DynInstPtr;
|
||||
typedef std::list<DynInstPtr>::iterator ListIt;
|
||||
|
||||
enum Command {
|
||||
AssignNextPC,
|
||||
|
||||
Reference in New Issue
Block a user