summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cpu/o3/iew.hh3
-rw-r--r--src/cpu/o3/iew_impl.hh42
-rw-r--r--src/cpu/o3/lsq_unit.hh2
-rw-r--r--src/cpu/o3/lsq_unit_impl.hh3
4 files changed, 50 insertions, 0 deletions
diff --git a/src/cpu/o3/iew.hh b/src/cpu/o3/iew.hh
index 6797410d8..3c37a47ca 100644
--- a/src/cpu/o3/iew.hh
+++ b/src/cpu/o3/iew.hh
@@ -251,6 +251,9 @@ class DefaultIEW
bool ableToIssue;
+ /** Check misprediction */
+ void checkMisprediction(DynInstPtr &inst);
+
private:
/** Sends commit proper information for a squash due to a branch
* mispredict.
diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh
index 751a26afd..b53b03fe0 100644
--- a/src/cpu/o3/iew_impl.hh
+++ b/src/cpu/o3/iew_impl.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved.
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2004-2006 The Regents of The University of Michigan
* All rights reserved.
*
@@ -1585,3 +1597,33 @@ DefaultIEW<Impl>::updateExeInstStats(DynInstPtr &inst)
}
}
}
+
+template <class Impl>
+void
+DefaultIEW<Impl>::checkMisprediction(DynInstPtr &inst)
+{
+ ThreadID tid = inst->threadNumber;
+
+ if (!fetchRedirect[tid] ||
+ toCommit->squashedSeqNum[tid] > inst->seqNum) {
+
+ if (inst->mispredicted()) {
+ fetchRedirect[tid] = true;
+
+ DPRINTF(IEW, "Execute: Branch mispredict detected.\n");
+ DPRINTF(IEW, "Predicted target was PC:%#x, NPC:%#x.\n",
+ inst->readPredPC(), inst->readPredNPC());
+ DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x,"
+ " NPC: %#x.\n", inst->readNextPC(),
+ inst->readNextNPC());
+ // If incorrect, then signal the ROB that it must be squashed.
+ squashDueToBranch(inst, tid);
+
+ if (inst->readPredTaken()) {
+ predictedTakenIncorrect++;
+ } else {
+ predictedNotTakenIncorrect++;
+ }
+ }
+ }
+}
diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh
index 10b1ed11a..a9047558d 100644
--- a/src/cpu/o3/lsq_unit.hh
+++ b/src/cpu/o3/lsq_unit.hh
@@ -530,6 +530,8 @@ LSQUnit<Impl>::read(Request *req, Request *sreqLow, Request *sreqHigh,
(load_idx != loadHead || !load_inst->isAtCommit())) {
iewStage->rescheduleMemInst(load_inst);
++lsqRescheduledLoads;
+ DPRINTF(LSQUnit, "Uncachable load [sn:%lli] PC %#x\n",
+ load_inst->seqNum, load_inst->readPC());
// Must delete request now that it wasn't handed off to
// memory. This is quite ugly. @todo: Figure out the proper
diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh
index dddfb7e1b..9e6bbe92f 100644
--- a/src/cpu/o3/lsq_unit_impl.hh
+++ b/src/cpu/o3/lsq_unit_impl.hh
@@ -989,6 +989,9 @@ LSQUnit<Impl>::writeback(DynInstPtr &inst, PacketPtr pkt)
iewStage->instToCommit(inst);
iewStage->activityThisCycle();
+
+ // see if this load changed the PC
+ iewStage->checkMisprediction(inst);
}
template <class Impl>