diff options
Diffstat (limited to 'src/cpu/o3')
-rw-r--r-- | src/cpu/o3/bpred_unit.hh | 14 | ||||
-rw-r--r-- | src/cpu/o3/bpred_unit_impl.hh | 63 | ||||
-rw-r--r-- | src/cpu/o3/commit_impl.hh | 7 | ||||
-rw-r--r-- | src/cpu/o3/decode_impl.hh | 4 |
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; |