summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKorey Sewell <ksewell@umich.edu>2010-06-25 17:42:35 -0400
committerKorey Sewell <ksewell@umich.edu>2010-06-25 17:42:35 -0400
commit868181f24df3d48170a4676e9df96928a0608e40 (patch)
tree66bca2a3c6fc7366db7c470a1af563ea1e27c9e2 /src
parent6bfd766f2c6c93cca3f79482bfddf7e6cdeb455e (diff)
downloadgem5-868181f24df3d48170a4676e9df96928a0608e40.tar.xz
inorder: Return Address Stack bug
the nextPC was getting sent to the branch predictor not the current PC, so the RAS was returning the wrong PC and mispredicting everything.
Diffstat (limited to 'src')
-rw-r--r--src/cpu/inorder/resources/bpred_unit.cc25
-rw-r--r--src/cpu/inorder/resources/bpred_unit.hh5
2 files changed, 16 insertions, 14 deletions
diff --git a/src/cpu/inorder/resources/bpred_unit.cc b/src/cpu/inorder/resources/bpred_unit.cc
index 0a78e518e..b08a393f7 100644
--- a/src/cpu/inorder/resources/bpred_unit.cc
+++ b/src/cpu/inorder/resources/bpred_unit.cc
@@ -66,7 +66,9 @@ BPredUnit::BPredUnit(Resource *_res, ThePipeline::Params *params)
}
for (int i=0; i < ThePipeline::MaxThreads; i++)
- RAS[i].init(params->RASSize);
+ RAS[i].init(params->RASSize);
+
+ instSize = sizeof(TheISA::MachInst);
}
std::string
@@ -147,7 +149,7 @@ BPredUnit::takeOverFrom()
bool
-BPredUnit::predict(DynInstPtr &inst, Addr &PC, ThreadID tid)
+BPredUnit::predict(DynInstPtr &inst, Addr &pred_PC, ThreadID tid)
{
// See if branch predictor predicts taken.
// If so, get its target addr either from the BTB or the RAS.
@@ -183,14 +185,14 @@ BPredUnit::predict(DynInstPtr &inst, Addr &PC, ThreadID tid)
} else {
++condPredicted;
- pred_taken = BPLookup(PC, bp_history);
+ pred_taken = BPLookup(pred_PC, bp_history);
DPRINTF(InOrderBPred, "[tid:%i]: Branch predictor predicted %i "
"for PC %#x\n",
tid, pred_taken, inst->readPC());
}
- PredictorHistory predict_record(inst->seqNum, PC, pred_taken,
+ PredictorHistory predict_record(inst->seqNum, pred_PC, pred_taken,
bp_history, tid);
// Now lookup in the BTB or RAS.
@@ -218,10 +220,11 @@ BPredUnit::predict(DynInstPtr &inst, Addr &PC, ThreadID tid)
++BTBLookups;
if (inst->isCall()) {
+
#if ISA_HAS_DELAY_SLOT
- Addr ras_pc = PC + (2 * sizeof(MachInst)); // Next Next PC
+ Addr ras_pc = pred_PC + instSize; // Next Next PC
#else
- Addr ras_pc = PC + sizeof(MachInst); // Next PC
+ Addr ras_pc = pred_PC; // Next PC
#endif
RAS[tid].push(ras_pc);
@@ -243,11 +246,11 @@ BPredUnit::predict(DynInstPtr &inst, Addr &PC, ThreadID tid)
DPRINTF(InOrderBPred, "[tid:%i]: Setting %#x predicted"
" target to %#x.\n",
tid, inst->readPC(), target);
- } else if (BTB.valid(PC, asid)) {
+ } else if (BTB.valid(pred_PC, asid)) {
++BTBHits;
// If it's not a return, use the BTB to get the target addr.
- target = BTB.lookup(PC, asid);
+ target = BTB.lookup(pred_PC, asid);
DPRINTF(InOrderBPred, "[tid:%i]: [asid:%i] Instruction %#x "
"predicted target is %#x.\n",
@@ -262,16 +265,14 @@ BPredUnit::predict(DynInstPtr &inst, Addr &PC, ThreadID tid)
if (pred_taken) {
// Set the PC and the instruction's predicted target.
- PC = target;
- inst->setPredTarg(target);
+ pred_PC = target;
} else {
#if ISA_HAS_DELAY_SLOT
// This value will be inst->PC + 4 (nextPC)
// Delay Slot archs need this to be inst->PC + 8 (nextNPC)
// so we increment one more time here.
- PC = PC + sizeof(MachInst);
+ pred_PC = pred_PC + instSize;
#endif
- inst->setPredTarg(PC);
}
predHist[tid].push_front(predict_record);
diff --git a/src/cpu/inorder/resources/bpred_unit.hh b/src/cpu/inorder/resources/bpred_unit.hh
index 8f4ef593d..881bfcc95 100644
--- a/src/cpu/inorder/resources/bpred_unit.hh
+++ b/src/cpu/inorder/resources/bpred_unit.hh
@@ -83,11 +83,11 @@ class BPredUnit
* Predicts whether or not the instruction is a taken branch, and the
* target of the branch if it is taken.
* @param inst The branch instruction.
- * @param PC The predicted PC is passed back through this parameter.
+ * @param pred_PC The predicted PC is passed back through this parameter.
* @param tid The thread id.
* @return Returns if the branch is taken or not.
*/
- bool predict(ThePipeline::DynInstPtr &inst, Addr &PC, ThreadID tid);
+ bool predict(ThePipeline::DynInstPtr &inst, Addr &pred_PC, ThreadID tid);
// @todo: Rename this function.
void BPUncond(void * &bp_history);
@@ -173,6 +173,7 @@ class BPredUnit
void dump();
private:
+ int instSize;
Resource *res;
struct PredictorHistory {