O3 CPU: Provide the squashing instruction
authorNilay Vaish <nilay@cs.wisc.edu>
Fri, 10 Feb 2012 14:37:28 +0000 (08:37 -0600)
committerNilay Vaish <nilay@cs.wisc.edu>
Fri, 10 Feb 2012 14:37:28 +0000 (08:37 -0600)
This patch adds a function to the ROB that will get the squashing instruction
from the ROB's list of instructions. This squashing instruction is used for
figuring out the macroop from which the fetch stage should fetch the microops.
Further, a check has been added that if the instructions are to be fetched
from the cache maintained by the fetch stage, then the data in the cache should
be valid and the PC of the thread being fetched from is same as the address of
the cache block.

src/cpu/o3/commit_impl.hh
src/cpu/o3/fetch_impl.hh
src/cpu/o3/rob.hh
src/cpu/o3/rob_impl.hh

index edf7e861b3b5b42ec96ad6f2965a3055ca09e837..a9b7959331e8aa68e6f1f2bec52061fc1ee3dd9a 100644 (file)
@@ -856,7 +856,8 @@ DefaultCommit<Impl>::commit()
                 fromIEW->mispredictInst[tid];
             toIEW->commitInfo[tid].branchTaken =
                 fromIEW->branchTaken[tid];
-            toIEW->commitInfo[tid].squashInst = NULL;
+            toIEW->commitInfo[tid].squashInst =
+                                    rob->findInst(tid, squashed_inst);
 
             toIEW->commitInfo[tid].pc = fromIEW->pc[tid];
 
index c8f7b0181bdfd5ec2a3592886482728c3079b739..48c21917a7844ab3ac986f474522cf8ab8467e71 100644 (file)
@@ -1189,8 +1189,15 @@ DefaultFetch<Impl>::fetch(bool &status_change)
         // StaticInst from the rom, the current macroop, or what's already
         // in the predecoder.
         bool needMem = !inRom && !curMacroop && !predecoder.extMachInstReady();
+        fetchAddr = (thisPC.instAddr() + pcOffset) & BaseCPU::PCMask;
+        Addr block_PC = icacheBlockAlignPC(fetchAddr);
 
         if (needMem) {
+            // If buffer is no longer valid or fetchAddr has moved to point
+            // to the next cache block then start fetch from icache.
+            if (!cacheDataValid[tid] || block_PC != cacheDataPC[tid])
+                break;
+
             if (blkOffset >= numInsts) {
                 // We need to process more memory, but we've run out of the
                 // current block.
index fadd99849685aacaba50d5c04632ed141c3f5e3a..d0b15695416a869428e67e751b7ebc7adfe2fc77 100644 (file)
@@ -122,6 +122,11 @@ class ROB
      */
     DynInstPtr readHeadInst(ThreadID tid);
 
+    /** Returns a pointer to the instruction with the given sequence if it is
+     *  in the ROB.
+     */
+    DynInstPtr findInst(ThreadID tid, InstSeqNum squash_inst);
+
     /** Returns pointer to the tail instruction within the ROB.  There is
      *  no guarantee as to the return value if the ROB is empty.
      *  @retval Pointer to the DynInst that is at the tail of the ROB.
index 0484f519c2466128814bbaacfdc0f260e1a3f29e..ee4a9e5763eb85e21b9fd4eb7528df2a686c7d4c 100644 (file)
@@ -544,3 +544,14 @@ ROB<Impl>::regStats()
         .desc("The number of ROB writes");
 }
 
+template <class Impl>
+typename Impl::DynInstPtr
+ROB<Impl>::findInst(ThreadID tid, InstSeqNum squash_inst)
+{
+    for (InstIt it = instList[tid].begin(); it != instList[tid].end(); it++) {
+        if ((*it)->seqNum == squash_inst) {
+            return *it;
+        }
+    }
+    return NULL;
+}