tage.cc revision 13685
111619Sandreas.sandberg@arm.com/*
210916Sandreas.sandberg@arm.com * Copyright (c) 2014 The University of Wisconsin
310916Sandreas.sandberg@arm.com *
410916Sandreas.sandberg@arm.com * Copyright (c) 2006 INRIA (Institut National de Recherche en
510916Sandreas.sandberg@arm.com * Informatique et en Automatique  / French National Research Institute
610916Sandreas.sandberg@arm.com * for Computer Science and Applied Mathematics)
710916Sandreas.sandberg@arm.com *
810916Sandreas.sandberg@arm.com * All rights reserved.
910916Sandreas.sandberg@arm.com *
1010916Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
1110916Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
1210916Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
1310916Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
1410916Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
1510916Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
1610916Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
1710916Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
1810916Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from
1910916Sandreas.sandberg@arm.com * this software without specific prior written permission.
2010916Sandreas.sandberg@arm.com *
2110916Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2210916Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2310916Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2410916Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2510916Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2610916Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2710916Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2810916Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2910916Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3010916Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3110916Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3210916Sandreas.sandberg@arm.com *
3310916Sandreas.sandberg@arm.com * Authors: Vignyan Reddy, Dibakar Gope and Arthur Perais,
3410916Sandreas.sandberg@arm.com * from André Seznec's code.
3510916Sandreas.sandberg@arm.com */
3610916Sandreas.sandberg@arm.com
3710916Sandreas.sandberg@arm.com/* @file
3810916Sandreas.sandberg@arm.com * Implementation of a TAGE branch predictor
3910916Sandreas.sandberg@arm.com */
4010916Sandreas.sandberg@arm.com
4110916Sandreas.sandberg@arm.com#include "cpu/pred/tage.hh"
4210916Sandreas.sandberg@arm.com
4310916Sandreas.sandberg@arm.com#include "base/intmath.hh"
4410916Sandreas.sandberg@arm.com#include "base/logging.hh"
4510916Sandreas.sandberg@arm.com#include "base/random.hh"
4610916Sandreas.sandberg@arm.com#include "base/trace.hh"
4710916Sandreas.sandberg@arm.com#include "debug/Fetch.hh"
4810916Sandreas.sandberg@arm.com#include "debug/Tage.hh"
4910916Sandreas.sandberg@arm.com
5010916Sandreas.sandberg@arm.comTAGE::TAGE(const TAGEParams *params) : BPredUnit(params), tage(params->tage)
5110916Sandreas.sandberg@arm.com{
5210916Sandreas.sandberg@arm.com}
5310916Sandreas.sandberg@arm.com
5410916Sandreas.sandberg@arm.com// PREDICTOR UPDATE
5510916Sandreas.sandberg@arm.comvoid
5610916Sandreas.sandberg@arm.comTAGE::update(ThreadID tid, Addr branch_pc, bool taken, void* bp_history,
5710916Sandreas.sandberg@arm.com              bool squashed, const StaticInstPtr & inst, Addr corrTarget)
5810916Sandreas.sandberg@arm.com{
5910916Sandreas.sandberg@arm.com    assert(bp_history);
6010916Sandreas.sandberg@arm.com
6110916Sandreas.sandberg@arm.com    TageBranchInfo *bi = static_cast<TageBranchInfo*>(bp_history);
6210916Sandreas.sandberg@arm.com    TAGEBase::BranchInfo *tage_bi = bi->tageBranchInfo;
6310916Sandreas.sandberg@arm.com
6411619Sandreas.sandberg@arm.com    assert(corrTarget != MaxAddr);
6511619Sandreas.sandberg@arm.com
6611619Sandreas.sandberg@arm.com    if (squashed) {
6711619Sandreas.sandberg@arm.com        // This restores the global history, then update it
6811619Sandreas.sandberg@arm.com        // and recomputes the folded histories.
6911619Sandreas.sandberg@arm.com        tage->squash(tid, taken, tage_bi, corrTarget);
7011619Sandreas.sandberg@arm.com        return;
7111619Sandreas.sandberg@arm.com    }
7211619Sandreas.sandberg@arm.com
7311619Sandreas.sandberg@arm.com    int nrand = random_mt.random<int>() & 3;
7411619Sandreas.sandberg@arm.com    if (bi->tageBranchInfo->condBranch) {
7511619Sandreas.sandberg@arm.com        DPRINTF(Tage, "Updating tables for branch:%lx; taken?:%d\n",
7611619Sandreas.sandberg@arm.com                branch_pc, taken);
7711619Sandreas.sandberg@arm.com        tage->updateStats(taken, bi->tageBranchInfo);
7811619Sandreas.sandberg@arm.com        tage->condBranchUpdate(tid, branch_pc, taken, tage_bi, nrand,
7911619Sandreas.sandberg@arm.com                               corrTarget, bi->tageBranchInfo->tagePred);
8011619Sandreas.sandberg@arm.com    }
8111619Sandreas.sandberg@arm.com
8211619Sandreas.sandberg@arm.com    // optional non speculative update of the histories
8311619Sandreas.sandberg@arm.com    tage->updateHistories(tid, branch_pc, taken, tage_bi, false, inst,
8411619Sandreas.sandberg@arm.com                          corrTarget);
8511619Sandreas.sandberg@arm.com    delete bi;
8611619Sandreas.sandberg@arm.com}
8711619Sandreas.sandberg@arm.com
8811619Sandreas.sandberg@arm.comvoid
8911619Sandreas.sandberg@arm.comTAGE::squash(ThreadID tid, void *bp_history)
9011619Sandreas.sandberg@arm.com{
9111619Sandreas.sandberg@arm.com    TageBranchInfo *bi = static_cast<TageBranchInfo*>(bp_history);
9211619Sandreas.sandberg@arm.com    DPRINTF(Tage, "Deleting branch info: %lx\n", bi->tageBranchInfo->branchPC);
9311619Sandreas.sandberg@arm.com    delete bi;
9411619Sandreas.sandberg@arm.com}
9511619Sandreas.sandberg@arm.com
9611619Sandreas.sandberg@arm.combool
9711619Sandreas.sandberg@arm.comTAGE::predict(ThreadID tid, Addr branch_pc, bool cond_branch, void* &b)
9811619Sandreas.sandberg@arm.com{
9911619Sandreas.sandberg@arm.com    TageBranchInfo *bi = new TageBranchInfo(*tage);//nHistoryTables+1);
10011619Sandreas.sandberg@arm.com    b = (void*)(bi);
10111619Sandreas.sandberg@arm.com    return tage->tagePredict(tid, branch_pc, cond_branch, bi->tageBranchInfo);
10211619Sandreas.sandberg@arm.com}
10311619Sandreas.sandberg@arm.com
10411619Sandreas.sandberg@arm.combool
10511619Sandreas.sandberg@arm.comTAGE::lookup(ThreadID tid, Addr branch_pc, void* &bp_history)
10611619Sandreas.sandberg@arm.com{
10711619Sandreas.sandberg@arm.com    bool retval = predict(tid, branch_pc, true, bp_history);
10811619Sandreas.sandberg@arm.com
10911619Sandreas.sandberg@arm.com    TageBranchInfo *bi = static_cast<TageBranchInfo*>(bp_history);
11011619Sandreas.sandberg@arm.com
11111619Sandreas.sandberg@arm.com    DPRINTF(Tage, "Lookup branch: %lx; predict:%d\n", branch_pc, retval);
11211619Sandreas.sandberg@arm.com
11311619Sandreas.sandberg@arm.com    tage->updateHistories(tid, branch_pc, retval, bi->tageBranchInfo, true);
11411619Sandreas.sandberg@arm.com
11511619Sandreas.sandberg@arm.com    return retval;
11611619Sandreas.sandberg@arm.com}
11711619Sandreas.sandberg@arm.com
11811619Sandreas.sandberg@arm.comvoid
11911619Sandreas.sandberg@arm.comTAGE::btbUpdate(ThreadID tid, Addr branch_pc, void* &bp_history)
12011619Sandreas.sandberg@arm.com{
12111619Sandreas.sandberg@arm.com    TageBranchInfo *bi = static_cast<TageBranchInfo*>(bp_history);
12211619Sandreas.sandberg@arm.com    tage->btbUpdate(tid, branch_pc, bi->tageBranchInfo);
12311619Sandreas.sandberg@arm.com}
12411619Sandreas.sandberg@arm.com
12511619Sandreas.sandberg@arm.comvoid
12611619Sandreas.sandberg@arm.comTAGE::uncondBranch(ThreadID tid, Addr br_pc, void* &bp_history)
12711619Sandreas.sandberg@arm.com{
128    DPRINTF(Tage, "UnConditionalBranch: %lx\n", br_pc);
129    predict(tid, br_pc, false, bp_history);
130    TageBranchInfo *bi = static_cast<TageBranchInfo*>(bp_history);
131    tage->updateHistories(tid, br_pc, true, bi->tageBranchInfo, true);
132}
133
134TAGE*
135TAGEParams::create()
136{
137    return new TAGE(this);
138}
139