summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNilay Vaish <nilay@cs.wisc.edu>2012-02-10 08:37:28 -0600
committerNilay Vaish <nilay@cs.wisc.edu>2012-02-10 08:37:28 -0600
commit8f7e03d4cf4810fa3e09b134c2cf5b6df78a39b0 (patch)
tree40f6b9425dd1b0d2c2f622abc1a8c254ab0cec01
parent0e597e944ae0cf368df06235e832bc441cb4e022 (diff)
downloadgem5-8f7e03d4cf4810fa3e09b134c2cf5b6df78a39b0.tar.xz
O3 CPU: Provide the squashing instruction
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.
-rw-r--r--src/cpu/o3/commit_impl.hh3
-rw-r--r--src/cpu/o3/fetch_impl.hh7
-rw-r--r--src/cpu/o3/rob.hh5
-rw-r--r--src/cpu/o3/rob_impl.hh11
4 files changed, 25 insertions, 1 deletions
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh
index edf7e861b..a9b795933 100644
--- a/src/cpu/o3/commit_impl.hh
+++ b/src/cpu/o3/commit_impl.hh
@@ -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];
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index c8f7b0181..48c21917a 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -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.
diff --git a/src/cpu/o3/rob.hh b/src/cpu/o3/rob.hh
index fadd99849..d0b156954 100644
--- a/src/cpu/o3/rob.hh
+++ b/src/cpu/o3/rob.hh
@@ -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.
diff --git a/src/cpu/o3/rob_impl.hh b/src/cpu/o3/rob_impl.hh
index 0484f519c..ee4a9e576 100644
--- a/src/cpu/o3/rob_impl.hh
+++ b/src/cpu/o3/rob_impl.hh
@@ -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;
+}