inorder: update support for branch delay slots
authorKorey Sewell <ksewell@umich.edu>
Mon, 20 Jun 2011 01:43:34 +0000 (21:43 -0400)
committerKorey Sewell <ksewell@umich.edu>
Mon, 20 Jun 2011 01:43:34 +0000 (21:43 -0400)
src/cpu/inorder/cpu.cc
src/cpu/inorder/inorder_dyn_inst.cc
src/cpu/inorder/inorder_dyn_inst.hh
src/cpu/inorder/resources/branch_predictor.cc
src/cpu/inorder/resources/execution_unit.cc
src/cpu/inorder/resources/fetch_seq_unit.cc
src/cpu/inorder/resources/fetch_seq_unit.hh

index ef6d5fb20d7c57aed7ace2227228f2d700b2a6f8..01eab9af7dfb26e41fb06824e6833a55c75c79c3 100644 (file)
@@ -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();
index 25f45837972b1761ab4087ca7ddcdc4ffe0f6363..dea1a7dfeab92aa2bd5971fa87a2c95f3165229d 100644 (file)
@@ -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;
index 1ef2b2af42e27686d74033c77ee8d71bd5f63974..ff60120a3318b894a70229382b2e58ef17d1d525 100644 (file)
@@ -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;
index 0507bc356516cb700d03db783a4c8aa9d07fcf90..a349918540caf9cb693012a02a09caa9902062ac 100644 (file)
@@ -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) {
index 4fca9e5e152c3e8ffd64b0641a9a31b27e459b45..6c9b6322fcf8755994109f2bda797be9d8313fbd 100644 (file)
@@ -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,
index 67f6c5102abd625bec899db119342c89d600c0d2..579f9d45b6f645e5353db37a7549c271e19e213b 100644 (file)
@@ -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]) {
index be3c59a131db35d451a374579e8731a63e87fd65..7c57fa17b413c5d7be455e847722a4b15d4f9bb7 100644 (file)
@@ -45,6 +45,7 @@
 class FetchSeqUnit : public Resource {
   public:
     typedef ThePipeline::DynInstPtr DynInstPtr;
+    typedef std::list<DynInstPtr>::iterator ListIt;
 
     enum Command {
         AssignNextPC,