summaryrefslogtreecommitdiff
path: root/src/cpu/pred/tournament.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/pred/tournament.cc')
-rw-r--r--src/cpu/pred/tournament.cc86
1 files changed, 53 insertions, 33 deletions
diff --git a/src/cpu/pred/tournament.cc b/src/cpu/pred/tournament.cc
index 9608dc011..3adafb608 100644
--- a/src/cpu/pred/tournament.cc
+++ b/src/cpu/pred/tournament.cc
@@ -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-2006 The Regents of The University of Michigan
* All rights reserved.
*
@@ -146,6 +158,18 @@ TournamentBP::updateLocalHistNotTaken(unsigned local_history_idx)
(localHistoryTable[local_history_idx] << 1);
}
+
+void
+TournamentBP::BTBUpdate(Addr &branch_addr, void * &bp_history)
+{
+ unsigned local_history_idx = calcLocHistIdx(branch_addr);
+ //Update Global History to Not Taken
+ globalHistory = globalHistory & (globalHistoryMask - 1);
+ //Update Local History to Not Taken
+ localHistoryTable[local_history_idx] =
+ localHistoryTable[local_history_idx] & (localPredictorMask - 1);
+}
+
bool
TournamentBP::lookup(Addr &branch_addr, void * &bp_history)
{
@@ -174,6 +198,7 @@ TournamentBP::lookup(Addr &branch_addr, void * &bp_history)
history->localPredTaken = local_prediction;
history->globalPredTaken = global_prediction;
history->globalUsed = choice_prediction;
+ history->localHistory = local_predictor_idx;
bp_history = (void *)history;
assert(globalHistory < globalPredictorSize &&
@@ -184,30 +209,22 @@ TournamentBP::lookup(Addr &branch_addr, void * &bp_history)
// all histories.
if (choice_prediction) {
if (global_prediction) {
-// updateHistoriesTaken(local_history_idx);
-// globalCtrs[globalHistory].increment();
-// localCtrs[local_history_idx].increment();
updateGlobalHistTaken();
+ updateLocalHistTaken(local_history_idx);
return true;
} else {
-// updateHistoriesNotTaken(local_history_idx);
-// globalCtrs[globalHistory].decrement();
-// localCtrs[local_history_idx].decrement();
updateGlobalHistNotTaken();
+ updateLocalHistNotTaken(local_history_idx);
return false;
}
} else {
if (local_prediction) {
-// updateHistoriesTaken(local_history_idx);
-// globalCtrs[globalHistory].increment();
-// localCtrs[local_history_idx].increment();
updateGlobalHistTaken();
+ updateLocalHistTaken(local_history_idx);
return true;
} else {
-// updateHistoriesNotTaken(local_history_idx);
-// globalCtrs[globalHistory].decrement();
-// localCtrs[local_history_idx].decrement();
updateGlobalHistNotTaken();
+ updateLocalHistNotTaken(local_history_idx);
return false;
}
}
@@ -222,16 +239,18 @@ TournamentBP::uncondBr(void * &bp_history)
history->localPredTaken = true;
history->globalPredTaken = true;
history->globalUsed = true;
+ history->localHistory = invalidPredictorIndex;
bp_history = static_cast<void *>(history);
updateGlobalHistTaken();
}
void
-TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history)
+TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history,
+ bool squashed)
{
unsigned local_history_idx;
- unsigned local_predictor_idx;
+ unsigned local_predictor_idx M5_VAR_USED;
unsigned local_predictor_hist;
// Get the local predictor's current prediction
@@ -259,33 +278,34 @@ TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history)
// resolution of the branch. Global history is updated
// speculatively and restored upon squash() calls, so it does not
// need to be updated.
+ unsigned old_local_pred_index = history->localHistory
+ & localPredictorMask;
if (taken) {
- localCtrs[local_predictor_idx].increment();
globalCtrs[history->globalHistory].increment();
-
- updateLocalHistTaken(local_history_idx);
+ if (old_local_pred_index != invalidPredictorIndex) {
+ localCtrs[old_local_pred_index].increment();
+ }
} else {
- localCtrs[local_predictor_idx].decrement();
globalCtrs[history->globalHistory].decrement();
-
- updateLocalHistNotTaken(local_history_idx);
+ if (old_local_pred_index != invalidPredictorIndex) {
+ localCtrs[old_local_pred_index].decrement();
+ }
}
- bool mispredict = false;
-
- //global predictor used and mispredicted
- if (history->globalUsed && history->globalPredTaken != taken)
- mispredict = true;
- //local predictor used and mispredicted
- else if (!history->globalUsed && history->localPredTaken != taken)
- mispredict = true;
-
- if (mispredict) {
+ if (squashed) {
if (taken) {
- globalHistory = globalHistory | 1;
+ globalHistory = (history->globalHistory << 1) | 1;
+ globalHistory = globalHistory & globalHistoryMask;
+ if (history->localHistory != invalidPredictorIndex)
+ localHistoryTable[local_history_idx] =
+ (history->localHistory << 1) | 1;
} else {
- unsigned mask = globalHistoryMask - 1;
- globalHistory = globalHistory & mask;
+ globalHistory = (history->globalHistory << 1);
+ globalHistory = globalHistory & globalHistoryMask;
+ if (history->localHistory != invalidPredictorIndex) {
+ localHistoryTable[local_history_idx] =
+ history->localHistory << 1;
+ }
}
}