merge whitespace changes
[gem5.git] / src / cpu / o3 / iew_impl.hh
index f24eaf2c428e209f344dbd2521b50f5d2dbba148..399c449092d708403adc5d4e3bffcfa141e931d0 100644 (file)
 #include "cpu/o3/iew.hh"
 
 template<class Impl>
-DefaultIEW<Impl>::DefaultIEW(Params *params)
+DefaultIEW<Impl>::DefaultIEW(O3CPU *_cpu, Params *params)
     : issueToExecQueue(params->backComSize, params->forwardComSize),
-      instQueue(params),
-      ldstQueue(params),
+      cpu(_cpu),
+      instQueue(_cpu, this, params),
+      ldstQueue(_cpu, this, params),
       fuPool(params->fuPool),
       commitToIEWDelay(params->commitToIEWDelay),
       renameToIEWDelay(params->renameToIEWDelay),
@@ -64,14 +65,10 @@ DefaultIEW<Impl>::DefaultIEW(Params *params)
     // Instruction queue needs the queue between issue and execute.
     instQueue.setIssueToExecuteQueue(&issueToExecQueue);
 
-    instQueue.setIEW(this);
-    ldstQueue.setIEW(this);
-
     for (int i=0; i < numThreads; i++) {
         dispatchStatus[i] = Running;
         stalls[i].commit = false;
         fetchRedirect[i] = false;
-        bdelayDoneSeqNum[i] = 0;
     }
 
     wbMax = wbWidth * params->wbDepth;
@@ -276,17 +273,6 @@ DefaultIEW<Impl>::initStage()
         toRename->iewInfo[tid].freeLSQEntries =
             ldstQueue.numFreeEntries(tid);
     }
-}
-
-template<class Impl>
-void
-DefaultIEW<Impl>::setCPU(O3CPU *cpu_ptr)
-{
-    DPRINTF(IEW, "Setting CPU pointer.\n");
-    cpu = cpu_ptr;
-
-    instQueue.setCPU(cpu_ptr);
-    ldstQueue.setCPU(cpu_ptr);
 
     cpu->activateStage(O3CPU::IEWIdx);
 }
@@ -295,7 +281,6 @@ template<class Impl>
 void
 DefaultIEW<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
 {
-    DPRINTF(IEW, "Setting time buffer pointer.\n");
     timeBuffer = tb_ptr;
 
     // Setup wire to read information from time buffer, from commit.
@@ -314,7 +299,6 @@ template<class Impl>
 void
 DefaultIEW<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr)
 {
-    DPRINTF(IEW, "Setting rename queue pointer.\n");
     renameQueue = rq_ptr;
 
     // Setup wire to read information from rename queue.
@@ -325,7 +309,6 @@ template<class Impl>
 void
 DefaultIEW<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr)
 {
-    DPRINTF(IEW, "Setting IEW queue pointer.\n");
     iewQueue = iq_ptr;
 
     // Setup wire to write instructions to commit.
@@ -336,7 +319,6 @@ template<class Impl>
 void
 DefaultIEW<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
 {
-    DPRINTF(IEW, "Setting active threads list pointer.\n");
     activeThreads = at_ptr;
 
     ldstQueue.setActiveThreads(at_ptr);
@@ -347,7 +329,6 @@ template<class Impl>
 void
 DefaultIEW<Impl>::setScoreboard(Scoreboard *sb_ptr)
 {
-    DPRINTF(IEW, "Setting scoreboard pointer.\n");
     scoreboard = sb_ptr;
 }
 
@@ -428,31 +409,14 @@ DefaultIEW<Impl>::squash(unsigned tid)
     instQueue.squash(tid);
 
     // Tell the LDSTQ to start squashing.
-#if ISA_HAS_DELAY_SLOT
-    ldstQueue.squash(fromCommit->commitInfo[tid].bdelayDoneSeqNum, tid);
-#else
     ldstQueue.squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
-#endif
     updatedQueues = true;
 
     // Clear the skid buffer in case it has any data in it.
     DPRINTF(IEW, "[tid:%i]: Removing skidbuffer instructions until [sn:%i].\n",
-            tid, fromCommit->commitInfo[tid].bdelayDoneSeqNum);
+            tid, fromCommit->commitInfo[tid].doneSeqNum);
 
     while (!skidBuffer[tid].empty()) {
-#if ISA_HAS_DELAY_SLOT
-        if (skidBuffer[tid].front()->seqNum <=
-            fromCommit->commitInfo[tid].bdelayDoneSeqNum) {
-            DPRINTF(IEW, "[tid:%i]: Cannot remove skidbuffer instructions "
-                    "that occur before delay slot [sn:%i].\n",
-                    fromCommit->commitInfo[tid].bdelayDoneSeqNum,
-                    tid);
-            break;
-        } else {
-            DPRINTF(IEW, "[tid:%i]: Removing instruction [sn:%i] from "
-                    "skidBuffer.\n", tid, skidBuffer[tid].front()->seqNum);
-        }
-#endif
         if (skidBuffer[tid].front()->isLoad() ||
             skidBuffer[tid].front()->isStore() ) {
             toRename->iewInfo[tid].dispatchedToLSQ++;
@@ -463,8 +427,6 @@ DefaultIEW<Impl>::squash(unsigned tid)
         skidBuffer[tid].pop();
     }
 
-    bdelayDoneSeqNum[tid] = fromCommit->commitInfo[tid].bdelayDoneSeqNum;
-
     emptyRenameInsts(tid);
 }
 
@@ -480,38 +442,19 @@ DefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, unsigned tid)
     toCommit->mispredPC[tid] = inst->readPC();
     toCommit->branchMispredict[tid] = true;
 
-    int instSize = sizeof(TheISA::MachInst);
 #if ISA_HAS_DELAY_SLOT
-    bool branch_taken =
+    int instSize = sizeof(TheISA::MachInst);
+    toCommit->branchTaken[tid] =
         !(inst->readNextPC() + instSize == inst->readNextNPC() &&
           (inst->readNextPC() == inst->readPC() + instSize ||
            inst->readNextPC() == inst->readPC() + 2 * instSize));
-    DPRINTF(Sparc, "Branch taken = %s [sn:%i]\n",
-            branch_taken ? "true": "false", inst->seqNum);
-
-    toCommit->branchTaken[tid] = branch_taken;
-
-    bool squashDelaySlot = true;
-//     (inst->readNextPC() != inst->readPC() + sizeof(TheISA::MachInst));
-    DPRINTF(Sparc, "Squash delay slot = %s [sn:%i]\n",
-            squashDelaySlot ? "true": "false", inst->seqNum);
-    toCommit->squashDelaySlot[tid] = squashDelaySlot;
-    //If we're squashing the delay slot, we need to pick back up at NextPC.
-    //Otherwise, NextPC isn't being squashed, so we should pick back up at
-    //NextNPC.
-    if (squashDelaySlot) {
-        toCommit->nextPC[tid] = inst->readNextPC();
-        toCommit->nextNPC[tid] = inst->readNextNPC();
-    } else {
-        toCommit->nextPC[tid] = inst->readNextNPC();
-        toCommit->nextNPC[tid] = inst->readNextNPC() + instSize;
-    }
 #else
     toCommit->branchTaken[tid] = inst->readNextPC() !=
         (inst->readPC() + sizeof(TheISA::MachInst));
-    toCommit->nextPC[tid] = inst->readNextPC();
-    toCommit->nextNPC[tid] = inst->readNextPC() + instSize;
 #endif
+    toCommit->nextPC[tid] = inst->readNextPC();
+    toCommit->nextNPC[tid] = inst->readNextNPC();
+    toCommit->nextMicroPC[tid] = inst->readNextMicroPC();
 
     toCommit->includeSquashInst[tid] = false;
 
@@ -528,11 +471,7 @@ DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, unsigned tid)
     toCommit->squash[tid] = true;
     toCommit->squashedSeqNum[tid] = inst->seqNum;
     toCommit->nextPC[tid] = inst->readNextPC();
-#if ISA_HAS_DELAY_SLOT
     toCommit->nextNPC[tid] = inst->readNextNPC();
-#else
-    toCommit->nextNPC[tid] = inst->readNextPC() + sizeof(TheISA::MachInst);
-#endif
     toCommit->branchMispredict[tid] = false;
 
     toCommit->includeSquashInst[tid] = false;
@@ -550,11 +489,7 @@ DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, unsigned tid)
     toCommit->squash[tid] = true;
     toCommit->squashedSeqNum[tid] = inst->seqNum;
     toCommit->nextPC[tid] = inst->readPC();
-#if ISA_HAS_DELAY_SLOT
     toCommit->nextNPC[tid] = inst->readNextPC();
-#else
-    toCommit->nextNPC[tid] = inst->readPC() + sizeof(TheISA::MachInst);
-#endif
     toCommit->branchMispredict[tid] = false;
 
     // Must include the broadcasted SN in the squash.
@@ -898,10 +833,8 @@ DefaultIEW<Impl>::sortInsts()
 {
     int insts_from_rename = fromRename->size;
 #ifdef DEBUG
-#if !ISA_HAS_DELAY_SLOT
     for (int i = 0; i < numThreads; i++)
         assert(insts[i].empty());
-#endif
 #endif
     for (int i = 0; i < insts_from_rename; ++i) {
         insts[fromRename->insts[i]->threadNumber].push(fromRename->insts[i]);
@@ -912,21 +845,9 @@ template <class Impl>
 void
 DefaultIEW<Impl>::emptyRenameInsts(unsigned tid)
 {
-    DPRINTF(IEW, "[tid:%i]: Removing incoming rename instructions until "
-            "[sn:%i].\n", tid, bdelayDoneSeqNum[tid]);
+    DPRINTF(IEW, "[tid:%i]: Removing incoming rename instructions\n", tid);
 
     while (!insts[tid].empty()) {
-#if ISA_HAS_DELAY_SLOT
-        if (insts[tid].front()->seqNum <= bdelayDoneSeqNum[tid]) {
-            DPRINTF(IEW, "[tid:%i]: Done removing, cannot remove instruction"
-                    " that occurs at or before delay slot [sn:%i].\n",
-                    tid, bdelayDoneSeqNum[tid]);
-            break;
-        } else {
-            DPRINTF(IEW, "[tid:%i]: Removing incoming rename instruction "
-                    "[sn:%i].\n", tid, insts[tid].front()->seqNum);
-        }
-#endif
 
         if (insts[tid].front()->isLoad() ||
             insts[tid].front()->isStore() ) {
@@ -1152,19 +1073,6 @@ DefaultIEW<Impl>::dispatchInsts(unsigned tid)
             // Same as non-speculative stores.
             inst->setCanCommit();
             instQueue.insertBarrier(inst);
-            add_to_iq = false;
-        } else if (inst->isNonSpeculative()) {
-            DPRINTF(IEW, "[tid:%i]: Issue: Nonspeculative instruction "
-                    "encountered, skipping.\n", tid);
-
-            // Same as non-speculative stores.
-            inst->setCanCommit();
-
-            // Specifically insert it as nonspeculative.
-            instQueue.insertNonSpec(inst);
-
-            ++iewDispNonSpecInsts;
-
             add_to_iq = false;
         } else if (inst->isNop()) {
             DPRINTF(IEW, "[tid:%i]: Issue: Nop instruction encountered, "
@@ -1193,6 +1101,20 @@ DefaultIEW<Impl>::dispatchInsts(unsigned tid)
         } else {
             add_to_iq = true;
         }
+        if (inst->isNonSpeculative()) {
+            DPRINTF(IEW, "[tid:%i]: Issue: Nonspeculative instruction "
+                    "encountered, skipping.\n", tid);
+
+            // Same as non-speculative stores.
+            inst->setCanCommit();
+
+            // Specifically insert it as nonspeculative.
+            instQueue.insertNonSpec(inst);
+
+            ++iewDispNonSpecInsts;
+
+            add_to_iq = false;
+        }
 
         // If the instruction queue is not full, then add the
         // instruction.
@@ -1379,6 +1301,7 @@ DefaultIEW<Impl>::executeInsts()
                     predictedNotTakenIncorrect++;
                 }
             } else if (ldstQueue.violation(tid)) {
+                assert(inst->isMemRef());
                 // If there was an ordering violation, then get the
                 // DynInst that caused the violation.  Note that this
                 // clears the violation signal.
@@ -1391,10 +1314,10 @@ DefaultIEW<Impl>::executeInsts()
 
                 // Ensure the violating instruction is older than
                 // current squash
-                if (fetchRedirect[tid] &&
-                    violator->seqNum >= toCommit->squashedSeqNum[tid])
+/*                if (fetchRedirect[tid] &&
+                    violator->seqNum >= toCommit->squashedSeqNum[tid] + 1)
                     continue;
-
+*/
                 fetchRedirect[tid] = true;
 
                 // Tell the instruction queue that a violation has occured.
@@ -1414,6 +1337,33 @@ DefaultIEW<Impl>::executeInsts()
 
                 squashDueToMemBlocked(inst, tid);
             }
+        } else {
+            // Reset any state associated with redirects that will not
+            // be used.
+            if (ldstQueue.violation(tid)) {
+                assert(inst->isMemRef());
+
+                DynInstPtr violator = ldstQueue.getMemDepViolator(tid);
+
+                DPRINTF(IEW, "LDSTQ detected a violation.  Violator PC: "
+                        "%#x, inst PC: %#x.  Addr is: %#x.\n",
+                        violator->readPC(), inst->readPC(), inst->physEffAddr);
+                DPRINTF(IEW, "Violation will not be handled because "
+                        "already squashing\n");
+
+                ++memOrderViolationEvents;
+            }
+            if (ldstQueue.loadBlocked(tid) &&
+                !ldstQueue.isLoadBlockedHandled(tid)) {
+                DPRINTF(IEW, "Load operation couldn't execute because the "
+                        "memory system is blocked.  PC: %#x [sn:%lli]\n",
+                        inst->readPC(), inst->seqNum);
+                DPRINTF(IEW, "Blocked load will not be handled because "
+                        "already squashing\n");
+
+                ldstQueue.setLoadBlockedHandled(tid);
+            }
+
         }
     }
 
@@ -1563,6 +1513,7 @@ DefaultIEW<Impl>::tick()
             //DPRINTF(IEW,"NonspecInst from thread %i",tid);
             if (fromCommit->commitInfo[tid].uncached) {
                 instQueue.replayMemInst(fromCommit->commitInfo[tid].uncachedLoad);
+                fromCommit->commitInfo[tid].uncachedLoad->setAtCommit();
             } else {
                 instQueue.scheduleNonSpec(
                     fromCommit->commitInfo[tid].nonSpecSeqNum);