/*
 * Copyright 2019 Texas A&M University
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  Author: Daniel A. Jiménez
 *  Adapted to gem5 by: Javier Bueno Hedo
 *
 */

/*
 * Multiperspective Perceptron Predictor (by Daniel A. Jiménez)
 */

#ifndef __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_HH__
#define __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_HH__

#include <array>
#include <vector>

#include "cpu/pred/bpred_unit.hh"
#include "params/MultiperspectivePerceptron.hh"

class MultiperspectivePerceptron : public BPredUnit
{
  protected:
    /**
     * Branch information data
     */
    class MPPBranchInfo
    {
        /** pc of the branch */
        const unsigned int pc;
        /** pc of the branch, shifted 2 bits to the right */
        const unsigned short int pc2;
        /** pc of the branch, hashed */
        const unsigned short int hpc;
        /** Whether this is a conditional branch */
        const bool condBranch;

        /**
         * PC Hash functions
         */
        static inline unsigned int hash1(unsigned int a)
        {
            a = (a ^ 0xdeadbeef) + (a<<4);
            a = a ^ (a>>10);
            a = a + (a<<7);
            a = a ^ (a>>13);
            return a;
        }

        static inline unsigned int hash2(unsigned int key)
        {
            int c2 = 0x27d4eb2d; // a prime or an odd constant
            key = (key ^ 61) ^ (key >> 16);
            key = key + (key << 3);
            key = key ^ (key >> 4);
            key = key * c2;
            key = key ^ (key >> 15);
            return key;
        }

        static inline unsigned int hash(unsigned int key, unsigned int i)
        {
            return hash2(key) * i + hash1(key);
        }

        static inline unsigned int hashPC(unsigned int pc, int pcshift)
        {
            if (pcshift < 0) {
                return hash(pc, -pcshift);
            } else if (pcshift < 11) {
                unsigned int x = pc;
                x ^= (pc >> pcshift);
                return x;
            } else {
                return pc >> (pcshift-11);
            }
        }

      public:
        /** Whether this branch has been filtered by the prefetcher */
        bool filtered;
        /** Result of the prediction (true is taken) */
        bool prediction;
        /** Score of the perceptron */
        int yout;

        MPPBranchInfo(Addr _pc, int pcshift, bool cb) : pc((unsigned int)_pc),
        pc2(pc >> 2), hpc(hashPC(pc, pcshift)), condBranch(cb),
        filtered(false), prediction(false), yout(0)
        { }

        unsigned int getPC() const
        {
            return pc;
        }
        unsigned short int getPC2() const
        {
            return pc2;
        }
        unsigned short int getHPC() const
        {
            return hpc;
        }
        unsigned int getHashFilter(bool last_ghist_bit) const
        {
            return last_ghist_bit ^ hpc;
        }
        bool isUnconditional() const
        {
            return !condBranch;
        }
    };

    /**
     * Entry of the branch filter
     */
    struct FilterEntry
    {
        /** Has this branch been taken at least once? */
        bool seenTaken;
        /** Has this branch been not taken at least once? */
        bool seenUntaken;

        FilterEntry() : seenTaken(false), seenUntaken(false) {}

        /** Whether this branch has always been observed as not taken */
        bool alwaysNotTakenSoFar() const {
            return seenUntaken & !seenTaken;
        }
        /** Whether this branch has always been observed as taken */
        bool alwaysTakenSoFar() const {
            return seenTaken & !seenUntaken;
        }
        /** Whether this branch has been observed before */
        bool neverSeen() const {
            return !seenTaken && !seenUntaken;
        }
    };


    /**
     * Local history entries, each enty contains the history of directions
     * taken by a given branch.
     */
    class LocalHistories
    {
        /** The array of histories */
        std::vector<unsigned int> localHistories;
        /** Size in bits of each history entry */
        const int localHistoryLength;

        /** Index function given the pc of the branch */
        unsigned int index(Addr pc) const {
            return (pc >> 2) % localHistories.size();
        }
        public:
        LocalHistories(int nlocal_histories, int histo_len) :
            localHistories(nlocal_histories), localHistoryLength(histo_len) {}

        /** Obtains the local history entry of a given branch */
        unsigned int operator[](Addr pc) const
        {
            return localHistories[index(pc)];
        }

        /** Adds a history bit to the local history entry of a given branch */
        void update(Addr pc, bool value)
        {
            assert(localHistories.size() > 0);
            unsigned int &pos = localHistories[index(pc)];
            pos <<= 1;
            pos |= value;
            pos &= ((1<<localHistoryLength)-1);
        }

        /** Returns the number of bits of each local history entry */
        int getLocalHistoryLength() const
        {
            return localHistoryLength;
        }

        /** Size in bits required by all history entries */
        int getSize() const
        {
            return localHistoryLength * localHistories.size();
        }
    };

    /**
     * Base class to implement the predictor tables.
     */
    struct HistorySpec
    {
        /** First parameter */
        const int p1;
        /** Second parameter */
        const int p2;
        /** Third parameter */
        const int p3;
        /** Coefficient of the feature, models the accuracy of the feature */
        const double coeff;
        /** Pre-assigned size in bits assigned to this feature */
        const int size;
        /** Width of the table in bits  */
        const int width;
        /** Reference to the branch predictor class */
        MultiperspectivePerceptron &mpp;

        HistorySpec(int _p1, int _p2, int _p3, double _coeff, int _size,
                int _width, MultiperspectivePerceptron &_mpp) : p1(_p1),
        p2(_p2), p3(_p3), coeff(_coeff), size(_size), width(_width),
        mpp(_mpp)
        {}

        /**
         * Gets the hash to index the table, using the pc of the branch,
         * and the index of the table.
         * @param tid Thread ID of the branch
         * @param pc address of the branch
         * @param pc2 address of the branch shifted 2 bits to the right
         * @param t integer index of the table
         * @result resulting hash value that will be used to index the table
         */
        virtual unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t)
            const = 0;
        /**
         * Sets the size requirements of the table, used when initializing
         * to set the proper size of the tables
         */
        virtual void setBitRequirements() const {}
    };

    /** Predictor parameters */
    const int blockSize;
    const int pcshift;
    const int threshold;
    const int bias0;
    const int bias1;
    const int biasmostly0;
    const int biasmostly1;
    const int nbest;
    const int tunebits;
    const int hshift;
    const unsigned long long int imli_mask1;
    const unsigned long long int imli_mask4;
    const unsigned long long int recencypos_mask;
    const double fudge;
    const int n_sign_bits;
    const int pcbit;
    const int decay;
    const unsigned int record_mask;
    const bool hash_taken;
    const bool tuneonly;
    const int extra_rounds;
    const int speed;
    const int budgetbits;
    const bool speculative_update;

    /** Transfer function for 6-width tables */
    static int xlat[];
    /** Transfer function for 5-width tables */
    static int xlat4[];

    /** History data is kept for each thread */
    struct ThreadData
    {
        ThreadData(int num_filter, int n_local_histories,
            int local_history_length, int assoc,
            const std::vector<std::vector<int>> &blurrypath_bits,
            int path_length, int ghist_length, int block_size,
            const std::vector<std::vector<std::vector<bool>>> &acyclic_bits,
            const std::vector<int> &modhist_indices,
            const std::vector<int> &modhist_lengths,
            const std::vector<int> &modpath_indices,
            const std::vector<int> &modpath_lengths,
            const std::vector<int> &table_sizes, int n_sign_bits);

        std::vector<FilterEntry> filterTable;
        std::vector<std::vector<bool>> acyclic_histories;
        std::vector<std::vector<unsigned int>> acyclic2_histories;

        void updateAcyclic(bool hashed_taken, unsigned int hpc) {
            for (int i = 0; i < acyclic_histories.size(); i += 1) {
                if (acyclic_histories[i].size() > 0) {
                    acyclic_histories[i][hpc%(i+2)] = hashed_taken;
                    acyclic2_histories[i][hpc%(i+2)] = hpc;
                }
            }
        }

        std::vector<std::vector<unsigned int>> blurrypath_histories;
        std::vector<unsigned int> ghist_words;
        std::vector<std::vector<unsigned short int>> modpath_histories;
        std::vector<std::vector<bool>> mod_histories;
        std::vector<unsigned short int> path_history;
        std::vector<unsigned int> imli_counter;
        LocalHistories localHistories;
        std::vector<unsigned int short> recency_stack;

        void insertRecency(unsigned int pc, int assoc) {
            int i = 0;
            for (i = 0; i < assoc; i += 1) {
                if (recency_stack[i] == pc) {
                    break;
                }
            }
            if (i == assoc) {
                i = assoc-1;
                recency_stack[i] = pc;
            }
            int j;
            unsigned int b = recency_stack[i];
            for (j = i; j >= 1; j -= 1) {
                recency_stack[j] = recency_stack[j-1];
            }
            recency_stack[0] = b;
        }

        bool last_ghist_bit;
        int occupancy;

        std::vector<int> mpreds;
        std::vector<std::vector<short int>> tables;
        std::vector<std::vector<std::array<bool, 2>>> sign_bits;
    };
    std::vector<ThreadData *> threadData;

    /** Predictor tables */
    std::vector<HistorySpec *> specs;
    std::vector<int> table_sizes;

    /** runtime values and data used to count the size in bits */
    bool doing_local;
    bool doing_recency;
    int assoc;
    int ghist_length;
    int modghist_length;
    int path_length;
    int thresholdCounter;
    int theta;
    int extrabits;
    std::vector<int> imli_counter_bits;
    std::vector<int> modhist_indices;
    std::vector<int> modhist_lengths;
    std::vector<int> modpath_indices;
    std::vector<int> modpath_lengths;
    std::vector<std::vector<int>> blurrypath_bits;
    std::vector<std::vector<std::vector<bool>>> acyclic_bits;

    /** Auxiliary function for MODHIST and GHISTMODPATH features */
    void insertModhistSpec(int p1, int p2) {
        int j = insert(modhist_indices, p1);
        if (modhist_lengths.size() < (j + 1)) {
            modhist_lengths.resize(j + 1);
        }
        if (modhist_lengths[j] < p2 + 1) {
            modhist_lengths[j] = p2 + 1;
        }
        if (p2 >= modghist_length) {
            modghist_length = p2 + 1;
        }
    }

    /** Auxiliary function for MODPATH and GHISTMODPATH features */
    void insertModpathSpec(int p1, int p2) {
        int j = insert(modpath_indices, p1);
        if (modpath_lengths.size() < (j + 1)) {
            modpath_lengths.resize(j + 1);
        }
        if (modpath_lengths[j] < p2 + 1) {
            modpath_lengths[j] = p2 + 1;
        }
        if (p2 >= path_length) {
            path_length = p2 + 1;
        }
    }

    /** Auxiliary function used by insertModhistSpec and insertModpathSpec*/
    int insert(std::vector<int> &v, int x)
    {
        for (int i = 0; i < v.size(); i += 1) {
            if (v[i] == x) {
                return i;
            }
        }
        v.push_back(x);
        return v.size()-1;
    }

    /**
     * Computes the size in bits of the structures needed to keep track
     * of the history and the predictor tables and assigns the sizes of
     * those tables that did not had their size specified.
     * @param num_filter_entries number of entries of the filter
     * @param nlocal_histories number of local history entries
     * @param local_history_length size of each local history entry
     * @param ignore_path_size ignore the path length storage
     */
    void computeBits(int num_filter_entries, int nlocal_histories,
            int local_history_length, bool ignore_path_size);

    /**
     * Creates the tables of the predictor
     */
    virtual void createSpecs() = 0;

    /**
     * Get the position index of a predictor table
     * @param tid Thread ID of the branch
     * @param bi branch informaiton data
     * @param spec predictor table
     * @param index integer index of the predictor table
     * @result index to access the predictor table
     */
    unsigned int getIndex(ThreadID tid, const MPPBranchInfo &bi,
            const HistorySpec &spec, int index) const;
    /**
     * Finds the best subset of features to use in case of a low-confidence
     * branch, returns the result as an ordered vector of the indices to the
     * predictor tables
     * @param tid Thread ID of the branch
     * @param vector to write the ordered list of indices of the best tables
     */
    void findBest(ThreadID tid, std::vector<int> &best_preds) const;

    /**
     * Computes the output of the predictor for a given branch and the
     * resulting best value in case the prediction has low confidence
     * @param tid Thread ID of the branch
     * @param bi branch informaiton data
     * @return resulting sum for low-confidence branch
     */
    int computeOutput(ThreadID tid, MPPBranchInfo &bi);

    /**
     * Trains the branch predictor with the given branch and direction
     * @param tid Thread ID of the branch
     * @param bi branch informaiton data
     * @param taken whether the branch was taken
     */
    void train(ThreadID tid, MPPBranchInfo &bi, bool taken);

    /**
     * Auxiliary function to increase a table counter depending on the
     * direction of the branch
     * @param taken whether the branch was taken
     * @param sign current sign of the table
     * @param c current value of the table
     * @param max_weight maximum value of the counter
     */
    void satIncDec(bool taken, bool &sign, int &c, int max_weight) const;

    /** Add a table spec to the prefetcher */
    void addSpec(HistorySpec *spec)
    {
        specs.push_back(spec);
    }

    /** Available features */

    class GHIST : public HistorySpec
    {
      public:
        GHIST(int p1, int p2, double coeff, int size, int width,
                MultiperspectivePerceptron &mpp)
            : HistorySpec(p1, p2, 0, coeff, size, width, mpp)
        {}

        unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
            override
        {
            return hash(mpp.threadData[tid]->ghist_words, mpp.blockSize, p1,
                        p2);
        }

        static unsigned int hash(const std::vector<unsigned int> &ghist_words,
                int block_size, int start_pos, int end_pos)
        {
            int a = start_pos;
            int b = end_pos;

            unsigned int x = 0;
            // am is the next multiple of block_size after a
            int am = (((a/block_size)*block_size)+block_size);
            // bm is the previous multiple of block_size before b
            int bm = (b/block_size)*block_size;

            // the 0th bit of ghist_words[a/block_size] is the most recent bit.
            // so the number of bits between a and am is the number to shift
            // right?

            // start out x as remainder bits from the beginning:
            // x = [ . . . . . b b b b b ]
            x += ghist_words[a / block_size] >> (a-am);
            // add in bits from the middle
            for (int i=am; i<bm; i+=block_size) {
                x += ghist_words[i / block_size];
            }
            // add in remainder bits from end:
            // x += [ b b b b b . . . . . ]
            unsigned int y = ghist_words[bm / block_size] & ((1<<(b - bm))-1);
            x += y << (block_size - (b - bm));
            return x;
        }
        void setBitRequirements() const override
        {
            if (mpp.ghist_length <= p2) {
                mpp.ghist_length = p2 + 1;
            }
        }
    };

    class ACYCLIC : public HistorySpec
    {
      public:
        ACYCLIC(int p1, int p2, int p3, double coeff, int size, int width,
                MultiperspectivePerceptron &mpp)
            : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
        {}

        unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
            override
        {
            int a = p1;
            int shift = p2;
            int style = p3;
            std::vector<std::vector<bool>> &acyclic_histories =
                mpp.threadData[tid]->acyclic_histories;
            std::vector<std::vector<unsigned int>> &acyclic2_histories =
                mpp.threadData[tid]->acyclic2_histories;

            unsigned int x = 0;
            if (style == -1) {
                unsigned int k = 0;
                for (int i = 0; i < a + 2; i += 1) {
                    x ^= acyclic_histories[a][i] << k;
                    k += 1;
                    k %= mpp.blockSize;
                }
            } else {
                for (int i = 0; i < a + 2; i += 1) {
                    x <<= shift;
                    x += acyclic2_histories[a][i];
                }
            }
            return x;
        }
        void setBitRequirements() const override
        {
            if (mpp.acyclic_bits.size() < (p1 + 1)) {
                mpp.acyclic_bits.resize(p1 + 1);
            }
            if (mpp.acyclic_bits[p1].size() < (p1 + 2)) {
                mpp.acyclic_bits[p1].resize(p1 + 2, std::vector<bool>(2));
            }
            for (int j = 0; j < p1 + 2; j += 1) {
                mpp.acyclic_bits[p1][j][!p3] = true;
            }
        }
    };

    class MODHIST : public HistorySpec
    {
      public:
        MODHIST(int p1, int p2, double coeff, int size, int width,
                MultiperspectivePerceptron &mpp)
            : HistorySpec(p1, p2, 0, coeff, size, width, mpp)
        {}

        unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
            override
        {
            int a = p1;
            int b = p2;
            std::vector<std::vector<bool>> &mod_histories =
                mpp.threadData[tid]->mod_histories;

            unsigned int x = 0, k = 0;
            for (int i = 0; i < b; i += 1) {
                x ^= mod_histories[a][i] << k;
                k += 1;
                k %= mpp.blockSize;
            }
            return x;
        }
        void setBitRequirements() const override
        {
            mpp.insertModhistSpec(p1, p2);
        }
    };

    class BIAS : public HistorySpec
    {
      public:
        BIAS(double coeff, int size, int width,
                MultiperspectivePerceptron &mpp)
            : HistorySpec(0, 0, 0, coeff, size, width, mpp)
        {}

        unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
            override
        {
            return 0;
        }
    };


    class RECENCY : public HistorySpec
    {
      public:
        RECENCY(int p1, int p2, int p3, double coeff, int size, int width,
                MultiperspectivePerceptron &mpp)
            : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
        {}

        unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
            override
        {
            int depth = p1;
            int shift = p2;
            int style = p3;
            std::vector<unsigned int short> &recency_stack =
                mpp.threadData[tid]->recency_stack;

            if (style == -1) {
                unsigned int x = 0;
                for (int i = 0; i < depth; i += 1) {
                    x <<= shift;
                    x += recency_stack[i];
                }
                return x;
            } else {
                unsigned int x = 0, k = 0;
                for (int i = 0; i < depth; i += 1) {
                    x ^= (!!(recency_stack[i] & (1 << shift))) << k;
                    k += 1;
                    k %= mpp.blockSize;
                }
                return x;
            }
        }
        void setBitRequirements() const override
        {
            if (mpp.assoc < p1) {
                mpp.assoc = p1;
            }
            mpp.doing_recency = true;
        }
    };

    class IMLI : public HistorySpec
    {
        public:
            IMLI(int p1, double coeff, int size, int width,
                    MultiperspectivePerceptron &mpp)
                : HistorySpec(p1, 0, 0, coeff, size, width, mpp)
            {}

            unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
                override
                {
                    assert(p1 >= 1);
                    assert(p1 <= 4);
                    return mpp.threadData[tid]->imli_counter[p1-1];
                }

            void setBitRequirements() const override
            {
                mpp.imli_counter_bits[p1 - 1] = 32;
            }
    };

    class PATH : public HistorySpec
    {
      public:
        PATH(int p1, int p2, int p3, double coeff, int size, int width,
                MultiperspectivePerceptron &mpp)
            : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
        {}

        unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
            override
        {
            int depth = p1;
            int shift = p2;
            int style = p3;
            std::vector<unsigned short int> &path_history =
                mpp.threadData[tid]->path_history;

            if (style == -1) {
                unsigned int x = 0;
                for (int i = 0; i < depth; i += 1) {
                    x <<= shift;
                    x += path_history[i];
                }
                return x;
            } else {
                unsigned int x = 0;
                int bm = (depth / mpp.blockSize) * mpp.blockSize;
                for (int i = 0; i < bm; i += mpp.blockSize) {
                    for (int j = 0; j < mpp.blockSize; j += 1) {
                        x ^= (!!(path_history[i + j] & (1 << shift))) << j;
                    }
                }
                int k = 0;
                for (int i = bm; i < depth; i += 1) {
                    x ^= (!!(path_history[i] & (1 << shift))) << k++;
                }
                return x;
            }
        }
        void setBitRequirements() const override
        {
            if (mpp.path_length <= p1) {
                mpp.path_length = p1 + 1;
            }
        }
    };

    class LOCAL : public HistorySpec
    {
      public:
        LOCAL(int p1, double coeff, int size, int width,
                MultiperspectivePerceptron &mpp)
            : HistorySpec(p1, 0, 0, coeff, size, width, mpp)
        {}

        unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
            override
        {
            unsigned int x = mpp.threadData[tid]->localHistories[pc];
            if (p1 != -1) {
                x &= ((1 << p1) - 1);
            }
            return x;
        }
        void setBitRequirements() const override
        {
            mpp.doing_local = true;
        }
    };

    class MODPATH : public HistorySpec
    {
      public:
        MODPATH(int p1, int p2, int p3, double coeff, int size, int width,
                MultiperspectivePerceptron &mpp)
            : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
        {}

        unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
            override
        {
            int a = p1;
            int depth = p2;
            int shift = p3;

            unsigned int x = 0;
            for (int i=0; i<depth; i += 1) {
                x <<= shift;
                x += mpp.threadData[tid]->modpath_histories[a][i];
            }
            return x;
        }
        void setBitRequirements() const override
        {
            mpp.insertModpathSpec(p1, p2);
        }
    };

    class GHISTPATH : public HistorySpec
    {
      public:
        GHISTPATH(int p1, int p2, int p3, double coeff, int size, int width,
                MultiperspectivePerceptron &mpp)
            : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
        {}

        unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
            override
        {
            int depth = p1;
            int shift = p2;
            int style = p3;
            std::vector<unsigned int> &ghist_words =
                mpp.threadData[tid]->ghist_words;
            std::vector<unsigned short int> &path_history =
                mpp.threadData[tid]->path_history;

            if (style == -1) {
                unsigned int x = 0;
                int bm = (depth / mpp.blockSize) * mpp.blockSize;
                unsigned int w;
                for (int i = 0; i < bm; i += mpp.blockSize) {
                    w = ghist_words[i / mpp.blockSize];
                    for (int j = 0; j < mpp.blockSize; j += 1) {
                        x <<= shift;
                        x += (path_history[i + j] << 1) | (w & 1);
                        w >>= 1;
                    }
                }
                w = ghist_words[bm / mpp.blockSize];
                for (int i = bm; i < depth; i += 1) {
                    x <<= shift;
                    x += (path_history[i] << 1) | (w & 1);
                    w >>= 1;
                }
                return x;
            } else {
                unsigned int x = 0;
                int bm = (depth / mpp.blockSize) * mpp.blockSize;
                unsigned int w = 0;
                for (int i = 0; i < bm; i += mpp.blockSize) {
                    w = ghist_words[i / mpp.blockSize];
                    for (int j = 0; j < mpp.blockSize; j += 1) {
                        x ^= (!!(path_history[i + j] & (1 << shift))) << j;
                        x ^= (w & 1) << j;
                        w >>= 1;
                    }
                }
                w = ghist_words[bm/mpp.blockSize];
                int k = 0;
                for (int i = bm; i < depth; i += 1) {
                    x ^= (!!(path_history[i] & (1 << shift))) << k;
                    x ^= (w & 1) << k;
                    w >>= 1;
                    k += 1;
                }
                return x;
            }
        }

        void setBitRequirements() const override
        {
            if (mpp.ghist_length <= p1) {
                mpp.ghist_length = p1 + 1;
            }
            if (mpp.path_length <= p1) {
                mpp.path_length = p1 + 1;
            }
        }
    };

    class GHISTMODPATH : public HistorySpec
    {
      public:
        GHISTMODPATH(int p1, int p2, int p3, double coeff, int size, int width,
                MultiperspectivePerceptron &mpp)
            : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
        {}

        unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
            override
        {
            int a = p1;
            int depth = p2;
            int shift = p3;
            std::vector<std::vector<unsigned short int>> &modpath_histories =
                mpp.threadData[tid]->modpath_histories;
            std::vector<std::vector<bool>> &mod_histories =
                mpp.threadData[tid]->mod_histories;

            unsigned int x = 0;
            for (int i = 0; i < depth; i += 1) {
                x <<= shift;
                x += (modpath_histories[a][i] << 1) | mod_histories[a][i];
            }
            return x;
        }
        void setBitRequirements() const override
        {
            mpp.insertModhistSpec(p1, p2);
            mpp.insertModpathSpec(p1, p2);
        }
    };

    class BLURRYPATH : public HistorySpec
    {
      public:
        BLURRYPATH(int p1, int p2, int p3, double coeff, int size, int width,
                MultiperspectivePerceptron &mpp)
            : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
        {}

        unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
            override
        {
            int scale = p1;
            int depth = p2;
            int shiftdelta = p3;

            if (shiftdelta == -1) shiftdelta = 0;
            int sdint = shiftdelta >> 2;
            int sdfrac = shiftdelta & 3;
            unsigned int x = 0;
            int shift = 0;
            int count = 0;
            for (int i = 0; i < depth; i += 1) {
                x += mpp.threadData[tid]->blurrypath_histories[scale][i] >>
                    shift;
                count += 1;
                if (count == sdfrac) {
                    shift += sdint;
                    count = 0;
                }
            }
            return x;

        }
        void setBitRequirements() const override
        {
            if (mpp.blurrypath_bits.size() < (p1 + 1)) {
                mpp.blurrypath_bits.resize(p1 + 1);
            }
            if (mpp.blurrypath_bits[p1].size() < p2) {
                mpp.blurrypath_bits[p1].resize(p2);
            }
            for (int j = 0; j < p2; j += 1) {
                mpp.blurrypath_bits[p1][j] = 32 - p1;
            }
        }
    };

    class RECENCYPOS : public HistorySpec
    {
      public:
        RECENCYPOS(int p1, double coeff, int size, int width,
                MultiperspectivePerceptron &mpp)
            : HistorySpec(p1, 0, 0, coeff, size, width, mpp)
        {}

        unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
            override
        {
            return hash(mpp.threadData[tid]->recency_stack, mpp.table_sizes,
                    pc2, p1, t);
        }

        static unsigned int hash(
            const std::vector<unsigned int short> &recency_stack,
            const std::vector<int> &table_sizes, unsigned short int pc, int l,
            int t)
        {
            // search for the PC

            for (int i = 0; i < l; i += 1) {
                if (recency_stack[i] == pc) {
                    return i * table_sizes[t] / l;
                }
            }

            // return last index in table on a miss

            return table_sizes[t] - 1;
        }

        void setBitRequirements() const override
        {
            if (mpp.assoc < p1) {
                mpp.assoc = p1;
            }
            mpp.doing_recency = true;
        }
    };

    class SGHISTPATH : public HistorySpec
    {
      public:
        SGHISTPATH(int p1, int p2, int p3, double coeff, int size, int width,
                MultiperspectivePerceptron &mpp)
            : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
        {}

        unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
            override
        {
            int a = p1;
            int b = p2;
            int shift = p3;
            std::vector<unsigned int> &ghist_words =
                mpp.threadData[tid]->ghist_words;
            std::vector<unsigned short int> &path_history =
                mpp.threadData[tid]->path_history;

            unsigned int x = 0;
            int bm = (b / mpp.blockSize) * mpp.blockSize;
            unsigned int w;
            for (int i = a; i < bm; i += mpp.blockSize) {
                w = ghist_words[i / mpp.blockSize];
                for (int j = 0; j < mpp.blockSize; j += 1) {
                    x <<= shift;
                    x += (path_history[i+j] << 1) | (w & 1);
                    w >>= 1;
                }
            }
            w = ghist_words[bm / mpp.blockSize];
            for (int i = bm; i < b; i += 1) {
                x <<= shift;
                x += (path_history[i] << 1) | (w & 1);
                w >>= 1;
            }
            return x;
        }
    };

    public:
    MultiperspectivePerceptron(const MultiperspectivePerceptronParams &params);

    /**
     * Sets the starting number of storage bits to compute the number of
     * table entries
     * @param bits number of bits used
     */
    void setExtraBits(int bits);

    void init() override;

    void uncondBranch(ThreadID tid, Addr pc, void * &bp_history) override;
    void squash(ThreadID tid, void *bp_history) override;
    bool lookup(ThreadID tid, Addr instPC, void * &bp_history) override;
    void update(ThreadID tid, Addr instPC, bool taken,
            void *bp_history, bool squashed,
            const StaticInstPtr & inst,
            Addr corrTarget) override;
    void btbUpdate(ThreadID tid, Addr branch_addr, void* &bp_history) override;
};
#endif//__CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_HH__
