summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
authorNathanael Premillieu <npremill@irisa.fr>2012-06-29 11:18:29 -0400
committerNathanael Premillieu <npremill@irisa.fr>2012-06-29 11:18:29 -0400
commitaf2b14a362281f36347728e13dcd6b2c4d3c4991 (patch)
tree4fc534d9f8ebdc693a90a3dc4a8ce185c6b093f6 /src/cpu
parent71daeb0b2b390f5f5a34addd3993f28851c91d72 (diff)
downloadgem5-af2b14a362281f36347728e13dcd6b2c4d3c4991.tar.xz
O3: Track if the RAS has been pushed or not to pop the RAS if neccessary.
Add new flag (named pushedRAS) in the PredictorHistory structure. This flag tracks whether the RAS has been pushed or not during a prediction. Then, in the squash function it is used to pop the RAS if necessary.
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/o3/bpred_unit.hh5
-rw-r--r--src/cpu/o3/bpred_unit_impl.hh7
2 files changed, 8 insertions, 4 deletions
diff --git a/src/cpu/o3/bpred_unit.hh b/src/cpu/o3/bpred_unit.hh
index 8bfab11a9..c1afb4720 100644
--- a/src/cpu/o3/bpred_unit.hh
+++ b/src/cpu/o3/bpred_unit.hh
@@ -207,7 +207,7 @@ class BPredUnit
bool pred_taken, void *bp_history,
ThreadID _tid)
: seqNum(seq_num), pc(instPC), bpHistory(bp_history), RASTarget(0),
- RASIndex(0), tid(_tid), predTaken(pred_taken), usedRAS(0),
+ RASIndex(0), tid(_tid), predTaken(pred_taken), usedRAS(0), pushedRAS(0),
wasCall(0), wasReturn(0), validBTB(0)
{}
@@ -242,6 +242,9 @@ class BPredUnit
/** Whether or not the RAS was used. */
bool usedRAS;
+ /* Wether or not the RAS was pushed */
+ bool pushedRAS;
+
/** Whether or not the instruction was a call. */
bool wasCall;
diff --git a/src/cpu/o3/bpred_unit_impl.hh b/src/cpu/o3/bpred_unit_impl.hh
index 1e75de90c..6f0e5e3e0 100644
--- a/src/cpu/o3/bpred_unit_impl.hh
+++ b/src/cpu/o3/bpred_unit_impl.hh
@@ -219,7 +219,7 @@ BPredUnit<Impl>::predict(DynInstPtr &inst, TheISA::PCState &pc, ThreadID tid)
if (inst->isCall()) {
RAS[tid].push(pc);
-
+ predict_record.pushedRAS = true;
// Record that it was a call so that the top RAS entry can
// be popped off if the speculation is incorrect.
predict_record.wasCall = true;
@@ -253,6 +253,7 @@ BPredUnit<Impl>::predict(DynInstPtr &inst, TheISA::PCState &pc, ThreadID tid)
tid, inst->seqNum, inst->pcState());
} else if (inst->isCall() && !inst->isUncondCtrl()) {
RAS[tid].pop();
+ predict_record.pushedRAS = false;
}
TheISA::advancePC(target, inst->staticInst);
}
@@ -308,7 +309,7 @@ BPredUnit<Impl>::squash(const InstSeqNum &squashed_sn, ThreadID tid)
RAS[tid].restore(pred_hist.front().RASIndex,
pred_hist.front().RASTarget);
- } else if(pred_hist.front().wasCall && pred_hist.front().validBTB) {
+ } else if(pred_hist.front().wasCall && pred_hist.front().pushedRAS) {
// Was a call but predicated false. Pop RAS here
DPRINTF(Fetch, "BranchPred: [tid: %i] Squashing"
" Call [sn:%i] PC: %s Popping RAS\n", tid,
@@ -408,7 +409,7 @@ BPredUnit<Impl>::squash(const InstSeqNum &squashed_sn,
hist_it->RASIndex, hist_it->RASTarget);
RAS[tid].restore(hist_it->RASIndex, hist_it->RASTarget);
- } else if (hist_it->wasCall && hist_it->validBTB) {
+ } else if (hist_it->wasCall && hist_it->pushedRAS) {
//Was a Call but predicated false. Pop RAS here
DPRINTF(Fetch, "BranchPred: [tid: %i] Incorrectly predicted"
" Call [sn:%i] PC: %s Popping RAS\n", tid,