changeset cd42a32dc8b6 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=cd42a32dc8b6
description:
        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:

 src/cpu/inorder/resources/bpred_unit.cc |  25 +++++++++++++------------
 src/cpu/inorder/resources/bpred_unit.hh |   5 +++--
 2 files changed, 16 insertions(+), 14 deletions(-)

diffs (112 lines):

diff -r b10c66a125f6 -r cd42a32dc8b6 src/cpu/inorder/resources/bpred_unit.cc
--- a/src/cpu/inorder/resources/bpred_unit.cc   Fri Jun 25 17:42:34 2010 -0400
+++ b/src/cpu/inorder/resources/bpred_unit.cc   Fri Jun 25 17:42:35 2010 -0400
@@ -66,7 +66,9 @@
     }
 
     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 @@
 
 
 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 @@
     } 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 @@
             ++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 @@
                 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 @@
 
     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 -r b10c66a125f6 -r cd42a32dc8b6 src/cpu/inorder/resources/bpred_unit.hh
--- a/src/cpu/inorder/resources/bpred_unit.hh   Fri Jun 25 17:42:34 2010 -0400
+++ b/src/cpu/inorder/resources/bpred_unit.hh   Fri Jun 25 17:42:35 2010 -0400
@@ -83,11 +83,11 @@
      * 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 @@
     void dump();
 
   private:
+    int instSize;
     Resource *res;
     
     struct PredictorHistory {
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to