From 2a59fcfbe9f4d68bfe3dcb263acf68b998e0705c Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 19 Jun 2011 21:43:34 -0400 Subject: [PATCH] inorder: update support for branch delay slots --- src/cpu/inorder/cpu.cc | 6 +- src/cpu/inorder/inorder_dyn_inst.cc | 2 +- src/cpu/inorder/inorder_dyn_inst.hh | 4 +- src/cpu/inorder/resources/branch_predictor.cc | 2 +- src/cpu/inorder/resources/execution_unit.cc | 9 +-- src/cpu/inorder/resources/fetch_seq_unit.cc | 72 ++++++------------- src/cpu/inorder/resources/fetch_seq_unit.hh | 1 + 7 files changed, 33 insertions(+), 63 deletions(-) diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index ef6d5fb20..01eab9af7 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -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(); diff --git a/src/cpu/inorder/inorder_dyn_inst.cc b/src/cpu/inorder/inorder_dyn_inst.cc index 25f458379..dea1a7dfe 100644 --- a/src/cpu/inorder/inorder_dyn_inst.cc +++ b/src/cpu/inorder/inorder_dyn_inst.cc @@ -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; diff --git a/src/cpu/inorder/inorder_dyn_inst.hh b/src/cpu/inorder/inorder_dyn_inst.hh index 1ef2b2af4..ff60120a3 100644 --- a/src/cpu/inorder/inorder_dyn_inst.hh +++ b/src/cpu/inorder/inorder_dyn_inst.hh @@ -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; diff --git a/src/cpu/inorder/resources/branch_predictor.cc b/src/cpu/inorder/resources/branch_predictor.cc index 0507bc356..a34991854 100644 --- a/src/cpu/inorder/resources/branch_predictor.cc +++ b/src/cpu/inorder/resources/branch_predictor.cc @@ -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) { diff --git a/src/cpu/inorder/resources/execution_unit.cc b/src/cpu/inorder/resources/execution_unit.cc index 4fca9e5e1..6c9b6322f 100644 --- a/src/cpu/inorder/resources/execution_unit.cc +++ b/src/cpu/inorder/resources/execution_unit.cc @@ -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, diff --git a/src/cpu/inorder/resources/fetch_seq_unit.cc b/src/cpu/inorder/resources/fetch_seq_unit.cc index 67f6c5102..579f9d45b 100644 --- a/src/cpu/inorder/resources/fetch_seq_unit.cc +++ b/src/cpu/inorder/resources/fetch_seq_unit.cc @@ -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]) { diff --git a/src/cpu/inorder/resources/fetch_seq_unit.hh b/src/cpu/inorder/resources/fetch_seq_unit.hh index be3c59a13..7c57fa17b 100644 --- a/src/cpu/inorder/resources/fetch_seq_unit.hh +++ b/src/cpu/inorder/resources/fetch_seq_unit.hh @@ -45,6 +45,7 @@ class FetchSeqUnit : public Resource { public: typedef ThePipeline::DynInstPtr DynInstPtr; + typedef std::list::iterator ListIt; enum Command { AssignNextPC, -- 2.30.2