bpred_unit.cc revision 13831
11689SN/A/*
210785Sgope@wisc.edu * Copyright (c) 2011-2012, 2014 ARM Limited
39480Snilay@cs.wisc.edu * Copyright (c) 2010 The University of Edinburgh
49480Snilay@cs.wisc.edu * Copyright (c) 2012 Mark D. Hill and David A. Wood
510785Sgope@wisc.edu * All rights reserved
610785Sgope@wisc.edu *
710785Sgope@wisc.edu * The license below extends only to copyright in the software and shall
810785Sgope@wisc.edu * not be construed as granting a license to any other intellectual
910785Sgope@wisc.edu * property including but not limited to intellectual property relating
1010785Sgope@wisc.edu * to a hardware implementation of the functionality of the software
1110785Sgope@wisc.edu * licensed hereunder.  You may use the software subject to the license
1210785Sgope@wisc.edu * terms below provided that you ensure that this notice is replicated
1310785Sgope@wisc.edu * unmodified and in its entirety in all distributions of the software,
1410785Sgope@wisc.edu * modified or unmodified, in source code or in binary form.
1510785Sgope@wisc.edu *
1610785Sgope@wisc.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan
171689SN/A * All rights reserved.
181689SN/A *
191689SN/A * Redistribution and use in source and binary forms, with or without
201689SN/A * modification, are permitted provided that the following conditions are
211689SN/A * met: redistributions of source code must retain the above copyright
221689SN/A * notice, this list of conditions and the following disclaimer;
231689SN/A * redistributions in binary form must reproduce the above copyright
241689SN/A * notice, this list of conditions and the following disclaimer in the
251689SN/A * documentation and/or other materials provided with the distribution;
261689SN/A * neither the name of the copyright holders nor the names of its
271689SN/A * contributors may be used to endorse or promote products derived from
281689SN/A * this software without specific prior written permission.
291689SN/A *
301689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
311689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
321689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
331689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
341689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
351689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
361689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
371689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
381689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
391689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
401689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
412665SN/A *
422665SN/A * Authors: Kevin Lim
431689SN/A */
441061SN/A
4510785Sgope@wisc.edu#include "cpu/pred/bpred_unit.hh"
461061SN/A
4710785Sgope@wisc.edu#include <algorithm>
4810785Sgope@wisc.edu
4910785Sgope@wisc.edu#include "arch/isa_traits.hh"
5010785Sgope@wisc.edu#include "arch/types.hh"
5110785Sgope@wisc.edu#include "arch/utility.hh"
5210785Sgope@wisc.edu#include "base/trace.hh"
5310785Sgope@wisc.edu#include "config/the_isa.hh"
5410785Sgope@wisc.edu#include "debug/Branch.hh"
5510785Sgope@wisc.edu
5610785Sgope@wisc.eduBPredUnit::BPredUnit(const Params *params)
5710785Sgope@wisc.edu    : SimObject(params),
5810785Sgope@wisc.edu      numThreads(params->numThreads),
5910785Sgope@wisc.edu      predHist(numThreads),
6010785Sgope@wisc.edu      BTB(params->BTBEntries,
6110785Sgope@wisc.edu          params->BTBTagSize,
6211432Smitch.hayenga@arm.com          params->instShiftAmt,
6311432Smitch.hayenga@arm.com          params->numThreads),
6410785Sgope@wisc.edu      RAS(numThreads),
6511433Smitch.hayenga@arm.com      useIndirect(params->useIndirect),
6611433Smitch.hayenga@arm.com      iPred(params->indirectHashGHR,
6711433Smitch.hayenga@arm.com            params->indirectHashTargets,
6811433Smitch.hayenga@arm.com            params->indirectSets,
6911433Smitch.hayenga@arm.com            params->indirectWays,
7011433Smitch.hayenga@arm.com            params->indirectTagSize,
7111433Smitch.hayenga@arm.com            params->indirectPathLength,
7211433Smitch.hayenga@arm.com            params->instShiftAmt,
7313810Spau.cabre@metempsy.com            params->numThreads,
7413810Spau.cabre@metempsy.com            params->indirectGHRBits),
7510785Sgope@wisc.edu      instShiftAmt(params->instShiftAmt)
769480Snilay@cs.wisc.edu{
7710785Sgope@wisc.edu    for (auto& r : RAS)
7810785Sgope@wisc.edu        r.init(params->RASSize);
7910785Sgope@wisc.edu}
8010785Sgope@wisc.edu
8110785Sgope@wisc.eduvoid
8210785Sgope@wisc.eduBPredUnit::regStats()
8310785Sgope@wisc.edu{
8411523Sdavid.guillen@arm.com    SimObject::regStats();
8511523Sdavid.guillen@arm.com
8610785Sgope@wisc.edu    lookups
8710785Sgope@wisc.edu        .name(name() + ".lookups")
8810785Sgope@wisc.edu        .desc("Number of BP lookups")
8910785Sgope@wisc.edu        ;
9010785Sgope@wisc.edu
9110785Sgope@wisc.edu    condPredicted
9210785Sgope@wisc.edu        .name(name() + ".condPredicted")
9310785Sgope@wisc.edu        .desc("Number of conditional branches predicted")
9410785Sgope@wisc.edu        ;
9510785Sgope@wisc.edu
9610785Sgope@wisc.edu    condIncorrect
9710785Sgope@wisc.edu        .name(name() + ".condIncorrect")
9810785Sgope@wisc.edu        .desc("Number of conditional branches incorrect")
9910785Sgope@wisc.edu        ;
10010785Sgope@wisc.edu
10110785Sgope@wisc.edu    BTBLookups
10210785Sgope@wisc.edu        .name(name() + ".BTBLookups")
10310785Sgope@wisc.edu        .desc("Number of BTB lookups")
10410785Sgope@wisc.edu        ;
10510785Sgope@wisc.edu
10610785Sgope@wisc.edu    BTBHits
10710785Sgope@wisc.edu        .name(name() + ".BTBHits")
10810785Sgope@wisc.edu        .desc("Number of BTB hits")
10910785Sgope@wisc.edu        ;
11010785Sgope@wisc.edu
11110785Sgope@wisc.edu    BTBCorrect
11210785Sgope@wisc.edu        .name(name() + ".BTBCorrect")
11310785Sgope@wisc.edu        .desc("Number of correct BTB predictions (this stat may not "
11410785Sgope@wisc.edu              "work properly.")
11510785Sgope@wisc.edu        ;
11610785Sgope@wisc.edu
11710785Sgope@wisc.edu    BTBHitPct
11810785Sgope@wisc.edu        .name(name() + ".BTBHitPct")
11910785Sgope@wisc.edu        .desc("BTB Hit Percentage")
12010785Sgope@wisc.edu        .precision(6);
12110785Sgope@wisc.edu    BTBHitPct = (BTBHits / BTBLookups) * 100;
12210785Sgope@wisc.edu
12310785Sgope@wisc.edu    usedRAS
12410785Sgope@wisc.edu        .name(name() + ".usedRAS")
12510785Sgope@wisc.edu        .desc("Number of times the RAS was used to get a target.")
12610785Sgope@wisc.edu        ;
12710785Sgope@wisc.edu
12810785Sgope@wisc.edu    RASIncorrect
12910785Sgope@wisc.edu        .name(name() + ".RASInCorrect")
13010785Sgope@wisc.edu        .desc("Number of incorrect RAS predictions.")
13110785Sgope@wisc.edu        ;
13211433Smitch.hayenga@arm.com
13311433Smitch.hayenga@arm.com    indirectLookups
13411433Smitch.hayenga@arm.com        .name(name() + ".indirectLookups")
13511433Smitch.hayenga@arm.com        .desc("Number of indirect predictor lookups.")
13611433Smitch.hayenga@arm.com        ;
13711433Smitch.hayenga@arm.com
13811433Smitch.hayenga@arm.com    indirectHits
13911433Smitch.hayenga@arm.com        .name(name() + ".indirectHits")
14011433Smitch.hayenga@arm.com        .desc("Number of indirect target hits.")
14111433Smitch.hayenga@arm.com        ;
14211433Smitch.hayenga@arm.com
14311433Smitch.hayenga@arm.com    indirectMisses
14411433Smitch.hayenga@arm.com        .name(name() + ".indirectMisses")
14511433Smitch.hayenga@arm.com        .desc("Number of indirect misses.")
14611433Smitch.hayenga@arm.com        ;
14711433Smitch.hayenga@arm.com
14811433Smitch.hayenga@arm.com    indirectMispredicted
14911433Smitch.hayenga@arm.com        .name(name() + "indirectMispredicted")
15011433Smitch.hayenga@arm.com        .desc("Number of mispredicted indirect branches.")
15111433Smitch.hayenga@arm.com        ;
15211433Smitch.hayenga@arm.com
15310785Sgope@wisc.edu}
15410785Sgope@wisc.edu
15510785Sgope@wisc.eduProbePoints::PMUUPtr
15610785Sgope@wisc.eduBPredUnit::pmuProbePoint(const char *name)
15710785Sgope@wisc.edu{
15810785Sgope@wisc.edu    ProbePoints::PMUUPtr ptr;
15910785Sgope@wisc.edu    ptr.reset(new ProbePoints::PMU(getProbeManager(), name));
16010785Sgope@wisc.edu
16110785Sgope@wisc.edu    return ptr;
16210785Sgope@wisc.edu}
16310785Sgope@wisc.edu
16410785Sgope@wisc.eduvoid
16510785Sgope@wisc.eduBPredUnit::regProbePoints()
16610785Sgope@wisc.edu{
16710785Sgope@wisc.edu    ppBranches = pmuProbePoint("Branches");
16810785Sgope@wisc.edu    ppMisses = pmuProbePoint("Misses");
16910785Sgope@wisc.edu}
17010785Sgope@wisc.edu
17110785Sgope@wisc.eduvoid
17210785Sgope@wisc.eduBPredUnit::drainSanityCheck() const
17310785Sgope@wisc.edu{
17410785Sgope@wisc.edu    // We shouldn't have any outstanding requests when we resume from
17510785Sgope@wisc.edu    // a drained system.
17610785Sgope@wisc.edu    for (const auto& ph M5_VAR_USED : predHist)
17710785Sgope@wisc.edu        assert(ph.empty());
17810785Sgope@wisc.edu}
17910785Sgope@wisc.edu
18010785Sgope@wisc.edubool
18110785Sgope@wisc.eduBPredUnit::predict(const StaticInstPtr &inst, const InstSeqNum &seqNum,
18210785Sgope@wisc.edu                   TheISA::PCState &pc, ThreadID tid)
18310785Sgope@wisc.edu{
18410785Sgope@wisc.edu    // See if branch predictor predicts taken.
18510785Sgope@wisc.edu    // If so, get its target addr either from the BTB or the RAS.
18610785Sgope@wisc.edu    // Save off record of branch stuff so the RAS can be fixed
18710785Sgope@wisc.edu    // up once it's done.
18810785Sgope@wisc.edu
18910785Sgope@wisc.edu    bool pred_taken = false;
19010785Sgope@wisc.edu    TheISA::PCState target = pc;
19110785Sgope@wisc.edu
19210785Sgope@wisc.edu    ++lookups;
19310785Sgope@wisc.edu    ppBranches->notify(1);
19410785Sgope@wisc.edu
19510785Sgope@wisc.edu    void *bp_history = NULL;
19613654Sjairo.balart@metempsy.com    void *indirect_history = NULL;
19710785Sgope@wisc.edu
19810785Sgope@wisc.edu    if (inst->isUncondCtrl()) {
19913831SAndrea.Mondelli@ucf.edu        DPRINTF(Branch, "[tid:%i] [sn:%llu] "
20013831SAndrea.Mondelli@ucf.edu            "Unconditional control\n",
20113831SAndrea.Mondelli@ucf.edu            tid,seqNum);
20210785Sgope@wisc.edu        pred_taken = true;
20310785Sgope@wisc.edu        // Tell the BP there was an unconditional branch.
20411434Smitch.hayenga@arm.com        uncondBranch(tid, pc.instAddr(), bp_history);
2059480Snilay@cs.wisc.edu    } else {
20610785Sgope@wisc.edu        ++condPredicted;
20711434Smitch.hayenga@arm.com        pred_taken = lookup(tid, pc.instAddr(), bp_history);
20810785Sgope@wisc.edu
20913831SAndrea.Mondelli@ucf.edu        DPRINTF(Branch, "[tid:%i] [sn:%llu] "
21013831SAndrea.Mondelli@ucf.edu                "Branch predictor predicted %i for PC %s\n",
21113831SAndrea.Mondelli@ucf.edu                tid, seqNum,  pred_taken, pc);
21210785Sgope@wisc.edu    }
21310785Sgope@wisc.edu
21413810Spau.cabre@metempsy.com    const bool orig_pred_taken = pred_taken;
21513654Sjairo.balart@metempsy.com    if (useIndirect) {
21613810Spau.cabre@metempsy.com        iPred.genIndirectInfo(tid, indirect_history);
21713654Sjairo.balart@metempsy.com    }
21813654Sjairo.balart@metempsy.com
21913831SAndrea.Mondelli@ucf.edu    DPRINTF(Branch, "[tid:%i] [sn:%llu] "
22013831SAndrea.Mondelli@ucf.edu            "Creating prediction history "
22110785Sgope@wisc.edu            "for PC %s\n", tid, seqNum, pc);
22210785Sgope@wisc.edu
22313654Sjairo.balart@metempsy.com    PredictorHistory predict_record(seqNum, pc.instAddr(), pred_taken,
22413654Sjairo.balart@metempsy.com                                    bp_history, indirect_history, tid, inst);
22510785Sgope@wisc.edu
22610785Sgope@wisc.edu    // Now lookup in the BTB or RAS.
22710785Sgope@wisc.edu    if (pred_taken) {
22810785Sgope@wisc.edu        if (inst->isReturn()) {
22910785Sgope@wisc.edu            ++usedRAS;
23010785Sgope@wisc.edu            predict_record.wasReturn = true;
23110785Sgope@wisc.edu            // If it's a function return call, then look up the address
23210785Sgope@wisc.edu            // in the RAS.
23310785Sgope@wisc.edu            TheISA::PCState rasTop = RAS[tid].top();
23410785Sgope@wisc.edu            target = TheISA::buildRetPC(pc, rasTop);
23510785Sgope@wisc.edu
23610785Sgope@wisc.edu            // Record the top entry of the RAS, and its index.
23710785Sgope@wisc.edu            predict_record.usedRAS = true;
23810785Sgope@wisc.edu            predict_record.RASIndex = RAS[tid].topIdx();
23910785Sgope@wisc.edu            predict_record.RASTarget = rasTop;
24010785Sgope@wisc.edu
24110785Sgope@wisc.edu            RAS[tid].pop();
24210785Sgope@wisc.edu
24313831SAndrea.Mondelli@ucf.edu            DPRINTF(Branch, "[tid:%i] [sn:%llu] Instruction %s is a return, "
24413831SAndrea.Mondelli@ucf.edu                    "RAS predicted target: %s, RAS index: %i\n",
24513831SAndrea.Mondelli@ucf.edu                    tid, seqNum, pc, target, predict_record.RASIndex);
24610785Sgope@wisc.edu        } else {
24710785Sgope@wisc.edu            ++BTBLookups;
24810785Sgope@wisc.edu
24910785Sgope@wisc.edu            if (inst->isCall()) {
25010785Sgope@wisc.edu                RAS[tid].push(pc);
25110785Sgope@wisc.edu                predict_record.pushedRAS = true;
25210785Sgope@wisc.edu
25310785Sgope@wisc.edu                // Record that it was a call so that the top RAS entry can
25410785Sgope@wisc.edu                // be popped off if the speculation is incorrect.
25510785Sgope@wisc.edu                predict_record.wasCall = true;
25610785Sgope@wisc.edu
25713831SAndrea.Mondelli@ucf.edu                DPRINTF(Branch,
25813831SAndrea.Mondelli@ucf.edu                        "[tid:%i] [sn:%llu] Instruction %s was a call, adding "
25913831SAndrea.Mondelli@ucf.edu                        "%s to the RAS index: %i\n",
26013831SAndrea.Mondelli@ucf.edu                        tid, seqNum, pc, pc, RAS[tid].topIdx());
26110785Sgope@wisc.edu            }
26210785Sgope@wisc.edu
26311433Smitch.hayenga@arm.com            if (inst->isDirectCtrl() || !useIndirect) {
26411433Smitch.hayenga@arm.com                // Check BTB on direct branches
26511433Smitch.hayenga@arm.com                if (BTB.valid(pc.instAddr(), tid)) {
26611433Smitch.hayenga@arm.com                    ++BTBHits;
26711433Smitch.hayenga@arm.com                    // If it's not a return, use the BTB to get target addr.
26811433Smitch.hayenga@arm.com                    target = BTB.lookup(pc.instAddr(), tid);
26913831SAndrea.Mondelli@ucf.edu                    DPRINTF(Branch,
27013831SAndrea.Mondelli@ucf.edu                            "[tid:%i] [sn:%llu] Instruction %s predicted "
27113831SAndrea.Mondelli@ucf.edu                            "target is %s\n",
27213831SAndrea.Mondelli@ucf.edu                            tid, seqNum, pc, target);
27311433Smitch.hayenga@arm.com                } else {
27413831SAndrea.Mondelli@ucf.edu                    DPRINTF(Branch, "[tid:%i] [sn:%llu] BTB doesn't have a "
27513831SAndrea.Mondelli@ucf.edu                            "valid entry\n",tid,seqNum);
27611433Smitch.hayenga@arm.com                    pred_taken = false;
27711433Smitch.hayenga@arm.com                    // The Direction of the branch predictor is altered
27811433Smitch.hayenga@arm.com                    // because the BTB did not have an entry
27911433Smitch.hayenga@arm.com                    // The predictor needs to be updated accordingly
28011433Smitch.hayenga@arm.com                    if (!inst->isCall() && !inst->isReturn()) {
28111434Smitch.hayenga@arm.com                        btbUpdate(tid, pc.instAddr(), bp_history);
28213831SAndrea.Mondelli@ucf.edu                        DPRINTF(Branch,
28313831SAndrea.Mondelli@ucf.edu                                "[tid:%i] [sn:%llu] btbUpdate "
28413831SAndrea.Mondelli@ucf.edu                                "called for %s\n",
28513831SAndrea.Mondelli@ucf.edu                                tid, seqNum, pc);
28611433Smitch.hayenga@arm.com                    } else if (inst->isCall() && !inst->isUncondCtrl()) {
28711433Smitch.hayenga@arm.com                        RAS[tid].pop();
28811433Smitch.hayenga@arm.com                        predict_record.pushedRAS = false;
28911433Smitch.hayenga@arm.com                    }
29011433Smitch.hayenga@arm.com                    TheISA::advancePC(target, inst);
29111433Smitch.hayenga@arm.com                }
29211429Sandreas.sandberg@arm.com            } else {
29311433Smitch.hayenga@arm.com                predict_record.wasIndirect = true;
29411433Smitch.hayenga@arm.com                ++indirectLookups;
29511433Smitch.hayenga@arm.com                //Consult indirect predictor on indirect control
29613654Sjairo.balart@metempsy.com                if (iPred.lookup(pc.instAddr(), target, tid)) {
29711433Smitch.hayenga@arm.com                    // Indirect predictor hit
29811433Smitch.hayenga@arm.com                    ++indirectHits;
29913831SAndrea.Mondelli@ucf.edu                    DPRINTF(Branch,
30013831SAndrea.Mondelli@ucf.edu                            "[tid:%i] [sn:%llu] "
30113831SAndrea.Mondelli@ucf.edu                            "Instruction %s predicted "
30213831SAndrea.Mondelli@ucf.edu                            "indirect target is %s\n",
30313831SAndrea.Mondelli@ucf.edu                            tid, seqNum, pc, target);
30411433Smitch.hayenga@arm.com                } else {
30511433Smitch.hayenga@arm.com                    ++indirectMisses;
30611433Smitch.hayenga@arm.com                    pred_taken = false;
30713831SAndrea.Mondelli@ucf.edu                    DPRINTF(Branch,
30813831SAndrea.Mondelli@ucf.edu                            "[tid:%i] [sn:%llu] "
30913831SAndrea.Mondelli@ucf.edu                            "Instruction %s no indirect "
31013831SAndrea.Mondelli@ucf.edu                            "target\n",
31113831SAndrea.Mondelli@ucf.edu                            tid, seqNum, pc);
31211433Smitch.hayenga@arm.com                    if (!inst->isCall() && !inst->isReturn()) {
31311433Smitch.hayenga@arm.com
31411433Smitch.hayenga@arm.com                    } else if (inst->isCall() && !inst->isUncondCtrl()) {
31511433Smitch.hayenga@arm.com                        RAS[tid].pop();
31611433Smitch.hayenga@arm.com                        predict_record.pushedRAS = false;
31711433Smitch.hayenga@arm.com                    }
31811433Smitch.hayenga@arm.com                    TheISA::advancePC(target, inst);
31911426Smitch.hayenga@arm.com                }
32011433Smitch.hayenga@arm.com                iPred.recordIndirect(pc.instAddr(), target.instAddr(), seqNum,
32111433Smitch.hayenga@arm.com                        tid);
32210785Sgope@wisc.edu            }
32310785Sgope@wisc.edu        }
32410785Sgope@wisc.edu    } else {
32510785Sgope@wisc.edu        if (inst->isReturn()) {
32610785Sgope@wisc.edu           predict_record.wasReturn = true;
32710785Sgope@wisc.edu        }
32810785Sgope@wisc.edu        TheISA::advancePC(target, inst);
32910785Sgope@wisc.edu    }
33013626Sjairo.balart@metempsy.com    predict_record.target = target.instAddr();
33110785Sgope@wisc.edu
33210785Sgope@wisc.edu    pc = target;
33310785Sgope@wisc.edu
33413810Spau.cabre@metempsy.com    if (useIndirect) {
33513810Spau.cabre@metempsy.com        // Update the indirect predictor with the direction prediction
33613810Spau.cabre@metempsy.com        // Note that this happens after indirect lookup, so it does not use
33713810Spau.cabre@metempsy.com        // the new information
33813810Spau.cabre@metempsy.com        // Note also that we use orig_pred_taken instead of pred_taken in
33913810Spau.cabre@metempsy.com        // as this is the actual outcome of the direction prediction
34013810Spau.cabre@metempsy.com        iPred.updateDirectionInfo(tid, orig_pred_taken);
34113810Spau.cabre@metempsy.com    }
34213810Spau.cabre@metempsy.com
34310785Sgope@wisc.edu    predHist[tid].push_front(predict_record);
34410785Sgope@wisc.edu
34513831SAndrea.Mondelli@ucf.edu    DPRINTF(Branch,
34613831SAndrea.Mondelli@ucf.edu            "[tid:%i] [sn:%llu] History entry added. "
34713831SAndrea.Mondelli@ucf.edu            "predHist.size(): %i\n",
34813831SAndrea.Mondelli@ucf.edu            tid, seqNum, predHist[tid].size());
34910785Sgope@wisc.edu
35010785Sgope@wisc.edu    return pred_taken;
35110785Sgope@wisc.edu}
35210785Sgope@wisc.edu
35310785Sgope@wisc.eduvoid
35410785Sgope@wisc.eduBPredUnit::update(const InstSeqNum &done_sn, ThreadID tid)
35510785Sgope@wisc.edu{
35613831SAndrea.Mondelli@ucf.edu    DPRINTF(Branch, "[tid:%i] Committing branches until "
35713831SAndrea.Mondelli@ucf.edu            "sn:%llu]\n", tid, done_sn);
35810785Sgope@wisc.edu
35910785Sgope@wisc.edu    while (!predHist[tid].empty() &&
36010785Sgope@wisc.edu           predHist[tid].back().seqNum <= done_sn) {
36110785Sgope@wisc.edu        // Update the branch predictor with the correct results.
36211783Sarthur.perais@inria.fr        update(tid, predHist[tid].back().pc,
36311783Sarthur.perais@inria.fr                    predHist[tid].back().predTaken,
36413626Sjairo.balart@metempsy.com                    predHist[tid].back().bpHistory, false,
36513626Sjairo.balart@metempsy.com                    predHist[tid].back().inst,
36613626Sjairo.balart@metempsy.com                    predHist[tid].back().target);
36710785Sgope@wisc.edu
36813810Spau.cabre@metempsy.com        if (useIndirect) {
36913810Spau.cabre@metempsy.com            iPred.commit(done_sn, tid, predHist[tid].back().indirectHistory);
37013810Spau.cabre@metempsy.com        }
37113654Sjairo.balart@metempsy.com
37210785Sgope@wisc.edu        predHist[tid].pop_back();
3739480Snilay@cs.wisc.edu    }
3749480Snilay@cs.wisc.edu}
37510785Sgope@wisc.edu
37610785Sgope@wisc.eduvoid
37710785Sgope@wisc.eduBPredUnit::squash(const InstSeqNum &squashed_sn, ThreadID tid)
37810785Sgope@wisc.edu{
37910785Sgope@wisc.edu    History &pred_hist = predHist[tid];
38010785Sgope@wisc.edu
38113810Spau.cabre@metempsy.com    if (useIndirect) {
38213810Spau.cabre@metempsy.com        iPred.squash(squashed_sn, tid);
38313810Spau.cabre@metempsy.com    }
38413810Spau.cabre@metempsy.com
38510785Sgope@wisc.edu    while (!pred_hist.empty() &&
38610785Sgope@wisc.edu           pred_hist.front().seqNum > squashed_sn) {
38710785Sgope@wisc.edu        if (pred_hist.front().usedRAS) {
38813831SAndrea.Mondelli@ucf.edu            DPRINTF(Branch, "[tid:%i] [squash sn:%llu]"
38913831SAndrea.Mondelli@ucf.edu                    " Restoring top of RAS to: %i,"
39013831SAndrea.Mondelli@ucf.edu                    " target: %s\n", tid, squashed_sn,
39110785Sgope@wisc.edu                    pred_hist.front().RASIndex, pred_hist.front().RASTarget);
39210785Sgope@wisc.edu
39310785Sgope@wisc.edu            RAS[tid].restore(pred_hist.front().RASIndex,
39410785Sgope@wisc.edu                             pred_hist.front().RASTarget);
39511321Ssteve.reinhardt@amd.com        } else if (pred_hist.front().wasCall && pred_hist.front().pushedRAS) {
39610785Sgope@wisc.edu             // Was a call but predicated false. Pop RAS here
39713831SAndrea.Mondelli@ucf.edu             DPRINTF(Branch, "[tid:%i] [squash sn:%llu] Squashing"
39813831SAndrea.Mondelli@ucf.edu                     "  Call [sn:%llu] PC: %s Popping RAS\n", tid, squashed_sn,
39910785Sgope@wisc.edu                     pred_hist.front().seqNum, pred_hist.front().pc);
40010785Sgope@wisc.edu             RAS[tid].pop();
40110785Sgope@wisc.edu        }
40210785Sgope@wisc.edu
40310785Sgope@wisc.edu        // This call should delete the bpHistory.
40411434Smitch.hayenga@arm.com        squash(tid, pred_hist.front().bpHistory);
40513733Ssrikant.bharadwaj@amd.com        if (useIndirect) {
40613810Spau.cabre@metempsy.com            iPred.deleteIndirectInfo(tid, pred_hist.front().indirectHistory);
40713733Ssrikant.bharadwaj@amd.com        }
40810785Sgope@wisc.edu
40913831SAndrea.Mondelli@ucf.edu        DPRINTF(Branch, "[tid:%i] [squash sn:%llu] "
41013831SAndrea.Mondelli@ucf.edu                "Removing history for [sn:%llu] "
41113831SAndrea.Mondelli@ucf.edu                "PC %#x\n", tid, squashed_sn, pred_hist.front().seqNum,
41210785Sgope@wisc.edu                pred_hist.front().pc);
41310785Sgope@wisc.edu
41410785Sgope@wisc.edu        pred_hist.pop_front();
41510785Sgope@wisc.edu
41613831SAndrea.Mondelli@ucf.edu        DPRINTF(Branch, "[tid:%i] [squash sn:%llu] predHist.size(): %i\n",
41713831SAndrea.Mondelli@ucf.edu                tid, squashed_sn, predHist[tid].size());
41810785Sgope@wisc.edu    }
41910785Sgope@wisc.edu}
42010785Sgope@wisc.edu
42110785Sgope@wisc.eduvoid
42210785Sgope@wisc.eduBPredUnit::squash(const InstSeqNum &squashed_sn,
42310785Sgope@wisc.edu                  const TheISA::PCState &corrTarget,
42410785Sgope@wisc.edu                  bool actually_taken, ThreadID tid)
42510785Sgope@wisc.edu{
42610785Sgope@wisc.edu    // Now that we know that a branch was mispredicted, we need to undo
42710785Sgope@wisc.edu    // all the branches that have been seen up until this branch and
42810785Sgope@wisc.edu    // fix up everything.
42910785Sgope@wisc.edu    // NOTE: This should be call conceivably in 2 scenarios:
43010785Sgope@wisc.edu    // (1) After an branch is executed, it updates its status in the ROB
43110785Sgope@wisc.edu    //     The commit stage then checks the ROB update and sends a signal to
43210785Sgope@wisc.edu    //     the fetch stage to squash history after the mispredict
43310785Sgope@wisc.edu    // (2) In the decode stage, you can find out early if a unconditional
43410785Sgope@wisc.edu    //     PC-relative, branch was predicted incorrectly. If so, a signal
43510785Sgope@wisc.edu    //     to the fetch stage is sent to squash history after the mispredict
43610785Sgope@wisc.edu
43710785Sgope@wisc.edu    History &pred_hist = predHist[tid];
43810785Sgope@wisc.edu
43910785Sgope@wisc.edu    ++condIncorrect;
44010785Sgope@wisc.edu    ppMisses->notify(1);
44110785Sgope@wisc.edu
44213831SAndrea.Mondelli@ucf.edu    DPRINTF(Branch, "[tid:%i] Squashing from sequence number %i, "
44313831SAndrea.Mondelli@ucf.edu            "setting target to %s\n", tid, squashed_sn, corrTarget);
44410785Sgope@wisc.edu
44510785Sgope@wisc.edu    // Squash All Branches AFTER this mispredicted branch
44610785Sgope@wisc.edu    squash(squashed_sn, tid);
44710785Sgope@wisc.edu
44810785Sgope@wisc.edu    // If there's a squash due to a syscall, there may not be an entry
44910785Sgope@wisc.edu    // corresponding to the squash.  In that case, don't bother trying to
45010785Sgope@wisc.edu    // fix up the entry.
45110785Sgope@wisc.edu    if (!pred_hist.empty()) {
45210785Sgope@wisc.edu
45310785Sgope@wisc.edu        auto hist_it = pred_hist.begin();
45410785Sgope@wisc.edu        //HistoryIt hist_it = find(pred_hist.begin(), pred_hist.end(),
45510785Sgope@wisc.edu        //                       squashed_sn);
45610785Sgope@wisc.edu
45710785Sgope@wisc.edu        //assert(hist_it != pred_hist.end());
45810785Sgope@wisc.edu        if (pred_hist.front().seqNum != squashed_sn) {
45910785Sgope@wisc.edu            DPRINTF(Branch, "Front sn %i != Squash sn %i\n",
46010785Sgope@wisc.edu                    pred_hist.front().seqNum, squashed_sn);
46110785Sgope@wisc.edu
46210785Sgope@wisc.edu            assert(pred_hist.front().seqNum == squashed_sn);
46310785Sgope@wisc.edu        }
46410785Sgope@wisc.edu
46510785Sgope@wisc.edu
46610785Sgope@wisc.edu        if ((*hist_it).usedRAS) {
46710785Sgope@wisc.edu            ++RASIncorrect;
46813831SAndrea.Mondelli@ucf.edu            DPRINTF(Branch,
46913831SAndrea.Mondelli@ucf.edu                    "[tid:%i] [squash sn:%llu] Incorrect RAS [sn:%llu]\n",
47013831SAndrea.Mondelli@ucf.edu                    tid, squashed_sn, hist_it->seqNum);
47110785Sgope@wisc.edu        }
47210785Sgope@wisc.edu
47311783Sarthur.perais@inria.fr        // There are separate functions for in-order and out-of-order
47411783Sarthur.perais@inria.fr        // branch prediction, but not for update. Therefore, this
47511783Sarthur.perais@inria.fr        // call should take into account that the mispredicted branch may
47611783Sarthur.perais@inria.fr        // be on the wrong path (i.e., OoO execution), and that the counter
47711783Sarthur.perais@inria.fr        // counter table(s) should not be updated. Thus, this call should
47811783Sarthur.perais@inria.fr        // restore the state of the underlying predictor, for instance the
47911783Sarthur.perais@inria.fr        // local/global histories. The counter tables will be updated when
48011783Sarthur.perais@inria.fr        // the branch actually commits.
48111783Sarthur.perais@inria.fr
48211783Sarthur.perais@inria.fr        // Remember the correct direction for the update at commit.
48311783Sarthur.perais@inria.fr        pred_hist.front().predTaken = actually_taken;
48413626Sjairo.balart@metempsy.com        pred_hist.front().target = corrTarget.instAddr();
48511783Sarthur.perais@inria.fr
48611434Smitch.hayenga@arm.com        update(tid, (*hist_it).pc, actually_taken,
48713626Sjairo.balart@metempsy.com               pred_hist.front().bpHistory, true, pred_hist.front().inst,
48813626Sjairo.balart@metempsy.com               corrTarget.instAddr());
48910785Sgope@wisc.edu
49013733Ssrikant.bharadwaj@amd.com        if (useIndirect) {
49113733Ssrikant.bharadwaj@amd.com            iPred.changeDirectionPrediction(tid,
49213733Ssrikant.bharadwaj@amd.com                pred_hist.front().indirectHistory, actually_taken);
49313733Ssrikant.bharadwaj@amd.com        }
49413654Sjairo.balart@metempsy.com
49510785Sgope@wisc.edu        if (actually_taken) {
49610785Sgope@wisc.edu            if (hist_it->wasReturn && !hist_it->usedRAS) {
49713831SAndrea.Mondelli@ucf.edu                 DPRINTF(Branch, "[tid:%i] [squash sn:%llu] "
49813831SAndrea.Mondelli@ucf.edu                        "Incorrectly predicted "
49913831SAndrea.Mondelli@ucf.edu                        "return [sn:%llu] PC: %#x\n", tid, squashed_sn,
50013831SAndrea.Mondelli@ucf.edu                        hist_it->seqNum,
50113831SAndrea.Mondelli@ucf.edu                        hist_it->pc);
50210785Sgope@wisc.edu                 RAS[tid].pop();
50310785Sgope@wisc.edu                 hist_it->usedRAS = true;
50410785Sgope@wisc.edu            }
50511433Smitch.hayenga@arm.com            if (hist_it->wasIndirect) {
50611433Smitch.hayenga@arm.com                ++indirectMispredicted;
50713810Spau.cabre@metempsy.com                iPred.recordTarget(
50813810Spau.cabre@metempsy.com                    hist_it->seqNum, pred_hist.front().indirectHistory,
50913810Spau.cabre@metempsy.com                    corrTarget, tid);
51011433Smitch.hayenga@arm.com            } else {
51113831SAndrea.Mondelli@ucf.edu                DPRINTF(Branch,"[tid:%i] [squash sn:%llu] "
51213831SAndrea.Mondelli@ucf.edu                        "BTB Update called for [sn:%llu] "
51313831SAndrea.Mondelli@ucf.edu                        "PC %#x\n", tid, squashed_sn,
51413831SAndrea.Mondelli@ucf.edu                        hist_it->seqNum, hist_it->pc);
51510785Sgope@wisc.edu
51611433Smitch.hayenga@arm.com                BTB.update((*hist_it).pc, corrTarget, tid);
51711433Smitch.hayenga@arm.com            }
51810785Sgope@wisc.edu        } else {
51910785Sgope@wisc.edu           //Actually not Taken
52010785Sgope@wisc.edu           if (hist_it->usedRAS) {
52113831SAndrea.Mondelli@ucf.edu                DPRINTF(Branch,
52213831SAndrea.Mondelli@ucf.edu                        "[tid:%i] [squash sn:%llu] Incorrectly predicted "
52313831SAndrea.Mondelli@ucf.edu                        "return [sn:%llu] PC: %#x Restoring RAS\n", tid,
52413831SAndrea.Mondelli@ucf.edu                        squashed_sn,
52510785Sgope@wisc.edu                        hist_it->seqNum, hist_it->pc);
52613831SAndrea.Mondelli@ucf.edu                DPRINTF(Branch,
52713831SAndrea.Mondelli@ucf.edu                        "[tid:%i] [squash sn:%llu] Restoring top of RAS "
52813831SAndrea.Mondelli@ucf.edu                        "to: %i, target: %s\n", tid, squashed_sn,
52910785Sgope@wisc.edu                        hist_it->RASIndex, hist_it->RASTarget);
53010785Sgope@wisc.edu                RAS[tid].restore(hist_it->RASIndex, hist_it->RASTarget);
53110785Sgope@wisc.edu                hist_it->usedRAS = false;
53210785Sgope@wisc.edu           } else if (hist_it->wasCall && hist_it->pushedRAS) {
53310785Sgope@wisc.edu                 //Was a Call but predicated false. Pop RAS here
53413831SAndrea.Mondelli@ucf.edu                 DPRINTF(Branch,
53513831SAndrea.Mondelli@ucf.edu                        "[tid:%i] [squash sn:%llu] "
53613831SAndrea.Mondelli@ucf.edu                        "Incorrectly predicted "
53713831SAndrea.Mondelli@ucf.edu                        "Call [sn:%llu] PC: %s Popping RAS\n",
53813831SAndrea.Mondelli@ucf.edu                        tid, squashed_sn,
53913831SAndrea.Mondelli@ucf.edu                        hist_it->seqNum, hist_it->pc);
54010785Sgope@wisc.edu                 RAS[tid].pop();
54110785Sgope@wisc.edu                 hist_it->pushedRAS = false;
54210785Sgope@wisc.edu           }
54310785Sgope@wisc.edu        }
54410785Sgope@wisc.edu    } else {
54513831SAndrea.Mondelli@ucf.edu        DPRINTF(Branch, "[tid:%i] [sn:%llu] pred_hist empty, can't "
54613831SAndrea.Mondelli@ucf.edu                "update\n", tid, squashed_sn);
54710785Sgope@wisc.edu    }
54810785Sgope@wisc.edu}
54910785Sgope@wisc.edu
55010785Sgope@wisc.eduvoid
55110785Sgope@wisc.eduBPredUnit::dump()
55210785Sgope@wisc.edu{
55310785Sgope@wisc.edu    int i = 0;
55410785Sgope@wisc.edu    for (const auto& ph : predHist) {
55510785Sgope@wisc.edu        if (!ph.empty()) {
55610785Sgope@wisc.edu            auto pred_hist_it = ph.begin();
55710785Sgope@wisc.edu
55810785Sgope@wisc.edu            cprintf("predHist[%i].size(): %i\n", i++, ph.size());
55910785Sgope@wisc.edu
56010785Sgope@wisc.edu            while (pred_hist_it != ph.end()) {
56113831SAndrea.Mondelli@ucf.edu                cprintf("sn:%llu], PC:%#x, tid:%i, predTaken:%i, "
56210785Sgope@wisc.edu                        "bpHistory:%#x\n",
56310785Sgope@wisc.edu                        pred_hist_it->seqNum, pred_hist_it->pc,
56410785Sgope@wisc.edu                        pred_hist_it->tid, pred_hist_it->predTaken,
56510785Sgope@wisc.edu                        pred_hist_it->bpHistory);
56610785Sgope@wisc.edu                pred_hist_it++;
56710785Sgope@wisc.edu            }
56810785Sgope@wisc.edu
56910785Sgope@wisc.edu            cprintf("\n");
57010785Sgope@wisc.edu        }
57110785Sgope@wisc.edu    }
57210785Sgope@wisc.edu}
57310785Sgope@wisc.edu
574