bpred_unit.hh revision 9046
12810SN/A/*
212724Snikos.nikoleris@arm.com * Copyright (c) 2011 ARM Limited
38856Sandreas.hansson@arm.com * All rights reserved
48856Sandreas.hansson@arm.com *
58856Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall
68856Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual
78856Sandreas.hansson@arm.com * property including but not limited to intellectual property relating
88856Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software
98856Sandreas.hansson@arm.com * licensed hereunder.  You may use the software subject to the license
108856Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated
118856Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software,
128856Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form.
138856Sandreas.hansson@arm.com *
142810SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
152810SN/A * All rights reserved.
162810SN/A *
172810SN/A * Redistribution and use in source and binary forms, with or without
182810SN/A * modification, are permitted provided that the following conditions are
192810SN/A * met: redistributions of source code must retain the above copyright
202810SN/A * notice, this list of conditions and the following disclaimer;
212810SN/A * redistributions in binary form must reproduce the above copyright
222810SN/A * notice, this list of conditions and the following disclaimer in the
232810SN/A * documentation and/or other materials provided with the distribution;
242810SN/A * neither the name of the copyright holders nor the names of its
252810SN/A * contributors may be used to endorse or promote products derived from
262810SN/A * this software without specific prior written permission.
272810SN/A *
282810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392810SN/A *
402810SN/A * Authors: Kevin Lim
4112724Snikos.nikoleris@arm.com */
422810SN/A
432810SN/A#ifndef __CPU_O3_BPRED_UNIT_HH__
442810SN/A#define __CPU_O3_BPRED_UNIT_HH__
452810SN/A
462810SN/A#include <list>
472810SN/A
482810SN/A#include "base/statistics.hh"
4911486Snikos.nikoleris@arm.com#include "base/types.hh"
5011486Snikos.nikoleris@arm.com#include "cpu/pred/2bit_local.hh"
5112724Snikos.nikoleris@arm.com#include "cpu/pred/btb.hh"
5212724Snikos.nikoleris@arm.com#include "cpu/pred/ras.hh"
538232Snate@binkert.org#include "cpu/pred/tournament.hh"
5412724Snikos.nikoleris@arm.com#include "cpu/inst_seq.hh"
5512724Snikos.nikoleris@arm.com
5611486Snikos.nikoleris@arm.comstruct DerivO3CPUParams;
5712724Snikos.nikoleris@arm.com
5812724Snikos.nikoleris@arm.com/**
5912724Snikos.nikoleris@arm.com * Basically a wrapper class to hold both the branch predictor
6012724Snikos.nikoleris@arm.com * and the BTB.
6112724Snikos.nikoleris@arm.com */
6212724Snikos.nikoleris@arm.comtemplate<class Impl>
6312724Snikos.nikoleris@arm.comclass BPredUnit
642810SN/A{
652810SN/A  private:
662810SN/A    typedef typename Impl::DynInstPtr DynInstPtr;
678856Sandreas.hansson@arm.com
688856Sandreas.hansson@arm.com    enum PredType {
698856Sandreas.hansson@arm.com        Local,
708922Swilliam.wang@arm.com        Tournament
7112084Sspwilson2@wisc.edu    };
7212084Sspwilson2@wisc.edu
738856Sandreas.hansson@arm.com    PredType predictor;
748856Sandreas.hansson@arm.com
754475SN/A    const std::string _name;
7611053Sandreas.hansson@arm.com
775034SN/A  public:
7812724Snikos.nikoleris@arm.com
7912724Snikos.nikoleris@arm.com    /**
8011377Sandreas.hansson@arm.com     * @param params The params object, that has the size of the BP and BTB.
8111377Sandreas.hansson@arm.com     */
8212724Snikos.nikoleris@arm.com    BPredUnit(DerivO3CPUParams *params);
8312724Snikos.nikoleris@arm.com
8412724Snikos.nikoleris@arm.com    const std::string &name() const { return _name; }
8512724Snikos.nikoleris@arm.com
8612724Snikos.nikoleris@arm.com    /**
8712724Snikos.nikoleris@arm.com     * Registers statistics.
8812724Snikos.nikoleris@arm.com     */
8912724Snikos.nikoleris@arm.com    void regStats();
9011053Sandreas.hansson@arm.com
9111722Ssophiane.senni@gmail.com    void switchOut();
9211722Ssophiane.senni@gmail.com
9311722Ssophiane.senni@gmail.com    void takeOverFrom();
9411722Ssophiane.senni@gmail.com
959263Smrinmoy.ghosh@arm.com    /**
965034SN/A     * Predicts whether or not the instruction is a taken branch, and the
9711331Sandreas.hansson@arm.com     * target of the branch if it is taken.
9812724Snikos.nikoleris@arm.com     * @param inst The branch instruction.
9910884Sandreas.hansson@arm.com     * @param PC The predicted PC is passed back through this parameter.
1004626SN/A     * @param tid The thread id.
10110360Sandreas.hansson@arm.com     * @return Returns if the branch is taken or not.
10211484Snikos.nikoleris@arm.com     */
1035034SN/A    bool predict(DynInstPtr &inst, TheISA::PCState &pc, ThreadID tid);
1048883SAli.Saidi@ARM.com
1058833Sdam.sunwoo@arm.com    // @todo: Rename this function.
1064458SN/A    void BPUncond(void * &bp_history);
10711377Sandreas.hansson@arm.com
10811377Sandreas.hansson@arm.com    /**
10911377Sandreas.hansson@arm.com     * Tells the branch predictor to commit any updates until the given
11011377Sandreas.hansson@arm.com     * sequence number.
11111377Sandreas.hansson@arm.com     * @param done_sn The sequence number to commit any older updates up until.
11211377Sandreas.hansson@arm.com     * @param tid The thread id.
11311331Sandreas.hansson@arm.com     */
11411331Sandreas.hansson@arm.com    void update(const InstSeqNum &done_sn, ThreadID tid);
11512724Snikos.nikoleris@arm.com
11612730Sodanrc@yahoo.com.br    /**
11712724Snikos.nikoleris@arm.com     * Squashes all outstanding updates until a given sequence number.
11812724Snikos.nikoleris@arm.com     * @param squashed_sn The sequence number to squash any younger updates up
11912724Snikos.nikoleris@arm.com     * until.
12012724Snikos.nikoleris@arm.com     * @param tid The thread id.
12112724Snikos.nikoleris@arm.com     */
12212724Snikos.nikoleris@arm.com    void squash(const InstSeqNum &squashed_sn, ThreadID tid);
12312724Snikos.nikoleris@arm.com
12412724Snikos.nikoleris@arm.com    /**
12512724Snikos.nikoleris@arm.com     * Squashes all outstanding updates until a given sequence number, and
12612724Snikos.nikoleris@arm.com     * corrects that sn's update with the proper address and taken/not taken.
12712724Snikos.nikoleris@arm.com     * @param squashed_sn The sequence number to squash any younger updates up
1282810SN/A     * until.
1292810SN/A     * @param corr_target The correct branch target.
1303013SN/A     * @param actually_taken The correct branch direction.
1318856Sandreas.hansson@arm.com     * @param tid The thread id.
1322810SN/A     */
1333013SN/A    void squash(const InstSeqNum &squashed_sn,
13410714Sandreas.hansson@arm.com                const TheISA::PCState &corr_target,
1352810SN/A                bool actually_taken, ThreadID tid);
1369614Srene.dejong@arm.com
1379614Srene.dejong@arm.com    /**
1389614Srene.dejong@arm.com     * @param bp_history Pointer to the history object.  The predictor
13910345SCurtis.Dunham@arm.com     * will need to update any state and delete the object.
14010714Sandreas.hansson@arm.com     */
14110345SCurtis.Dunham@arm.com    void BPSquash(void *bp_history);
1429614Srene.dejong@arm.com
1432810SN/A    /**
1442810SN/A     * Looks up a given PC in the BP to see if it is taken or not taken.
1452810SN/A     * @param inst_PC The PC to look up.
1468856Sandreas.hansson@arm.com     * @param bp_history Pointer that will be set to an object that
1472810SN/A     * has the branch predictor state associated with the lookup.
1483013SN/A     * @return Whether the branch is taken or not taken.
14910714Sandreas.hansson@arm.com     */
1503013SN/A    bool BPLookup(Addr instPC, void * &bp_history);
1518856Sandreas.hansson@arm.com
15210714Sandreas.hansson@arm.com     /**
1538922Swilliam.wang@arm.com     * If a branch is not taken, because the BTB address is invalid or missing,
1542897SN/A     * this function sets the appropriate counter in the global and local
1552810SN/A     * predictors to not taken.
1562810SN/A     * @param inst_PC The PC to look up the local predictor.
15710344Sandreas.hansson@arm.com     * @param bp_history Pointer that will be set to an object that
15810344Sandreas.hansson@arm.com     * has the branch predictor state associated with the lookup.
15910344Sandreas.hansson@arm.com     */
16010714Sandreas.hansson@arm.com    void BPBTBUpdate(Addr instPC, void * &bp_history);
16110344Sandreas.hansson@arm.com
16210344Sandreas.hansson@arm.com    /**
16310344Sandreas.hansson@arm.com     * Looks up a given PC in the BTB to see if a matching entry exists.
16410713Sandreas.hansson@arm.com     * @param inst_PC The PC to look up.
16510344Sandreas.hansson@arm.com     * @return Whether the BTB contains the given PC.
1662844SN/A     */
16712730Sodanrc@yahoo.com.br    bool BTBValid(Addr instPC)
16812730Sodanrc@yahoo.com.br    { return BTB.valid(instPC, 0); }
16912730Sodanrc@yahoo.com.br
17012730Sodanrc@yahoo.com.br    /**
17112730Sodanrc@yahoo.com.br     * Looks up a given PC in the BTB to get the predicted target.
17212730Sodanrc@yahoo.com.br     * @param inst_PC The PC to look up.
17312730Sodanrc@yahoo.com.br     * @return The address of the target of the branch.
17412730Sodanrc@yahoo.com.br     */
17512730Sodanrc@yahoo.com.br    TheISA::PCState BTBLookup(Addr instPC)
17612730Sodanrc@yahoo.com.br    { return BTB.lookup(instPC, 0); }
1772810SN/A
1782858SN/A    /**
1792858SN/A     * Updates the BP with taken/not taken information.
18012724Snikos.nikoleris@arm.com     * @param inst_PC The branch's PC that will be updated.
1818922Swilliam.wang@arm.com     * @param taken Whether the branch was taken or not taken.
18212724Snikos.nikoleris@arm.com     * @param bp_history Pointer to the branch predictor state that is
18312724Snikos.nikoleris@arm.com     * associated with the branch lookup that is being updated.
1842858SN/A     * @param squashed Set to true when this function is called during a
1852858SN/A     * squash operation.
1869294Sandreas.hansson@arm.com     * @todo Make this update flexible enough to handle a global predictor.
1879294Sandreas.hansson@arm.com     */
1888922Swilliam.wang@arm.com    void BPUpdate(Addr instPC, bool taken, void *bp_history, bool squashed);
1898922Swilliam.wang@arm.com
19012724Snikos.nikoleris@arm.com    /**
1918922Swilliam.wang@arm.com     * Updates the BTB with the target of a branch.
1928922Swilliam.wang@arm.com     * @param inst_PC The branch's PC that will be updated.
1938922Swilliam.wang@arm.com     * @param target_PC The branch's target that will be added to the BTB.
1948922Swilliam.wang@arm.com     */
1958922Swilliam.wang@arm.com    void BTBUpdate(Addr instPC, const TheISA::PCState &target)
1969294Sandreas.hansson@arm.com    { BTB.update(instPC, target, 0); }
1979294Sandreas.hansson@arm.com
1988922Swilliam.wang@arm.com    void dump();
1998922Swilliam.wang@arm.com
20012724Snikos.nikoleris@arm.com  private:
2018922Swilliam.wang@arm.com    struct PredictorHistory {
2028922Swilliam.wang@arm.com        /**
2038922Swilliam.wang@arm.com         * Makes a predictor history struct that contains any
2048922Swilliam.wang@arm.com         * information needed to update the predictor, BTB, and RAS.
2054628SN/A         */
20610821Sandreas.hansson@arm.com        PredictorHistory(const InstSeqNum &seq_num, Addr instPC,
20710821Sandreas.hansson@arm.com                         bool pred_taken, void *bp_history,
20810821Sandreas.hansson@arm.com                         ThreadID _tid)
20910821Sandreas.hansson@arm.com            : seqNum(seq_num), pc(instPC), bpHistory(bp_history), RASTarget(0),
21010821Sandreas.hansson@arm.com              RASIndex(0), tid(_tid), predTaken(pred_taken), usedRAS(0),
21110821Sandreas.hansson@arm.com              wasCall(0), wasReturn(0), validBTB(0)
21210821Sandreas.hansson@arm.com        {}
21310821Sandreas.hansson@arm.com
21410821Sandreas.hansson@arm.com        bool operator==(const PredictorHistory &entry) const {
21510821Sandreas.hansson@arm.com            return this->seqNum == entry.seqNum;
21610821Sandreas.hansson@arm.com        }
2172858SN/A
21812724Snikos.nikoleris@arm.com        /** The sequence number for the predictor history entry. */
21912724Snikos.nikoleris@arm.com        InstSeqNum seqNum;
22012724Snikos.nikoleris@arm.com
22112724Snikos.nikoleris@arm.com        /** The PC associated with the sequence number. */
22212724Snikos.nikoleris@arm.com        Addr pc;
22312724Snikos.nikoleris@arm.com
22412724Snikos.nikoleris@arm.com        /** Pointer to the history object passed back from the branch
22512724Snikos.nikoleris@arm.com         * predictor.  It is used to update or restore state of the
22612724Snikos.nikoleris@arm.com         * branch predictor.
22712724Snikos.nikoleris@arm.com         */
22812724Snikos.nikoleris@arm.com        void *bpHistory;
22912724Snikos.nikoleris@arm.com
23012724Snikos.nikoleris@arm.com        /** The RAS target (only valid if a return). */
23112724Snikos.nikoleris@arm.com        TheISA::PCState RASTarget;
23212724Snikos.nikoleris@arm.com
23312724Snikos.nikoleris@arm.com        /** The RAS index of the instruction (only valid if a call). */
23412724Snikos.nikoleris@arm.com        unsigned RASIndex;
23512724Snikos.nikoleris@arm.com
23612724Snikos.nikoleris@arm.com        /** The thread id. */
23712724Snikos.nikoleris@arm.com        ThreadID tid;
23812724Snikos.nikoleris@arm.com
23912724Snikos.nikoleris@arm.com        /** Whether or not it was predicted taken. */
24012724Snikos.nikoleris@arm.com        bool predTaken;
24112724Snikos.nikoleris@arm.com
24212724Snikos.nikoleris@arm.com        /** Whether or not the RAS was used. */
24312724Snikos.nikoleris@arm.com        bool usedRAS;
24412724Snikos.nikoleris@arm.com
24512724Snikos.nikoleris@arm.com        /** Whether or not the instruction was a call. */
24612724Snikos.nikoleris@arm.com        bool wasCall;
24712724Snikos.nikoleris@arm.com
24812724Snikos.nikoleris@arm.com        /** Whether or not the instruction was a return. */
24912724Snikos.nikoleris@arm.com        bool wasReturn;
25012724Snikos.nikoleris@arm.com        /** Whether or not the instruction had a valid BTB entry. */
25112724Snikos.nikoleris@arm.com        bool validBTB;
25212724Snikos.nikoleris@arm.com    };
25312724Snikos.nikoleris@arm.com
25412724Snikos.nikoleris@arm.com    typedef std::list<PredictorHistory> History;
25512724Snikos.nikoleris@arm.com    typedef typename History::iterator HistoryIt;
25612724Snikos.nikoleris@arm.com
25712724Snikos.nikoleris@arm.com    /**
25812724Snikos.nikoleris@arm.com     * The per-thread predictor history. This is used to update the predictor
25912724Snikos.nikoleris@arm.com     * as instructions are committed, or restore it to the proper state after
26012724Snikos.nikoleris@arm.com     * a squash.
26112724Snikos.nikoleris@arm.com     */
26212724Snikos.nikoleris@arm.com    History predHist[Impl::MaxThreads];
26312724Snikos.nikoleris@arm.com
26412724Snikos.nikoleris@arm.com    /** The local branch predictor. */
26512724Snikos.nikoleris@arm.com    LocalBP *localBP;
26612724Snikos.nikoleris@arm.com
26712724Snikos.nikoleris@arm.com    /** The tournament branch predictor. */
26812724Snikos.nikoleris@arm.com    TournamentBP *tournamentBP;
26912724Snikos.nikoleris@arm.com
27012724Snikos.nikoleris@arm.com    /** The BTB. */
27112724Snikos.nikoleris@arm.com    DefaultBTB BTB;
27212724Snikos.nikoleris@arm.com
27312724Snikos.nikoleris@arm.com    /** The per-thread return address stack. */
27412724Snikos.nikoleris@arm.com    ReturnAddrStack RAS[Impl::MaxThreads];
27512724Snikos.nikoleris@arm.com
27612724Snikos.nikoleris@arm.com    /** Stat for number of BP lookups. */
27712724Snikos.nikoleris@arm.com    Stats::Scalar lookups;
27812724Snikos.nikoleris@arm.com    /** Stat for number of conditional branches predicted. */
27912724Snikos.nikoleris@arm.com    Stats::Scalar condPredicted;
28012724Snikos.nikoleris@arm.com    /** Stat for number of conditional branches predicted incorrectly. */
28112724Snikos.nikoleris@arm.com    Stats::Scalar condIncorrect;
28212724Snikos.nikoleris@arm.com    /** Stat for number of BTB lookups. */
28312724Snikos.nikoleris@arm.com    Stats::Scalar BTBLookups;
28412724Snikos.nikoleris@arm.com    /** Stat for number of BTB hits. */
28512724Snikos.nikoleris@arm.com    Stats::Scalar BTBHits;
28612724Snikos.nikoleris@arm.com    /** Stat for number of times the BTB is correct. */
28712724Snikos.nikoleris@arm.com    Stats::Scalar BTBCorrect;
28812724Snikos.nikoleris@arm.com    /** Stat for number of times the RAS is used to get a target. */
28912724Snikos.nikoleris@arm.com    Stats::Scalar usedRAS;
29012724Snikos.nikoleris@arm.com    /** Stat for number of times the RAS is incorrect. */
29112724Snikos.nikoleris@arm.com    Stats::Scalar RASIncorrect;
29212724Snikos.nikoleris@arm.com};
29312724Snikos.nikoleris@arm.com
29412724Snikos.nikoleris@arm.com#endif // __CPU_O3_BPRED_UNIT_HH__
29512724Snikos.nikoleris@arm.com