#include "cpu/checker/cpu.hh"
#include "cpu/checker/thread_context.hh"
#include "cpu/exetrace.hh"
+#include "cpu/pred/bpred_unit.hh"
#include "cpu/profile.hh"
#include "cpu/simple_thread.hh"
#include "cpu/smt.hh"
using namespace TheISA;
BaseSimpleCPU::BaseSimpleCPU(BaseSimpleCPUParams *p)
- : BaseCPU(p), traceData(NULL), thread(NULL)
+ : BaseCPU(p),
+ branchPred(p->branchPred),
+ traceData(NULL), thread(NULL)
{
if (FullSystem)
thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb,
idleFraction = constant(1.0) - notIdleFraction;
numIdleCycles = idleFraction * numCycles;
numBusyCycles = (notIdleFraction)*numCycles;
+
+ numBranches
+ .name(name() + ".Branches")
+ .desc("Number of branches fetched")
+ .prereq(numBranches);
+
+ numPredictedBranches
+ .name(name() + ".predictedBranches")
+ .desc("Number of branches predicted as taken")
+ .prereq(numPredictedBranches);
+
+ numBranchMispred
+ .name(name() + ".BranchMispred")
+ .desc("Number of branch mispredictions")
+ .prereq(numBranchMispred);
}
void
curStaticInst->getName(), curStaticInst->machInst);
#endif // TRACING_ON
}
+
+ if (branchPred && curStaticInst && curStaticInst->isControl()) {
+ // Use a fake sequence number since we only have one
+ // instruction in flight at the same time.
+ const InstSeqNum cur_sn(0);
+ const ThreadID tid(0);
+ pred_pc = thread->pcState();
+ const bool predict_taken(
+ branchPred->predict(curStaticInst, cur_sn, pred_pc, tid));
+
+ if (predict_taken)
+ ++numPredictedBranches;
+ }
}
void
CPA::cpa()->swAutoBegin(tc, pc.nextInstAddr());
}
+ if (curStaticInst->isControl()) {
+ ++numBranches;
+ }
+
/* Power model statistics */
//integer alu accesses
if (curStaticInst->isInteger()){
}
}
-
void
BaseSimpleCPU::advancePC(Fault fault)
{
+ const bool branching(thread->pcState().branching());
+
//Since we're moving to a new pc, zero out the offset
fetchOffset = 0;
if (fault != NoFault) {
thread->pcState(pcState);
}
}
+
+ if (branchPred && curStaticInst && curStaticInst->isControl()) {
+ // Use a fake sequence number since we only have one
+ // instruction in flight at the same time.
+ const InstSeqNum cur_sn(0);
+ const ThreadID tid(0);
+
+ if (pred_pc == thread->pcState()) {
+ // Correctly predicted branch
+ branchPred->update(cur_sn, tid);
+ } else {
+ // Mis-predicted branch
+ branchPred->squash(cur_sn, pcState(),
+ branching, tid);
+ ++numBranchMispred;
+ }
+ }
}
void
}
struct BaseSimpleCPUParams;
-
+class BPredUnit;
class BaseSimpleCPU : public BaseCPU
{
typedef TheISA::FloatRegBits FloatRegBits;
typedef TheISA::CCReg CCReg;
+ BPredUnit *branchPred;
+
protected:
Trace::InstRecord *traceData;
Stats::Scalar dcacheRetryCycles;
Counter lastDcacheRetry;
+ /// @{
+ /// Total number of branches fetched
+ Stats::Scalar numBranches;
+ /// Number of branches predicted as taken
+ Stats::Scalar numPredictedBranches;
+ /// Number of misprediced branches
+ Stats::Scalar numBranchMispred;
+ /// @}
+
void serializeThread(std::ostream &os, ThreadID tid);
void unserializeThread(Checkpoint *cp, const std::string §ion,
ThreadID tid);
bool misspeculating() { return thread->misspeculating(); }
ThreadContext *tcBase() { return tc; }
+
+ private:
+ TheISA::PCState pred_pc;
};
#endif // __CPU_SIMPLE_BASE_HH__