Allow for multiple redirects to happen on a single cycle (only the one for the oldest...
authorKevin Lim <ktlim@umich.edu>
Tue, 12 Dec 2006 22:35:46 +0000 (17:35 -0500)
committerKevin Lim <ktlim@umich.edu>
Tue, 12 Dec 2006 22:35:46 +0000 (17:35 -0500)
This fixes a minor bug when multiple FU completions come back out of order (due to the order in which the FUs are freed up), and the oldest redirect isn't recorded properly.  The eon benchmark should run now.

src/cpu/o3/iew_impl.hh:
    Allow for multiple redirects to happen on a single cycle (only the one for the oldest instruction is passed on to commit).

--HG--
extra : convert_revision : b7d202dee1754539ed814f0fac59adb8c6328ee1

src/cpu/o3/iew_impl.hh

index ba5260fe209c99e99b3be34f9d19da63100bf20e..76047b295353e17127700b6dd617d80c1a8c2373 100644 (file)
@@ -514,6 +514,7 @@ DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, unsigned tid)
     toCommit->squash[tid] = true;
     toCommit->squashedSeqNum[tid] = inst->seqNum;
     toCommit->nextPC[tid] = inst->readNextPC();
+    toCommit->branchMispredict[tid] = false;
 
     toCommit->includeSquashInst[tid] = false;
 
@@ -530,6 +531,7 @@ DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, unsigned tid)
     toCommit->squash[tid] = true;
     toCommit->squashedSeqNum[tid] = inst->seqNum;
     toCommit->nextPC[tid] = inst->readPC();
+    toCommit->branchMispredict[tid] = false;
 
     // Must include the broadcasted SN in the squash.
     toCommit->includeSquashInst[tid] = true;
@@ -1291,7 +1293,8 @@ DefaultIEW<Impl>::executeInsts()
                 } else if (fault != NoFault) {
                     // If the instruction faulted, then we need to send it along to commit
                     // without the instruction completing.
-                    DPRINTF(IEW, "Store has fault! [sn:%lli]\n", inst->seqNum);
+                    DPRINTF(IEW, "Store has fault %s! [sn:%lli]\n",
+                            fault->name(), inst->seqNum);
 
                     // Send this instruction to commit, also make sure iew stage
                     // realizes there is activity.
@@ -1328,7 +1331,8 @@ DefaultIEW<Impl>::executeInsts()
         // instruction first, so the branch resolution order will be correct.
         unsigned tid = inst->threadNumber;
 
-        if (!fetchRedirect[tid]) {
+        if (!fetchRedirect[tid] ||
+            toCommit->squashedSeqNum[tid] > inst->seqNum) {
 
             if (inst->mispredicted()) {
                 fetchRedirect[tid] = true;
@@ -1350,8 +1354,6 @@ DefaultIEW<Impl>::executeInsts()
                     predictedNotTakenIncorrect++;
                 }
             } else if (ldstQueue.violation(tid)) {
-                fetchRedirect[tid] = true;
-
                 // If there was an ordering violation, then get the
                 // DynInst that caused the violation.  Note that this
                 // clears the violation signal.
@@ -1362,6 +1364,14 @@ DefaultIEW<Impl>::executeInsts()
                         "%#x, inst PC: %#x.  Addr is: %#x.\n",
                         violator->readPC(), inst->readPC(), inst->physEffAddr);
 
+                // Ensure the violating instruction is older than
+                // current squash
+                if (fetchRedirect[tid] &&
+                    violator->seqNum >= toCommit->squashedSeqNum[tid])
+                    continue;
+
+                fetchRedirect[tid] = true;
+
                 // Tell the instruction queue that a violation has occured.
                 instQueue.violation(inst, violator);