114081Sjavier.bueno@metempsy.com/*
214081Sjavier.bueno@metempsy.com * Copyright 2019 Texas A&M University
314081Sjavier.bueno@metempsy.com *
414081Sjavier.bueno@metempsy.com * Redistribution and use in source and binary forms, with or without
514081Sjavier.bueno@metempsy.com * modification, are permitted provided that the following conditions are met:
614081Sjavier.bueno@metempsy.com *
714081Sjavier.bueno@metempsy.com * 1. Redistributions of source code must retain the above copyright notice,
814081Sjavier.bueno@metempsy.com *    this list of conditions and the following disclaimer.
914081Sjavier.bueno@metempsy.com *
1014081Sjavier.bueno@metempsy.com * 2. Redistributions in binary form must reproduce the above copyright notice,
1114081Sjavier.bueno@metempsy.com *    this list of conditions and the following disclaimer in the documentation
1214081Sjavier.bueno@metempsy.com *    and/or other materials provided with the distribution.
1314081Sjavier.bueno@metempsy.com *
1414081Sjavier.bueno@metempsy.com * 3. Neither the name of the copyright holder nor the names of its
1514081Sjavier.bueno@metempsy.com *    contributors may be used to endorse or promote products derived from this
1614081Sjavier.bueno@metempsy.com *    software without specific prior written permission.
1714081Sjavier.bueno@metempsy.com *
1814081Sjavier.bueno@metempsy.com *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1914081Sjavier.bueno@metempsy.com *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2014081Sjavier.bueno@metempsy.com *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2114081Sjavier.bueno@metempsy.com *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2214081Sjavier.bueno@metempsy.com *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2314081Sjavier.bueno@metempsy.com *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2414081Sjavier.bueno@metempsy.com *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2514081Sjavier.bueno@metempsy.com *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2614081Sjavier.bueno@metempsy.com *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2714081Sjavier.bueno@metempsy.com *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2814081Sjavier.bueno@metempsy.com *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2914081Sjavier.bueno@metempsy.com *
3014081Sjavier.bueno@metempsy.com *  Author: Daniel A. Jiménez
3114081Sjavier.bueno@metempsy.com *  Adapted to gem5 by: Javier Bueno Hedo
3214081Sjavier.bueno@metempsy.com *
3314081Sjavier.bueno@metempsy.com */
3414081Sjavier.bueno@metempsy.com
3514081Sjavier.bueno@metempsy.com/*
3614081Sjavier.bueno@metempsy.com * Multiperspective Perceptron Predictor with TAGE (by Daniel A. Jiménez)
3714081Sjavier.bueno@metempsy.com */
3814081Sjavier.bueno@metempsy.com
3914081Sjavier.bueno@metempsy.com#include "cpu/pred/multiperspective_perceptron_tage.hh"
4014081Sjavier.bueno@metempsy.com
4114081Sjavier.bueno@metempsy.com#include "base/random.hh"
4214081Sjavier.bueno@metempsy.com
4314081Sjavier.bueno@metempsy.comvoid
4414081Sjavier.bueno@metempsy.comMPP_TAGE::calculateParameters()
4514081Sjavier.bueno@metempsy.com{
4614081Sjavier.bueno@metempsy.com   assert(tunedHistoryLengths.size() == (nHistoryTables+1));
4714081Sjavier.bueno@metempsy.com   for (int i = 0; i <= nHistoryTables; i += 1) {
4814081Sjavier.bueno@metempsy.com      histLengths[i] = tunedHistoryLengths[i];
4914081Sjavier.bueno@metempsy.com   }
5014081Sjavier.bueno@metempsy.com}
5114081Sjavier.bueno@metempsy.com
5214081Sjavier.bueno@metempsy.comvoid
5314081Sjavier.bueno@metempsy.comMPP_TAGE::handleTAGEUpdate(Addr branch_pc, bool taken,
5414081Sjavier.bueno@metempsy.com                           TAGEBase::BranchInfo* bi)
5514081Sjavier.bueno@metempsy.com{
5614081Sjavier.bueno@metempsy.com    if (bi->hitBank > 0) {
5714081Sjavier.bueno@metempsy.com        if (abs (2 * gtable[bi->hitBank][bi->hitBankIndex].ctr + 1) == 1) {
5814081Sjavier.bueno@metempsy.com            if (bi->longestMatchPred != taken) {
5914081Sjavier.bueno@metempsy.com                // acts as a protection
6014081Sjavier.bueno@metempsy.com                if (bi->altBank > 0) {
6114081Sjavier.bueno@metempsy.com                    ctrUpdate(gtable[bi->altBank][bi->altBankIndex].ctr, taken,
6214081Sjavier.bueno@metempsy.com                              tagTableCounterBits);
6314081Sjavier.bueno@metempsy.com                }
6414081Sjavier.bueno@metempsy.com                if (bi->altBank == 0){
6514081Sjavier.bueno@metempsy.com                    baseUpdate(branch_pc, taken, bi);
6614081Sjavier.bueno@metempsy.com                }
6714081Sjavier.bueno@metempsy.com            }
6814081Sjavier.bueno@metempsy.com        }
6914081Sjavier.bueno@metempsy.com
7014081Sjavier.bueno@metempsy.com        ctrUpdate(gtable[bi->hitBank][bi->hitBankIndex].ctr, taken,
7114081Sjavier.bueno@metempsy.com                  tagTableCounterBits);
7214081Sjavier.bueno@metempsy.com
7314081Sjavier.bueno@metempsy.com        //sign changes: no way it can have been useful
7414081Sjavier.bueno@metempsy.com        if (abs (2 * gtable[bi->hitBank][bi->hitBankIndex].ctr + 1) == 1) {
7514081Sjavier.bueno@metempsy.com            gtable[bi->hitBank][bi->hitBankIndex].u = 0;
7614081Sjavier.bueno@metempsy.com        }
7714081Sjavier.bueno@metempsy.com    } else {
7814081Sjavier.bueno@metempsy.com        baseUpdate(branch_pc, taken, bi);
7914081Sjavier.bueno@metempsy.com    }
8014081Sjavier.bueno@metempsy.com
8114081Sjavier.bueno@metempsy.com    if ((bi->longestMatchPred != bi->altTaken) &&
8214081Sjavier.bueno@metempsy.com        (bi->longestMatchPred == taken) &&
8314081Sjavier.bueno@metempsy.com        (gtable[bi->hitBank][bi->hitBankIndex].u < (1 << tagTableUBits) -1)) {
8414081Sjavier.bueno@metempsy.com            gtable[bi->hitBank][bi->hitBankIndex].u++;
8514081Sjavier.bueno@metempsy.com    }
8614081Sjavier.bueno@metempsy.com}
8714081Sjavier.bueno@metempsy.com
8814081Sjavier.bueno@metempsy.comvoid
8914081Sjavier.bueno@metempsy.comMPP_TAGE::handleAllocAndUReset(bool alloc, bool taken,
9014081Sjavier.bueno@metempsy.com                               TAGEBase::BranchInfo* bi, int nrand)
9114081Sjavier.bueno@metempsy.com{
9214081Sjavier.bueno@metempsy.com    if (!alloc) {
9314081Sjavier.bueno@metempsy.com        return;
9414081Sjavier.bueno@metempsy.com    }
9514081Sjavier.bueno@metempsy.com
9614081Sjavier.bueno@metempsy.com    int a = 1;
9714081Sjavier.bueno@metempsy.com
9814081Sjavier.bueno@metempsy.com    if ((random_mt.random<int>() & 127) < 32) {
9914081Sjavier.bueno@metempsy.com        a = 2;
10014081Sjavier.bueno@metempsy.com    }
10114081Sjavier.bueno@metempsy.com    int dep = bi->hitBank + a;
10214081Sjavier.bueno@metempsy.com
10314081Sjavier.bueno@metempsy.com    int penalty = 0;
10414081Sjavier.bueno@metempsy.com    int numAllocated = 0;
10514081Sjavier.bueno@metempsy.com    int T = 1;
10614081Sjavier.bueno@metempsy.com
10714081Sjavier.bueno@metempsy.com    for (int i = dep; i <= nHistoryTables; i += 1) {
10814081Sjavier.bueno@metempsy.com        if (noSkip[i]) {
10914081Sjavier.bueno@metempsy.com            if (gtable[i][bi->tableIndices[i]].u == 0) {
11014081Sjavier.bueno@metempsy.com                gtable[i][bi->tableIndices[i]].tag = bi->tableTags[i];
11114081Sjavier.bueno@metempsy.com                gtable[i][bi->tableIndices[i]].ctr = taken ? 0 : -1;
11214081Sjavier.bueno@metempsy.com                numAllocated++;
11314081Sjavier.bueno@metempsy.com                if (T <= 0) {
11414081Sjavier.bueno@metempsy.com                    break;
11514081Sjavier.bueno@metempsy.com                }
11614081Sjavier.bueno@metempsy.com                i += 1;
11714081Sjavier.bueno@metempsy.com                T -= 1;
11814081Sjavier.bueno@metempsy.com            } else {
11914081Sjavier.bueno@metempsy.com                penalty++;
12014081Sjavier.bueno@metempsy.com            }
12114081Sjavier.bueno@metempsy.com        } else { assert(false); }
12214081Sjavier.bueno@metempsy.com    }
12314081Sjavier.bueno@metempsy.com
12414081Sjavier.bueno@metempsy.com    tCounter += (penalty - numAllocated);
12514081Sjavier.bueno@metempsy.com
12614081Sjavier.bueno@metempsy.com    handleUReset();
12714081Sjavier.bueno@metempsy.com}
12814081Sjavier.bueno@metempsy.com
12914081Sjavier.bueno@metempsy.comvoid
13014081Sjavier.bueno@metempsy.comMPP_TAGE::handleUReset()
13114081Sjavier.bueno@metempsy.com{
13214081Sjavier.bueno@metempsy.com    //just the best formula for the Championship:
13314081Sjavier.bueno@metempsy.com    //In practice when one out of two entries are useful
13414081Sjavier.bueno@metempsy.com    if (tCounter < 0) {
13514081Sjavier.bueno@metempsy.com        tCounter = 0;
13614081Sjavier.bueno@metempsy.com    }
13714081Sjavier.bueno@metempsy.com
13814081Sjavier.bueno@metempsy.com    if (tCounter >= ((ULL(1) << logUResetPeriod))) {
13914081Sjavier.bueno@metempsy.com        // Update the u bits for the short tags table
14014081Sjavier.bueno@metempsy.com        for (int i = 1; i <= nHistoryTables; i++) {
14114081Sjavier.bueno@metempsy.com            for (int j = 0; j < (ULL(1) << logTagTableSizes[i]); j++) {
14214081Sjavier.bueno@metempsy.com                resetUctr(gtable[i][j].u);
14314081Sjavier.bueno@metempsy.com            }
14414081Sjavier.bueno@metempsy.com        }
14514081Sjavier.bueno@metempsy.com
14614081Sjavier.bueno@metempsy.com        tCounter = 0;
14714081Sjavier.bueno@metempsy.com    }
14814081Sjavier.bueno@metempsy.com}
14914081Sjavier.bueno@metempsy.com
15014081Sjavier.bueno@metempsy.comvoid
15114081Sjavier.bueno@metempsy.comMPP_TAGE::resetUctr(uint8_t &u)
15214081Sjavier.bueno@metempsy.com{
15314081Sjavier.bueno@metempsy.com    // On real HW it should be u >>= 1 instead of if > 0 then u--
15414081Sjavier.bueno@metempsy.com    if (u > 0) {
15514081Sjavier.bueno@metempsy.com        u--;
15614081Sjavier.bueno@metempsy.com    }
15714081Sjavier.bueno@metempsy.com}
15814081Sjavier.bueno@metempsy.com
15914081Sjavier.bueno@metempsy.com
16014081Sjavier.bueno@metempsy.comint
16114081Sjavier.bueno@metempsy.comMPP_TAGE::bindex(Addr pc_in) const
16214081Sjavier.bueno@metempsy.com{
16314081Sjavier.bueno@metempsy.com    uint32_t pc = (uint32_t) pc_in;
16414081Sjavier.bueno@metempsy.com    return ((pc ^ (pc >> 4)) &
16514081Sjavier.bueno@metempsy.com            ((ULL(1) << (logTagTableSizes[0])) - 1));
16614081Sjavier.bueno@metempsy.com}
16714081Sjavier.bueno@metempsy.com
16814081Sjavier.bueno@metempsy.comunsigned
16914081Sjavier.bueno@metempsy.comMPP_TAGE::getUseAltIdx(TAGEBase::BranchInfo* bi, Addr branch_pc)
17014081Sjavier.bueno@metempsy.com{
17114081Sjavier.bueno@metempsy.com    uint32_t hpc = ((uint32_t) branch_pc);
17214081Sjavier.bueno@metempsy.com    hpc = (hpc ^(hpc >> 4));
17314081Sjavier.bueno@metempsy.com    return 2 * ((hpc & ((numUseAltOnNa/2)-1)) ^ bi->longestMatchPred) +
17414081Sjavier.bueno@metempsy.com           ((bi->hitBank > (nHistoryTables / 3)) ? 1 : 0);
17514081Sjavier.bueno@metempsy.com}
17614081Sjavier.bueno@metempsy.com
17714081Sjavier.bueno@metempsy.comvoid
17814081Sjavier.bueno@metempsy.comMPP_TAGE::adjustAlloc(bool & alloc, bool taken, bool pred_taken)
17914081Sjavier.bueno@metempsy.com{
18014081Sjavier.bueno@metempsy.com    // Do not allocate too often if the prediction is ok
18114081Sjavier.bueno@metempsy.com    if ((taken == pred_taken) && ((random_mt.random<int>() & 31) != 0)) {
18214081Sjavier.bueno@metempsy.com        alloc = false;
18314081Sjavier.bueno@metempsy.com    }
18414081Sjavier.bueno@metempsy.com}
18514081Sjavier.bueno@metempsy.com
18614081Sjavier.bueno@metempsy.comvoid
18714081Sjavier.bueno@metempsy.comMPP_TAGE::updateHistories(
18814081Sjavier.bueno@metempsy.com    ThreadID tid, Addr branch_pc, bool taken, TAGEBase::BranchInfo* b,
18914081Sjavier.bueno@metempsy.com    bool speculative, const StaticInstPtr &inst, Addr target)
19014081Sjavier.bueno@metempsy.com{
19114081Sjavier.bueno@metempsy.com    if (speculative != speculativeHistUpdate) {
19214081Sjavier.bueno@metempsy.com        return;
19314081Sjavier.bueno@metempsy.com    }
19414081Sjavier.bueno@metempsy.com    // speculation is not implemented
19514081Sjavier.bueno@metempsy.com    assert(! speculative);
19614081Sjavier.bueno@metempsy.com
19714081Sjavier.bueno@metempsy.com    ThreadHistory& tHist = threadHistory[tid];
19814081Sjavier.bueno@metempsy.com
19914081Sjavier.bueno@metempsy.com    int brtype = inst->isDirectCtrl() ? 0 : 2;
20014081Sjavier.bueno@metempsy.com    if (! inst->isUncondCtrl()) {
20114081Sjavier.bueno@metempsy.com        ++brtype;
20214081Sjavier.bueno@metempsy.com    }
20314081Sjavier.bueno@metempsy.com    updatePathAndGlobalHistory(tHist, brtype, taken, branch_pc, target);
20414081Sjavier.bueno@metempsy.com}
20514081Sjavier.bueno@metempsy.com
20614081Sjavier.bueno@metempsy.comvoid
20714081Sjavier.bueno@metempsy.comMPP_TAGE::updatePathAndGlobalHistory(
20814081Sjavier.bueno@metempsy.com    ThreadHistory& tHist, int brtype, bool taken, Addr branch_pc, Addr target)
20914081Sjavier.bueno@metempsy.com{
21014081Sjavier.bueno@metempsy.com    // TAGE update
21114081Sjavier.bueno@metempsy.com    int tmp = (branch_pc << 1) + taken;
21214081Sjavier.bueno@metempsy.com    int path = branch_pc;
21314081Sjavier.bueno@metempsy.com
21414081Sjavier.bueno@metempsy.com    int maxt = (brtype & 1) ? 1 : 4;
21514081Sjavier.bueno@metempsy.com
21614081Sjavier.bueno@metempsy.com    for (int t = 0; t < maxt; t++) {
21714081Sjavier.bueno@metempsy.com        bool dir = (tmp & 1);
21814081Sjavier.bueno@metempsy.com        tmp >>= 1;
21914081Sjavier.bueno@metempsy.com        int pathbit = (path & 127);
22014081Sjavier.bueno@metempsy.com        path >>= 1;
22114081Sjavier.bueno@metempsy.com        updateGHist(tHist.gHist, dir, tHist.globalHistory, tHist.ptGhist);
22214081Sjavier.bueno@metempsy.com        tHist.pathHist = (tHist.pathHist << 1) ^ pathbit;
22314081Sjavier.bueno@metempsy.com        for (int i = 1; i <= nHistoryTables; i++) {
22414081Sjavier.bueno@metempsy.com            tHist.computeIndices[i].update(tHist.gHist);
22514081Sjavier.bueno@metempsy.com            tHist.computeTags[0][i].update(tHist.gHist);
22614081Sjavier.bueno@metempsy.com            tHist.computeTags[1][i].update(tHist.gHist);
22714081Sjavier.bueno@metempsy.com        }
22814081Sjavier.bueno@metempsy.com    }
22914081Sjavier.bueno@metempsy.com}
23014081Sjavier.bueno@metempsy.com
23114081Sjavier.bueno@metempsy.combool
23214081Sjavier.bueno@metempsy.comMPP_TAGE::isHighConfidence(TAGEBase::BranchInfo *bi) const
23314081Sjavier.bueno@metempsy.com{
23414081Sjavier.bueno@metempsy.com    if (bi->hitBank > 0) {
23514081Sjavier.bueno@metempsy.com        return (abs(2 * gtable[bi->hitBank][bi->hitBankIndex].ctr + 1)) >=
23614081Sjavier.bueno@metempsy.com               ((1 << tagTableCounterBits) - 1);
23714081Sjavier.bueno@metempsy.com    } else {
23814081Sjavier.bueno@metempsy.com        int bim = (btablePrediction[bi->bimodalIndex] << 1)
23914081Sjavier.bueno@metempsy.com            + btableHysteresis[bi->bimodalIndex >> logRatioBiModalHystEntries];
24014081Sjavier.bueno@metempsy.com        return (bim == 0) || (bim == 3);
24114081Sjavier.bueno@metempsy.com    }
24214081Sjavier.bueno@metempsy.com
24314081Sjavier.bueno@metempsy.com}
24414081Sjavier.bueno@metempsy.com
24514081Sjavier.bueno@metempsy.comMPP_TAGE*
24614081Sjavier.bueno@metempsy.comMPP_TAGEParams::create()
24714081Sjavier.bueno@metempsy.com{
24814081Sjavier.bueno@metempsy.com    return new MPP_TAGE(this);
24914081Sjavier.bueno@metempsy.com}
25014081Sjavier.bueno@metempsy.com
25114081Sjavier.bueno@metempsy.combool
25214081Sjavier.bueno@metempsy.comMPP_LoopPredictor::calcConf(int index) const
25314081Sjavier.bueno@metempsy.com{
25414081Sjavier.bueno@metempsy.com    return LoopPredictor::calcConf(index) ||
25514081Sjavier.bueno@metempsy.com           (ltable[index].confidence * ltable[index].numIter > 128);
25614081Sjavier.bueno@metempsy.com}
25714081Sjavier.bueno@metempsy.com
25814081Sjavier.bueno@metempsy.combool
25914081Sjavier.bueno@metempsy.comMPP_LoopPredictor::optionalAgeInc() const
26014081Sjavier.bueno@metempsy.com{
26114081Sjavier.bueno@metempsy.com    return ((random_mt.random<int>() & 7) == 0);
26214081Sjavier.bueno@metempsy.com}
26314081Sjavier.bueno@metempsy.com
26414081Sjavier.bueno@metempsy.comMPP_LoopPredictor*
26514081Sjavier.bueno@metempsy.comMPP_LoopPredictorParams::create()
26614081Sjavier.bueno@metempsy.com{
26714081Sjavier.bueno@metempsy.com    return new MPP_LoopPredictor(this);
26814081Sjavier.bueno@metempsy.com}
26914081Sjavier.bueno@metempsy.com
27014081Sjavier.bueno@metempsy.comMPP_StatisticalCorrector::MPP_StatisticalCorrector(
27114081Sjavier.bueno@metempsy.com        const MPP_StatisticalCorrectorParams *p) : StatisticalCorrector(p),
27214081Sjavier.bueno@metempsy.com    thirdH(0), pnb(p->pnb), logPnb(p->logPnb), pm(p->pm), gnb(p->gnb),
27314081Sjavier.bueno@metempsy.com    logGnb(p->logGnb), gm(p->gm)
27414081Sjavier.bueno@metempsy.com{
27514081Sjavier.bueno@metempsy.com    initGEHLTable(pnb, pm, pgehl, logPnb, wp, -1);
27614081Sjavier.bueno@metempsy.com    initGEHLTable(gnb, gm, ggehl, logGnb, wg, -1);
27714081Sjavier.bueno@metempsy.com
27814081Sjavier.bueno@metempsy.com    for (int8_t &pos : wl) {
27914081Sjavier.bueno@metempsy.com        pos = -1;
28014081Sjavier.bueno@metempsy.com    }
28114081Sjavier.bueno@metempsy.com}
28214081Sjavier.bueno@metempsy.com
28314081Sjavier.bueno@metempsy.comvoid
28414081Sjavier.bueno@metempsy.comMPP_StatisticalCorrector::initBias()
28514081Sjavier.bueno@metempsy.com{
28614081Sjavier.bueno@metempsy.com    for (int j = 0; j < (1 << logBias); j++) {
28714081Sjavier.bueno@metempsy.com        if (j & 1) {
28814081Sjavier.bueno@metempsy.com            bias[j] = 15;
28914081Sjavier.bueno@metempsy.com            biasSK[j] = 15;
29014081Sjavier.bueno@metempsy.com        } else {
29114081Sjavier.bueno@metempsy.com            bias[j] = -16;
29214081Sjavier.bueno@metempsy.com            biasSK[j] = -16;
29314081Sjavier.bueno@metempsy.com        }
29414081Sjavier.bueno@metempsy.com    }
29514081Sjavier.bueno@metempsy.com}
29614081Sjavier.bueno@metempsy.com
29714081Sjavier.bueno@metempsy.comunsigned
29814081Sjavier.bueno@metempsy.comMPP_StatisticalCorrector::getIndBias(Addr branch_pc,
29914081Sjavier.bueno@metempsy.com        StatisticalCorrector::BranchInfo* bi, bool bias) const
30014081Sjavier.bueno@metempsy.com{
30114081Sjavier.bueno@metempsy.com    unsigned int truncated_pc = branch_pc;
30214081Sjavier.bueno@metempsy.com    return ((truncated_pc << 1) + bi->predBeforeSC) & ((1 << logBias) - 1);
30314081Sjavier.bueno@metempsy.com}
30414081Sjavier.bueno@metempsy.com
30514081Sjavier.bueno@metempsy.comunsigned
30614081Sjavier.bueno@metempsy.comMPP_StatisticalCorrector::getIndBiasSK(Addr branch_pc,
30714081Sjavier.bueno@metempsy.com        StatisticalCorrector::BranchInfo* bi) const
30814081Sjavier.bueno@metempsy.com{
30914081Sjavier.bueno@metempsy.com    return (((branch_pc ^ (branch_pc >> (logBias - 1))) << 1)
31014081Sjavier.bueno@metempsy.com            + bi->predBeforeSC) & ((1 << logBias) - 1);
31114081Sjavier.bueno@metempsy.com}
31214081Sjavier.bueno@metempsy.com
31314081Sjavier.bueno@metempsy.comunsigned
31414081Sjavier.bueno@metempsy.comMPP_StatisticalCorrector::getIndBiasBank(Addr branch_pc,
31514081Sjavier.bueno@metempsy.com        StatisticalCorrector::BranchInfo* bi, int hitBank, int altBank) const
31614081Sjavier.bueno@metempsy.com{
31714081Sjavier.bueno@metempsy.com    return 0;
31814081Sjavier.bueno@metempsy.com}
31914081Sjavier.bueno@metempsy.com
32014081Sjavier.bueno@metempsy.comint
32114081Sjavier.bueno@metempsy.comMPP_StatisticalCorrector::gIndexLogsSubstr(int nbr, int i)
32214081Sjavier.bueno@metempsy.com{
32314081Sjavier.bueno@metempsy.com    return (i >= (nbr - 2)) ? 1 : 0;
32414081Sjavier.bueno@metempsy.com}
32514081Sjavier.bueno@metempsy.com
32614081Sjavier.bueno@metempsy.comunsigned
32714081Sjavier.bueno@metempsy.comMPP_StatisticalCorrector::getIndUpd(Addr branch_pc) const
32814081Sjavier.bueno@metempsy.com{
32914081Sjavier.bueno@metempsy.com    return ((branch_pc ^ (branch_pc >> 4)) & ((1 << (logSizeUp)) - 1));
33014081Sjavier.bueno@metempsy.com}
33114081Sjavier.bueno@metempsy.com
33214081Sjavier.bueno@metempsy.comvoid
33314081Sjavier.bueno@metempsy.comMPP_StatisticalCorrector::gUpdate(Addr branch_pc, bool taken, int64_t hist,
33414081Sjavier.bueno@metempsy.com                   std::vector<int> & length, std::vector<int8_t> * tab,
33514081Sjavier.bueno@metempsy.com                   int nbr, int logs, std::vector<int8_t> & w,
33614081Sjavier.bueno@metempsy.com                   StatisticalCorrector::BranchInfo* bi)
33714081Sjavier.bueno@metempsy.com{
33814081Sjavier.bueno@metempsy.com    int percsum = 0;
33914081Sjavier.bueno@metempsy.com    for (int i = 0; i < nbr; i++) {
34014081Sjavier.bueno@metempsy.com        int64_t bhist = hist & ((int64_t) ((1 << length[i]) - 1));
34114081Sjavier.bueno@metempsy.com        int64_t index = gIndex(branch_pc, bhist, logs, nbr, i);
34214081Sjavier.bueno@metempsy.com        percsum += (2 * tab[i][index] + 1);
34314081Sjavier.bueno@metempsy.com        ctrUpdate(tab[i][index], taken, scCountersWidth - (i < (nbr - 1)));
34414081Sjavier.bueno@metempsy.com    }
34514081Sjavier.bueno@metempsy.com}
34614081Sjavier.bueno@metempsy.com
34714081Sjavier.bueno@metempsy.combool
34814081Sjavier.bueno@metempsy.comMPP_StatisticalCorrector::scPredict(ThreadID tid, Addr branch_pc,
34914081Sjavier.bueno@metempsy.com        bool cond_branch, StatisticalCorrector::BranchInfo* bi,
35014081Sjavier.bueno@metempsy.com        bool prev_pred_taken, bool bias_bit, bool use_conf_ctr,
35114081Sjavier.bueno@metempsy.com        int8_t conf_ctr, unsigned conf_bits, int hitBank, int altBank,
35214081Sjavier.bueno@metempsy.com        int64_t phist, int init_lsum)
35314081Sjavier.bueno@metempsy.com{
35414081Sjavier.bueno@metempsy.com    bool pred_taken = prev_pred_taken;
35514081Sjavier.bueno@metempsy.com    if (cond_branch) {
35614081Sjavier.bueno@metempsy.com
35714081Sjavier.bueno@metempsy.com        bi->predBeforeSC = prev_pred_taken;
35814081Sjavier.bueno@metempsy.com
35914081Sjavier.bueno@metempsy.com        int lsum = init_lsum;
36014081Sjavier.bueno@metempsy.com
36114081Sjavier.bueno@metempsy.com        getBiasLSUM(branch_pc, bi, lsum);
36214081Sjavier.bueno@metempsy.com
36314081Sjavier.bueno@metempsy.com        int thres = gPredictions(tid, branch_pc, bi, lsum, phist);
36414081Sjavier.bueno@metempsy.com
36514081Sjavier.bueno@metempsy.com        // These will be needed at update time
36614081Sjavier.bueno@metempsy.com        bi->lsum = lsum;
36714081Sjavier.bueno@metempsy.com        bi->thres = thres;
36814081Sjavier.bueno@metempsy.com        bi->scPred = (lsum >= 0);
36914081Sjavier.bueno@metempsy.com
37014081Sjavier.bueno@metempsy.com        if (pred_taken != bi->scPred) {
37114081Sjavier.bueno@metempsy.com            pred_taken = bi->scPred;
37214081Sjavier.bueno@metempsy.com
37314081Sjavier.bueno@metempsy.com            if (bi->highConf /* comes from tage prediction */) {
37414081Sjavier.bueno@metempsy.com              if ((abs(lsum) < thres / 3))
37514081Sjavier.bueno@metempsy.com                pred_taken = (firstH < 0) ? bi->scPred : prev_pred_taken;
37614081Sjavier.bueno@metempsy.com              else if ((abs(lsum) < 2 * thres / 3))
37714081Sjavier.bueno@metempsy.com                pred_taken = (secondH < 0) ? bi->scPred : prev_pred_taken;
37814081Sjavier.bueno@metempsy.com              else if ((abs(lsum) < thres))
37914081Sjavier.bueno@metempsy.com                pred_taken = (thirdH < 0) ? bi->scPred : prev_pred_taken;
38014081Sjavier.bueno@metempsy.com            }
38114081Sjavier.bueno@metempsy.com        }
38214081Sjavier.bueno@metempsy.com    }
38314081Sjavier.bueno@metempsy.com
38414081Sjavier.bueno@metempsy.com    return pred_taken;
38514081Sjavier.bueno@metempsy.com}
38614081Sjavier.bueno@metempsy.com
38714081Sjavier.bueno@metempsy.comMultiperspectivePerceptronTAGE::MultiperspectivePerceptronTAGE(
38814081Sjavier.bueno@metempsy.com    const MultiperspectivePerceptronTAGEParams *p)
38914081Sjavier.bueno@metempsy.com  : MultiperspectivePerceptron(p), tage(p->tage),
39014081Sjavier.bueno@metempsy.com    loopPredictor(p->loop_predictor),
39114081Sjavier.bueno@metempsy.com    statisticalCorrector(p->statistical_corrector)
39214081Sjavier.bueno@metempsy.com{
39314081Sjavier.bueno@metempsy.com    fatal_if(tage->isSpeculativeUpdateEnabled(),
39414081Sjavier.bueno@metempsy.com        "Speculative updates support is not implemented");
39514081Sjavier.bueno@metempsy.com}
39614081Sjavier.bueno@metempsy.com
39714081Sjavier.bueno@metempsy.comvoid
39814081Sjavier.bueno@metempsy.comMultiperspectivePerceptronTAGE::init()
39914081Sjavier.bueno@metempsy.com{
40014081Sjavier.bueno@metempsy.com    tage->init();
40114081Sjavier.bueno@metempsy.com    int numBitsTage = tage->getSizeInBits();
40214081Sjavier.bueno@metempsy.com    int numBitsLoopPred = loopPredictor->getSizeInBits();
40314081Sjavier.bueno@metempsy.com    int numBitsStatisticalCorrector = statisticalCorrector->getSizeInBits();
40414081Sjavier.bueno@metempsy.com
40514081Sjavier.bueno@metempsy.com    setExtraBits(numBitsTage + numBitsLoopPred + numBitsStatisticalCorrector);
40614081Sjavier.bueno@metempsy.com    MultiperspectivePerceptron::init();
40714081Sjavier.bueno@metempsy.com}
40814081Sjavier.bueno@metempsy.com
40914081Sjavier.bueno@metempsy.com
41014081Sjavier.bueno@metempsy.comunsigned int
41114081Sjavier.bueno@metempsy.comMultiperspectivePerceptronTAGE::getIndex(ThreadID tid, MPPTAGEBranchInfo &bi,
41214081Sjavier.bueno@metempsy.com        const HistorySpec &spec, int index) const
41314081Sjavier.bueno@metempsy.com{
41414081Sjavier.bueno@metempsy.com    // get the hash for the feature
41514081Sjavier.bueno@metempsy.com    unsigned int g = spec.getHash(tid, bi.getPC(), bi.getPC() >> 2, index);
41614081Sjavier.bueno@metempsy.com    // shift it and xor it with the hashed PC
41714081Sjavier.bueno@metempsy.com    unsigned long long int h = g;
41814081Sjavier.bueno@metempsy.com    h <<= 20;
41914081Sjavier.bueno@metempsy.com    h ^= (bi.getPC() ^ (bi.getPC() >> 2));
42014081Sjavier.bueno@metempsy.com
42114081Sjavier.bueno@metempsy.com    // maybe xor in an IMLI counter
42214081Sjavier.bueno@metempsy.com    if ((1ull << index) & imli_mask1) {
42314081Sjavier.bueno@metempsy.com        h += threadData[tid]->imli_counter[0];
42414081Sjavier.bueno@metempsy.com    }
42514081Sjavier.bueno@metempsy.com    if ((1ull << index) & imli_mask4) {
42614081Sjavier.bueno@metempsy.com        h += threadData[tid]->imli_counter[3];
42714081Sjavier.bueno@metempsy.com    }
42814081Sjavier.bueno@metempsy.com
42914081Sjavier.bueno@metempsy.com    // return it modulo the table size
43014081Sjavier.bueno@metempsy.com    return h % table_sizes[index];
43114081Sjavier.bueno@metempsy.com}
43214081Sjavier.bueno@metempsy.com
43314081Sjavier.bueno@metempsy.com
43414081Sjavier.bueno@metempsy.comint
43514081Sjavier.bueno@metempsy.comMultiperspectivePerceptronTAGE::computePartialSum(ThreadID tid,
43614081Sjavier.bueno@metempsy.com                                                  MPPTAGEBranchInfo &bi) const
43714081Sjavier.bueno@metempsy.com{
43814081Sjavier.bueno@metempsy.com    int yout = 0;
43914081Sjavier.bueno@metempsy.com    for (int i = 0; i < specs.size(); i += 1) {
44014081Sjavier.bueno@metempsy.com        yout += specs[i]->coeff *
44114081Sjavier.bueno@metempsy.com            threadData[tid]->tables[i][getIndex(tid, bi, *specs[i], i)];
44214081Sjavier.bueno@metempsy.com    }
44314081Sjavier.bueno@metempsy.com    return yout;
44414081Sjavier.bueno@metempsy.com}
44514081Sjavier.bueno@metempsy.com
44614081Sjavier.bueno@metempsy.comvoid
44714081Sjavier.bueno@metempsy.comMultiperspectivePerceptronTAGE::updatePartial(ThreadID tid,
44814081Sjavier.bueno@metempsy.com                                              MPPTAGEBranchInfo &bi,
44914081Sjavier.bueno@metempsy.com                                              bool taken)
45014081Sjavier.bueno@metempsy.com{
45114081Sjavier.bueno@metempsy.com    // update tables
45214081Sjavier.bueno@metempsy.com    for (int i = 0; i < specs.size(); i += 1) {
45314081Sjavier.bueno@metempsy.com        unsigned int idx = getIndex(tid, bi, *specs[i], i);
45414081Sjavier.bueno@metempsy.com        short int *c =
45514081Sjavier.bueno@metempsy.com            &threadData[tid]->tables[i][idx];
45614081Sjavier.bueno@metempsy.com        short int max_weight = (1 << (specs[i]->width - 1)) - 1;
45714081Sjavier.bueno@metempsy.com        short int min_weight = -(1 << (specs[i]->width - 1));
45814081Sjavier.bueno@metempsy.com        if (taken) {
45914081Sjavier.bueno@metempsy.com            if (*c < max_weight) {
46014081Sjavier.bueno@metempsy.com                *c += 1;
46114081Sjavier.bueno@metempsy.com            }
46214081Sjavier.bueno@metempsy.com        } else {
46314081Sjavier.bueno@metempsy.com            if (*c > min_weight) {
46414081Sjavier.bueno@metempsy.com                *c -= 1;
46514081Sjavier.bueno@metempsy.com            }
46614081Sjavier.bueno@metempsy.com        }
46714081Sjavier.bueno@metempsy.com    }
46814081Sjavier.bueno@metempsy.com}
46914081Sjavier.bueno@metempsy.com
47014081Sjavier.bueno@metempsy.comvoid
47114081Sjavier.bueno@metempsy.comMultiperspectivePerceptronTAGE::updateHistories(ThreadID tid,
47214081Sjavier.bueno@metempsy.com                                                MPPTAGEBranchInfo &bi,
47314081Sjavier.bueno@metempsy.com                                                bool taken)
47414081Sjavier.bueno@metempsy.com{
47514081Sjavier.bueno@metempsy.com    unsigned int hpc = (bi.getPC() ^ (bi.getPC() >> 2));
47614081Sjavier.bueno@metempsy.com    unsigned int pc = bi.getPC();
47714081Sjavier.bueno@metempsy.com
47814081Sjavier.bueno@metempsy.com    // update recency stack
47914081Sjavier.bueno@metempsy.com    unsigned short recency_pc = pc >> 2;
48014081Sjavier.bueno@metempsy.com    threadData[tid]->insertRecency(recency_pc, assoc);
48114081Sjavier.bueno@metempsy.com
48214081Sjavier.bueno@metempsy.com    // update acyclic history
48314081Sjavier.bueno@metempsy.com    threadData[tid]->updateAcyclic(taken, hpc);
48414081Sjavier.bueno@metempsy.com
48514081Sjavier.bueno@metempsy.com    // update modpath histories
48614081Sjavier.bueno@metempsy.com    for (int ii = 0; ii < modpath_indices.size(); ii +=1) {
48714081Sjavier.bueno@metempsy.com        int i = modpath_indices[ii];
48814081Sjavier.bueno@metempsy.com        if (hpc % (i + 2) == 0) {
48914081Sjavier.bueno@metempsy.com            memmove(&threadData[tid]->modpath_histories[i][1],
49014081Sjavier.bueno@metempsy.com                    &threadData[tid]->modpath_histories[i][0],
49114081Sjavier.bueno@metempsy.com                    sizeof(unsigned short int) * (modpath_lengths[ii] - 1));
49214081Sjavier.bueno@metempsy.com            threadData[tid]->modpath_histories[i][0] = hpc;
49314081Sjavier.bueno@metempsy.com        }
49414081Sjavier.bueno@metempsy.com    }
49514081Sjavier.bueno@metempsy.com
49614081Sjavier.bueno@metempsy.com    // update modulo histories
49714081Sjavier.bueno@metempsy.com    for (int ii = 0; ii < modhist_indices.size(); ii += 1) {
49814081Sjavier.bueno@metempsy.com        int i = modhist_indices[ii];
49914081Sjavier.bueno@metempsy.com        if (hpc % (i + 2) == 0) {
50014081Sjavier.bueno@metempsy.com            for (int j = modhist_lengths[ii] - 1; j > 0; j -= 1) {
50114081Sjavier.bueno@metempsy.com                threadData[tid]->mod_histories[i][j] =
50214081Sjavier.bueno@metempsy.com                    threadData[tid]->mod_histories[i][j-1];
50314081Sjavier.bueno@metempsy.com            }
50414081Sjavier.bueno@metempsy.com            threadData[tid]->mod_histories[i][0] = taken;
50514081Sjavier.bueno@metempsy.com        }
50614081Sjavier.bueno@metempsy.com    }
50714081Sjavier.bueno@metempsy.com
50814081Sjavier.bueno@metempsy.com    // update blurry history
50914081Sjavier.bueno@metempsy.com    std::vector<std::vector<unsigned int>> &blurrypath_histories =
51014081Sjavier.bueno@metempsy.com        threadData[tid]->blurrypath_histories;
51114081Sjavier.bueno@metempsy.com    for (int i = 0; i < blurrypath_histories.size(); i += 1)
51214081Sjavier.bueno@metempsy.com    {
51314081Sjavier.bueno@metempsy.com        if (blurrypath_histories[i].size() > 0) {
51414081Sjavier.bueno@metempsy.com            unsigned int z = pc >> i;
51514081Sjavier.bueno@metempsy.com            if (blurrypath_histories[i][0] != z) {
51614081Sjavier.bueno@metempsy.com                memmove(&blurrypath_histories[i][1],
51714081Sjavier.bueno@metempsy.com                        &blurrypath_histories[i][0],
51814081Sjavier.bueno@metempsy.com                        sizeof(unsigned int) *
51914081Sjavier.bueno@metempsy.com                        (blurrypath_histories[i].size() - 1));
52014081Sjavier.bueno@metempsy.com                blurrypath_histories[i][0] = z;
52114081Sjavier.bueno@metempsy.com            }
52214081Sjavier.bueno@metempsy.com        }
52314081Sjavier.bueno@metempsy.com    }
52414081Sjavier.bueno@metempsy.com}
52514081Sjavier.bueno@metempsy.com
52614081Sjavier.bueno@metempsy.combool
52714081Sjavier.bueno@metempsy.comMultiperspectivePerceptronTAGE::lookup(ThreadID tid, Addr instPC,
52814081Sjavier.bueno@metempsy.com                                   void * &bp_history)
52914081Sjavier.bueno@metempsy.com{
53014081Sjavier.bueno@metempsy.com    MPPTAGEBranchInfo *bi =
53114081Sjavier.bueno@metempsy.com        new MPPTAGEBranchInfo(instPC, pcshift, true, *tage, *loopPredictor,
53214081Sjavier.bueno@metempsy.com                              *statisticalCorrector);
53314081Sjavier.bueno@metempsy.com    bp_history = (void *)bi;
53414081Sjavier.bueno@metempsy.com    bool pred_taken = tage->tagePredict(tid, instPC, true, bi->tageBranchInfo);
53514081Sjavier.bueno@metempsy.com
53614081Sjavier.bueno@metempsy.com    pred_taken = loopPredictor->loopPredict(tid, instPC, true,
53714081Sjavier.bueno@metempsy.com            bi->lpBranchInfo, pred_taken, instShiftAmt);
53814081Sjavier.bueno@metempsy.com
53914081Sjavier.bueno@metempsy.com    bi->scBranchInfo->highConf = tage->isHighConfidence(bi->tageBranchInfo);
54014081Sjavier.bueno@metempsy.com
54114081Sjavier.bueno@metempsy.com    int init_lsum = 22;
54214081Sjavier.bueno@metempsy.com    if (!pred_taken) {
54314081Sjavier.bueno@metempsy.com        init_lsum = -init_lsum;
54414081Sjavier.bueno@metempsy.com    }
54514081Sjavier.bueno@metempsy.com    init_lsum += computePartialSum(tid, *bi);
54614081Sjavier.bueno@metempsy.com
54714081Sjavier.bueno@metempsy.com    pred_taken = statisticalCorrector->scPredict(tid, instPC, true,
54814081Sjavier.bueno@metempsy.com            bi->scBranchInfo, pred_taken, false /* bias_bit: unused */,
54914081Sjavier.bueno@metempsy.com            false /* use_tage_ctr: unused */, 0 /* conf_ctr: unused */,
55014081Sjavier.bueno@metempsy.com            0 /* conf_bits: unused */, 0 /* hitBank: unused */,
55114081Sjavier.bueno@metempsy.com            0 /* altBank: unused */, tage->getPathHist(tid), init_lsum);
55214081Sjavier.bueno@metempsy.com    bi->predictedTaken = pred_taken;
55314081Sjavier.bueno@metempsy.com    bi->lpBranchInfo->predTaken = pred_taken;
55414081Sjavier.bueno@metempsy.com    return pred_taken;
55514081Sjavier.bueno@metempsy.com}
55614081Sjavier.bueno@metempsy.com
55714081Sjavier.bueno@metempsy.com
55814081Sjavier.bueno@metempsy.comvoid
55914081Sjavier.bueno@metempsy.comMPP_StatisticalCorrector::condBranchUpdate(ThreadID tid, Addr branch_pc,
56014081Sjavier.bueno@metempsy.com        bool taken, StatisticalCorrector::BranchInfo *bi, Addr corrTarget,
56114081Sjavier.bueno@metempsy.com        bool bias_bit, int hitBank, int altBank, int64_t phist)
56214081Sjavier.bueno@metempsy.com{
56314081Sjavier.bueno@metempsy.com    bool scPred = (bi->lsum >= 0);
56414081Sjavier.bueno@metempsy.com
56514081Sjavier.bueno@metempsy.com    if (bi->predBeforeSC != scPred) {
56614081Sjavier.bueno@metempsy.com        if (abs(bi->lsum) < bi->thres) {
56714081Sjavier.bueno@metempsy.com            if (bi->highConf) {
56814081Sjavier.bueno@metempsy.com                if (abs(bi->lsum) < bi->thres / 3) {
56914081Sjavier.bueno@metempsy.com                    ctrUpdate(firstH, (bi->predBeforeSC == taken),
57014081Sjavier.bueno@metempsy.com                              chooserConfWidth);
57114081Sjavier.bueno@metempsy.com                } else if (abs(bi->lsum) < 2 * bi->thres / 3) {
57214081Sjavier.bueno@metempsy.com                    ctrUpdate(secondH, (bi->predBeforeSC == taken),
57314081Sjavier.bueno@metempsy.com                              chooserConfWidth);
57414081Sjavier.bueno@metempsy.com                } else if (abs(bi->lsum) < bi->thres) {
57514081Sjavier.bueno@metempsy.com                    ctrUpdate(thirdH, (bi->predBeforeSC == taken),
57614081Sjavier.bueno@metempsy.com                              chooserConfWidth);
57714081Sjavier.bueno@metempsy.com                }
57814081Sjavier.bueno@metempsy.com            }
57914081Sjavier.bueno@metempsy.com        }
58014081Sjavier.bueno@metempsy.com    }
58114081Sjavier.bueno@metempsy.com
58214081Sjavier.bueno@metempsy.com    if ((scPred != taken) || ((abs(bi->lsum) < bi->thres))) {
58314081Sjavier.bueno@metempsy.com
58414081Sjavier.bueno@metempsy.com        ctrUpdate(pUpdateThreshold[getIndUpd(branch_pc)], (scPred != taken),
58514081Sjavier.bueno@metempsy.com                  pUpdateThresholdWidth + 1); //+1 because the sign is ignored
58614081Sjavier.bueno@metempsy.com        if (pUpdateThreshold[getIndUpd(branch_pc)] < 0)
58714081Sjavier.bueno@metempsy.com            pUpdateThreshold[getIndUpd(branch_pc)] = 0;
58814081Sjavier.bueno@metempsy.com
58914081Sjavier.bueno@metempsy.com        unsigned indBias = getIndBias(branch_pc, bi, false);
59014081Sjavier.bueno@metempsy.com        unsigned indBiasSK = getIndBiasSK(branch_pc, bi);
59114081Sjavier.bueno@metempsy.com
59214081Sjavier.bueno@metempsy.com        ctrUpdate(bias[indBias], taken, scCountersWidth);
59314081Sjavier.bueno@metempsy.com        ctrUpdate(biasSK[indBiasSK], taken, scCountersWidth);
59414081Sjavier.bueno@metempsy.com
59514081Sjavier.bueno@metempsy.com        gUpdates(tid, branch_pc, taken, bi, phist);
59614081Sjavier.bueno@metempsy.com    }
59714081Sjavier.bueno@metempsy.com}
59814081Sjavier.bueno@metempsy.com
59914081Sjavier.bueno@metempsy.comvoid
60014081Sjavier.bueno@metempsy.comMultiperspectivePerceptronTAGE::update(ThreadID tid, Addr instPC, bool taken,
60114081Sjavier.bueno@metempsy.com                                   void *bp_history, bool squashed,
60214081Sjavier.bueno@metempsy.com                                   const StaticInstPtr & inst,
60314081Sjavier.bueno@metempsy.com                                   Addr corrTarget)
60414081Sjavier.bueno@metempsy.com{
60514081Sjavier.bueno@metempsy.com    assert(bp_history);
60614081Sjavier.bueno@metempsy.com    MPPTAGEBranchInfo *bi = static_cast<MPPTAGEBranchInfo*>(bp_history);
60714081Sjavier.bueno@metempsy.com
60814081Sjavier.bueno@metempsy.com    assert(corrTarget != MaxAddr);
60914081Sjavier.bueno@metempsy.com
61014081Sjavier.bueno@metempsy.com    if (squashed) {
61114081Sjavier.bueno@metempsy.com        if (tage->isSpeculativeUpdateEnabled()) {
61214081Sjavier.bueno@metempsy.com            // This restores the global history, then update it
61314081Sjavier.bueno@metempsy.com            // and recomputes the folded histories.
61414081Sjavier.bueno@metempsy.com            tage->squash(tid, taken, bi->tageBranchInfo, corrTarget);
61514081Sjavier.bueno@metempsy.com            if (bi->tageBranchInfo->condBranch) {
61614081Sjavier.bueno@metempsy.com                loopPredictor->squashLoop(bi->lpBranchInfo);
61714081Sjavier.bueno@metempsy.com            }
61814081Sjavier.bueno@metempsy.com        }
61914081Sjavier.bueno@metempsy.com        return;
62014081Sjavier.bueno@metempsy.com    }
62114081Sjavier.bueno@metempsy.com
62214081Sjavier.bueno@metempsy.com    if (bi->isUnconditional()) {
62314081Sjavier.bueno@metempsy.com        statisticalCorrector->scHistoryUpdate(instPC, inst, taken,
62414081Sjavier.bueno@metempsy.com                bi->scBranchInfo, corrTarget);
62514081Sjavier.bueno@metempsy.com        tage->updateHistories(tid, instPC, taken, bi->tageBranchInfo, false,
62614081Sjavier.bueno@metempsy.com                inst, corrTarget);
62714081Sjavier.bueno@metempsy.com    } else {
62814081Sjavier.bueno@metempsy.com        tage->updateStats(taken, bi->tageBranchInfo);
62914081Sjavier.bueno@metempsy.com        loopPredictor->updateStats(taken, bi->lpBranchInfo);
63014081Sjavier.bueno@metempsy.com        statisticalCorrector->updateStats(taken, bi->scBranchInfo);
63114081Sjavier.bueno@metempsy.com
63214081Sjavier.bueno@metempsy.com        loopPredictor->condBranchUpdate(tid, instPC, taken,
63314081Sjavier.bueno@metempsy.com                bi->tageBranchInfo->tagePred, bi->lpBranchInfo, instShiftAmt);
63414081Sjavier.bueno@metempsy.com
63514081Sjavier.bueno@metempsy.com        bool scPred = (bi->scBranchInfo->lsum >= 0);
63614081Sjavier.bueno@metempsy.com        if ((scPred != taken) ||
63714081Sjavier.bueno@metempsy.com            ((abs(bi->scBranchInfo->lsum) < bi->scBranchInfo->thres))) {
63814081Sjavier.bueno@metempsy.com            updatePartial(tid, *bi, taken);
63914081Sjavier.bueno@metempsy.com        }
64014081Sjavier.bueno@metempsy.com        statisticalCorrector->condBranchUpdate(tid, instPC, taken,
64114081Sjavier.bueno@metempsy.com                bi->scBranchInfo, corrTarget, false /* bias_bit: unused */,
64214081Sjavier.bueno@metempsy.com                0 /* hitBank: unused */, 0 /* altBank: unused*/,
64314081Sjavier.bueno@metempsy.com                tage->getPathHist(tid));
64414081Sjavier.bueno@metempsy.com
64514081Sjavier.bueno@metempsy.com        tage->condBranchUpdate(tid, instPC, taken, bi->tageBranchInfo,
64614081Sjavier.bueno@metempsy.com                               random_mt.random<int>(), corrTarget,
64714081Sjavier.bueno@metempsy.com                               bi->predictedTaken, true);
64814081Sjavier.bueno@metempsy.com
64914081Sjavier.bueno@metempsy.com        updateHistories(tid, *bi, taken);
65014081Sjavier.bueno@metempsy.com
65114081Sjavier.bueno@metempsy.com        if (!tage->isSpeculativeUpdateEnabled()) {
65214081Sjavier.bueno@metempsy.com            if (inst->isCondCtrl() && inst->isDirectCtrl()
65314081Sjavier.bueno@metempsy.com                && !inst->isCall() && !inst->isReturn()) {
65414081Sjavier.bueno@metempsy.com                uint32_t truncated_target = corrTarget;
65514081Sjavier.bueno@metempsy.com                uint32_t truncated_pc = instPC;
65614081Sjavier.bueno@metempsy.com                if (truncated_target < truncated_pc) {
65714081Sjavier.bueno@metempsy.com                    if (!taken) {
65814081Sjavier.bueno@metempsy.com                        threadData[tid]->imli_counter[0] = 0;
65914081Sjavier.bueno@metempsy.com                    } else {
66014081Sjavier.bueno@metempsy.com                        threadData[tid]->imli_counter[0] += 1;
66114081Sjavier.bueno@metempsy.com                    }
66214081Sjavier.bueno@metempsy.com                } else {
66314081Sjavier.bueno@metempsy.com                    if (taken) {
66414081Sjavier.bueno@metempsy.com                        threadData[tid]->imli_counter[3] = 0;
66514081Sjavier.bueno@metempsy.com                    } else {
66614081Sjavier.bueno@metempsy.com                        threadData[tid]->imli_counter[3] += 1;
66714081Sjavier.bueno@metempsy.com                    }
66814081Sjavier.bueno@metempsy.com                }
66914081Sjavier.bueno@metempsy.com            }
67014081Sjavier.bueno@metempsy.com
67114081Sjavier.bueno@metempsy.com            statisticalCorrector->scHistoryUpdate(instPC, inst, taken,
67214081Sjavier.bueno@metempsy.com                    bi->scBranchInfo, corrTarget);
67314081Sjavier.bueno@metempsy.com
67414081Sjavier.bueno@metempsy.com            tage->updateHistories(tid, instPC, taken, bi->tageBranchInfo,
67514081Sjavier.bueno@metempsy.com                                  false, inst, corrTarget);
67614081Sjavier.bueno@metempsy.com        }
67714081Sjavier.bueno@metempsy.com    }
67814081Sjavier.bueno@metempsy.com    delete bi;
67914081Sjavier.bueno@metempsy.com}
68014081Sjavier.bueno@metempsy.com
68114081Sjavier.bueno@metempsy.comvoid
68214081Sjavier.bueno@metempsy.comMultiperspectivePerceptronTAGE::uncondBranch(ThreadID tid, Addr pc,
68314081Sjavier.bueno@metempsy.com                                             void * &bp_history)
68414081Sjavier.bueno@metempsy.com{
68514081Sjavier.bueno@metempsy.com    MPPTAGEBranchInfo *bi =
68614081Sjavier.bueno@metempsy.com        new MPPTAGEBranchInfo(pc, pcshift, false, *tage, *loopPredictor,
68714081Sjavier.bueno@metempsy.com                              *statisticalCorrector);
68814081Sjavier.bueno@metempsy.com    bp_history = (void *) bi;
68914081Sjavier.bueno@metempsy.com}
69014081Sjavier.bueno@metempsy.com
69114081Sjavier.bueno@metempsy.comvoid
69214081Sjavier.bueno@metempsy.comMultiperspectivePerceptronTAGE::squash(ThreadID tid, void *bp_history)
69314081Sjavier.bueno@metempsy.com{
69414081Sjavier.bueno@metempsy.com    assert(bp_history);
69514081Sjavier.bueno@metempsy.com    MPPTAGEBranchInfo *bi = static_cast<MPPTAGEBranchInfo*>(bp_history);
69614081Sjavier.bueno@metempsy.com    delete bi;
69714081Sjavier.bueno@metempsy.com}
698