diff -r 90a9d710f759 -r 84bc3ada672c src/cpu/pred/base.hh --- a/src/cpu/pred/base.hh Sat Jul 10 01:55:00 2010 +0100 +++ b/src/cpu/pred/base.hh Sat Jul 10 02:11:39 2010 +0100 @@ -38,6 +38,7 @@ #include "base/statistics.hh" #include "base/types.hh" #include "cpu/inst_seq.hh" +#include "cpu/static_inst.hh" #include "params/BaseBPredUnit.hh" #include "sim/sim_object.hh" @@ -55,6 +56,13 @@ * @param params The params object, that has the size of the BP. */ BaseBPredUnit(const Params *params); + + /** + * Warm the branch predictor by making predictions for a branch and + * then immediately updating depending on whether it was correct or not. + */ + virtual void + warm(StaticInstPtr inst, Addr PC, Addr target, ThreadID tid) = 0; }; #endif // __CPU_PRED_BASE_HH__ diff -r 90a9d710f759 -r 84bc3ada672c src/cpu/pred/bpred_unit.hh --- a/src/cpu/pred/bpred_unit.hh Sat Jul 10 01:55:00 2010 +0100 +++ b/src/cpu/pred/bpred_unit.hh Sat Jul 10 02:11:39 2010 +0100 @@ -43,6 +43,7 @@ #include "cpu/pred/btb.hh" #include "cpu/pred/ras.hh" #include "cpu/pred/tournament.hh" +#include "cpu/static_inst.hh" /** * A branch predictor based on the base class. This is templated by the @@ -120,6 +121,12 @@ bool actually_taken, ThreadID tid); /** + * Warm the branch predictor by making predictions for a branch and + * then immediately updating depending on whether it was correct or not. + */ + virtual void warm(StaticInstPtr inst, Addr PC, Addr target, ThreadID tid); + + /** * @param bp_history Pointer to the history object. The predictor * will need to update any state and delete the object. */ diff -r 90a9d710f759 -r 84bc3ada672c src/cpu/pred/bpred_unit_impl.hh --- a/src/cpu/pred/bpred_unit_impl.hh Sat Jul 10 01:55:00 2010 +0100 +++ b/src/cpu/pred/bpred_unit_impl.hh Sat Jul 10 02:11:39 2010 +0100 @@ -38,6 +38,7 @@ #include "base/traceflags.hh" #include "config/the_isa.hh" #include "cpu/pred/bpred_unit.hh" +#include "cpu/static_inst.hh" template BPredUnit::BPredUnit(const Params *params) @@ -366,6 +367,46 @@ template void +BPredUnit::warm(StaticInstPtr inst, Addr PC, Addr target, ThreadID tid) +{ + using TheISA::MachInst; + + bool predTaken = false; + void *bpHistory = NULL; + + // Get a prediction from the predictor. + if (inst->isUncondCtrl()) { + predTaken = true; + BPUncond(bpHistory); + } else { + predTaken = BPLookup(PC, bpHistory); + } + + // Keep the RAS correct. + if (inst->isReturn()) { + RAS[tid].pop(); + } else { + if (inst->isCall()) { +#if ISA_HAS_DELAY_SLOT + Addr ras_pc = PC + (2 * sizeof(MachInst)); // Next Next PC +#else + Addr ras_pc = PC + sizeof(MachInst); // Next PC +#endif + RAS[tid].push(ras_pc); + } + + // And keep the BTB correct too. + if (target != PC + sizeof(MachInst)) { + BTB.update(PC, target, tid); + } + } + + // Update the predictor and BTB with the correct results. + BPUpdate(PC, predTaken, bpHistory); +} + +template +void BPredUnit::BPUncond(void * &bp_history) { // Only the tournament predictor cares about unconditional branches. diff -r 90a9d710f759 -r 84bc3ada672c src/cpu/simple/BaseSimpleCPU.py --- a/src/cpu/simple/BaseSimpleCPU.py Sat Jul 10 01:55:00 2010 +0100 +++ b/src/cpu/simple/BaseSimpleCPU.py Sat Jul 10 02:11:39 2010 +0100 @@ -28,7 +28,9 @@ from m5.params import * from BaseCPU import BaseCPU +from BaseBPredUnit import BaseBPredUnit class BaseSimpleCPU(BaseCPU): type = 'BaseSimpleCPU' abstract = True + branchPred = Param.BaseBPredUnit(NULL, "Branch Predictor") diff -r 90a9d710f759 -r 84bc3ada672c src/cpu/simple/base.hh --- a/src/cpu/simple/base.hh Sat Jul 10 01:55:00 2010 +0100 +++ b/src/cpu/simple/base.hh Sat Jul 10 02:11:39 2010 +0100 @@ -40,6 +40,7 @@ #include "cpu/base.hh" #include "cpu/simple_thread.hh" #include "cpu/pc_event.hh" +#include "cpu/pred/base.hh" #include "cpu/static_inst.hh" #include "mem/packet.hh" #include "mem/port.hh" @@ -118,6 +119,7 @@ * objects to modify this thread's state. */ ThreadContext *tc; + protected: enum Status { @@ -150,6 +152,9 @@ // The predecoder TheISA::Predecoder predecoder; + /** The branch predictor for this CPU to warm. */ + BaseBPredUnit *branchPred; + StaticInstPtr curStaticInst; StaticInstPtr curMacroStaticInst; diff -r 90a9d710f759 -r 84bc3ada672c src/cpu/simple/base.cc --- a/src/cpu/simple/base.cc Sat Jul 10 01:55:00 2010 +0100 +++ b/src/cpu/simple/base.cc Sat Jul 10 02:11:39 2010 +0100 @@ -54,6 +54,7 @@ #include "config/the_isa.hh" #include "cpu/base.hh" #include "cpu/exetrace.hh" +#include "cpu/pred/base.hh" #include "cpu/profile.hh" #include "cpu/simple/base.hh" #include "cpu/simple_thread.hh" @@ -83,7 +84,8 @@ using namespace TheISA; BaseSimpleCPU::BaseSimpleCPU(BaseSimpleCPUParams *p) - : BaseCPU(p), traceData(NULL), thread(NULL), predecoder(NULL) + : BaseCPU(p), traceData(NULL), thread(NULL), predecoder(NULL), + branchPred(p->branchPred) { #if FULL_SYSTEM thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb); @@ -489,6 +491,12 @@ CPA::cpa()->swAutoBegin(tc, thread->readNextPC()); } + // Warm the branch predictor if it exists. + if (branchPred && curStaticInst->isControl()) { + branchPred->warm(curStaticInst, thread->readPC(), + thread->readNextPC(), thread->threadId()); + } + traceFunctions(thread->readPC()); if (traceData) {