113626Sjairo.balart@metempsy.com/*
213626Sjairo.balart@metempsy.com * Copyright (c) 2014 The University of Wisconsin
313626Sjairo.balart@metempsy.com *
413626Sjairo.balart@metempsy.com * Copyright (c) 2006 INRIA (Institut National de Recherche en
513626Sjairo.balart@metempsy.com * Informatique et en Automatique  / French National Research Institute
613626Sjairo.balart@metempsy.com * for Computer Science and Applied Mathematics)
713626Sjairo.balart@metempsy.com *
813626Sjairo.balart@metempsy.com * All rights reserved.
913626Sjairo.balart@metempsy.com *
1013626Sjairo.balart@metempsy.com * Redistribution and use in source and binary forms, with or without
1113626Sjairo.balart@metempsy.com * modification, are permitted provided that the following conditions are
1213626Sjairo.balart@metempsy.com * met: redistributions of source code must retain the above copyright
1313626Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer;
1413626Sjairo.balart@metempsy.com * redistributions in binary form must reproduce the above copyright
1513626Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer in the
1613626Sjairo.balart@metempsy.com * documentation and/or other materials provided with the distribution;
1713626Sjairo.balart@metempsy.com * neither the name of the copyright holders nor the names of its
1813626Sjairo.balart@metempsy.com * contributors may be used to endorse or promote products derived from
1913626Sjairo.balart@metempsy.com * this software without specific prior written permission.
2013626Sjairo.balart@metempsy.com *
2113626Sjairo.balart@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2213626Sjairo.balart@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2313626Sjairo.balart@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2413626Sjairo.balart@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2513626Sjairo.balart@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2613626Sjairo.balart@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2713626Sjairo.balart@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2813626Sjairo.balart@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2913626Sjairo.balart@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3013626Sjairo.balart@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3113626Sjairo.balart@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3213626Sjairo.balart@metempsy.com *
3313626Sjairo.balart@metempsy.com * Authors: Vignyan Reddy, Dibakar Gope and Arthur Perais,
3413626Sjairo.balart@metempsy.com * from André Seznec's code.
3513626Sjairo.balart@metempsy.com */
3613626Sjairo.balart@metempsy.com
3713626Sjairo.balart@metempsy.com/* @file
3813626Sjairo.balart@metempsy.com * Implementation of a TAGE branch predictor. TAGE is a global-history based
3913626Sjairo.balart@metempsy.com * branch predictor. It features a PC-indexed bimodal predictor and N
4013626Sjairo.balart@metempsy.com * partially tagged tables, indexed with a hash of the PC and the global
4113626Sjairo.balart@metempsy.com * branch history. The different lengths of global branch history used to
4213626Sjairo.balart@metempsy.com * index the partially tagged tables grow geometrically. A small path history
4313626Sjairo.balart@metempsy.com * is also used in the hash.
4413626Sjairo.balart@metempsy.com *
4513626Sjairo.balart@metempsy.com * All TAGE tables are accessed in parallel, and the one using the longest
4613626Sjairo.balart@metempsy.com * history that matches provides the prediction (some exceptions apply).
4713626Sjairo.balart@metempsy.com * Entries are allocated in components using a longer history than the
4813626Sjairo.balart@metempsy.com * one that predicted when the prediction is incorrect.
4913626Sjairo.balart@metempsy.com */
5013626Sjairo.balart@metempsy.com
5113626Sjairo.balart@metempsy.com#ifndef __CPU_PRED_TAGE_BASE
5213626Sjairo.balart@metempsy.com#define __CPU_PRED_TAGE_BASE
5313626Sjairo.balart@metempsy.com
5413626Sjairo.balart@metempsy.com#include <vector>
5513626Sjairo.balart@metempsy.com
5613626Sjairo.balart@metempsy.com#include "base/statistics.hh"
5713626Sjairo.balart@metempsy.com#include "cpu/static_inst.hh"
5813626Sjairo.balart@metempsy.com#include "params/TAGEBase.hh"
5913626Sjairo.balart@metempsy.com#include "sim/sim_object.hh"
6013626Sjairo.balart@metempsy.com
6113626Sjairo.balart@metempsy.comclass TAGEBase : public SimObject
6213626Sjairo.balart@metempsy.com{
6313626Sjairo.balart@metempsy.com  public:
6413626Sjairo.balart@metempsy.com    TAGEBase(const TAGEBaseParams *p);
6513626Sjairo.balart@metempsy.com    void regStats() override;
6613626Sjairo.balart@metempsy.com    void init() override;
6713626Sjairo.balart@metempsy.com
6813626Sjairo.balart@metempsy.com  protected:
6913626Sjairo.balart@metempsy.com    // Prediction Structures
7013626Sjairo.balart@metempsy.com
7113626Sjairo.balart@metempsy.com    // Tage Entry
7213626Sjairo.balart@metempsy.com    struct TageEntry
7313626Sjairo.balart@metempsy.com    {
7413626Sjairo.balart@metempsy.com        int8_t ctr;
7513626Sjairo.balart@metempsy.com        uint16_t tag;
7613626Sjairo.balart@metempsy.com        uint8_t u;
7713626Sjairo.balart@metempsy.com        TageEntry() : ctr(0), tag(0), u(0) { }
7813626Sjairo.balart@metempsy.com    };
7913626Sjairo.balart@metempsy.com
8013626Sjairo.balart@metempsy.com    // Folded History Table - compressed history
8113626Sjairo.balart@metempsy.com    // to mix with instruction PC to index partially
8213626Sjairo.balart@metempsy.com    // tagged tables.
8313626Sjairo.balart@metempsy.com    struct FoldedHistory
8413626Sjairo.balart@metempsy.com    {
8513626Sjairo.balart@metempsy.com        unsigned comp;
8613626Sjairo.balart@metempsy.com        int compLength;
8713626Sjairo.balart@metempsy.com        int origLength;
8813626Sjairo.balart@metempsy.com        int outpoint;
8913626Sjairo.balart@metempsy.com        int bufferSize;
9013626Sjairo.balart@metempsy.com
9113626Sjairo.balart@metempsy.com        FoldedHistory()
9213626Sjairo.balart@metempsy.com        {
9313626Sjairo.balart@metempsy.com            comp = 0;
9413626Sjairo.balart@metempsy.com        }
9513626Sjairo.balart@metempsy.com
9613626Sjairo.balart@metempsy.com        void init(int original_length, int compressed_length)
9713626Sjairo.balart@metempsy.com        {
9813626Sjairo.balart@metempsy.com            origLength = original_length;
9913626Sjairo.balart@metempsy.com            compLength = compressed_length;
10013626Sjairo.balart@metempsy.com            outpoint = original_length % compressed_length;
10113626Sjairo.balart@metempsy.com        }
10213626Sjairo.balart@metempsy.com
10313626Sjairo.balart@metempsy.com        void update(uint8_t * h)
10413626Sjairo.balart@metempsy.com        {
10513626Sjairo.balart@metempsy.com            comp = (comp << 1) | h[0];
10613626Sjairo.balart@metempsy.com            comp ^= h[origLength] << outpoint;
10713626Sjairo.balart@metempsy.com            comp ^= (comp >> compLength);
10813626Sjairo.balart@metempsy.com            comp &= (ULL(1) << compLength) - 1;
10913626Sjairo.balart@metempsy.com        }
11013626Sjairo.balart@metempsy.com    };
11113626Sjairo.balart@metempsy.com
11213626Sjairo.balart@metempsy.com  public:
11313626Sjairo.balart@metempsy.com
11413626Sjairo.balart@metempsy.com    // provider type
11513626Sjairo.balart@metempsy.com    enum {
11613626Sjairo.balart@metempsy.com        BIMODAL_ONLY = 0,
11713626Sjairo.balart@metempsy.com        TAGE_LONGEST_MATCH,
11813626Sjairo.balart@metempsy.com        BIMODAL_ALT_MATCH,
11913626Sjairo.balart@metempsy.com        TAGE_ALT_MATCH,
12013626Sjairo.balart@metempsy.com        LAST_TAGE_PROVIDER_TYPE = TAGE_ALT_MATCH
12113626Sjairo.balart@metempsy.com    };
12213626Sjairo.balart@metempsy.com
12313626Sjairo.balart@metempsy.com    // Primary branch history entry
12413626Sjairo.balart@metempsy.com    struct BranchInfo
12513626Sjairo.balart@metempsy.com    {
12613626Sjairo.balart@metempsy.com        int pathHist;
12713626Sjairo.balart@metempsy.com        int ptGhist;
12813626Sjairo.balart@metempsy.com        int hitBank;
12913626Sjairo.balart@metempsy.com        int hitBankIndex;
13013626Sjairo.balart@metempsy.com        int altBank;
13113626Sjairo.balart@metempsy.com        int altBankIndex;
13213626Sjairo.balart@metempsy.com        int bimodalIndex;
13313626Sjairo.balart@metempsy.com
13413626Sjairo.balart@metempsy.com        bool tagePred;
13513626Sjairo.balart@metempsy.com        bool altTaken;
13613626Sjairo.balart@metempsy.com        bool condBranch;
13713626Sjairo.balart@metempsy.com        bool longestMatchPred;
13813626Sjairo.balart@metempsy.com        bool pseudoNewAlloc;
13913626Sjairo.balart@metempsy.com        Addr branchPC;
14013626Sjairo.balart@metempsy.com
14113626Sjairo.balart@metempsy.com        // Pointer to dynamically allocated storage
14213626Sjairo.balart@metempsy.com        // to save table indices and folded histories.
14313626Sjairo.balart@metempsy.com        // To do one call to new instead of five.
14413626Sjairo.balart@metempsy.com        int *storage;
14513626Sjairo.balart@metempsy.com
14613626Sjairo.balart@metempsy.com        // Pointers to actual saved array within the dynamically
14713626Sjairo.balart@metempsy.com        // allocated storage.
14813626Sjairo.balart@metempsy.com        int *tableIndices;
14913626Sjairo.balart@metempsy.com        int *tableTags;
15013626Sjairo.balart@metempsy.com        int *ci;
15113626Sjairo.balart@metempsy.com        int *ct0;
15213626Sjairo.balart@metempsy.com        int *ct1;
15313626Sjairo.balart@metempsy.com
15413626Sjairo.balart@metempsy.com        // for stats purposes
15513626Sjairo.balart@metempsy.com        unsigned provider;
15613626Sjairo.balart@metempsy.com
15713626Sjairo.balart@metempsy.com        BranchInfo(const TAGEBase &tage)
15813626Sjairo.balart@metempsy.com            : pathHist(0), ptGhist(0),
15913626Sjairo.balart@metempsy.com              hitBank(0), hitBankIndex(0),
16013626Sjairo.balart@metempsy.com              altBank(0), altBankIndex(0),
16113626Sjairo.balart@metempsy.com              bimodalIndex(0),
16213626Sjairo.balart@metempsy.com              tagePred(false), altTaken(false),
16313626Sjairo.balart@metempsy.com              condBranch(false), longestMatchPred(false),
16413626Sjairo.balart@metempsy.com              pseudoNewAlloc(false), branchPC(0),
16513626Sjairo.balart@metempsy.com              provider(-1)
16613626Sjairo.balart@metempsy.com        {
16713626Sjairo.balart@metempsy.com            int sz = tage.nHistoryTables + 1;
16813626Sjairo.balart@metempsy.com            storage = new int [sz * 5];
16913626Sjairo.balart@metempsy.com            tableIndices = storage;
17013626Sjairo.balart@metempsy.com            tableTags = storage + sz;
17113626Sjairo.balart@metempsy.com            ci = tableTags + sz;
17213626Sjairo.balart@metempsy.com            ct0 = ci + sz;
17313626Sjairo.balart@metempsy.com            ct1 = ct0 + sz;
17413626Sjairo.balart@metempsy.com        }
17513626Sjairo.balart@metempsy.com
17613626Sjairo.balart@metempsy.com        virtual ~BranchInfo()
17713626Sjairo.balart@metempsy.com        {
17813626Sjairo.balart@metempsy.com            delete[] storage;
17913626Sjairo.balart@metempsy.com        }
18013626Sjairo.balart@metempsy.com    };
18113626Sjairo.balart@metempsy.com
18213626Sjairo.balart@metempsy.com    virtual BranchInfo *makeBranchInfo();
18313626Sjairo.balart@metempsy.com
18413626Sjairo.balart@metempsy.com    /**
18513626Sjairo.balart@metempsy.com     * Computes the index used to access the
18613626Sjairo.balart@metempsy.com     * bimodal table.
18713626Sjairo.balart@metempsy.com     * @param pc_in The unshifted branch PC.
18813626Sjairo.balart@metempsy.com     */
18913626Sjairo.balart@metempsy.com    virtual int bindex(Addr pc_in) const;
19013626Sjairo.balart@metempsy.com
19113626Sjairo.balart@metempsy.com    /**
19213626Sjairo.balart@metempsy.com     * Computes the index used to access a
19313626Sjairo.balart@metempsy.com     * partially tagged table.
19413626Sjairo.balart@metempsy.com     * @param tid The thread ID used to select the
19513626Sjairo.balart@metempsy.com     * global histories to use.
19613626Sjairo.balart@metempsy.com     * @param pc The unshifted branch PC.
19713626Sjairo.balart@metempsy.com     * @param bank The partially tagged table to access.
19813626Sjairo.balart@metempsy.com     */
19913626Sjairo.balart@metempsy.com    virtual int gindex(ThreadID tid, Addr pc, int bank) const;
20013626Sjairo.balart@metempsy.com
20113626Sjairo.balart@metempsy.com    /**
20213626Sjairo.balart@metempsy.com     * Utility function to shuffle the path history
20313626Sjairo.balart@metempsy.com     * depending on which tagged table we are accessing.
20413626Sjairo.balart@metempsy.com     * @param phist The path history.
20513626Sjairo.balart@metempsy.com     * @param size Number of path history bits to use.
20613626Sjairo.balart@metempsy.com     * @param bank The partially tagged table to access.
20713626Sjairo.balart@metempsy.com     */
20813626Sjairo.balart@metempsy.com    virtual int F(int phist, int size, int bank) const;
20913626Sjairo.balart@metempsy.com
21013626Sjairo.balart@metempsy.com    /**
21113626Sjairo.balart@metempsy.com     * Computes the partial tag of a tagged table.
21213626Sjairo.balart@metempsy.com     * @param tid the thread ID used to select the
21313626Sjairo.balart@metempsy.com     * global histories to use.
21413626Sjairo.balart@metempsy.com     * @param pc The unshifted branch PC.
21513626Sjairo.balart@metempsy.com     * @param bank The partially tagged table to access.
21613626Sjairo.balart@metempsy.com     */
21713626Sjairo.balart@metempsy.com    virtual uint16_t gtag(ThreadID tid, Addr pc, int bank) const;
21813626Sjairo.balart@metempsy.com
21913626Sjairo.balart@metempsy.com    /**
22013626Sjairo.balart@metempsy.com     * Updates a direction counter based on the actual
22113626Sjairo.balart@metempsy.com     * branch outcome.
22213626Sjairo.balart@metempsy.com     * @param ctr Reference to counter to update.
22313626Sjairo.balart@metempsy.com     * @param taken Actual branch outcome.
22413626Sjairo.balart@metempsy.com     * @param nbits Counter width.
22513626Sjairo.balart@metempsy.com     */
22613626Sjairo.balart@metempsy.com    template<typename T>
22713626Sjairo.balart@metempsy.com    static void ctrUpdate(T & ctr, bool taken, int nbits);
22813626Sjairo.balart@metempsy.com
22913626Sjairo.balart@metempsy.com    /**
23013626Sjairo.balart@metempsy.com     * Updates an unsigned counter based on up/down parameter
23113626Sjairo.balart@metempsy.com     * @param ctr Reference to counter to update.
23213626Sjairo.balart@metempsy.com     * @param up Boolean indicating if the counter is incremented/decremented
23313626Sjairo.balart@metempsy.com     * If true it is incremented, if false it is decremented
23413626Sjairo.balart@metempsy.com     * @param nbits Counter width.
23513626Sjairo.balart@metempsy.com     */
23613626Sjairo.balart@metempsy.com    static void unsignedCtrUpdate(uint8_t & ctr, bool up, unsigned nbits);
23713626Sjairo.balart@metempsy.com
23813626Sjairo.balart@metempsy.com    /**
23913626Sjairo.balart@metempsy.com     * Get a branch prediction from the bimodal
24013626Sjairo.balart@metempsy.com     * predictor.
24113626Sjairo.balart@metempsy.com     * @param pc The unshifted branch PC.
24213626Sjairo.balart@metempsy.com     * @param bi Pointer to information on the
24313626Sjairo.balart@metempsy.com     * prediction.
24413626Sjairo.balart@metempsy.com     */
24513626Sjairo.balart@metempsy.com    virtual bool getBimodePred(Addr pc, BranchInfo* bi) const;
24613626Sjairo.balart@metempsy.com
24713626Sjairo.balart@metempsy.com    /**
24813626Sjairo.balart@metempsy.com     * Updates the bimodal predictor.
24913626Sjairo.balart@metempsy.com     * @param pc The unshifted branch PC.
25013626Sjairo.balart@metempsy.com     * @param taken The actual branch outcome.
25113626Sjairo.balart@metempsy.com     * @param bi Pointer to information on the prediction
25213626Sjairo.balart@metempsy.com     * recorded at prediction time.
25313626Sjairo.balart@metempsy.com     */
25413626Sjairo.balart@metempsy.com    void baseUpdate(Addr pc, bool taken, BranchInfo* bi);
25513626Sjairo.balart@metempsy.com
25613626Sjairo.balart@metempsy.com   /**
25713626Sjairo.balart@metempsy.com    * (Speculatively) updates the global branch history.
25813626Sjairo.balart@metempsy.com    * @param h Reference to pointer to global branch history.
25913626Sjairo.balart@metempsy.com    * @param dir (Predicted) outcome to update the histories
26013626Sjairo.balart@metempsy.com    * with.
26113626Sjairo.balart@metempsy.com    * @param tab
26213626Sjairo.balart@metempsy.com    * @param PT Reference to path history.
26313626Sjairo.balart@metempsy.com    */
26413626Sjairo.balart@metempsy.com    void updateGHist(uint8_t * &h, bool dir, uint8_t * tab, int &PT);
26513626Sjairo.balart@metempsy.com
26613626Sjairo.balart@metempsy.com    /**
26713626Sjairo.balart@metempsy.com     * Update TAGE. Called at execute to repair histories on a misprediction
26813626Sjairo.balart@metempsy.com     * and at commit to update the tables.
26913626Sjairo.balart@metempsy.com     * @param tid The thread ID to select the global
27013626Sjairo.balart@metempsy.com     * histories to use.
27113626Sjairo.balart@metempsy.com     * @param branch_pc The unshifted branch PC.
27213626Sjairo.balart@metempsy.com     * @param taken Actual branch outcome.
27313626Sjairo.balart@metempsy.com     * @param bi Pointer to information on the prediction
27413626Sjairo.balart@metempsy.com     * recorded at prediction time.
27513626Sjairo.balart@metempsy.com     */
27613626Sjairo.balart@metempsy.com    void update(ThreadID tid, Addr branch_pc, bool taken, BranchInfo* bi);
27713626Sjairo.balart@metempsy.com
27813626Sjairo.balart@metempsy.com   /**
27913626Sjairo.balart@metempsy.com    * (Speculatively) updates global histories (path and direction).
28013626Sjairo.balart@metempsy.com    * Also recomputes compressed (folded) histories based on the
28113626Sjairo.balart@metempsy.com    * branch direction.
28213626Sjairo.balart@metempsy.com    * @param tid The thread ID to select the histories
28313626Sjairo.balart@metempsy.com    * to update.
28413626Sjairo.balart@metempsy.com    * @param branch_pc The unshifted branch PC.
28513626Sjairo.balart@metempsy.com    * @param taken (Predicted) branch direction.
28613626Sjairo.balart@metempsy.com    * @param b Wrapping pointer to BranchInfo (to allow
28713626Sjairo.balart@metempsy.com    * storing derived class prediction information in the
28813626Sjairo.balart@metempsy.com    * base class).
28913626Sjairo.balart@metempsy.com    */
29013626Sjairo.balart@metempsy.com    virtual void updateHistories(
29113626Sjairo.balart@metempsy.com        ThreadID tid, Addr branch_pc, bool taken, BranchInfo* b,
29213626Sjairo.balart@metempsy.com        bool speculative,
29313626Sjairo.balart@metempsy.com        const StaticInstPtr & inst = StaticInst::nullStaticInstPtr,
29413626Sjairo.balart@metempsy.com        Addr target = MaxAddr);
29513626Sjairo.balart@metempsy.com
29613626Sjairo.balart@metempsy.com    /**
29713626Sjairo.balart@metempsy.com     * Restores speculatively updated path and direction histories.
29813626Sjairo.balart@metempsy.com     * Also recomputes compressed (folded) histories based on the
29913626Sjairo.balart@metempsy.com     * correct branch outcome.
30013626Sjairo.balart@metempsy.com     * This version of squash() is called once on a branch misprediction.
30113626Sjairo.balart@metempsy.com     * @param tid The Thread ID to select the histories to rollback.
30213626Sjairo.balart@metempsy.com     * @param taken The correct branch outcome.
30313626Sjairo.balart@metempsy.com     * @param bp_history Wrapping pointer to BranchInfo (to allow
30413626Sjairo.balart@metempsy.com     * storing derived class prediction information in the
30513626Sjairo.balart@metempsy.com     * base class).
30613626Sjairo.balart@metempsy.com     * @param target The correct branch target
30713626Sjairo.balart@metempsy.com     * @post bp_history points to valid memory.
30813626Sjairo.balart@metempsy.com     */
30913626Sjairo.balart@metempsy.com    virtual void squash(
31013626Sjairo.balart@metempsy.com        ThreadID tid, bool taken, BranchInfo *bi, Addr target);
31113626Sjairo.balart@metempsy.com
31213626Sjairo.balart@metempsy.com    /**
31313626Sjairo.balart@metempsy.com     * Update TAGE for conditional branches.
31413626Sjairo.balart@metempsy.com     * @param branch_pc The unshifted branch PC.
31513626Sjairo.balart@metempsy.com     * @param taken Actual branch outcome.
31613626Sjairo.balart@metempsy.com     * @param bi Pointer to information on the prediction
31713626Sjairo.balart@metempsy.com     * recorded at prediction time.
31813626Sjairo.balart@metempsy.com     * @nrand Random int number from 0 to 3
31913626Sjairo.balart@metempsy.com     * @param corrTarget The correct branch target
32013685Sjavier.bueno@metempsy.com     * @param pred Final prediction for this branch
32114081Sjavier.bueno@metempsy.com     * @param preAdjustAlloc call adjustAlloc before checking
32214081Sjavier.bueno@metempsy.com     * pseudo newly allocated entries
32313626Sjairo.balart@metempsy.com     */
32413626Sjairo.balart@metempsy.com    virtual void condBranchUpdate(
32513626Sjairo.balart@metempsy.com        ThreadID tid, Addr branch_pc, bool taken, BranchInfo* bi,
32614081Sjavier.bueno@metempsy.com        int nrand, Addr corrTarget, bool pred, bool preAdjustAlloc = false);
32713626Sjairo.balart@metempsy.com
32813626Sjairo.balart@metempsy.com    /**
32913626Sjairo.balart@metempsy.com     * TAGE prediction called from TAGE::predict
33013626Sjairo.balart@metempsy.com     * @param tid The thread ID to select the global
33113626Sjairo.balart@metempsy.com     * histories to use.
33213626Sjairo.balart@metempsy.com     * @param branch_pc The unshifted branch PC.
33313626Sjairo.balart@metempsy.com     * @param cond_branch True if the branch is conditional.
33413626Sjairo.balart@metempsy.com     * @param bi Pointer to the BranchInfo
33513626Sjairo.balart@metempsy.com     */
33613626Sjairo.balart@metempsy.com    bool tagePredict(
33713626Sjairo.balart@metempsy.com        ThreadID tid, Addr branch_pc, bool cond_branch, BranchInfo* bi);
33813626Sjairo.balart@metempsy.com
33913626Sjairo.balart@metempsy.com    /**
34013626Sjairo.balart@metempsy.com     * Update the stats
34113626Sjairo.balart@metempsy.com     * @param taken Actual branch outcome
34213626Sjairo.balart@metempsy.com     * @param bi Pointer to information on the prediction
34313626Sjairo.balart@metempsy.com     * recorded at prediction time.
34413626Sjairo.balart@metempsy.com     */
34513626Sjairo.balart@metempsy.com    virtual void updateStats(bool taken, BranchInfo* bi);
34613626Sjairo.balart@metempsy.com
34713626Sjairo.balart@metempsy.com    /**
34813626Sjairo.balart@metempsy.com     * Instantiates the TAGE table entries
34913626Sjairo.balart@metempsy.com     */
35013626Sjairo.balart@metempsy.com    virtual void buildTageTables();
35113626Sjairo.balart@metempsy.com
35213626Sjairo.balart@metempsy.com    /**
35313626Sjairo.balart@metempsy.com     * Calculates the history lengths
35413626Sjairo.balart@metempsy.com     * and some other paramters in derived classes
35513626Sjairo.balart@metempsy.com     */
35613626Sjairo.balart@metempsy.com    virtual void calculateParameters();
35713626Sjairo.balart@metempsy.com
35813626Sjairo.balart@metempsy.com    /**
35913626Sjairo.balart@metempsy.com     * On a prediction, calculates the TAGE indices and tags for
36013626Sjairo.balart@metempsy.com     * all the different history lengths
36113626Sjairo.balart@metempsy.com     */
36213626Sjairo.balart@metempsy.com    virtual void calculateIndicesAndTags(
36313626Sjairo.balart@metempsy.com        ThreadID tid, Addr branch_pc, BranchInfo* bi);
36413626Sjairo.balart@metempsy.com
36513626Sjairo.balart@metempsy.com    /**
36613626Sjairo.balart@metempsy.com     * Calculation of the index for useAltPredForNewlyAllocated
36713626Sjairo.balart@metempsy.com     * On this base TAGE implementation it is always 0
36813626Sjairo.balart@metempsy.com     */
36914081Sjavier.bueno@metempsy.com    virtual unsigned getUseAltIdx(BranchInfo* bi, Addr branch_pc);
37013626Sjairo.balart@metempsy.com
37113626Sjairo.balart@metempsy.com    /**
37213626Sjairo.balart@metempsy.com     * Extra calculation to tell whether TAGE allocaitons may happen or not
37313626Sjairo.balart@metempsy.com     * on an update
37413626Sjairo.balart@metempsy.com     * For this base TAGE implementation it does nothing
37513626Sjairo.balart@metempsy.com     */
37613685Sjavier.bueno@metempsy.com    virtual void adjustAlloc(bool & alloc, bool taken, bool pred_taken);
37713626Sjairo.balart@metempsy.com
37813626Sjairo.balart@metempsy.com    /**
37913626Sjairo.balart@metempsy.com     * Handles Allocation and U bits reset on an update
38013626Sjairo.balart@metempsy.com     */
38113626Sjairo.balart@metempsy.com    virtual void handleAllocAndUReset(
38213626Sjairo.balart@metempsy.com        bool alloc, bool taken, BranchInfo* bi, int nrand);
38313626Sjairo.balart@metempsy.com
38413626Sjairo.balart@metempsy.com    /**
38513626Sjairo.balart@metempsy.com     * Handles the U bits reset
38613626Sjairo.balart@metempsy.com     */
38713626Sjairo.balart@metempsy.com    virtual void handleUReset();
38813626Sjairo.balart@metempsy.com
38913626Sjairo.balart@metempsy.com    /**
39013626Sjairo.balart@metempsy.com     * Handles the update of the TAGE entries
39113626Sjairo.balart@metempsy.com     */
39213626Sjairo.balart@metempsy.com    virtual void handleTAGEUpdate(
39313626Sjairo.balart@metempsy.com        Addr branch_pc, bool taken, BranchInfo* bi);
39413626Sjairo.balart@metempsy.com
39513626Sjairo.balart@metempsy.com    /**
39613626Sjairo.balart@metempsy.com     * Algorithm for resetting a single U counter
39713626Sjairo.balart@metempsy.com     */
39813626Sjairo.balart@metempsy.com    virtual void resetUctr(uint8_t & u);
39913626Sjairo.balart@metempsy.com
40013626Sjairo.balart@metempsy.com    /**
40113626Sjairo.balart@metempsy.com     * Extra steps for calculating altTaken
40213626Sjairo.balart@metempsy.com     * For this base TAGE class it does nothing
40313626Sjairo.balart@metempsy.com     */
40413626Sjairo.balart@metempsy.com    virtual void extraAltCalc(BranchInfo* bi);
40513626Sjairo.balart@metempsy.com
40614081Sjavier.bueno@metempsy.com    virtual bool isHighConfidence(BranchInfo* bi) const
40714081Sjavier.bueno@metempsy.com    {
40814081Sjavier.bueno@metempsy.com        return false;
40914081Sjavier.bueno@metempsy.com    }
41014081Sjavier.bueno@metempsy.com
41113626Sjairo.balart@metempsy.com    void btbUpdate(ThreadID tid, Addr branch_addr, BranchInfo* &bi);
41213626Sjairo.balart@metempsy.com    unsigned getGHR(ThreadID tid, BranchInfo *bi) const;
41313626Sjairo.balart@metempsy.com    int8_t getCtr(int hitBank, int hitBankIndex) const;
41413626Sjairo.balart@metempsy.com    unsigned getTageCtrBits() const;
41513626Sjairo.balart@metempsy.com    int getPathHist(ThreadID tid) const;
41613626Sjairo.balart@metempsy.com    bool isSpeculativeUpdateEnabled() const;
41714081Sjavier.bueno@metempsy.com    size_t getSizeInBits() const;
41813626Sjairo.balart@metempsy.com
41913626Sjairo.balart@metempsy.com  protected:
42013626Sjairo.balart@metempsy.com    const unsigned logRatioBiModalHystEntries;
42113626Sjairo.balart@metempsy.com    const unsigned nHistoryTables;
42213626Sjairo.balart@metempsy.com    const unsigned tagTableCounterBits;
42313626Sjairo.balart@metempsy.com    const unsigned tagTableUBits;
42413626Sjairo.balart@metempsy.com    const unsigned histBufferSize;
42513626Sjairo.balart@metempsy.com    const unsigned minHist;
42613626Sjairo.balart@metempsy.com    const unsigned maxHist;
42713626Sjairo.balart@metempsy.com    const unsigned pathHistBits;
42813626Sjairo.balart@metempsy.com
42913626Sjairo.balart@metempsy.com    std::vector<unsigned> tagTableTagWidths;
43013626Sjairo.balart@metempsy.com    std::vector<int> logTagTableSizes;
43113626Sjairo.balart@metempsy.com
43213626Sjairo.balart@metempsy.com    std::vector<bool> btablePrediction;
43313626Sjairo.balart@metempsy.com    std::vector<bool> btableHysteresis;
43413626Sjairo.balart@metempsy.com    TageEntry **gtable;
43513626Sjairo.balart@metempsy.com
43613626Sjairo.balart@metempsy.com    // Keep per-thread histories to
43713626Sjairo.balart@metempsy.com    // support SMT.
43813626Sjairo.balart@metempsy.com    struct ThreadHistory {
43913626Sjairo.balart@metempsy.com        // Speculative path history
44013626Sjairo.balart@metempsy.com        // (LSB of branch address)
44113626Sjairo.balart@metempsy.com        int pathHist;
44213626Sjairo.balart@metempsy.com
44313626Sjairo.balart@metempsy.com        // Speculative branch direction
44413626Sjairo.balart@metempsy.com        // history (circular buffer)
44513626Sjairo.balart@metempsy.com        // @TODO Convert to std::vector<bool>
44613626Sjairo.balart@metempsy.com        uint8_t *globalHistory;
44713626Sjairo.balart@metempsy.com
44813626Sjairo.balart@metempsy.com        // Pointer to most recent branch outcome
44913626Sjairo.balart@metempsy.com        uint8_t* gHist;
45013626Sjairo.balart@metempsy.com
45113626Sjairo.balart@metempsy.com        // Index to most recent branch outcome
45213626Sjairo.balart@metempsy.com        int ptGhist;
45313626Sjairo.balart@metempsy.com
45413626Sjairo.balart@metempsy.com        // Speculative folded histories.
45513626Sjairo.balart@metempsy.com        FoldedHistory *computeIndices;
45613626Sjairo.balart@metempsy.com        FoldedHistory *computeTags[2];
45713626Sjairo.balart@metempsy.com    };
45813626Sjairo.balart@metempsy.com
45913626Sjairo.balart@metempsy.com    std::vector<ThreadHistory> threadHistory;
46013626Sjairo.balart@metempsy.com
46113626Sjairo.balart@metempsy.com    /**
46213626Sjairo.balart@metempsy.com     * Initialization of the folded histories
46313626Sjairo.balart@metempsy.com     */
46413626Sjairo.balart@metempsy.com    virtual void initFoldedHistories(ThreadHistory & history);
46513626Sjairo.balart@metempsy.com
46613626Sjairo.balart@metempsy.com    int *histLengths;
46713626Sjairo.balart@metempsy.com    int *tableIndices;
46813626Sjairo.balart@metempsy.com    int *tableTags;
46913626Sjairo.balart@metempsy.com
47013626Sjairo.balart@metempsy.com    std::vector<int8_t> useAltPredForNewlyAllocated;
47113626Sjairo.balart@metempsy.com    int64_t tCounter;
47213626Sjairo.balart@metempsy.com    uint64_t logUResetPeriod;
47314081Sjavier.bueno@metempsy.com    const int64_t initialTCounterValue;
47413626Sjairo.balart@metempsy.com    unsigned numUseAltOnNa;
47513626Sjairo.balart@metempsy.com    unsigned useAltOnNaBits;
47613626Sjairo.balart@metempsy.com    unsigned maxNumAlloc;
47713626Sjairo.balart@metempsy.com
47813626Sjairo.balart@metempsy.com    // Tells which tables are active
47913626Sjairo.balart@metempsy.com    // (for the base TAGE implementation all are active)
48013626Sjairo.balart@metempsy.com    // Some other classes use this for handling associativity
48113626Sjairo.balart@metempsy.com    std::vector<bool> noSkip;
48213626Sjairo.balart@metempsy.com
48313626Sjairo.balart@metempsy.com    const bool speculativeHistUpdate;
48413626Sjairo.balart@metempsy.com
48513626Sjairo.balart@metempsy.com    const unsigned instShiftAmt;
48613626Sjairo.balart@metempsy.com
48714081Sjavier.bueno@metempsy.com    bool initialized;
48814081Sjavier.bueno@metempsy.com
48913626Sjairo.balart@metempsy.com    // stats
49013626Sjairo.balart@metempsy.com    Stats::Scalar tageLongestMatchProviderCorrect;
49113626Sjairo.balart@metempsy.com    Stats::Scalar tageAltMatchProviderCorrect;
49213626Sjairo.balart@metempsy.com    Stats::Scalar bimodalAltMatchProviderCorrect;
49313626Sjairo.balart@metempsy.com    Stats::Scalar tageBimodalProviderCorrect;
49413626Sjairo.balart@metempsy.com    Stats::Scalar tageLongestMatchProviderWrong;
49513626Sjairo.balart@metempsy.com    Stats::Scalar tageAltMatchProviderWrong;
49613626Sjairo.balart@metempsy.com    Stats::Scalar bimodalAltMatchProviderWrong;
49713626Sjairo.balart@metempsy.com    Stats::Scalar tageBimodalProviderWrong;
49813626Sjairo.balart@metempsy.com    Stats::Scalar tageAltMatchProviderWouldHaveHit;
49913626Sjairo.balart@metempsy.com    Stats::Scalar tageLongestMatchProviderWouldHaveHit;
50013626Sjairo.balart@metempsy.com
50113626Sjairo.balart@metempsy.com    Stats::Vector tageLongestMatchProvider;
50213626Sjairo.balart@metempsy.com    Stats::Vector tageAltMatchProvider;
50313626Sjairo.balart@metempsy.com};
50413626Sjairo.balart@metempsy.com
50513626Sjairo.balart@metempsy.com#endif // __CPU_PRED_TAGE_BASE
506