summaryrefslogtreecommitdiff
path: root/src/cpu/o3/iew_impl.hh
diff options
context:
space:
mode:
authorGeoffrey Blake <geoffrey.blake@arm.com>2011-05-13 17:27:00 -0500
committerGeoffrey Blake <geoffrey.blake@arm.com>2011-05-13 17:27:00 -0500
commitb79650ceaaabb87f9bfe145663e2bfa3281ed7df (patch)
tree0ae613ca1d1b232300b057531ceb333074fb2845 /src/cpu/o3/iew_impl.hh
parentf7b3900c133cd8661588a03383a8c1511f8a89ff (diff)
downloadgem5-b79650ceaaabb87f9bfe145663e2bfa3281ed7df.tar.xz
O3: Fix an issue with a load & branch instruction and mem dep squashing
Instructions that load an address and are control instructions can execute down the wrong path if they were predicted correctly and then instructions following them are squashed. If an instruction is a memory and control op use the predicted address for the next PC instead of just advancing the PC. Without this change NPC is used for the next instruction, but predPC is used to verify that the branch was successful so the wrong path is silently executed.
Diffstat (limited to 'src/cpu/o3/iew_impl.hh')
-rw-r--r--src/cpu/o3/iew_impl.hh12
1 files changed, 10 insertions, 2 deletions
diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh
index 23f551ee3..3bdf1f28d 100644
--- a/src/cpu/o3/iew_impl.hh
+++ b/src/cpu/o3/iew_impl.hh
@@ -485,8 +485,16 @@ DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, ThreadID tid)
inst->seqNum < toCommit->squashedSeqNum[tid]) {
toCommit->squash[tid] = true;
toCommit->squashedSeqNum[tid] = inst->seqNum;
- TheISA::PCState pc = inst->pcState();
- TheISA::advancePC(pc, inst->staticInst);
+ TheISA::PCState pc;
+ if (inst->isMemRef() && inst->isIndirectCtrl()) {
+ // If an operation is a control operation as well as a memory
+ // reference we need to use the predicted PC, not the PC+N
+ // This instruction will verify misprediction based on predPC
+ pc = inst->readPredTarg();
+ } else {
+ pc = inst->pcState();
+ TheISA::advancePC(pc, inst->staticInst);
+ }
toCommit->pc[tid] = pc;
toCommit->mispredictInst[tid] = NULL;