111784Sarthur.perais@inria.fr/*
211784Sarthur.perais@inria.fr * Copyright (c) 2014 The University of Wisconsin
311784Sarthur.perais@inria.fr *
411784Sarthur.perais@inria.fr * Copyright (c) 2006 INRIA (Institut National de Recherche en
511784Sarthur.perais@inria.fr * Informatique et en Automatique  / French National Research Institute
611784Sarthur.perais@inria.fr * for Computer Science and Applied Mathematics)
711784Sarthur.perais@inria.fr *
811784Sarthur.perais@inria.fr * All rights reserved.
911784Sarthur.perais@inria.fr *
1011784Sarthur.perais@inria.fr * Redistribution and use in source and binary forms, with or without
1111784Sarthur.perais@inria.fr * modification, are permitted provided that the following conditions are
1211784Sarthur.perais@inria.fr * met: redistributions of source code must retain the above copyright
1311784Sarthur.perais@inria.fr * notice, this list of conditions and the following disclaimer;
1411784Sarthur.perais@inria.fr * redistributions in binary form must reproduce the above copyright
1511784Sarthur.perais@inria.fr * notice, this list of conditions and the following disclaimer in the
1611784Sarthur.perais@inria.fr * documentation and/or other materials provided with the distribution;
1711784Sarthur.perais@inria.fr * neither the name of the copyright holders nor the names of its
1811784Sarthur.perais@inria.fr * contributors may be used to endorse or promote products derived from
1911784Sarthur.perais@inria.fr * this software without specific prior written permission.
2011784Sarthur.perais@inria.fr *
2111784Sarthur.perais@inria.fr * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2211784Sarthur.perais@inria.fr * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2311784Sarthur.perais@inria.fr * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2411784Sarthur.perais@inria.fr * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2511784Sarthur.perais@inria.fr * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2611784Sarthur.perais@inria.fr * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2711784Sarthur.perais@inria.fr * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2811784Sarthur.perais@inria.fr * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2911784Sarthur.perais@inria.fr * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3011784Sarthur.perais@inria.fr * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3111784Sarthur.perais@inria.fr * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3211784Sarthur.perais@inria.fr *
3311784Sarthur.perais@inria.fr * Authors: Vignyan Reddy, Dibakar Gope and Arthur Perais,
3411784Sarthur.perais@inria.fr * from André Seznec's code.
3511784Sarthur.perais@inria.fr */
3611784Sarthur.perais@inria.fr
3711784Sarthur.perais@inria.fr/* @file
3811784Sarthur.perais@inria.fr * Implementation of a L-TAGE branch predictor
3911784Sarthur.perais@inria.fr */
4011784Sarthur.perais@inria.fr
4111784Sarthur.perais@inria.fr#include "cpu/pred/ltage.hh"
4211784Sarthur.perais@inria.fr
4311784Sarthur.perais@inria.fr#include "base/intmath.hh"
4412334Sgabeblack@google.com#include "base/logging.hh"
4513685Sjavier.bueno@metempsy.com#include "base/random.hh"
4611784Sarthur.perais@inria.fr#include "base/trace.hh"
4711784Sarthur.perais@inria.fr#include "debug/Fetch.hh"
4811784Sarthur.perais@inria.fr#include "debug/LTage.hh"
4911784Sarthur.perais@inria.fr
5011784Sarthur.perais@inria.frLTAGE::LTAGE(const LTAGEParams *params)
5113627Sjavier.bueno@metempsy.com  : TAGE(params), loopPredictor(params->loop_predictor)
5211784Sarthur.perais@inria.fr{
5311784Sarthur.perais@inria.fr}
5411784Sarthur.perais@inria.fr
5513685Sjavier.bueno@metempsy.comvoid
5613685Sjavier.bueno@metempsy.comLTAGE::init()
5713685Sjavier.bueno@metempsy.com{
5813685Sjavier.bueno@metempsy.com    TAGE::init();
5913685Sjavier.bueno@metempsy.com}
6013685Sjavier.bueno@metempsy.com
6111784Sarthur.perais@inria.fr//prediction
6211784Sarthur.perais@inria.frbool
6311784Sarthur.perais@inria.frLTAGE::predict(ThreadID tid, Addr branch_pc, bool cond_branch, void* &b)
6411784Sarthur.perais@inria.fr{
6513627Sjavier.bueno@metempsy.com    LTageBranchInfo *bi = new LTageBranchInfo(*tage, *loopPredictor);
6611784Sarthur.perais@inria.fr    b = (void*)(bi);
6713454Spau.cabre@metempsy.com
6813626Sjairo.balart@metempsy.com    bool pred_taken = tage->tagePredict(tid, branch_pc, cond_branch,
6913626Sjairo.balart@metempsy.com                                        bi->tageBranchInfo);
7011784Sarthur.perais@inria.fr
7113627Sjavier.bueno@metempsy.com    pred_taken = loopPredictor->loopPredict(tid, branch_pc, cond_branch,
7213627Sjavier.bueno@metempsy.com                                            bi->lpBranchInfo, pred_taken,
7313627Sjavier.bueno@metempsy.com                                            instShiftAmt);
7411784Sarthur.perais@inria.fr    if (cond_branch) {
7513627Sjavier.bueno@metempsy.com        if (bi->lpBranchInfo->loopPredUsed) {
7613626Sjairo.balart@metempsy.com            bi->tageBranchInfo->provider = LOOP;
7711784Sarthur.perais@inria.fr        }
7811784Sarthur.perais@inria.fr        DPRINTF(LTage, "Predict for %lx: taken?:%d, loopTaken?:%d, "
7911784Sarthur.perais@inria.fr                "loopValid?:%d, loopUseCounter:%d, tagePred:%d, altPred:%d\n",
8013627Sjavier.bueno@metempsy.com                branch_pc, pred_taken, bi->lpBranchInfo->loopPred,
8113627Sjavier.bueno@metempsy.com                bi->lpBranchInfo->loopPredValid,
8213627Sjavier.bueno@metempsy.com                loopPredictor->getLoopUseCounter(),
8313627Sjavier.bueno@metempsy.com                bi->tageBranchInfo->tagePred, bi->tageBranchInfo->altTaken);
8413627Sjavier.bueno@metempsy.com    }
8513493Spau.cabre@metempsy.com
8613627Sjavier.bueno@metempsy.com    // record final prediction
8713627Sjavier.bueno@metempsy.com    bi->lpBranchInfo->predTaken = pred_taken;
8813454Spau.cabre@metempsy.com
8911784Sarthur.perais@inria.fr    return pred_taken;
9011784Sarthur.perais@inria.fr}
9111784Sarthur.perais@inria.fr
9213685Sjavier.bueno@metempsy.com// PREDICTOR UPDATE
9311784Sarthur.perais@inria.frvoid
9413626Sjairo.balart@metempsy.comLTAGE::update(ThreadID tid, Addr branch_pc, bool taken, void* bp_history,
9513626Sjairo.balart@metempsy.com              bool squashed, const StaticInstPtr & inst, Addr corrTarget)
9611784Sarthur.perais@inria.fr{
9713626Sjairo.balart@metempsy.com    assert(bp_history);
9811784Sarthur.perais@inria.fr
9913626Sjairo.balart@metempsy.com    LTageBranchInfo* bi = static_cast<LTageBranchInfo*>(bp_history);
10013626Sjairo.balart@metempsy.com
10113627Sjavier.bueno@metempsy.com    assert(corrTarget != MaxAddr);
10213627Sjavier.bueno@metempsy.com
10313626Sjairo.balart@metempsy.com    if (squashed) {
10413626Sjairo.balart@metempsy.com        if (tage->isSpeculativeUpdateEnabled()) {
10513626Sjairo.balart@metempsy.com            // This restores the global history, then update it
10613626Sjairo.balart@metempsy.com            // and recomputes the folded histories.
10713626Sjairo.balart@metempsy.com            tage->squash(tid, taken, bi->tageBranchInfo, corrTarget);
10813627Sjavier.bueno@metempsy.com
10913627Sjavier.bueno@metempsy.com            if (bi->tageBranchInfo->condBranch) {
11013627Sjavier.bueno@metempsy.com                loopPredictor->squashLoop(bi->lpBranchInfo);
11113627Sjavier.bueno@metempsy.com            }
11213626Sjairo.balart@metempsy.com        }
11313626Sjairo.balart@metempsy.com        return;
11413493Spau.cabre@metempsy.com    }
11511784Sarthur.perais@inria.fr
11613685Sjavier.bueno@metempsy.com    int nrand = random_mt.random<int>() & 3;
11713626Sjairo.balart@metempsy.com    if (bi->tageBranchInfo->condBranch) {
11813626Sjairo.balart@metempsy.com        DPRINTF(LTage, "Updating tables for branch:%lx; taken?:%d\n",
11913626Sjairo.balart@metempsy.com                branch_pc, taken);
12013626Sjairo.balart@metempsy.com        tage->updateStats(taken, bi->tageBranchInfo);
12113626Sjairo.balart@metempsy.com
12213627Sjavier.bueno@metempsy.com        loopPredictor->updateStats(taken, bi->lpBranchInfo);
12313627Sjavier.bueno@metempsy.com
12413627Sjavier.bueno@metempsy.com        loopPredictor->condBranchUpdate(tid, branch_pc, taken,
12513685Sjavier.bueno@metempsy.com            bi->tageBranchInfo->tagePred, bi->lpBranchInfo, instShiftAmt);
12613626Sjairo.balart@metempsy.com
12713626Sjairo.balart@metempsy.com        tage->condBranchUpdate(tid, branch_pc, taken, bi->tageBranchInfo,
12813685Sjavier.bueno@metempsy.com            nrand, corrTarget, bi->lpBranchInfo->predTaken);
12911784Sarthur.perais@inria.fr    }
13011784Sarthur.perais@inria.fr
13113626Sjairo.balart@metempsy.com    tage->updateHistories(tid, branch_pc, taken, bi->tageBranchInfo, false,
13213626Sjairo.balart@metempsy.com                          inst, corrTarget);
13313493Spau.cabre@metempsy.com
13413626Sjairo.balart@metempsy.com    delete bi;
13511784Sarthur.perais@inria.fr}
13611784Sarthur.perais@inria.fr
13711784Sarthur.perais@inria.frvoid
13811784Sarthur.perais@inria.frLTAGE::squash(ThreadID tid, void *bp_history)
13911784Sarthur.perais@inria.fr{
14013454Spau.cabre@metempsy.com    LTageBranchInfo* bi = (LTageBranchInfo*)(bp_history);
14113626Sjairo.balart@metempsy.com
14213626Sjairo.balart@metempsy.com    if (bi->tageBranchInfo->condBranch) {
14313627Sjavier.bueno@metempsy.com        loopPredictor->squash(tid, bi->lpBranchInfo);
14411784Sarthur.perais@inria.fr    }
14511784Sarthur.perais@inria.fr
14613454Spau.cabre@metempsy.com    TAGE::squash(tid, bp_history);
14711784Sarthur.perais@inria.fr}
14811784Sarthur.perais@inria.fr
14913455Spau.cabre@metempsy.comvoid
15013455Spau.cabre@metempsy.comLTAGE::regStats()
15113455Spau.cabre@metempsy.com{
15213455Spau.cabre@metempsy.com    TAGE::regStats();
15313455Spau.cabre@metempsy.com}
15413455Spau.cabre@metempsy.com
15511784Sarthur.perais@inria.frLTAGE*
15611784Sarthur.perais@inria.frLTAGEParams::create()
15711784Sarthur.perais@inria.fr{
15811784Sarthur.perais@inria.fr    return new LTAGE(this);
15911784Sarthur.perais@inria.fr}
160