src/cpu/pred/bi_mode.cc
/* Only the selected direction predictor will be updated with the final
 * outcome; the status of the unselected one will not be altered. The choice
 * predictor is always updated with the branch outcome, except when the
 * choice is opposite to the branch outcome but the selected counter of
 * the direction predictors makes a correct final prediction.
 */
Only the selected direction predictor will be updated with the final
outcome; the status of the unselected one will not be altered. The choice
predictor is always updated with the branch outcome, except when the
choice is opposite to the branch outcome but the selected counter of
the direction predictors makes a correct final prediction.
Only the selected direction predictor will be updated with the final outcome ; the status of the unselected one will not be altered . The choice predictor is always updated with the branch outcome except when the choice is opposite to the branch outcome but the selected counter of the direction predictors makes a correct final prediction .
void
BiModeBP::update(ThreadID tid, Addr branchAddr, bool taken, void *bpHistory,
                 bool squashed, const StaticInstPtr & inst, Addr corrTarget)
{
    assert(bpHistory);
    BPHistory *history = static_cast<BPHistory*>(bpHistory);
    if (squashed) {
        globalHistoryReg[tid] = (history->globalHistoryReg << 1) | taken;
        return;
    }
    unsigned choiceHistoryIdx = ((branchAddr >> instShiftAmt)
                                & choiceHistoryMask);
    unsigned globalHistoryIdx = (((branchAddr >> instShiftAmt)
                                ^ history->globalHistoryReg)
                                & globalHistoryMask);
    assert(choiceHistoryIdx < choicePredictorSize);
    assert(globalHistoryIdx < globalPredictorSize);
    if (history->takenUsed) {
        if (taken) {
            takenCounters[globalHistoryIdx]++;
        } else {
            takenCounters[globalHistoryIdx]--;
        }
    } else {
        if (taken) {
            notTakenCounters[globalHistoryIdx]++;
        } else {
            notTakenCounters[globalHistoryIdx]--;
        }
    }
    if (history->finalPred == taken) {
        if (history->finalPred == history->takenUsed) {
            if (taken) {
                choiceCounters[choiceHistoryIdx]++;
            } else {
                choiceCounters[choiceHistoryIdx]--;
            }
        }
    } else {
        if (taken) {
            choiceCounters[choiceHistoryIdx]++;
        } else {
            choiceCounters[choiceHistoryIdx]--;
        }
    }
    delete history;
}
void BiModeBP :: update ( ThreadID tid , Addr branchAddr , bool taken , void * bpHistory , bool squashed , const StaticInstPtr & inst , Addr corrTarget ) { assert ( bpHistory ) ; BPHistory * history = static_cast < BPHistory * > ( bpHistory ) ; if ( squashed ) { globalHistoryReg [ tid ] = ( history -> globalHistoryReg << 1 ) | taken ; return ; } unsigned choiceHistoryIdx = ( ( branchAddr >> instShiftAmt ) & choiceHistoryMask ) ; unsigned globalHistoryIdx = ( ( ( branchAddr >> instShiftAmt ) ^ history -> globalHistoryReg ) & globalHistoryMask ) ; assert ( choiceHistoryIdx < choicePredictorSize ) ; assert ( globalHistoryIdx < globalPredictorSize ) ; if ( history -> takenUsed ) { if ( taken ) { takenCounters [ globalHistoryIdx ] ++ ; } else { takenCounters [ globalHistoryIdx ] -- ; } } else { if ( taken ) { notTakenCounters [ globalHistoryIdx ] ++ ; } else { notTakenCounters [ globalHistoryIdx ] -- ; } } if ( history -> finalPred == taken ) { if ( history -> finalPred == history -> takenUsed ) { if ( taken ) { choiceCounters [ choiceHistoryIdx ] ++ ; } else { choiceCounters [ choiceHistoryIdx ] -- ; } } } else { if ( taken ) { choiceCounters [ choiceHistoryIdx ] ++ ; } else { choiceCounters [ choiceHistoryIdx ] -- ; } } delete history ; }
Only the selected direction predictor will be updated with the final
 outcome; the status of the unselected one will not be altered.
Only the selected direction predictor will be updated with the final outcome ; the status of the unselected one will not be altered .
// We do not update the counters speculatively on a squash. // We just restore the global history register. // if the taken array's prediction was used, update it // if the not-taken array's prediction was used, update it /* If the final prediction matches the actual branch's
        * outcome and the choice predictor matches the final
        * outcome, we update the choice predictor, otherwise it
        * is not updated. While the designers of the bi-mode
        * predictor don't explicity say why this is done, one
        * can infer that it is to preserve the choice predictor's
        * bias with respect to the branch being predicted; afterall,
        * the whole point of the bi-mode predictor is to identify the
        * atypical case when a branch deviates from its bias.
        */ // always update the choice predictor on an incorrect prediction