Update the predictor with the actual outcome of a branch at `pc`. Call this once per branch instruction as it exits the EX stage.
(&mut self, pc: u64, was_taken: bool, actual_target: u64, predicted_taken: bool)
| 53 | pub fn update(&mut self, pc: u64, was_taken: bool, actual_target: u64, predicted_taken: bool) { |
| 54 | let idx = Self::pht_idx(pc); |
| 55 | |
| 56 | if was_taken { |
| 57 | if self.pht[idx] < 3 { |
| 58 | self.pht[idx] += 1; |
| 59 | } |
| 60 | self.btb.insert(pc, actual_target); |
| 61 | } else if self.pht[idx] > 0 { |
| 62 | self.pht[idx] -= 1; |
| 63 | } |
| 64 | |
| 65 | self.stats.total += 1; |
| 66 | if was_taken == predicted_taken { |
| 67 | self.stats.correct += 1; |
| 68 | } else { |
| 69 | self.stats.mispredicted += 1; |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | pub fn stats(&self) -> &PredictorStats { |
| 74 | &self.stats |
| 75 | } |
| 76 | |
| 77 | /// Clear PHT and BTB, preserving stats. Called on an address-space change so |
| 78 | /// another process's entries at the same virtual PCs cannot mispredict. |