113685Sjavier.bueno@metempsy.com/*
213685Sjavier.bueno@metempsy.com * Copyright (c) 2018 Metempsy Technology Consulting
313685Sjavier.bueno@metempsy.com * All rights reserved.
413685Sjavier.bueno@metempsy.com *
513685Sjavier.bueno@metempsy.com * Copyright (c) 2006 INRIA (Institut National de Recherche en
613685Sjavier.bueno@metempsy.com * Informatique et en Automatique  / French National Research Institute
713685Sjavier.bueno@metempsy.com * for Computer Science and Applied Mathematics)
813685Sjavier.bueno@metempsy.com *
913685Sjavier.bueno@metempsy.com * All rights reserved.
1013685Sjavier.bueno@metempsy.com *
1113685Sjavier.bueno@metempsy.com * Redistribution and use in source and binary forms, with or without
1213685Sjavier.bueno@metempsy.com * modification, are permitted provided that the following conditions are
1313685Sjavier.bueno@metempsy.com * met: redistributions of source code must retain the above copyright
1413685Sjavier.bueno@metempsy.com * notice, this list of conditions and the following disclaimer;
1513685Sjavier.bueno@metempsy.com * redistributions in binary form must reproduce the above copyright
1613685Sjavier.bueno@metempsy.com * notice, this list of conditions and the following disclaimer in the
1713685Sjavier.bueno@metempsy.com * documentation and/or other materials provided with the distribution;
1813685Sjavier.bueno@metempsy.com * neither the name of the copyright holders nor the names of its
1913685Sjavier.bueno@metempsy.com * contributors may be used to endorse or promote products derived from
2013685Sjavier.bueno@metempsy.com * this software without specific prior written permission.
2113685Sjavier.bueno@metempsy.com *
2213685Sjavier.bueno@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2313685Sjavier.bueno@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2413685Sjavier.bueno@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2513685Sjavier.bueno@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2613685Sjavier.bueno@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2713685Sjavier.bueno@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2813685Sjavier.bueno@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2913685Sjavier.bueno@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3013685Sjavier.bueno@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3113685Sjavier.bueno@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3213685Sjavier.bueno@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3313685Sjavier.bueno@metempsy.com *
3413685Sjavier.bueno@metempsy.com * Author: André Seznec, Pau Cabre, Javier Bueno
3513685Sjavier.bueno@metempsy.com *
3613685Sjavier.bueno@metempsy.com */
3713685Sjavier.bueno@metempsy.com
3813685Sjavier.bueno@metempsy.com/*
3913685Sjavier.bueno@metempsy.com * TAGE-SC-L branch predictor base class (devised by Andre Seznec)
4013685Sjavier.bueno@metempsy.com * It consits of a TAGE + a statistical corrector (SC) + a loop predictor (L)
4113685Sjavier.bueno@metempsy.com */
4213685Sjavier.bueno@metempsy.com
4313685Sjavier.bueno@metempsy.com#include "cpu/pred/tage_sc_l.hh"
4413685Sjavier.bueno@metempsy.com
4513685Sjavier.bueno@metempsy.com#include "base/random.hh"
4613685Sjavier.bueno@metempsy.com#include "debug/TageSCL.hh"
4713685Sjavier.bueno@metempsy.com
4813685Sjavier.bueno@metempsy.combool
4913685Sjavier.bueno@metempsy.comTAGE_SC_L_LoopPredictor::calcConf(int index) const
5013685Sjavier.bueno@metempsy.com{
5113685Sjavier.bueno@metempsy.com    return LoopPredictor::calcConf(index) ||
5213685Sjavier.bueno@metempsy.com           (ltable[index].confidence * ltable[index].numIter > 128);
5313685Sjavier.bueno@metempsy.com}
5413685Sjavier.bueno@metempsy.com
5513685Sjavier.bueno@metempsy.combool
5613685Sjavier.bueno@metempsy.comTAGE_SC_L_LoopPredictor::optionalAgeInc() const
5713685Sjavier.bueno@metempsy.com{
5813685Sjavier.bueno@metempsy.com    return (random_mt.random<int>() & 7) == 0;
5913685Sjavier.bueno@metempsy.com}
6013685Sjavier.bueno@metempsy.com
6113685Sjavier.bueno@metempsy.comTAGE_SC_L_LoopPredictor *
6213685Sjavier.bueno@metempsy.comTAGE_SC_L_LoopPredictorParams::create()
6313685Sjavier.bueno@metempsy.com{
6413685Sjavier.bueno@metempsy.com    return new TAGE_SC_L_LoopPredictor(this);
6513685Sjavier.bueno@metempsy.com}
6613685Sjavier.bueno@metempsy.com
6713685Sjavier.bueno@metempsy.comTAGE_SC_L::TAGE_SC_L(const TAGE_SC_LParams *p)
6813685Sjavier.bueno@metempsy.com  : LTAGE(p), statisticalCorrector(p->statistical_corrector)
6913685Sjavier.bueno@metempsy.com{
7013685Sjavier.bueno@metempsy.com}
7113685Sjavier.bueno@metempsy.com
7213685Sjavier.bueno@metempsy.comTAGEBase::BranchInfo*
7313685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::makeBranchInfo()
7413685Sjavier.bueno@metempsy.com{
7513685Sjavier.bueno@metempsy.com    return new BranchInfo(*this);
7613685Sjavier.bueno@metempsy.com}
7713685Sjavier.bueno@metempsy.comvoid
7813685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::calculateParameters()
7913685Sjavier.bueno@metempsy.com{
8013685Sjavier.bueno@metempsy.com    unsigned numHistLengths = nHistoryTables/2;
8113685Sjavier.bueno@metempsy.com    histLengths[1] = minHist;
8213685Sjavier.bueno@metempsy.com    histLengths[numHistLengths] = maxHist;
8313685Sjavier.bueno@metempsy.com
8413685Sjavier.bueno@metempsy.com    // This calculates the different history lenghts
8513685Sjavier.bueno@metempsy.com    // there are only numHistLengths different lengths
8613685Sjavier.bueno@metempsy.com    // They are initially set to the lower half of histLengths
8713685Sjavier.bueno@metempsy.com    for (int i = 2; i <= numHistLengths; i++) {
8813685Sjavier.bueno@metempsy.com        histLengths[i] = (int) (((double) minHist *
8913685Sjavier.bueno@metempsy.com                       pow ((double) (maxHist) / (double) minHist,
9013685Sjavier.bueno@metempsy.com                           (double) (i - 1) / (double) ((numHistLengths - 1))))
9113685Sjavier.bueno@metempsy.com                       + 0.5);
9213685Sjavier.bueno@metempsy.com    }
9313685Sjavier.bueno@metempsy.com
9413685Sjavier.bueno@metempsy.com    // This copies and duplicates the values from the lower half of the table
9513685Sjavier.bueno@metempsy.com    // Ex: 4, 6, 9, 13 would get exanded to 4, 4, 6, 6, 9, 9, 13, 13
9613685Sjavier.bueno@metempsy.com    for (int i = nHistoryTables; i > 1; i--)
9713685Sjavier.bueno@metempsy.com    {
9813685Sjavier.bueno@metempsy.com        histLengths[i] = histLengths[(i + 1) / 2];
9913685Sjavier.bueno@metempsy.com    }
10013685Sjavier.bueno@metempsy.com
10113685Sjavier.bueno@metempsy.com    for (int i = 1; i <= nHistoryTables; i++)
10213685Sjavier.bueno@metempsy.com    {
10313685Sjavier.bueno@metempsy.com        tagTableTagWidths.push_back(
10413685Sjavier.bueno@metempsy.com            (i < firstLongTagTable) ? shortTagsSize : longTagsSize);
10513685Sjavier.bueno@metempsy.com
10613685Sjavier.bueno@metempsy.com        logTagTableSizes.push_back(logTagTableSize);
10713685Sjavier.bueno@metempsy.com    }
10813685Sjavier.bueno@metempsy.com}
10913685Sjavier.bueno@metempsy.com
11013685Sjavier.bueno@metempsy.comvoid
11113685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::buildTageTables()
11213685Sjavier.bueno@metempsy.com{
11313685Sjavier.bueno@metempsy.com    // Trick! We only allocate entries for tables 1 and firstLongTagTable and
11413685Sjavier.bueno@metempsy.com    // make the other tables point to these allocated entries
11513685Sjavier.bueno@metempsy.com
11613685Sjavier.bueno@metempsy.com    gtable[1] = new TageEntry[shortTagsTageFactor * (1 << logTagTableSize)];
11713685Sjavier.bueno@metempsy.com    gtable[firstLongTagTable] =
11813685Sjavier.bueno@metempsy.com        new TageEntry[longTagsTageFactor * (1 << logTagTableSize)];
11913685Sjavier.bueno@metempsy.com    for (int i = 2; i < firstLongTagTable; ++i) {
12013685Sjavier.bueno@metempsy.com        gtable[i] = gtable[1];
12113685Sjavier.bueno@metempsy.com    }
12213685Sjavier.bueno@metempsy.com    for (int i = firstLongTagTable + 1; i <= nHistoryTables; ++i) {
12313685Sjavier.bueno@metempsy.com        gtable[i] = gtable[firstLongTagTable];
12413685Sjavier.bueno@metempsy.com    }
12513685Sjavier.bueno@metempsy.com}
12613685Sjavier.bueno@metempsy.com
12713685Sjavier.bueno@metempsy.comvoid
12813685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::calculateIndicesAndTags(
12913685Sjavier.bueno@metempsy.com    ThreadID tid, Addr pc, TAGEBase::BranchInfo* bi)
13013685Sjavier.bueno@metempsy.com{
13113685Sjavier.bueno@metempsy.com    // computes the table addresses and the partial tags
13213685Sjavier.bueno@metempsy.com
13313685Sjavier.bueno@metempsy.com    for (int i = 1; i <= nHistoryTables; i += 2) {
13413685Sjavier.bueno@metempsy.com        tableIndices[i] = gindex(tid, pc, i);
13513685Sjavier.bueno@metempsy.com        tableTags[i] = gtag(tid, pc, i);
13613685Sjavier.bueno@metempsy.com        tableTags[i + 1] = tableTags[i];
13713685Sjavier.bueno@metempsy.com        tableIndices[i + 1] = tableIndices[i] ^
13813685Sjavier.bueno@metempsy.com                             (tableTags[i] & ((1 << logTagTableSizes[i]) - 1));
13913685Sjavier.bueno@metempsy.com
14013685Sjavier.bueno@metempsy.com        bi->tableTags[i] = tableTags[i];
14113685Sjavier.bueno@metempsy.com        bi->tableTags[i+1] = tableTags[i+1];
14213685Sjavier.bueno@metempsy.com    }
14313685Sjavier.bueno@metempsy.com
14413685Sjavier.bueno@metempsy.com    Addr t = (pc ^ (threadHistory[tid].pathHist &
14513685Sjavier.bueno@metempsy.com                    ((1 << histLengths[firstLongTagTable]) - 1)))
14613685Sjavier.bueno@metempsy.com             % longTagsTageFactor;
14713685Sjavier.bueno@metempsy.com
14813685Sjavier.bueno@metempsy.com    for (int i = firstLongTagTable; i <= nHistoryTables; i++) {
14913685Sjavier.bueno@metempsy.com        if (noSkip[i]) {
15013685Sjavier.bueno@metempsy.com            tableIndices[i] += (t << logTagTableSizes[i]);
15113685Sjavier.bueno@metempsy.com            bi->tableIndices[i] = tableIndices[i];
15213685Sjavier.bueno@metempsy.com            t++;
15313685Sjavier.bueno@metempsy.com            t = t % longTagsTageFactor;
15413685Sjavier.bueno@metempsy.com        }
15513685Sjavier.bueno@metempsy.com    }
15613685Sjavier.bueno@metempsy.com
15713685Sjavier.bueno@metempsy.com    t = (pc ^ (threadHistory[tid].pathHist & ((1 << histLengths[1]) - 1)))
15813685Sjavier.bueno@metempsy.com        % shortTagsTageFactor;
15913685Sjavier.bueno@metempsy.com
16013685Sjavier.bueno@metempsy.com    for (int i = 1; i <= firstLongTagTable - 1; i++) {
16113685Sjavier.bueno@metempsy.com        if (noSkip[i]) {
16213685Sjavier.bueno@metempsy.com            tableIndices[i] += (t << logTagTableSizes[i]);
16313685Sjavier.bueno@metempsy.com            bi->tableIndices[i] = tableIndices[i];
16413685Sjavier.bueno@metempsy.com            t++;
16513685Sjavier.bueno@metempsy.com            t = t % shortTagsTageFactor;
16613685Sjavier.bueno@metempsy.com        }
16713685Sjavier.bueno@metempsy.com    }
16813685Sjavier.bueno@metempsy.com}
16913685Sjavier.bueno@metempsy.com
17013685Sjavier.bueno@metempsy.comunsigned
17114081Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::getUseAltIdx(TAGEBase::BranchInfo* bi, Addr branch_pc)
17213685Sjavier.bueno@metempsy.com{
17313685Sjavier.bueno@metempsy.com    BranchInfo *tbi = static_cast<BranchInfo *>(bi);
17413685Sjavier.bueno@metempsy.com    unsigned idx;
17513685Sjavier.bueno@metempsy.com    idx = ((((bi->hitBank-1)/8)<<1)+tbi->altConf) % (numUseAltOnNa-1);
17613685Sjavier.bueno@metempsy.com    return idx;
17713685Sjavier.bueno@metempsy.com}
17813685Sjavier.bueno@metempsy.com
17913685Sjavier.bueno@metempsy.comint
18013685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::gindex(ThreadID tid, Addr pc, int bank) const
18113685Sjavier.bueno@metempsy.com{
18213685Sjavier.bueno@metempsy.com    int index;
18313685Sjavier.bueno@metempsy.com    int hlen = (histLengths[bank] > pathHistBits) ? pathHistBits :
18413685Sjavier.bueno@metempsy.com                                                    histLengths[bank];
18513685Sjavier.bueno@metempsy.com    unsigned int shortPc = pc;
18613685Sjavier.bueno@metempsy.com
18713685Sjavier.bueno@metempsy.com    // pc is not shifted by instShiftAmt in this implementation
18813685Sjavier.bueno@metempsy.com    index = shortPc ^
18913685Sjavier.bueno@metempsy.com            (shortPc >> ((int) abs(logTagTableSizes[bank] - bank) + 1)) ^
19013685Sjavier.bueno@metempsy.com            threadHistory[tid].computeIndices[bank].comp ^
19113685Sjavier.bueno@metempsy.com            F(threadHistory[tid].pathHist, hlen, bank);
19213685Sjavier.bueno@metempsy.com
19313685Sjavier.bueno@metempsy.com    index = gindex_ext(index, bank);
19413685Sjavier.bueno@metempsy.com
19513685Sjavier.bueno@metempsy.com    return (index & ((ULL(1) << (logTagTableSizes[bank])) - 1));
19613685Sjavier.bueno@metempsy.com}
19713685Sjavier.bueno@metempsy.com
19813685Sjavier.bueno@metempsy.comint
19913685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::F(int a, int size, int bank) const
20013685Sjavier.bueno@metempsy.com{
20113685Sjavier.bueno@metempsy.com    int a1, a2;
20213685Sjavier.bueno@metempsy.com
20313685Sjavier.bueno@metempsy.com    a = a & ((ULL(1) << size) - 1);
20413685Sjavier.bueno@metempsy.com    a1 = (a & ((ULL(1) << logTagTableSizes[bank]) - 1));
20513685Sjavier.bueno@metempsy.com    a2 = (a >> logTagTableSizes[bank]);
20613685Sjavier.bueno@metempsy.com
20713685Sjavier.bueno@metempsy.com    if (bank < logTagTableSizes[bank]) {
20813685Sjavier.bueno@metempsy.com        a2 = ((a2 << bank) & ((ULL(1) << logTagTableSizes[bank]) - 1))
20913685Sjavier.bueno@metempsy.com             + (a2 >> (logTagTableSizes[bank] - bank));
21013685Sjavier.bueno@metempsy.com    }
21113685Sjavier.bueno@metempsy.com
21213685Sjavier.bueno@metempsy.com    a = a1 ^ a2;
21313685Sjavier.bueno@metempsy.com
21413685Sjavier.bueno@metempsy.com    if (bank < logTagTableSizes[bank]) {
21513685Sjavier.bueno@metempsy.com        a = ((a << bank) & ((ULL(1) << logTagTableSizes[bank]) - 1))
21613685Sjavier.bueno@metempsy.com            + (a >> (logTagTableSizes[bank] - bank));
21713685Sjavier.bueno@metempsy.com    }
21813685Sjavier.bueno@metempsy.com
21913685Sjavier.bueno@metempsy.com    return a;
22013685Sjavier.bueno@metempsy.com}
22113685Sjavier.bueno@metempsy.com
22213685Sjavier.bueno@metempsy.comint
22313685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::bindex(Addr pc) const
22413685Sjavier.bueno@metempsy.com{
22513685Sjavier.bueno@metempsy.com    return ((pc ^ (pc >> instShiftAmt)) &
22613685Sjavier.bueno@metempsy.com            ((ULL(1) << (logTagTableSizes[0])) - 1));
22713685Sjavier.bueno@metempsy.com}
22813685Sjavier.bueno@metempsy.com
22913685Sjavier.bueno@metempsy.comvoid
23013685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::updatePathAndGlobalHistory(
23113685Sjavier.bueno@metempsy.com    ThreadHistory& tHist, int brtype, bool taken, Addr branch_pc, Addr target)
23213685Sjavier.bueno@metempsy.com{
23313685Sjavier.bueno@metempsy.com    // TAGE update
23413685Sjavier.bueno@metempsy.com    int tmp = ((branch_pc ^ (branch_pc >> instShiftAmt))) ^ taken;
23513685Sjavier.bueno@metempsy.com    int path = branch_pc ^ (branch_pc >> instShiftAmt)
23613685Sjavier.bueno@metempsy.com                         ^ (branch_pc >> (instShiftAmt+2));
23713685Sjavier.bueno@metempsy.com    if ((brtype == 3) & taken) {
23813685Sjavier.bueno@metempsy.com         tmp = (tmp ^ (target >> instShiftAmt));
23913685Sjavier.bueno@metempsy.com         path = path ^ (target >> instShiftAmt) ^ (target >> (instShiftAmt+2));
24013685Sjavier.bueno@metempsy.com    }
24113685Sjavier.bueno@metempsy.com
24213685Sjavier.bueno@metempsy.com    // some branch types use 3 bits in global history, the others just 2
24313685Sjavier.bueno@metempsy.com    int maxt = (brtype == 2) ? 3 : 2;
24413685Sjavier.bueno@metempsy.com
24513685Sjavier.bueno@metempsy.com    for (int t = 0; t < maxt; t++) {
24613685Sjavier.bueno@metempsy.com        bool dir = (tmp & 1);
24713685Sjavier.bueno@metempsy.com        tmp >>= 1;
24813685Sjavier.bueno@metempsy.com        int pathbit = (path & 127);
24913685Sjavier.bueno@metempsy.com        path >>= 1;
25013685Sjavier.bueno@metempsy.com        updateGHist(tHist.gHist, dir, tHist.globalHistory, tHist.ptGhist);
25113685Sjavier.bueno@metempsy.com        tHist.pathHist = (tHist.pathHist << 1) ^ pathbit;
25213685Sjavier.bueno@metempsy.com        if (truncatePathHist) {
25313685Sjavier.bueno@metempsy.com            // The 8KB implementation does not do this truncation
25413685Sjavier.bueno@metempsy.com            tHist.pathHist = (tHist.pathHist & ((ULL(1) << pathHistBits) - 1));
25513685Sjavier.bueno@metempsy.com        }
25613685Sjavier.bueno@metempsy.com        for (int i = 1; i <= nHistoryTables; i++) {
25713685Sjavier.bueno@metempsy.com            tHist.computeIndices[i].update(tHist.gHist);
25813685Sjavier.bueno@metempsy.com            tHist.computeTags[0][i].update(tHist.gHist);
25913685Sjavier.bueno@metempsy.com            tHist.computeTags[1][i].update(tHist.gHist);
26013685Sjavier.bueno@metempsy.com        }
26113685Sjavier.bueno@metempsy.com    }
26213685Sjavier.bueno@metempsy.com}
26313685Sjavier.bueno@metempsy.com
26413685Sjavier.bueno@metempsy.comvoid
26513685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::updateHistories(
26613685Sjavier.bueno@metempsy.com    ThreadID tid, Addr branch_pc, bool taken, TAGEBase::BranchInfo* b,
26713685Sjavier.bueno@metempsy.com    bool speculative, const StaticInstPtr &inst, Addr target)
26813685Sjavier.bueno@metempsy.com{
26913685Sjavier.bueno@metempsy.com    if (speculative != speculativeHistUpdate) {
27013685Sjavier.bueno@metempsy.com        return;
27113685Sjavier.bueno@metempsy.com    }
27213685Sjavier.bueno@metempsy.com    // speculation is not implemented
27313685Sjavier.bueno@metempsy.com    assert(! speculative);
27413685Sjavier.bueno@metempsy.com
27513685Sjavier.bueno@metempsy.com    ThreadHistory& tHist = threadHistory[tid];
27613685Sjavier.bueno@metempsy.com
27713685Sjavier.bueno@metempsy.com    int brtype = inst->isDirectCtrl() ? 0 : 2;
27813685Sjavier.bueno@metempsy.com    if (! inst->isUncondCtrl()) {
27913685Sjavier.bueno@metempsy.com        ++brtype;
28013685Sjavier.bueno@metempsy.com    }
28113685Sjavier.bueno@metempsy.com    updatePathAndGlobalHistory(tHist, brtype, taken, branch_pc, target);
28213685Sjavier.bueno@metempsy.com
28313685Sjavier.bueno@metempsy.com    DPRINTF(TageSCL, "Updating global histories with branch:%lx; taken?:%d, "
28413685Sjavier.bueno@metempsy.com            "path Hist: %x; pointer:%d\n", branch_pc, taken, tHist.pathHist,
28513685Sjavier.bueno@metempsy.com            tHist.ptGhist);
28613685Sjavier.bueno@metempsy.com}
28713685Sjavier.bueno@metempsy.com
28813685Sjavier.bueno@metempsy.comvoid
28913685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::squash(ThreadID tid, bool taken, TAGEBase::BranchInfo *bi,
29013685Sjavier.bueno@metempsy.com                       Addr target)
29113685Sjavier.bueno@metempsy.com{
29213685Sjavier.bueno@metempsy.com    fatal("Speculation is not implemented");
29313685Sjavier.bueno@metempsy.com}
29413685Sjavier.bueno@metempsy.com
29513685Sjavier.bueno@metempsy.comvoid
29613685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::adjustAlloc(bool & alloc, bool taken, bool pred_taken)
29713685Sjavier.bueno@metempsy.com{
29813685Sjavier.bueno@metempsy.com    // Do not allocate too often if the prediction is ok
29913685Sjavier.bueno@metempsy.com    if ((taken == pred_taken) && ((random_mt.random<int>() & 31) != 0)) {
30013685Sjavier.bueno@metempsy.com        alloc = false;
30113685Sjavier.bueno@metempsy.com    }
30213685Sjavier.bueno@metempsy.com}
30313685Sjavier.bueno@metempsy.com
30413685Sjavier.bueno@metempsy.comint
30513685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::calcDep(TAGEBase::BranchInfo* bi)
30613685Sjavier.bueno@metempsy.com{
30713685Sjavier.bueno@metempsy.com    int a = 1;
30813685Sjavier.bueno@metempsy.com    if ((random_mt.random<int>() & 127) < 32) {
30913685Sjavier.bueno@metempsy.com        a = 2;
31013685Sjavier.bueno@metempsy.com    }
31113685Sjavier.bueno@metempsy.com    return ((((bi->hitBank - 1 + 2 * a) & 0xffe)) ^
31213685Sjavier.bueno@metempsy.com            (random_mt.random<int>() & 1));
31313685Sjavier.bueno@metempsy.com}
31413685Sjavier.bueno@metempsy.com
31513685Sjavier.bueno@metempsy.comvoid
31613685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::handleUReset()
31713685Sjavier.bueno@metempsy.com{
31813685Sjavier.bueno@metempsy.com    //just the best formula for the Championship:
31913685Sjavier.bueno@metempsy.com    //In practice when one out of two entries are useful
32013685Sjavier.bueno@metempsy.com    if (tCounter < 0) {
32113685Sjavier.bueno@metempsy.com        tCounter = 0;
32213685Sjavier.bueno@metempsy.com    }
32313685Sjavier.bueno@metempsy.com
32413685Sjavier.bueno@metempsy.com    if (tCounter >= ((ULL(1) << logUResetPeriod))) {
32513685Sjavier.bueno@metempsy.com        // Update the u bits for the short tags table
32613685Sjavier.bueno@metempsy.com        for (int j = 0; j < (shortTagsTageFactor*(1<<logTagTableSize)); j++) {
32713685Sjavier.bueno@metempsy.com            resetUctr(gtable[1][j].u);
32813685Sjavier.bueno@metempsy.com        }
32913685Sjavier.bueno@metempsy.com
33013685Sjavier.bueno@metempsy.com        // Update the u bits for the long tags table
33113685Sjavier.bueno@metempsy.com        for (int j = 0; j < (longTagsTageFactor*(1<<logTagTableSize)); j++) {
33213685Sjavier.bueno@metempsy.com            resetUctr(gtable[firstLongTagTable][j].u);
33313685Sjavier.bueno@metempsy.com        }
33413685Sjavier.bueno@metempsy.com
33513685Sjavier.bueno@metempsy.com        tCounter = 0;
33613685Sjavier.bueno@metempsy.com    }
33713685Sjavier.bueno@metempsy.com}
33813685Sjavier.bueno@metempsy.com
33913685Sjavier.bueno@metempsy.combool
34013685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::getBimodePred(Addr pc, TAGEBase::BranchInfo* tage_bi) const
34113685Sjavier.bueno@metempsy.com{
34213685Sjavier.bueno@metempsy.com    TAGE_SC_L_TAGE::BranchInfo *bi =
34313685Sjavier.bueno@metempsy.com        static_cast<TAGE_SC_L_TAGE::BranchInfo *>(tage_bi);
34413685Sjavier.bueno@metempsy.com
34513685Sjavier.bueno@metempsy.com    int bim = (btablePrediction[bi->bimodalIndex] << 1)
34613685Sjavier.bueno@metempsy.com        + btableHysteresis[bi->bimodalIndex >> logRatioBiModalHystEntries];
34713685Sjavier.bueno@metempsy.com
34813685Sjavier.bueno@metempsy.com    bi->highConf = (bim == 0) || (bim == 3);
34913685Sjavier.bueno@metempsy.com    bi->lowConf = ! bi->highConf;
35013685Sjavier.bueno@metempsy.com    bi->altConf = bi->highConf;
35113685Sjavier.bueno@metempsy.com    bi->medConf = false;
35213685Sjavier.bueno@metempsy.com    return TAGEBase::getBimodePred(pc, tage_bi);
35313685Sjavier.bueno@metempsy.com}
35413685Sjavier.bueno@metempsy.com
35513685Sjavier.bueno@metempsy.comvoid
35613685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::extraAltCalc(TAGEBase::BranchInfo* bi)
35713685Sjavier.bueno@metempsy.com{
35813685Sjavier.bueno@metempsy.com    TAGE_SC_L_TAGE::BranchInfo *tage_scl_bi =
35913685Sjavier.bueno@metempsy.com        static_cast<TAGE_SC_L_TAGE::BranchInfo *>(bi);
36013685Sjavier.bueno@metempsy.com    int8_t ctr = gtable[bi->altBank][bi->altBankIndex].ctr;
36113685Sjavier.bueno@metempsy.com    tage_scl_bi->altConf = (abs(2*ctr + 1) > 1);
36213685Sjavier.bueno@metempsy.com}
36313685Sjavier.bueno@metempsy.com
36413685Sjavier.bueno@metempsy.combool
36513685Sjavier.bueno@metempsy.comTAGE_SC_L::predict(ThreadID tid, Addr branch_pc, bool cond_branch, void* &b)
36613685Sjavier.bueno@metempsy.com{
36713685Sjavier.bueno@metempsy.com    TageSCLBranchInfo *bi = new TageSCLBranchInfo(*tage,
36813685Sjavier.bueno@metempsy.com                                                  *statisticalCorrector,
36913685Sjavier.bueno@metempsy.com                                                  *loopPredictor);
37013685Sjavier.bueno@metempsy.com    b = (void*)(bi);
37113685Sjavier.bueno@metempsy.com
37213685Sjavier.bueno@metempsy.com    bool pred_taken = tage->tagePredict(tid, branch_pc, cond_branch,
37313685Sjavier.bueno@metempsy.com                                        bi->tageBranchInfo);
37413685Sjavier.bueno@metempsy.com    pred_taken = loopPredictor->loopPredict(tid, branch_pc, cond_branch,
37513685Sjavier.bueno@metempsy.com                                            bi->lpBranchInfo, pred_taken,
37613685Sjavier.bueno@metempsy.com                                            instShiftAmt);
37713685Sjavier.bueno@metempsy.com
37813685Sjavier.bueno@metempsy.com    if (bi->lpBranchInfo->loopPredUsed) {
37913685Sjavier.bueno@metempsy.com        bi->tageBranchInfo->provider = LOOP;
38013685Sjavier.bueno@metempsy.com    }
38113685Sjavier.bueno@metempsy.com
38213685Sjavier.bueno@metempsy.com    TAGE_SC_L_TAGE::BranchInfo* tage_scl_bi =
38313685Sjavier.bueno@metempsy.com        static_cast<TAGE_SC_L_TAGE::BranchInfo *>(bi->tageBranchInfo);
38413685Sjavier.bueno@metempsy.com
38513685Sjavier.bueno@metempsy.com    // Copy the confidences computed by TAGE
38613685Sjavier.bueno@metempsy.com    bi->scBranchInfo->lowConf = tage_scl_bi->lowConf;
38713685Sjavier.bueno@metempsy.com    bi->scBranchInfo->highConf = tage_scl_bi->highConf;
38813685Sjavier.bueno@metempsy.com    bi->scBranchInfo->altConf = tage_scl_bi->altConf;
38913685Sjavier.bueno@metempsy.com    bi->scBranchInfo->medConf = tage_scl_bi->medConf;
39013685Sjavier.bueno@metempsy.com
39113685Sjavier.bueno@metempsy.com    bool use_tage_ctr = bi->tageBranchInfo->hitBank > 0;
39213685Sjavier.bueno@metempsy.com    int8_t tage_ctr = use_tage_ctr ?
39313685Sjavier.bueno@metempsy.com        tage->getCtr(tage_scl_bi->hitBank, tage_scl_bi->hitBankIndex) : 0;
39413685Sjavier.bueno@metempsy.com    bool bias = (bi->tageBranchInfo->longestMatchPred !=
39513685Sjavier.bueno@metempsy.com                 bi->tageBranchInfo->altTaken);
39613685Sjavier.bueno@metempsy.com
39713685Sjavier.bueno@metempsy.com    pred_taken = statisticalCorrector->scPredict(tid, branch_pc, cond_branch,
39813685Sjavier.bueno@metempsy.com            bi->scBranchInfo, pred_taken, bias, use_tage_ctr, tage_ctr,
39913685Sjavier.bueno@metempsy.com            tage->getTageCtrBits(), bi->tageBranchInfo->hitBank,
40013685Sjavier.bueno@metempsy.com            bi->tageBranchInfo->altBank, tage->getPathHist(tid));
40113685Sjavier.bueno@metempsy.com
40213685Sjavier.bueno@metempsy.com    if (bi->scBranchInfo->usedScPred) {
40313685Sjavier.bueno@metempsy.com        bi->tageBranchInfo->provider = SC;
40413685Sjavier.bueno@metempsy.com    }
40513685Sjavier.bueno@metempsy.com
40613685Sjavier.bueno@metempsy.com    // record final prediction
40713685Sjavier.bueno@metempsy.com    bi->lpBranchInfo->predTaken = pred_taken;
40813685Sjavier.bueno@metempsy.com
40913685Sjavier.bueno@metempsy.com    return pred_taken;
41013685Sjavier.bueno@metempsy.com}
41113685Sjavier.bueno@metempsy.com
41213685Sjavier.bueno@metempsy.comvoid
41313685Sjavier.bueno@metempsy.comTAGE_SC_L::update(ThreadID tid, Addr branch_pc, bool taken, void *bp_history,
41413685Sjavier.bueno@metempsy.com        bool squashed, const StaticInstPtr & inst, Addr corrTarget)
41513685Sjavier.bueno@metempsy.com{
41613685Sjavier.bueno@metempsy.com    assert(bp_history);
41713685Sjavier.bueno@metempsy.com
41813685Sjavier.bueno@metempsy.com    TageSCLBranchInfo* bi = static_cast<TageSCLBranchInfo*>(bp_history);
41913685Sjavier.bueno@metempsy.com    TAGE_SC_L_TAGE::BranchInfo* tage_bi =
42013685Sjavier.bueno@metempsy.com        static_cast<TAGE_SC_L_TAGE::BranchInfo *>(bi->tageBranchInfo);
42113685Sjavier.bueno@metempsy.com
42213685Sjavier.bueno@metempsy.com    assert(corrTarget != MaxAddr);
42313685Sjavier.bueno@metempsy.com
42413685Sjavier.bueno@metempsy.com    if (squashed) {
42513685Sjavier.bueno@metempsy.com        if (tage->isSpeculativeUpdateEnabled()) {
42613685Sjavier.bueno@metempsy.com            // This restores the global history, then update it
42713685Sjavier.bueno@metempsy.com            // and recomputes the folded histories.
42813685Sjavier.bueno@metempsy.com            tage->squash(tid, taken, tage_bi, corrTarget);
42913685Sjavier.bueno@metempsy.com            if (bi->tageBranchInfo->condBranch) {
43013685Sjavier.bueno@metempsy.com                loopPredictor->squashLoop(bi->lpBranchInfo);
43113685Sjavier.bueno@metempsy.com            }
43213685Sjavier.bueno@metempsy.com        }
43313685Sjavier.bueno@metempsy.com        return;
43413685Sjavier.bueno@metempsy.com    }
43513685Sjavier.bueno@metempsy.com
43613685Sjavier.bueno@metempsy.com    int nrand = random_mt.random<int>() & 3;
43713685Sjavier.bueno@metempsy.com    if (tage_bi->condBranch) {
43813685Sjavier.bueno@metempsy.com        DPRINTF(TageSCL, "Updating tables for branch:%lx; taken?:%d\n",
43913685Sjavier.bueno@metempsy.com                branch_pc, taken);
44013685Sjavier.bueno@metempsy.com        tage->updateStats(taken, bi->tageBranchInfo);
44113685Sjavier.bueno@metempsy.com
44213685Sjavier.bueno@metempsy.com        loopPredictor->updateStats(taken, bi->lpBranchInfo);
44313685Sjavier.bueno@metempsy.com
44413685Sjavier.bueno@metempsy.com        statisticalCorrector->updateStats(taken, bi->scBranchInfo);
44513685Sjavier.bueno@metempsy.com
44613685Sjavier.bueno@metempsy.com        bool bias = (bi->tageBranchInfo->longestMatchPred !=
44713685Sjavier.bueno@metempsy.com                     bi->tageBranchInfo->altTaken);
44813685Sjavier.bueno@metempsy.com        statisticalCorrector->condBranchUpdate(tid, branch_pc, taken,
44913685Sjavier.bueno@metempsy.com            bi->scBranchInfo, corrTarget, bias, bi->tageBranchInfo->hitBank,
45013685Sjavier.bueno@metempsy.com            bi->tageBranchInfo->altBank, tage->getPathHist(tid));
45113685Sjavier.bueno@metempsy.com
45213685Sjavier.bueno@metempsy.com        loopPredictor->condBranchUpdate(tid, branch_pc, taken,
45313685Sjavier.bueno@metempsy.com                bi->tageBranchInfo->tagePred, bi->lpBranchInfo, instShiftAmt);
45413685Sjavier.bueno@metempsy.com
45513685Sjavier.bueno@metempsy.com        tage->condBranchUpdate(tid, branch_pc, taken, bi->tageBranchInfo,
45613685Sjavier.bueno@metempsy.com                               nrand, corrTarget, bi->lpBranchInfo->predTaken);
45713685Sjavier.bueno@metempsy.com    }
45813685Sjavier.bueno@metempsy.com
45913685Sjavier.bueno@metempsy.com    if (!tage->isSpeculativeUpdateEnabled()) {
46014081Sjavier.bueno@metempsy.com        statisticalCorrector->scHistoryUpdate(branch_pc, inst, taken,
46113685Sjavier.bueno@metempsy.com                                              bi->scBranchInfo, corrTarget);
46213685Sjavier.bueno@metempsy.com
46313685Sjavier.bueno@metempsy.com        tage->updateHistories(tid, branch_pc, taken, bi->tageBranchInfo, false,
46413685Sjavier.bueno@metempsy.com                              inst, corrTarget);
46513685Sjavier.bueno@metempsy.com    }
46613685Sjavier.bueno@metempsy.com
46713685Sjavier.bueno@metempsy.com    delete bi;
46813685Sjavier.bueno@metempsy.com}
46913685Sjavier.bueno@metempsy.com
47013685Sjavier.bueno@metempsy.comvoid
47113685Sjavier.bueno@metempsy.comTAGE_SC_L::regStats()
47213685Sjavier.bueno@metempsy.com{
47313685Sjavier.bueno@metempsy.com    LTAGE::regStats();
47413685Sjavier.bueno@metempsy.com}
475