* Authors: Kevin Lim
*/
+#include "cpu/pred/2bit_local.hh"
+
#include "base/intmath.hh"
#include "base/misc.hh"
#include "base/trace.hh"
-#include "cpu/pred/2bit_local.hh"
+#include "debug/Fetch.hh"
-LocalBP::LocalBP(unsigned _localPredictorSize,
- unsigned _localCtrBits,
- unsigned _instShiftAmt)
- : localPredictorSize(_localPredictorSize),
- localCtrBits(_localCtrBits),
- instShiftAmt(_instShiftAmt)
+LocalBP::LocalBP(const LocalBPParams *params)
+ : BPredUnit(params),
+ localPredictorSize(params->localPredictorSize),
+ localCtrBits(params->localCtrBits)
{
if (!isPowerOf2(localPredictorSize)) {
fatal("Invalid local predictor size!\n");
// Setup the index mask.
indexMask = localPredictorSets - 1;
- DPRINTF(Fetch, "Branch predictor: index mask: %#x\n", indexMask);
+ DPRINTF(Fetch, "index mask: %#x\n", indexMask);
// Setup the array of counters for the local predictor.
localCtrs.resize(localPredictorSets);
- for (int i = 0; i < localPredictorSets; ++i)
- localCtrs[i].setBits(_localCtrBits);
+ for (unsigned i = 0; i < localPredictorSets; ++i)
+ localCtrs[i].setBits(localCtrBits);
- DPRINTF(Fetch, "Branch predictor: local predictor size: %i\n",
+ DPRINTF(Fetch, "local predictor size: %i\n",
localPredictorSize);
- DPRINTF(Fetch, "Branch predictor: local counter bits: %i\n", localCtrBits);
+ DPRINTF(Fetch, "local counter bits: %i\n", localCtrBits);
- DPRINTF(Fetch, "Branch predictor: instruction shift amount: %i\n",
+ DPRINTF(Fetch, "instruction shift amount: %i\n",
instShiftAmt);
}
void
LocalBP::reset()
{
- for (int i = 0; i < localPredictorSets; ++i) {
+ for (unsigned i = 0; i < localPredictorSets; ++i) {
localCtrs[i].reset();
}
}
+void
+LocalBP::btbUpdate(ThreadID tid, Addr branch_addr, void * &bp_history)
+{
+// Place holder for a function that is called to update predictor history when
+// a BTB entry is invalid or not found.
+}
+
+
bool
-LocalBP::lookup(Addr &branch_addr, void * &bp_history)
+LocalBP::lookup(ThreadID tid, Addr branch_addr, void * &bp_history)
{
bool taken;
uint8_t counter_val;
unsigned local_predictor_idx = getLocalIndex(branch_addr);
- DPRINTF(Fetch, "Branch predictor: Looking up index %#x\n",
+ DPRINTF(Fetch, "Looking up index %#x\n",
local_predictor_idx);
counter_val = localCtrs[local_predictor_idx].read();
- DPRINTF(Fetch, "Branch predictor: prediction is %i.\n",
+ DPRINTF(Fetch, "prediction is %i.\n",
(int)counter_val);
taken = getPrediction(counter_val);
#if 0
// Speculative update.
if (taken) {
- DPRINTF(Fetch, "Branch predictor: Branch updated as taken.\n");
+ DPRINTF(Fetch, "Branch updated as taken.\n");
localCtrs[local_predictor_idx].increment();
} else {
- DPRINTF(Fetch, "Branch predictor: Branch updated as not taken.\n");
+ DPRINTF(Fetch, "Branch updated as not taken.\n");
localCtrs[local_predictor_idx].decrement();
}
#endif
}
void
-LocalBP::update(Addr &branch_addr, bool taken, void *bp_history)
+LocalBP::update(ThreadID tid, Addr branch_addr, bool taken, void *bp_history,
+ bool squashed)
{
assert(bp_history == NULL);
unsigned local_predictor_idx;
+ // No state to restore, and we do not update on the wrong
+ // path.
+ if (squashed) {
+ return;
+ }
+
// Update the local predictor.
local_predictor_idx = getLocalIndex(branch_addr);
- DPRINTF(Fetch, "Branch predictor: Looking up index %#x\n",
- local_predictor_idx);
+ DPRINTF(Fetch, "Looking up index %#x\n", local_predictor_idx);
if (taken) {
- DPRINTF(Fetch, "Branch predictor: Branch updated as taken.\n");
+ DPRINTF(Fetch, "Branch updated as taken.\n");
localCtrs[local_predictor_idx].increment();
} else {
- DPRINTF(Fetch, "Branch predictor: Branch updated as not taken.\n");
+ DPRINTF(Fetch, "Branch updated as not taken.\n");
localCtrs[local_predictor_idx].decrement();
}
}
{
return (branch_addr >> instShiftAmt) & indexMask;
}
+
+void
+LocalBP::uncondBranch(ThreadID tid, Addr pc, void *&bp_history)
+{
+}
+
+LocalBP*
+LocalBPParams::create()
+{
+ return new LocalBP(this);
+}