/*
+ * Copyright (c) 2011, 2014 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.
*
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Kevin Lim
+ * Timothy M. Jones
+ * Nilay Vaish
*/
-#ifndef __CPU_O3_TOURNAMENT_PRED_HH__
-#define __CPU_O3_TOURNAMENT_PRED_HH__
+#ifndef __CPU_PRED_TOURNAMENT_PRED_HH__
+#define __CPU_PRED_TOURNAMENT_PRED_HH__
#include <vector>
#include "base/types.hh"
-#include "cpu/o3/sat_counter.hh"
+#include "cpu/pred/bpred_unit.hh"
+#include "cpu/pred/sat_counter.hh"
+#include "params/TournamentBP.hh"
/**
* Implements a tournament branch predictor, hopefully identical to the one
* used in the 21264. It has a local predictor, which uses a local history
* table to index into a table of counters, and a global predictor, which
* uses a global history to index into a table of counters. A choice
- * predictor chooses between the two. Only the global history register
- * is speculatively updated, the rest are updated upon branches committing
- * or misspeculating.
+ * predictor chooses between the two. Both the global history register
+ * and the selected local history are speculatively updated.
*/
-class TournamentBP
+class TournamentBP : public BPredUnit
{
public:
/**
* Default branch predictor constructor.
*/
- TournamentBP(unsigned localPredictorSize,
- unsigned localCtrBits,
- unsigned localHistoryTableSize,
- unsigned localHistoryBits,
- unsigned globalPredictorSize,
- unsigned globalHistoryBits,
- unsigned globalCtrBits,
- unsigned choicePredictorSize,
- unsigned choiceCtrBits,
- unsigned instShiftAmt);
+ TournamentBP(const TournamentBPParams *params);
/**
* Looks up the given address in the branch predictor and returns
* @param bp_history Pointer that will be set to the BPHistory object.
* @return Whether or not the branch is taken.
*/
- bool lookup(Addr &branch_addr, void * &bp_history);
+ bool lookup(ThreadID tid, Addr branch_addr, void * &bp_history);
/**
* Records that there was an unconditional branch, and modifies
* global history stored in it.
* @param bp_history Pointer that will be set to the BPHistory object.
*/
- void uncondBr(void * &bp_history);
-
+ void uncondBranch(ThreadID tid, Addr pc, void * &bp_history);
+ /**
+ * Updates the branch predictor to Not Taken if a BTB entry is
+ * invalid or not found.
+ * @param branch_addr The address of the branch to look up.
+ * @param bp_history Pointer to any bp history state.
+ * @return Whether or not the branch is taken.
+ */
+ void btbUpdate(ThreadID tid, Addr branch_addr, void * &bp_history);
/**
* Updates the branch predictor with the actual result of a branch.
* @param branch_addr The address of the branch to update.
* @param taken Whether or not the branch was taken.
* @param bp_history Pointer to the BPHistory object that was created
* when the branch was predicted.
+ * @param squashed is set when this function is called during a squash
+ * operation.
*/
- void update(Addr &branch_addr, bool taken, void *bp_history);
+ void update(ThreadID tid, Addr branch_addr, bool taken, void *bp_history,
+ bool squashed);
/**
* Restores the global branch history on a squash.
* @param bp_history Pointer to the BPHistory object that has the
* previous global branch history in it.
*/
- void squash(void *bp_history);
+ void squash(ThreadID tid, void *bp_history);
- /** Returns the global history. */
- inline unsigned readGlobalHist() { return globalHistory; }
+ unsigned getGHR(ThreadID tid, void *bp_history) const;
private:
/**
inline unsigned calcLocHistIdx(Addr &branch_addr);
/** Updates global history as taken. */
- inline void updateGlobalHistTaken();
+ inline void updateGlobalHistTaken(ThreadID tid);
/** Updates global history as not taken. */
- inline void updateGlobalHistNotTaken();
+ inline void updateGlobalHistNotTaken(ThreadID tid);
/**
* Updates local histories as taken.
static int newCount;
#endif
unsigned globalHistory;
+ unsigned localHistoryIdx;
+ unsigned localHistory;
bool localPredTaken;
bool globalPredTaken;
bool globalUsed;
};
+ /** Flag for invalid predictor index */
+ static const int invalidPredictorIndex = -1;
/** Local counters. */
std::vector<SatCounter> localCtrs;
- /** Size of the local predictor. */
+ /** Number of counters in the local predictor. */
unsigned localPredictorSize;
- /** Mask to get the proper index bits into the predictor. */
+ /** Mask to truncate values stored in the local history table. */
unsigned localPredictorMask;
/** Number of bits of the local predictor's counters. */
/** Array of local history table entries. */
std::vector<unsigned> localHistoryTable;
- /** Size of the local history table. */
+ /** Number of entries in the local history table. */
unsigned localHistoryTableSize;
- /** Number of bits for each entry of the local history table.
- * @todo Doesn't this come from the size of the local predictor?
- */
+ /** Number of bits for each entry of the local history table. */
unsigned localHistoryBits;
- /** Mask to get the proper local history. */
- unsigned localHistoryMask;
-
/** Array of counters that make up the global predictor. */
std::vector<SatCounter> globalCtrs;
- /** Size of the global predictor. */
+ /** Number of entries in the global predictor. */
unsigned globalPredictorSize;
/** Number of bits of the global predictor's counters. */
unsigned globalCtrBits;
- /** Global history register. */
- unsigned globalHistory;
+ /** Global history register. Contains as much history as specified by
+ * globalHistoryBits. Actual number of bits used is determined by
+ * globalHistoryMask and choiceHistoryMask. */
+ std::vector<unsigned> globalHistory;
- /** Number of bits for the global history. */
+ /** Number of bits for the global history. Determines maximum number of
+ entries in global and choice predictor tables. */
unsigned globalHistoryBits;
- /** Mask to get the proper global history. */
+ /** Mask to apply to globalHistory to access global history table.
+ * Based on globalPredictorSize.*/
unsigned globalHistoryMask;
+ /** Mask to apply to globalHistory to access choice history table.
+ * Based on choicePredictorSize.*/
+ unsigned choiceHistoryMask;
+
+ /** Mask to control how much history is stored. All of it might not be
+ * used. */
+ unsigned historyRegisterMask;
+
/** Array of counters that make up the choice predictor. */
std::vector<SatCounter> choiceCtrs;
- /** Size of the choice predictor (identical to the global predictor). */
+ /** Number of entries in the choice predictor. */
unsigned choicePredictorSize;
- /** Number of bits of the choice predictor's counters. */
+ /** Number of bits in the choice predictor's counters. */
unsigned choiceCtrBits;
- /** Number of bits to shift the instruction over to get rid of the word
- * offset.
- */
- unsigned instShiftAmt;
-
- /** Threshold for the counter value; above the threshold is taken,
+ /** Thresholds for the counter value; above the threshold is taken,
* equal to or below the threshold is not taken.
*/
- unsigned threshold;
+ unsigned localThreshold;
+ unsigned globalThreshold;
+ unsigned choiceThreshold;
};
-#endif // __CPU_O3_TOURNAMENT_PRED_HH__
+#endif // __CPU_PRED_TOURNAMENT_PRED_HH__