summaryrefslogtreecommitdiff
path: root/src/cpu/o3
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/o3')
-rw-r--r--src/cpu/o3/bpred_unit.hh14
-rw-r--r--src/cpu/o3/bpred_unit_impl.hh63
-rw-r--r--src/cpu/o3/commit_impl.hh7
-rw-r--r--src/cpu/o3/decode_impl.hh4
4 files changed, 73 insertions, 15 deletions
diff --git a/src/cpu/o3/bpred_unit.hh b/src/cpu/o3/bpred_unit.hh
index 8dbba9085..d3ae93b38 100644
--- a/src/cpu/o3/bpred_unit.hh
+++ b/src/cpu/o3/bpred_unit.hh
@@ -137,6 +137,16 @@ class BPredUnit
*/
bool BPLookup(Addr instPC, void * &bp_history);
+ /**
+ * If a branch is not taken, because the BTB address is invalid or missing,
+ * this function sets the appropriate counter in the global and local
+ * predictors to not taken.
+ * @param inst_PC The PC to look up the local predictor.
+ * @param bp_history Pointer that will be set to an object that
+ * has the branch predictor state associated with the lookup.
+ */
+ void BPBTBUpdate(Addr instPC, void * &bp_history);
+
/**
* Looks up a given PC in the BTB to see if a matching entry exists.
* @param inst_PC The PC to look up.
@@ -159,9 +169,11 @@ class BPredUnit
* @param taken Whether the branch was taken or not taken.
* @param bp_history Pointer to the branch predictor state that is
* associated with the branch lookup that is being updated.
+ * @param squashed Set to true when this function is called during a
+ * squash operation.
* @todo Make this update flexible enough to handle a global predictor.
*/
- void BPUpdate(Addr instPC, bool taken, void *bp_history);
+ void BPUpdate(Addr instPC, bool taken, void *bp_history, bool squashed);
/**
* Updates the BTB with the target of a branch.
diff --git a/src/cpu/o3/bpred_unit_impl.hh b/src/cpu/o3/bpred_unit_impl.hh
index e0292e232..8502f342c 100644
--- a/src/cpu/o3/bpred_unit_impl.hh
+++ b/src/cpu/o3/bpred_unit_impl.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2011 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-2005 The Regents of The University of Michigan
* All rights reserved.
*
@@ -166,12 +178,11 @@ BPredUnit<Impl>::predict(DynInstPtr &inst, TheISA::PCState &pc, ThreadID tid)
BPUncond(bp_history);
} else {
++condPredicted;
-
pred_taken = BPLookup(pc.instAddr(), bp_history);
- DPRINTF(Fetch, "BranchPred: [tid:%i]: Branch predictor predicted %i "
- "for PC %s\n",
- tid, pred_taken, inst->pcState());
+ DPRINTF(Fetch, "BranchPred:[tid:%i]: [sn:%i] Branch predictor"
+ " predicted %i for PC %s\n",
+ tid, inst->seqNum, pred_taken, inst->pcState());
}
DPRINTF(Fetch, "BranchPred: [tid:%i]: [sn:%i] Creating prediction history "
@@ -231,6 +242,15 @@ BPredUnit<Impl>::predict(DynInstPtr &inst, TheISA::PCState &pc, ThreadID tid)
DPRINTF(Fetch, "BranchPred: [tid:%i]: BTB doesn't have a "
"valid entry.\n",tid);
pred_taken = false;
+ // The Direction of the branch predictor is altered because the
+ // BTB did not have an entry
+ // The predictor needs to be updated accordingly
+ if (!inst->isCall() && !inst->isReturn()) {
+ BPBTBUpdate(pc.instAddr(), bp_history);
+ DPRINTF(Fetch, "BranchPred: [tid:%i]:[sn:%i] BPBTBUpdate"
+ " called for %s\n",
+ tid, inst->seqNum, inst->pcState());
+ }
TheISA::advancePC(target, inst->staticInst);
}
@@ -261,7 +281,7 @@ BPredUnit<Impl>::update(const InstSeqNum &done_sn, ThreadID tid)
// Update the branch predictor with the correct results.
BPUpdate(predHist[tid].back().pc,
predHist[tid].back().predTaken,
- predHist[tid].back().bpHistory);
+ predHist[tid].back().bpHistory, false);
predHist[tid].pop_back();
}
@@ -356,12 +376,15 @@ BPredUnit<Impl>::squash(const InstSeqNum &squashed_sn,
}
BPUpdate((*hist_it).pc, actually_taken,
- pred_hist.front().bpHistory);
-
- BTB.update((*hist_it).pc, corrTarget, tid);
-
- DPRINTF(Fetch, "BranchPred: [tid:%i]: Removing history for [sn:%i] "
- "PC %s.\n", tid, (*hist_it).seqNum, (*hist_it).pc);
+ pred_hist.front().bpHistory, true);
+ if (actually_taken){
+ DPRINTF(Fetch,"BranchPred: [tid: %i] BTB Update called for [sn:%i]"
+ " PC: %s\n", tid,(*hist_it).seqNum, (*hist_it).pc);
+ BTB.update((*hist_it).pc, corrTarget, tid);
+ }
+ DPRINTF(Fetch, "BranchPred: [tid:%i]: Removing history for [sn:%i]"
+ " PC %s Actually Taken: %i\n", tid, (*hist_it).seqNum,
+ (*hist_it).pc, actually_taken);
pred_hist.erase(hist_it);
@@ -407,12 +430,26 @@ BPredUnit<Impl>::BPLookup(Addr instPC, void * &bp_history)
template <class Impl>
void
-BPredUnit<Impl>::BPUpdate(Addr instPC, bool taken, void *bp_history)
+BPredUnit<Impl>::BPBTBUpdate(Addr instPC, void * &bp_history)
+{
+ if (predictor == Local) {
+ return localBP->BTBUpdate(instPC, bp_history);
+ } else if (predictor == Tournament) {
+ return tournamentBP->BTBUpdate(instPC, bp_history);
+ } else {
+ panic("Predictor type is unexpected value!");
+ }
+}
+
+template <class Impl>
+void
+BPredUnit<Impl>::BPUpdate(Addr instPC, bool taken, void *bp_history,
+ bool squashed)
{
if (predictor == Local) {
localBP->update(instPC, taken, bp_history);
} else if (predictor == Tournament) {
- tournamentBP->update(instPC, taken, bp_history);
+ tournamentBP->update(instPC, taken, bp_history, squashed);
} else {
panic("Predictor type is unexpected value!");
}
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh
index 7ca42ae5b..b4cc4b017 100644
--- a/src/cpu/o3/commit_impl.hh
+++ b/src/cpu/o3/commit_impl.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 ARM Limited
+ * Copyright (c) 2010-2011 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -868,6 +868,11 @@ DefaultCommit<Impl>::commit()
fromIEW->branchTaken[tid];
toIEW->commitInfo[tid].squashInst =
rob->findInst(tid, squashed_inst);
+ if (toIEW->commitInfo[tid].mispredictInst) {
+ if (toIEW->commitInfo[tid].mispredictInst->isUncondCtrl()) {
+ toIEW->commitInfo[tid].branchTaken = true;
+ }
+ }
toIEW->commitInfo[tid].pc = fromIEW->pc[tid];
diff --git a/src/cpu/o3/decode_impl.hh b/src/cpu/o3/decode_impl.hh
index 60bca1041..22b89f4a8 100644
--- a/src/cpu/o3/decode_impl.hh
+++ b/src/cpu/o3/decode_impl.hh
@@ -278,11 +278,15 @@ DefaultDecode<Impl>::squash(DynInstPtr &inst, ThreadID tid)
// Send back mispredict information.
toFetch->decodeInfo[tid].branchMispredict = true;
toFetch->decodeInfo[tid].predIncorrect = true;
+ toFetch->decodeInfo[tid].mispredictInst = inst;
toFetch->decodeInfo[tid].squash = true;
toFetch->decodeInfo[tid].doneSeqNum = inst->seqNum;
toFetch->decodeInfo[tid].nextPC = inst->branchTarget();
toFetch->decodeInfo[tid].branchTaken = inst->pcState().branching();
toFetch->decodeInfo[tid].squashInst = inst;
+ if (toFetch->decodeInfo[tid].mispredictInst->isUncondCtrl()) {
+ toFetch->decodeInfo[tid].branchTaken = true;
+ }
InstSeqNum squash_seq_num = inst->seqNum;