summaryrefslogtreecommitdiff
path: root/src/cpu/inorder/resources/branch_predictor.cc
diff options
context:
space:
mode:
authorKorey Sewell <ksewell@umich.edu>2010-06-23 18:19:18 -0400
committerKorey Sewell <ksewell@umich.edu>2010-06-23 18:19:18 -0400
commitdefab3ffd5d2e37215d3f9433dc9fc754a90a9a9 (patch)
tree1fad74d7a7358dbcf6481781c05afe2ba31a97d6 /src/cpu/inorder/resources/branch_predictor.cc
parent9f0d8f252c2de0b9ac5654b2c35e913831eba756 (diff)
downloadgem5-defab3ffd5d2e37215d3f9433dc9fc754a90a9a9.tar.xz
inorder: update branch predictor
- use InOrderBPred instead of Resource for DPRINTFs - account for DELAY SLOT in updating RAS and in squashing - don't let squashed instructions update the predictor - the BTB needs to use the ASID not the TID to work for multithreaded programs - add stats for BTB hits
Diffstat (limited to 'src/cpu/inorder/resources/branch_predictor.cc')
-rw-r--r--src/cpu/inorder/resources/branch_predictor.cc89
1 files changed, 56 insertions, 33 deletions
diff --git a/src/cpu/inorder/resources/branch_predictor.cc b/src/cpu/inorder/resources/branch_predictor.cc
index a4ebfe33d..b0a497837 100644
--- a/src/cpu/inorder/resources/branch_predictor.cc
+++ b/src/cpu/inorder/resources/branch_predictor.cc
@@ -78,42 +78,48 @@ BranchPredictor::execute(int slot_num)
{
case PredictBranch:
{
- Addr pred_PC = inst->readNextPC();
-
- if (inst->isControl()) {
- // If not, the pred_PC be updated to pc+8
- // If predicted, the pred_PC will be updated to new target value
- bool predict_taken = branchPred.predict(inst, pred_PC, tid);
+ if (inst->seqNum > cpu->squashSeqNum[tid] &&
+ curTick == cpu->lastSquashCycle[tid]) {
+ DPRINTF(InOrderStage, "[tid:%u]: [sn:%i]: squashed, skipping prediction \n",
+ tid, inst->seqNum);
+ } else {
+ Addr pred_PC = inst->readNextPC();
- if (predict_taken) {
- DPRINTF(InOrderBPred, "[tid:%i]: [sn:%i]: Branch predicted true.\n",
- tid, seq_num);
+ if (inst->isControl()) {
+ // If not, the pred_PC be updated to pc+8
+ // If predicted, the pred_PC will be updated to new target value
+ bool predict_taken = branchPred.predict(inst, pred_PC, tid);
- inst->setPredTarg(pred_PC);
+ if (predict_taken) {
+ DPRINTF(InOrderBPred, "[tid:%i]: [sn:%i]: Branch predicted true.\n",
+ tid, seq_num);
- predictedTaken++;
- } else {
- DPRINTF(InOrderBPred, "[tid:%i]: [sn:%i]: Branch predicted false.\n",
- tid, seq_num);
+ inst->setPredTarg(pred_PC);
- if (inst->isCondDelaySlot())
- {
- inst->setPredTarg(inst->readPC() + (2 * instSize));
+ predictedTaken++;
} else {
- inst->setPredTarg(pred_PC);
- }
+ DPRINTF(InOrderBPred, "[tid:%i]: [sn:%i]: Branch predicted false.\n",
+ tid, seq_num);
- predictedNotTaken++;
- }
+ if (inst->isCondDelaySlot())
+ {
+ inst->setPredTarg(inst->readPC() + (2 * instSize));
+ } else {
+ inst->setPredTarg(pred_PC);
+ }
- inst->setBranchPred(predict_taken);
+ predictedNotTaken++;
+ }
- DPRINTF(InOrderBPred, "[tid:%i]: [sn:%i]: Predicted PC is %08p.\n",
+ inst->setBranchPred(predict_taken);
+
+ DPRINTF(InOrderBPred, "[tid:%i]: [sn:%i]: Predicted PC is %08p.\n",
tid, seq_num, pred_PC);
- } else {
- DPRINTF(InOrderBPred, "[tid:%i]: Ignoring [sn:%i] because this isn't "
- "a control instruction.\n", tid, seq_num);
+ } else {
+ //DPRINTF(InOrderBPred, "[tid:%i]: Ignoring [sn:%i] because this isn't "
+ // "a control instruction.\n", tid, seq_num);
+ }
}
bpred_req->done();
@@ -122,11 +128,17 @@ BranchPredictor::execute(int slot_num)
case UpdatePredictor:
{
- DPRINTF(InOrderBPred, "[tid:%i]: [sn:%i]: Updating Branch Predictor.\n",
- tid, seq_num);
+ if (inst->seqNum > cpu->squashSeqNum[tid] &&
+ curTick == cpu->lastSquashCycle[tid]) {
+ DPRINTF(InOrderStage, "[tid:%u]: [sn:%i]: squashed, skipping branch predictor update \n",
+ tid, inst->seqNum);
+ } else {
+ DPRINTF(InOrderBPred, "[tid:%i]: [sn:%i]: Updating Branch Predictor.\n",
+ tid, seq_num);
- branchPred.update(seq_num, tid);
+ branchPred.update(seq_num, tid);
+ }
bpred_req->done();
}
@@ -141,10 +153,21 @@ void
BranchPredictor::squash(DynInstPtr inst, int squash_stage,
InstSeqNum squash_seq_num, ThreadID tid)
{
- DPRINTF(InOrderBPred, "Squashing...\n");
- Addr corr_targ=inst->readPredPC();
- bool taken=inst->predTaken();
- branchPred.squash(squash_seq_num,corr_targ,taken,tid);
+ DPRINTF(InOrderBPred, "[tid:%i][sn:%i] Squashing...\n", tid, inst->seqNum);
+
+#if ISA_HAS_DELAY_SLOT
+ // We need to squash the actual branch , NOT the delay slot
+ // in the branch predictor
+ squash_seq_num = squash_seq_num - 1;
+#endif
+
+ if(squash_stage>=ThePipeline::BackEndStartStage) {
+ Addr corr_targ=inst->readPredPC();
+ bool taken=inst->predTaken();
+ branchPred.squash(squash_seq_num,corr_targ,taken,tid);
+ } else {
+ branchPred.squash(squash_seq_num, tid);
+ }
}
void