113627Sjavier.bueno@metempsy.com/*
213627Sjavier.bueno@metempsy.com * Copyright (c) 2014 The University of Wisconsin
313627Sjavier.bueno@metempsy.com *
413627Sjavier.bueno@metempsy.com * Copyright (c) 2006 INRIA (Institut National de Recherche en
513627Sjavier.bueno@metempsy.com * Informatique et en Automatique  / French National Research Institute
613627Sjavier.bueno@metempsy.com * for Computer Science and Applied Mathematics)
713627Sjavier.bueno@metempsy.com *
813627Sjavier.bueno@metempsy.com * All rights reserved.
913627Sjavier.bueno@metempsy.com *
1013627Sjavier.bueno@metempsy.com * Redistribution and use in source and binary forms, with or without
1113627Sjavier.bueno@metempsy.com * modification, are permitted provided that the following conditions are
1213627Sjavier.bueno@metempsy.com * met: redistributions of source code must retain the above copyright
1313627Sjavier.bueno@metempsy.com * notice, this list of conditions and the following disclaimer;
1413627Sjavier.bueno@metempsy.com * redistributions in binary form must reproduce the above copyright
1513627Sjavier.bueno@metempsy.com * notice, this list of conditions and the following disclaimer in the
1613627Sjavier.bueno@metempsy.com * documentation and/or other materials provided with the distribution;
1713627Sjavier.bueno@metempsy.com * neither the name of the copyright holders nor the names of its
1813627Sjavier.bueno@metempsy.com * contributors may be used to endorse or promote products derived from
1913627Sjavier.bueno@metempsy.com * this software without specific prior written permission.
2013627Sjavier.bueno@metempsy.com *
2113627Sjavier.bueno@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2213627Sjavier.bueno@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2313627Sjavier.bueno@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2413627Sjavier.bueno@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2513627Sjavier.bueno@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2613627Sjavier.bueno@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2713627Sjavier.bueno@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2813627Sjavier.bueno@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2913627Sjavier.bueno@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3013627Sjavier.bueno@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3113627Sjavier.bueno@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3213627Sjavier.bueno@metempsy.com *
3313627Sjavier.bueno@metempsy.com * Authors: Vignyan Reddy, Dibakar Gope and Arthur Perais,
3413627Sjavier.bueno@metempsy.com * from André Seznec's code.
3513627Sjavier.bueno@metempsy.com */
3613627Sjavier.bueno@metempsy.com
3713627Sjavier.bueno@metempsy.com#include "cpu/pred/loop_predictor.hh"
3813627Sjavier.bueno@metempsy.com
3913685Sjavier.bueno@metempsy.com#include "base/random.hh"
4013685Sjavier.bueno@metempsy.com#include "debug/LTage.hh"
4113627Sjavier.bueno@metempsy.com#include "params/LoopPredictor.hh"
4213627Sjavier.bueno@metempsy.com
4313627Sjavier.bueno@metempsy.comLoopPredictor::LoopPredictor(LoopPredictorParams *p)
4413627Sjavier.bueno@metempsy.com  : SimObject(p), logSizeLoopPred(p->logSizeLoopPred),
4513627Sjavier.bueno@metempsy.com    loopTableAgeBits(p->loopTableAgeBits),
4613627Sjavier.bueno@metempsy.com    loopTableConfidenceBits(p->loopTableConfidenceBits),
4713627Sjavier.bueno@metempsy.com    loopTableTagBits(p->loopTableTagBits),
4813627Sjavier.bueno@metempsy.com    loopTableIterBits(p->loopTableIterBits),
4913627Sjavier.bueno@metempsy.com    logLoopTableAssoc(p->logLoopTableAssoc),
5013627Sjavier.bueno@metempsy.com    confidenceThreshold((1 << loopTableConfidenceBits) - 1),
5113627Sjavier.bueno@metempsy.com    loopTagMask((1 << loopTableTagBits) - 1),
5213627Sjavier.bueno@metempsy.com    loopNumIterMask((1 << loopTableIterBits) - 1),
5313627Sjavier.bueno@metempsy.com    loopSetMask((1 << (logSizeLoopPred - logLoopTableAssoc)) - 1),
5413627Sjavier.bueno@metempsy.com    loopUseCounter(-1),
5513627Sjavier.bueno@metempsy.com    withLoopBits(p->withLoopBits),
5613627Sjavier.bueno@metempsy.com    useDirectionBit(p->useDirectionBit),
5713627Sjavier.bueno@metempsy.com    useSpeculation(p->useSpeculation),
5813627Sjavier.bueno@metempsy.com    useHashing(p->useHashing),
5913627Sjavier.bueno@metempsy.com    restrictAllocation(p->restrictAllocation),
6013627Sjavier.bueno@metempsy.com    initialLoopIter(p->initialLoopIter),
6113627Sjavier.bueno@metempsy.com    initialLoopAge(p->initialLoopAge),
6213627Sjavier.bueno@metempsy.com    optionalAgeReset(p->optionalAgeReset)
6313627Sjavier.bueno@metempsy.com{
6413627Sjavier.bueno@metempsy.com    assert(initialLoopAge <= ((1 << loopTableAgeBits) - 1));
6513627Sjavier.bueno@metempsy.com}
6613627Sjavier.bueno@metempsy.com
6713627Sjavier.bueno@metempsy.comvoid
6813627Sjavier.bueno@metempsy.comLoopPredictor::init()
6913627Sjavier.bueno@metempsy.com{
7013627Sjavier.bueno@metempsy.com    // we use uint16_t type for these vales, so they cannot be more than
7113627Sjavier.bueno@metempsy.com    // 16 bits
7213627Sjavier.bueno@metempsy.com    assert(loopTableTagBits <= 16);
7313627Sjavier.bueno@metempsy.com    assert(loopTableIterBits <= 16);
7413627Sjavier.bueno@metempsy.com
7513627Sjavier.bueno@metempsy.com    assert(logSizeLoopPred >= logLoopTableAssoc);
7613627Sjavier.bueno@metempsy.com
7713627Sjavier.bueno@metempsy.com    ltable = new LoopEntry[ULL(1) << logSizeLoopPred];
7813627Sjavier.bueno@metempsy.com}
7913627Sjavier.bueno@metempsy.com
8013627Sjavier.bueno@metempsy.comLoopPredictor::BranchInfo*
8113627Sjavier.bueno@metempsy.comLoopPredictor::makeBranchInfo()
8213627Sjavier.bueno@metempsy.com{
8313627Sjavier.bueno@metempsy.com    return new BranchInfo();
8413627Sjavier.bueno@metempsy.com}
8513627Sjavier.bueno@metempsy.com
8613627Sjavier.bueno@metempsy.comint
8713627Sjavier.bueno@metempsy.comLoopPredictor::lindex(Addr pc_in, unsigned instShiftAmt) const
8813627Sjavier.bueno@metempsy.com{
8913627Sjavier.bueno@metempsy.com    // The loop table is implemented as a linear table
9013627Sjavier.bueno@metempsy.com    // If associativity is N (N being 1 << logLoopTableAssoc),
9113627Sjavier.bueno@metempsy.com    // the first N entries are for set 0, the next N entries are for set 1,
9213627Sjavier.bueno@metempsy.com    // and so on.
9313627Sjavier.bueno@metempsy.com    // Thus, this function calculates the set and then it gets left shifted
9413627Sjavier.bueno@metempsy.com    // by logLoopTableAssoc in order to return the index of the first of the
9513627Sjavier.bueno@metempsy.com    // N entries of the set
9613627Sjavier.bueno@metempsy.com    Addr pc = pc_in >> instShiftAmt;
9713627Sjavier.bueno@metempsy.com    if (useHashing) {
9813627Sjavier.bueno@metempsy.com        pc ^= pc_in;
9913627Sjavier.bueno@metempsy.com    }
10013627Sjavier.bueno@metempsy.com    return ((pc & loopSetMask) << logLoopTableAssoc);
10113627Sjavier.bueno@metempsy.com}
10213627Sjavier.bueno@metempsy.com
10313627Sjavier.bueno@metempsy.comint
10413627Sjavier.bueno@metempsy.comLoopPredictor::finallindex(int index, int lowPcBits, int way) const
10513627Sjavier.bueno@metempsy.com{
10613627Sjavier.bueno@metempsy.com    return (useHashing ? (index ^ ((lowPcBits >> way) << logLoopTableAssoc)) :
10713627Sjavier.bueno@metempsy.com                         (index))
10813627Sjavier.bueno@metempsy.com           + way;
10913627Sjavier.bueno@metempsy.com}
11013627Sjavier.bueno@metempsy.com
11113627Sjavier.bueno@metempsy.com//loop prediction: only used if high confidence
11213627Sjavier.bueno@metempsy.combool
11313627Sjavier.bueno@metempsy.comLoopPredictor::getLoop(Addr pc, BranchInfo* bi, bool speculative,
11413627Sjavier.bueno@metempsy.com                       unsigned instShiftAmt) const
11513627Sjavier.bueno@metempsy.com{
11613627Sjavier.bueno@metempsy.com    bi->loopHit = -1;
11713627Sjavier.bueno@metempsy.com    bi->loopPredValid = false;
11813627Sjavier.bueno@metempsy.com    bi->loopIndex = lindex(pc, instShiftAmt);
11913627Sjavier.bueno@metempsy.com
12013627Sjavier.bueno@metempsy.com    if (useHashing) {
12113627Sjavier.bueno@metempsy.com        unsigned pcShift = logSizeLoopPred - logLoopTableAssoc;
12213627Sjavier.bueno@metempsy.com        bi->loopIndexB = (pc >> pcShift) & loopSetMask;
12313627Sjavier.bueno@metempsy.com        bi->loopTag = (pc >> pcShift) ^ (pc >> (pcShift + loopTableTagBits));
12413627Sjavier.bueno@metempsy.com        bi->loopTag &= loopTagMask;
12513627Sjavier.bueno@metempsy.com    } else {
12613627Sjavier.bueno@metempsy.com        unsigned pcShift = instShiftAmt + logSizeLoopPred - logLoopTableAssoc;
12713627Sjavier.bueno@metempsy.com        bi->loopTag = (pc >> pcShift) & loopTagMask;
12813627Sjavier.bueno@metempsy.com        // bi->loopIndexB is not used without hash
12913627Sjavier.bueno@metempsy.com    }
13013627Sjavier.bueno@metempsy.com
13113627Sjavier.bueno@metempsy.com    for (int i = 0; i < (1 << logLoopTableAssoc); i++) {
13213627Sjavier.bueno@metempsy.com        int idx = finallindex(bi->loopIndex, bi->loopIndexB, i);
13313627Sjavier.bueno@metempsy.com        if (ltable[idx].tag == bi->loopTag) {
13413627Sjavier.bueno@metempsy.com            bi->loopHit = i;
13513627Sjavier.bueno@metempsy.com            bi->loopPredValid = calcConf(idx);
13613627Sjavier.bueno@metempsy.com
13713627Sjavier.bueno@metempsy.com            uint16_t iter = speculative ? ltable[idx].currentIterSpec
13813627Sjavier.bueno@metempsy.com                                        : ltable[idx].currentIter;
13913627Sjavier.bueno@metempsy.com
14013627Sjavier.bueno@metempsy.com            if ((iter + 1) == ltable[idx].numIter) {
14113627Sjavier.bueno@metempsy.com                return useDirectionBit ? !(ltable[idx].dir) : false;
14213627Sjavier.bueno@metempsy.com            } else {
14313627Sjavier.bueno@metempsy.com                return useDirectionBit ? (ltable[idx].dir) : true;
14413627Sjavier.bueno@metempsy.com            }
14513627Sjavier.bueno@metempsy.com        }
14613627Sjavier.bueno@metempsy.com    }
14713627Sjavier.bueno@metempsy.com    return false;
14813627Sjavier.bueno@metempsy.com}
14913627Sjavier.bueno@metempsy.com
15013627Sjavier.bueno@metempsy.combool
15113627Sjavier.bueno@metempsy.comLoopPredictor::calcConf(int index) const
15213627Sjavier.bueno@metempsy.com{
15313627Sjavier.bueno@metempsy.com    return ltable[index].confidence == confidenceThreshold;
15413627Sjavier.bueno@metempsy.com}
15513627Sjavier.bueno@metempsy.com
15613627Sjavier.bueno@metempsy.comvoid
15713627Sjavier.bueno@metempsy.comLoopPredictor::specLoopUpdate(bool taken, BranchInfo* bi)
15813627Sjavier.bueno@metempsy.com{
15913627Sjavier.bueno@metempsy.com    if (bi->loopHit>=0) {
16013627Sjavier.bueno@metempsy.com        int index = finallindex(bi->loopIndex, bi->loopIndexB, bi->loopHit);
16113627Sjavier.bueno@metempsy.com        if (taken != ltable[index].dir) {
16213627Sjavier.bueno@metempsy.com            ltable[index].currentIterSpec = 0;
16313627Sjavier.bueno@metempsy.com        } else {
16413627Sjavier.bueno@metempsy.com            ltable[index].currentIterSpec =
16513627Sjavier.bueno@metempsy.com                (ltable[index].currentIterSpec + 1) & loopNumIterMask;
16613627Sjavier.bueno@metempsy.com        }
16713627Sjavier.bueno@metempsy.com    }
16813627Sjavier.bueno@metempsy.com}
16913627Sjavier.bueno@metempsy.com
17013627Sjavier.bueno@metempsy.combool
17113685Sjavier.bueno@metempsy.comLoopPredictor::optionalAgeInc() const
17213627Sjavier.bueno@metempsy.com{
17313627Sjavier.bueno@metempsy.com    return false;
17413627Sjavier.bueno@metempsy.com}
17513627Sjavier.bueno@metempsy.com
17613627Sjavier.bueno@metempsy.comvoid
17713685Sjavier.bueno@metempsy.comLoopPredictor::loopUpdate(Addr pc, bool taken, BranchInfo* bi, bool tage_pred)
17813627Sjavier.bueno@metempsy.com{
17913627Sjavier.bueno@metempsy.com    int idx = finallindex(bi->loopIndex, bi->loopIndexB, bi->loopHit);
18013627Sjavier.bueno@metempsy.com    if (bi->loopHit >= 0) {
18113627Sjavier.bueno@metempsy.com        //already a hit
18213627Sjavier.bueno@metempsy.com        if (bi->loopPredValid) {
18313627Sjavier.bueno@metempsy.com            if (taken != bi->loopPred) {
18413627Sjavier.bueno@metempsy.com                // free the entry
18513627Sjavier.bueno@metempsy.com                ltable[idx].numIter = 0;
18613627Sjavier.bueno@metempsy.com                ltable[idx].age = 0;
18713627Sjavier.bueno@metempsy.com                ltable[idx].confidence = 0;
18813627Sjavier.bueno@metempsy.com                ltable[idx].currentIter = 0;
18913627Sjavier.bueno@metempsy.com                return;
19013685Sjavier.bueno@metempsy.com            } else if (bi->loopPred != tage_pred || optionalAgeInc()) {
19113685Sjavier.bueno@metempsy.com                DPRINTF(LTage, "Loop Prediction success:%lx\n",pc);
19213627Sjavier.bueno@metempsy.com                unsignedCtrUpdate(ltable[idx].age, true, loopTableAgeBits);
19313627Sjavier.bueno@metempsy.com            }
19413627Sjavier.bueno@metempsy.com        }
19513627Sjavier.bueno@metempsy.com
19613627Sjavier.bueno@metempsy.com        ltable[idx].currentIter =
19713627Sjavier.bueno@metempsy.com            (ltable[idx].currentIter + 1) & loopNumIterMask;
19813627Sjavier.bueno@metempsy.com        if (ltable[idx].currentIter > ltable[idx].numIter) {
19913627Sjavier.bueno@metempsy.com            ltable[idx].confidence = 0;
20013627Sjavier.bueno@metempsy.com            if (ltable[idx].numIter != 0) {
20113627Sjavier.bueno@metempsy.com                // free the entry
20213627Sjavier.bueno@metempsy.com                ltable[idx].numIter = 0;
20313627Sjavier.bueno@metempsy.com                if (optionalAgeReset) {
20413627Sjavier.bueno@metempsy.com                    ltable[idx].age = 0;
20513627Sjavier.bueno@metempsy.com                }
20613627Sjavier.bueno@metempsy.com            }
20713627Sjavier.bueno@metempsy.com        }
20813627Sjavier.bueno@metempsy.com
20913627Sjavier.bueno@metempsy.com        if (taken != (useDirectionBit ? ltable[idx].dir : true)) {
21013627Sjavier.bueno@metempsy.com            if (ltable[idx].currentIter == ltable[idx].numIter) {
21113685Sjavier.bueno@metempsy.com                DPRINTF(LTage, "Loop End predicted successfully:%lx\n", pc);
21213627Sjavier.bueno@metempsy.com                unsignedCtrUpdate(ltable[idx].confidence, true,
21313627Sjavier.bueno@metempsy.com                                  loopTableConfidenceBits);
21413627Sjavier.bueno@metempsy.com                //just do not predict when the loop count is 1 or 2
21513627Sjavier.bueno@metempsy.com                if (ltable[idx].numIter < 3) {
21613627Sjavier.bueno@metempsy.com                    // free the entry
21713627Sjavier.bueno@metempsy.com                    ltable[idx].dir = taken; // ignored if no useDirectionBit
21813627Sjavier.bueno@metempsy.com                    ltable[idx].numIter = 0;
21913627Sjavier.bueno@metempsy.com                    ltable[idx].age = 0;
22013627Sjavier.bueno@metempsy.com                    ltable[idx].confidence = 0;
22113627Sjavier.bueno@metempsy.com                }
22213627Sjavier.bueno@metempsy.com            } else {
22313685Sjavier.bueno@metempsy.com                DPRINTF(LTage, "Loop End predicted incorrectly:%lx\n", pc);
22413627Sjavier.bueno@metempsy.com                if (ltable[idx].numIter == 0) {
22513627Sjavier.bueno@metempsy.com                    // first complete nest;
22613627Sjavier.bueno@metempsy.com                    ltable[idx].confidence = 0;
22713627Sjavier.bueno@metempsy.com                    ltable[idx].numIter = ltable[idx].currentIter;
22813627Sjavier.bueno@metempsy.com                } else {
22913627Sjavier.bueno@metempsy.com                    //not the same number of iterations as last time: free the
23013627Sjavier.bueno@metempsy.com                    //entry
23113627Sjavier.bueno@metempsy.com                    ltable[idx].numIter = 0;
23213627Sjavier.bueno@metempsy.com                    if (optionalAgeReset) {
23313627Sjavier.bueno@metempsy.com                        ltable[idx].age = 0;
23413627Sjavier.bueno@metempsy.com                    }
23513627Sjavier.bueno@metempsy.com                    ltable[idx].confidence = 0;
23613627Sjavier.bueno@metempsy.com                }
23713627Sjavier.bueno@metempsy.com            }
23813627Sjavier.bueno@metempsy.com            ltable[idx].currentIter = 0;
23913627Sjavier.bueno@metempsy.com        }
24013627Sjavier.bueno@metempsy.com
24113627Sjavier.bueno@metempsy.com    } else if (useDirectionBit ? (bi->predTaken != taken) : taken) {
24213685Sjavier.bueno@metempsy.com        if ((random_mt.random<int>() & 3) == 0 || !restrictAllocation) {
24313627Sjavier.bueno@metempsy.com            //try to allocate an entry on taken branch
24413685Sjavier.bueno@metempsy.com            int nrand = random_mt.random<int>();
24513627Sjavier.bueno@metempsy.com            for (int i = 0; i < (1 << logLoopTableAssoc); i++) {
24613627Sjavier.bueno@metempsy.com                int loop_hit = (nrand + i) & ((1 << logLoopTableAssoc) - 1);
24713627Sjavier.bueno@metempsy.com                idx = finallindex(bi->loopIndex, bi->loopIndexB, loop_hit);
24813627Sjavier.bueno@metempsy.com                if (ltable[idx].age == 0) {
24913685Sjavier.bueno@metempsy.com                    DPRINTF(LTage,
25013685Sjavier.bueno@metempsy.com                            "Allocating loop pred entry for branch %lx\n",
25113685Sjavier.bueno@metempsy.com                            pc);
25213627Sjavier.bueno@metempsy.com                    ltable[idx].dir = !taken; // ignored if no useDirectionBit
25313627Sjavier.bueno@metempsy.com                    ltable[idx].tag = bi->loopTag;
25413627Sjavier.bueno@metempsy.com                    ltable[idx].numIter = 0;
25513627Sjavier.bueno@metempsy.com                    ltable[idx].age = initialLoopAge;
25613627Sjavier.bueno@metempsy.com                    ltable[idx].confidence = 0;
25713627Sjavier.bueno@metempsy.com                    ltable[idx].currentIter = initialLoopIter;
25813627Sjavier.bueno@metempsy.com                    break;
25913627Sjavier.bueno@metempsy.com
26013627Sjavier.bueno@metempsy.com                } else {
26113627Sjavier.bueno@metempsy.com                    ltable[idx].age--;
26213627Sjavier.bueno@metempsy.com                }
26313627Sjavier.bueno@metempsy.com                if (restrictAllocation) {
26413627Sjavier.bueno@metempsy.com                    break;
26513627Sjavier.bueno@metempsy.com                }
26613627Sjavier.bueno@metempsy.com            }
26713627Sjavier.bueno@metempsy.com        }
26813627Sjavier.bueno@metempsy.com    }
26913627Sjavier.bueno@metempsy.com}
27013627Sjavier.bueno@metempsy.com
27113627Sjavier.bueno@metempsy.combool
27213627Sjavier.bueno@metempsy.comLoopPredictor::loopPredict(ThreadID tid, Addr branch_pc, bool cond_branch,
27313627Sjavier.bueno@metempsy.com                   BranchInfo* bi, bool prev_pred_taken, unsigned instShiftAmt)
27413627Sjavier.bueno@metempsy.com{
27513627Sjavier.bueno@metempsy.com    bool pred_taken = prev_pred_taken;
27613627Sjavier.bueno@metempsy.com    if (cond_branch) {
27713627Sjavier.bueno@metempsy.com        // loop prediction
27813627Sjavier.bueno@metempsy.com        bi->loopPred = getLoop(branch_pc, bi, useSpeculation, instShiftAmt);
27913627Sjavier.bueno@metempsy.com
28013627Sjavier.bueno@metempsy.com        if ((loopUseCounter >= 0) && bi->loopPredValid) {
28113627Sjavier.bueno@metempsy.com            pred_taken = bi->loopPred;
28213627Sjavier.bueno@metempsy.com            bi->loopPredUsed = true;
28313627Sjavier.bueno@metempsy.com        }
28413627Sjavier.bueno@metempsy.com
28513627Sjavier.bueno@metempsy.com        if (useSpeculation) {
28613627Sjavier.bueno@metempsy.com            specLoopUpdate(pred_taken, bi);
28713627Sjavier.bueno@metempsy.com        }
28813627Sjavier.bueno@metempsy.com    }
28913627Sjavier.bueno@metempsy.com
29013627Sjavier.bueno@metempsy.com    return pred_taken;
29113627Sjavier.bueno@metempsy.com}
29213627Sjavier.bueno@metempsy.com
29313627Sjavier.bueno@metempsy.comvoid
29413627Sjavier.bueno@metempsy.comLoopPredictor::squash(ThreadID tid, BranchInfo *bi)
29513627Sjavier.bueno@metempsy.com{
29613627Sjavier.bueno@metempsy.com    if (bi->loopHit >= 0) {
29713627Sjavier.bueno@metempsy.com        int idx = finallindex(bi->loopIndex,
29813627Sjavier.bueno@metempsy.com                bi->loopIndexB,
29913627Sjavier.bueno@metempsy.com                bi->loopHit);
30013627Sjavier.bueno@metempsy.com        ltable[idx].currentIterSpec = bi->currentIter;
30113627Sjavier.bueno@metempsy.com    }
30213627Sjavier.bueno@metempsy.com}
30313627Sjavier.bueno@metempsy.com
30413627Sjavier.bueno@metempsy.comvoid
30513627Sjavier.bueno@metempsy.comLoopPredictor::squashLoop(BranchInfo* bi)
30613627Sjavier.bueno@metempsy.com{
30713627Sjavier.bueno@metempsy.com    if (bi->loopHit >= 0) {
30813627Sjavier.bueno@metempsy.com        int idx = finallindex(bi->loopIndex,
30913627Sjavier.bueno@metempsy.com                bi->loopIndexB,
31013627Sjavier.bueno@metempsy.com                bi->loopHit);
31113627Sjavier.bueno@metempsy.com        ltable[idx].currentIterSpec = bi->currentIter;
31213627Sjavier.bueno@metempsy.com    }
31313627Sjavier.bueno@metempsy.com}
31413627Sjavier.bueno@metempsy.com
31513627Sjavier.bueno@metempsy.comvoid
31613627Sjavier.bueno@metempsy.comLoopPredictor::updateStats(bool taken, BranchInfo* bi)
31713627Sjavier.bueno@metempsy.com{
31813627Sjavier.bueno@metempsy.com    if (taken == bi->loopPred) {
31913627Sjavier.bueno@metempsy.com        loopPredictorCorrect++;
32013627Sjavier.bueno@metempsy.com    } else {
32113627Sjavier.bueno@metempsy.com        loopPredictorWrong++;
32213627Sjavier.bueno@metempsy.com    }
32313627Sjavier.bueno@metempsy.com}
32413627Sjavier.bueno@metempsy.com
32513627Sjavier.bueno@metempsy.comvoid
32613627Sjavier.bueno@metempsy.comLoopPredictor::condBranchUpdate(ThreadID tid, Addr branch_pc, bool taken,
32713627Sjavier.bueno@metempsy.com                                bool tage_pred, BranchInfo* bi,
32813685Sjavier.bueno@metempsy.com                                unsigned instShiftAmt)
32913627Sjavier.bueno@metempsy.com{
33013627Sjavier.bueno@metempsy.com    if (useSpeculation) {
33113627Sjavier.bueno@metempsy.com        // recalculate loop prediction without speculation
33213627Sjavier.bueno@metempsy.com        // It is ok to overwrite the loop prediction fields in bi
33313627Sjavier.bueno@metempsy.com        // as the stats have already been updated with the previous
33413627Sjavier.bueno@metempsy.com        // values
33513627Sjavier.bueno@metempsy.com        bi->loopPred = getLoop(branch_pc, bi, false, instShiftAmt);
33613627Sjavier.bueno@metempsy.com    }
33713627Sjavier.bueno@metempsy.com
33813627Sjavier.bueno@metempsy.com    if (bi->loopPredValid) {
33913627Sjavier.bueno@metempsy.com        if (bi->predTaken != bi->loopPred) {
34013627Sjavier.bueno@metempsy.com            signedCtrUpdate(loopUseCounter,
34113627Sjavier.bueno@metempsy.com                      (bi->loopPred == taken),
34213627Sjavier.bueno@metempsy.com                      withLoopBits);
34313627Sjavier.bueno@metempsy.com        }
34413627Sjavier.bueno@metempsy.com    }
34513627Sjavier.bueno@metempsy.com
34613685Sjavier.bueno@metempsy.com    loopUpdate(branch_pc, taken, bi, tage_pred);
34713627Sjavier.bueno@metempsy.com}
34813627Sjavier.bueno@metempsy.com
34913627Sjavier.bueno@metempsy.comvoid
35013627Sjavier.bueno@metempsy.comLoopPredictor::regStats()
35113627Sjavier.bueno@metempsy.com{
35213627Sjavier.bueno@metempsy.com    loopPredictorCorrect
35313627Sjavier.bueno@metempsy.com        .name(name() + ".loopPredictorCorrect")
35413627Sjavier.bueno@metempsy.com        .desc("Number of times the loop predictor is the provider and "
35513627Sjavier.bueno@metempsy.com              "the prediction is correct");
35613627Sjavier.bueno@metempsy.com
35713627Sjavier.bueno@metempsy.com    loopPredictorWrong
35813627Sjavier.bueno@metempsy.com        .name(name() + ".loopPredictorWrong")
35913627Sjavier.bueno@metempsy.com        .desc("Number of times the loop predictor is the provider and "
36013627Sjavier.bueno@metempsy.com              "the prediction is wrong");
36113627Sjavier.bueno@metempsy.com}
36213627Sjavier.bueno@metempsy.com
36314081Sjavier.bueno@metempsy.comsize_t
36414081Sjavier.bueno@metempsy.comLoopPredictor::getSizeInBits() const
36514081Sjavier.bueno@metempsy.com{
36614081Sjavier.bueno@metempsy.com    return (1ULL << logSizeLoopPred) *
36714081Sjavier.bueno@metempsy.com        ((useSpeculation ? 3 : 2) * loopTableIterBits +
36814081Sjavier.bueno@metempsy.com        loopTableConfidenceBits + loopTableTagBits +
36914081Sjavier.bueno@metempsy.com        loopTableAgeBits + useDirectionBit);
37014081Sjavier.bueno@metempsy.com}
37114081Sjavier.bueno@metempsy.com
37213627Sjavier.bueno@metempsy.comLoopPredictor *
37313627Sjavier.bueno@metempsy.comLoopPredictorParams::create()
37413627Sjavier.bueno@metempsy.com{
37513627Sjavier.bueno@metempsy.com    return new LoopPredictor(this);
37613627Sjavier.bueno@metempsy.com}
377