diff --git a/src/cpu/pred/BranchPredictor.py b/src/cpu/pred/BranchPredictor.py
index 9c59574..967489a 100644
--- a/src/cpu/pred/BranchPredictor.py
+++ b/src/cpu/pred/BranchPredictor.py
@@ -475,3 +475,85 @@
     tage = TAGE_SC_L_TAGE_8KB()
     loop_predictor = TAGE_SC_L_8KB_LoopPredictor()
     statistical_corrector = TAGE_SC_L_8KB_StatisticalCorrector()
+
+class MultiperspectivePerceptron(BranchPredictor):
+    type = 'MultiperspectivePerceptron'
+    cxx_class = 'MultiperspectivePerceptron'
+    cxx_header = 'cpu/pred/multiperspective_perceptron.hh'
+    abstract = True
+
+    num_filter_entries = Param.Int("Number of filter entries")
+    num_local_histories = Param.Int("Number of local history entries")
+    local_history_length = Param.Int(11,
+        "Length in bits of each history entry")
+
+    block_size = Param.Int(21,
+        "number of ghist bits in a 'block'; this is the width of an initial "
+        "hash of ghist")
+    pcshift = Param.Int(-10, "Shift for hashing PC")
+    threshold = Param.Int(1, "Threshold for deciding low/high confidence")
+    bias0 = Param.Int(-5,
+        "Bias perceptron output this much on all-bits-zero local history")
+    bias1 = Param.Int(5,
+        "Bias perceptron output this much on all-bits-one local history")
+    biasmostly0 = Param.Int(-1,
+        "Bias perceptron output this much on almost-all-bits-zero local "
+        "history")
+    biasmostly1 = Param.Int(1,
+        "Bias perceptron output this much on almost-all-bits-one local "
+        "history")
+    nbest = Param.Int(20,
+        "Use this many of the top performing tables on a low-confidence "
+        "branch")
+    tunebits = Param.Int(24, "Number of bits in misprediction counters")
+    hshift = Param.Int(-6,
+        "How much to shift initial feauture hash before XORing with PC bits")
+    imli_mask1 = Param.UInt64(
+        "Which tables should have their indices hashed with the first IMLI "
+        "counter")
+    imli_mask4 = Param.UInt64(
+        "Which tables should have their indices hashed with the fourth IMLI "
+        "counter")
+    recencypos_mask = Param.UInt64(
+        "Which tables should have their indices hashed with the recency "
+        "position")
+    fudge = Param.Float(0.245, "Fudge factor to multiply by perceptron output")
+    n_sign_bits = Param.Int(2, "Number of sign bits per magnitude")
+    pcbit = Param.Int(2, "Bit from the PC to use for hashing global history")
+    decay = Param.Int(0, "Whether and how often to decay a random weight")
+    record_mask = Param.Int(191,
+        "Which histories are updated with filtered branch outcomes")
+    hash_taken = Param.Bool(False,
+        "Hash the taken/not taken value with a PC bit")
+    tuneonly = Param.Bool(True,
+        "If true, only count mispredictions of low-confidence branches")
+    extra_rounds = Param.Int(1,
+        "Number of extra rounds of training a single weight on a "
+        "low-confidence prediction")
+    speed = Param.Int(9, "Adaptive theta learning speed")
+    initial_theta = Param.Int(10, "Initial theta")
+    budgetbits = Param.Int("Hardware budget in bits")
+    speculative_update = Param.Bool(False,
+        "Use speculative update for histories")
+
+class MultiperspectivePerceptron8KB(MultiperspectivePerceptron):
+    type = 'MultiperspectivePerceptron8KB'
+    cxx_class = 'MultiperspectivePerceptron8KB'
+    cxx_header = 'cpu/pred/multiperspective_perceptron_8KB.hh'
+    budgetbits = 8192 * 8 + 2048
+    num_local_histories = 48
+    num_filter_entries = 0
+    imli_mask1 = 0x6
+    imli_mask4 = 0x4400
+    recencypos_mask = 0x100000090
+
+class MultiperspectivePerceptron64KB(MultiperspectivePerceptron):
+    type = 'MultiperspectivePerceptron64KB'
+    cxx_class = 'MultiperspectivePerceptron64KB'
+    cxx_header = 'cpu/pred/multiperspective_perceptron_64KB.hh'
+    budgetbits = 65536 * 8 + 2048
+    num_local_histories = 510
+    num_filter_entries = 18025
+    imli_mask1 = 0xc1000
+    imli_mask4 = 0x80008000
+    recencypos_mask = 0x100000090
diff --git a/src/cpu/pred/SConscript b/src/cpu/pred/SConscript
index 7365861..27821a4 100644
--- a/src/cpu/pred/SConscript
+++ b/src/cpu/pred/SConscript
@@ -48,6 +48,9 @@
 Source('tage.cc')
 Source('loop_predictor.cc')
 Source('ltage.cc')
+Source('multiperspective_perceptron.cc')
+Source('multiperspective_perceptron_8KB.cc')
+Source('multiperspective_perceptron_64KB.cc')
 Source('statistical_corrector.cc')
 Source('tage_sc_l.cc')
 Source('tage_sc_l_8KB.cc')
diff --git a/src/cpu/pred/multiperspective_perceptron.cc b/src/cpu/pred/multiperspective_perceptron.cc
new file mode 100644
index 0000000..47bbb02
--- /dev/null
+++ b/src/cpu/pred/multiperspective_perceptron.cc
@@ -0,0 +1,808 @@
+/*
+ * 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)
+  */
+
+#include "cpu/pred/multiperspective_perceptron.hh"
+
+#include "debug/Branch.hh"
+
+int
+MultiperspectivePerceptron::xlat[] =
+    {1,3,4,5,7,8,9,11,12,14,15,17,19,21,23,25,27,29,32,34,37,41,45,49,53,58,63,
+     69,76,85,94,106,};
+int
+MultiperspectivePerceptron::xlat4[] =
+    {0,4,5,7,9,11,12,14,16,17,19,22,28,33,39,45,};
+
+MultiperspectivePerceptron::ThreadData::ThreadData(int num_filters,
+        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)
+      : filterTable(num_filters), acyclic_histories(acyclic_bits.size()),
+        acyclic2_histories(acyclic_bits.size()),
+        blurrypath_histories(blurrypath_bits.size()),
+        ghist_words(ghist_length/block_size+1, 0),
+        path_history(path_length, 0), imli_counter(4,0),
+        localHistories(n_local_histories, local_history_length),
+        recency_stack(assoc), last_ghist_bit(false), occupancy(0)
+{
+    for (int i = 0; i < blurrypath_bits.size(); i+= 1) {
+        blurrypath_histories[i].resize(blurrypath_bits[i].size());
+    }
+
+    for (int i = 0; i < acyclic_bits.size(); i += 1) {
+        acyclic_histories[i].resize(acyclic_bits[i].size());
+        acyclic2_histories[i].resize(acyclic_bits[i].size());
+    }
+
+    int max_modhist_idx = -1;
+    for (auto &elem : modhist_indices) {
+        max_modhist_idx = (max_modhist_idx < elem) ? elem : max_modhist_idx;
+    }
+    if (max_modhist_idx >= 0) {
+        mod_histories.resize(max_modhist_idx + 1);
+    }
+    for (int i = 0; i < modhist_lengths.size(); i+= 1) {
+        mod_histories[modhist_indices[i]].resize(modhist_lengths[i]);
+    }
+
+    int max_modpath_idx = -1;
+    for (auto &elem : modpath_indices) {
+        max_modpath_idx = (max_modpath_idx < elem) ? elem : max_modpath_idx;
+    }
+    if (max_modpath_idx >= 0) {
+        modpath_histories.resize(max_modpath_idx + 1);
+    }
+    for (int i = 0; i < modpath_lengths.size(); i+= 1) {
+        modpath_histories[modpath_indices[i]].resize(modpath_lengths[i]);
+    }
+
+    for (int i = 0; i < table_sizes.size(); i += 1) {
+        mpreds.push_back(0);
+        tables.push_back(std::vector<short int>(table_sizes[i]));
+        sign_bits.push_back(std::vector<std::array<bool, 2>>(table_sizes[i]));
+        for (int j = 0; j < table_sizes[i]; j += 1) {
+            for (int k = 0; k < n_sign_bits; k += 1) {
+                sign_bits[i][j][k] = (i & 1) | (k & 1);
+            }
+        }
+    }
+}
+
+MultiperspectivePerceptron::MultiperspectivePerceptron(
+    const MultiperspectivePerceptronParams *p) : BPredUnit(p),
+    blockSize(p->block_size), pcshift(p->pcshift), threshold(p->threshold),
+    bias0(p->bias0), bias1(p->bias1), biasmostly0(p->biasmostly0),
+    biasmostly1(p->biasmostly1), nbest(p->nbest), tunebits(p->tunebits),
+    hshift(p->hshift), imli_mask1(p->imli_mask1), imli_mask4(p->imli_mask4),
+    recencypos_mask(p->recencypos_mask), fudge(p->fudge),
+    n_sign_bits(p->n_sign_bits), pcbit(p->pcbit), decay(p->decay),
+    record_mask(p->record_mask), hash_taken(p->hash_taken),
+    tuneonly(p->tuneonly), extra_rounds(p->extra_rounds), speed(p->speed),
+    budgetbits(p->budgetbits), speculative_update(p->speculative_update),
+    threadData(p->numThreads, nullptr), doing_local(false),
+    doing_recency(false), assoc(0), ghist_length(1), modghist_length(1),
+    path_length(1), randSeed(0xdeadbeef), thresholdCounter(0),
+    theta(p->initial_theta), imli_counter_bits(4), modhist_indices(),
+    modhist_lengths(), modpath_indices(), modpath_lengths()
+{
+    fatal_if(speculative_update, "Speculative update not implemented");
+}
+
+void
+MultiperspectivePerceptron::init()
+{
+    createSpecs();
+
+    for (auto &spec : specs) {
+        // initial assignation of values
+        table_sizes.push_back(spec->size);
+    }
+
+    // Update bit requirements and runtime values
+    for (auto &spec : specs) {
+        spec->setBitRequirements();
+    }
+    const MultiperspectivePerceptronParams *p =
+        static_cast<const MultiperspectivePerceptronParams *>(params());
+
+    computeBits(p->num_filter_entries, p->num_local_histories,
+                p->local_history_length);
+
+    for (int i = 0; i < threadData.size(); i += 1) {
+        threadData[i] = new ThreadData(p->num_filter_entries,
+                                       p->num_local_histories,
+                                       p->local_history_length, assoc,
+                                       blurrypath_bits, path_length,
+                                       ghist_length, blockSize, acyclic_bits,
+                                       modhist_indices, modhist_lengths,
+                                       modpath_indices, modpath_lengths,
+                                       table_sizes, n_sign_bits);
+    }
+}
+
+void
+MultiperspectivePerceptron::computeBits(int num_filter_entries,
+        int nlocal_histories, int local_history_length) {
+    int totalbits = 0;
+    for (auto &imli_bits : imli_counter_bits) {
+        totalbits += imli_bits;
+    }
+    totalbits += ghist_length;
+    totalbits += path_length * 16;
+    totalbits += (threshold >= 0) ? (tunebits * specs.size()) : 0;
+    for (auto &len : modhist_lengths) {
+        totalbits += len;
+    }
+    for (auto &len : modpath_lengths) {
+        totalbits += 16 * len;
+    }
+    totalbits += doing_local ? (nlocal_histories * local_history_length) : 0;
+    totalbits += doing_recency ? (assoc * 16) : 0;
+
+    for (auto &bv : blurrypath_bits) {
+        for (auto &bve : bv) {
+            totalbits += bve;
+        }
+    }
+    totalbits += num_filter_entries * 2;
+
+    for (auto &abi : acyclic_bits) {
+        for (auto &abj : abi) {
+            for (auto abk : abj) {
+                totalbits += abk;
+            }
+        }
+    }
+
+    int remaining = budgetbits - totalbits;
+
+    // count the tables that have already been assigned sizes
+    int num_sized = 0;
+    for (int i = 0; i < specs.size(); i +=1) {
+        if (table_sizes[i] != 0) {
+            int sz = table_sizes[i] * (specs[i]->width + (n_sign_bits - 1));
+            totalbits += sz;
+            remaining -= sz;
+            num_sized += 1;
+        }
+    }
+
+    // whatever is left, we divide among the rest of the tables
+    int table_size_bits = (remaining / (specs.size()-num_sized));
+    for (int i = 0; i < specs.size(); i += 1) {
+        // if a table doesn't have a size yet, give it one and count those bits
+        if (!table_sizes[i]) {
+            int my_table_size = table_size_bits /
+                (specs[i]->width + (n_sign_bits - 1)); // extra sign bits
+            table_sizes[i] = my_table_size;
+            totalbits += my_table_size * (specs[i]->width + (n_sign_bits - 1));
+        }
+    }
+
+    DPRINTF(Branch, "%d bits of metadata so far, %d left out of "
+            "%d total budget\n", totalbits, remaining, budgetbits);
+    DPRINTF(Branch, "table size is %d bits, %d entries for 5 bit, %d entries "
+            "for 6 bit\n", table_size_bits,
+            table_size_bits / (5 + (n_sign_bits - 1)),
+            table_size_bits / (6 + (n_sign_bits - 1)));
+    DPRINTF(Branch, "%d total bits (%0.2fKB)\n", totalbits,
+            totalbits / 8192.0);
+}
+
+void
+MultiperspectivePerceptron::findBest(ThreadID tid,
+                                     std::vector<int> &best_preds) const
+{
+    if (threshold < 0) {
+        return;
+    }
+    struct BestPair {
+        int index;
+        int mpreds;
+        bool operator<(BestPair const &bp) const
+        {
+            return mpreds < bp.mpreds;
+        }
+    };
+    std::vector<BestPair> pairs(best_preds.size());
+    for (int i = 0; i < best_preds.size(); i += 1) {
+        pairs[i].index = i;
+        pairs[i].mpreds = threadData[tid]->mpreds[i];
+    }
+    std::sort(pairs.begin(), pairs.end());
+    for (int i = 0; i < (std::min(nbest, (int) best_preds.size())); i += 1) {
+        best_preds[i] = pairs[i].index;
+    }
+}
+
+unsigned int
+MultiperspectivePerceptron::getIndex(ThreadID tid, const MPPBranchInfo &bi,
+                                     const HistorySpec &spec, int index) const
+{
+    unsigned int g = spec.getHash(tid, bi.getPC(), bi.getPC2(), index);
+    unsigned long long int h = g;
+     // shift the hash from the feature to xor with the hashed PC
+    if (hshift < 0) {
+        h <<= -hshift;
+        h ^= bi.getPC2();
+    } else {
+        h <<= hshift;
+        h ^= bi.getHPC();
+    }
+    // xor in the imli counter(s) and/or recency position based on the masks
+    if ((1ull<<index) & imli_mask1) {
+        h ^= threadData[tid]->imli_counter[0];
+    }
+    if ((1ull<<index) & imli_mask4) {
+        h ^= threadData[tid]->imli_counter[3];
+    }
+    if (doing_recency) {
+        if ((1ull<<index) & recencypos_mask) {
+            h ^= RECENCYPOS::hash(threadData[tid]->recency_stack, table_sizes,
+                    bi.getPC2(), 31, index);
+        }
+    }
+    h %= table_sizes[index];
+    return h;
+}
+
+int
+MultiperspectivePerceptron::computeOutput(ThreadID tid, MPPBranchInfo &bi)
+{
+    // list of best predictors
+    std::vector<int> best_preds(specs.size(), -1);
+
+    // initialize sum
+    bi.yout = 0;
+
+    // bias the prediction by whether the local history is
+    // one of four distinctive patterns
+    int lhist = threadData[tid]->localHistories[bi.getPC()];
+    int history_len = threadData[tid]->localHistories.getLocalHistoryLength();
+    if (lhist == 0) {
+        bi.yout = bias0;
+    } else if (lhist == ((1<<history_len)-1)) {
+        bi.yout = bias1;
+    } else if (lhist == (1<<(history_len-1))) {
+        bi.yout = biasmostly0;
+    } else if (lhist == ((1<<(history_len-1))-1)) {
+        bi.yout = biasmostly1;
+    }
+    // find the best subset of features to use in case of a low-confidence
+    // branch
+    findBest(tid, best_preds);
+
+    // begin computation of the sum for low-confidence branch
+    int bestval = 0;
+
+    for (int i = 0; i < specs.size(); i += 1) {
+        HistorySpec const &spec = *specs[i];
+        // get the hash to index the table
+        unsigned int hashed_idx = getIndex(tid, bi, spec, i);
+        // add the weight; first get the weight's magnitude
+        int counter = threadData[tid]->tables[i][hashed_idx];
+        // get the sign
+        bool sign =
+          threadData[tid]->sign_bits[i][hashed_idx][bi.getHPC() % n_sign_bits];
+        // apply the transfer function and multiply by a coefficient
+        int weight = spec.coeff * ((spec.width == 5) ?
+                                   xlat4[counter] : xlat[counter]);
+        // apply the sign
+        int val = sign ? -weight : weight;
+        // add the value
+        bi.yout += val;
+        // if this is one of those good features, add the value to bestval
+        if (threshold >= 0) {
+            for (int j = 0;
+                 j < std::min(nbest, (int) best_preds.size());
+                 j += 1)
+            {
+                if (best_preds[j] == i) {
+                    bestval += val;
+                    break;
+                }
+            }
+        }
+    }
+    // apply a fudge factor to affect when training is triggered
+    bi.yout *= fudge;
+    return bestval;
+}
+
+void
+MultiperspectivePerceptron::satIncDec(bool taken, bool &sign, int &counter,
+                                      int max_weight) const
+{
+    if (taken) {
+        // increment sign/magnitude
+        if (sign) {
+            // go toward 0 away from negative max weight
+            if (counter == 0) {
+                sign = false; // moved to positive 0
+            } else {
+                counter -= 1;
+            }
+        } else {
+            // go toward max weight away from 0
+            if (counter < max_weight) {
+                counter += 1;
+            }
+        }
+    } else {
+        // decrement sign/magnitude
+        if (sign) {
+            // go toward negative max weight down from 0
+            if (counter < max_weight) {
+                counter += 1;
+            }
+        } else {
+            // go toward 0 away from max weight
+            if (counter == 0) {
+                sign = true; // negative 0
+            } else {
+                counter -= 1;
+            }
+        }
+    }
+}
+
+void
+MultiperspectivePerceptron::train(ThreadID tid, MPPBranchInfo &bi, bool taken)
+{
+    std::vector<std::vector<short int>> &tables = threadData[tid]->tables;
+    std::vector<std::vector<std::array<bool, 2>>> &sign_bits =
+            threadData[tid]->sign_bits;
+    std::vector<int> &mpreds = threadData[tid]->mpreds;
+    // was the prediction correct?
+    bool correct = (bi.yout >= 1) == taken;
+    // what is the magnitude of yout?
+    int abs_yout = abs(bi.yout);
+    // keep track of mispredictions per table
+    if (threshold >= 0) if (!tuneonly || (abs_yout <= threshold)) {
+        bool halve = false;
+
+        // for each table, figure out if there was a misprediction
+        for (int i = 0; i < specs.size(); i += 1) {
+            HistorySpec const &spec = *specs[i];
+            // get the hash to index the table
+            unsigned int hashed_idx = getIndex(tid, bi, spec, i);
+            bool sign = sign_bits[i][hashed_idx][bi.getHPC() % n_sign_bits];
+            int counter = tables[i][hashed_idx];
+            int weight = spec.coeff * ((spec.width == 5) ?
+                                       xlat4[counter] : xlat[counter]);
+            if (sign) weight = -weight;
+            bool pred = weight >= 1;
+            if (pred != taken) {
+                mpreds[i] += 1;
+                if (mpreds[i] == (1 << tunebits) - 1) {
+                    halve = true;
+                }
+            }
+        }
+        // if we reach the maximum counter value, halve all the counters
+        if (halve) {
+            for (int i = 0; i < specs.size(); i += 1) {
+                mpreds[i] /= 2;
+            }
+        }
+    }
+    // if the branch was predicted incorrectly or the correct
+    // prediction was weak, update the weights
+    bool do_train = !correct || (abs_yout <= theta);
+    if (!do_train) return;
+
+    // adaptive theta training, adapted from O-GEHL
+    if (!correct) {
+        thresholdCounter += 1;
+        if (thresholdCounter >= speed) {
+            theta += 1;
+            thresholdCounter = 0;
+        }
+    }
+    if (correct && abs_yout < theta) {
+        thresholdCounter -= 1;
+        if (thresholdCounter <= -speed) {
+            theta -= 1;
+            thresholdCounter = 0;
+        }
+    }
+
+    // train the weights, computing what the value of yout
+    // would have been if these updates had been applied before
+    int newyout = 0;
+    for (int i = 0; i < specs.size(); i += 1) {
+        HistorySpec const &spec = *specs[i];
+        // get the magnitude
+        unsigned int hashed_idx = getIndex(tid, bi, spec, i);
+        int counter = tables[i][hashed_idx];
+        // get the sign
+        bool sign = sign_bits[i][hashed_idx][bi.getHPC() % n_sign_bits];
+        // increment/decrement if taken/not taken
+        satIncDec(taken, sign, counter, (1 << (spec.width - 1)) - 1);
+        // update the magnitude and sign
+        tables[i][hashed_idx] = counter;
+        sign_bits[i][hashed_idx][bi.getHPC() % n_sign_bits] = sign;
+        int weight = ((spec.width == 5) ? xlat4[counter] : xlat[counter]);
+        // update the new version of yout
+        if (sign) {
+            newyout -= weight;
+        } else {
+            newyout += weight;
+        }
+    }
+
+    // if the prediction still would have been incorrect even
+    // with the updated weights, update some more weights to
+    // try to fix the problem
+    if ((newyout >= 1) != taken) {
+        if (extra_rounds != -1) {
+            int round_counter = 0;
+            bool found;
+            do {
+                // udpate a random weight
+                int besti = -1;
+                int nrand = rand_r(&randSeed) % specs.size();
+                int pout;
+                found = false;
+                for (int j = 0; j < specs.size(); j += 1) {
+                    int i = (nrand + j) % specs.size();
+                    HistorySpec const &spec = *specs[i];
+                    unsigned int hashed_idx = getIndex(tid, bi, spec, i);
+                    int counter = tables[i][hashed_idx];
+                    bool sign =
+                        sign_bits[i][hashed_idx][bi.getHPC() % n_sign_bits];
+                    int weight = ((spec.width == 5) ?
+                            xlat4[counter] : xlat[counter]);
+                    int signed_weight = sign ? -weight : weight;
+                    pout = newyout - signed_weight;
+                    if ((pout >= 1) == taken) {
+                        // we have found a weight that if we blow
+                        // it away will help!
+                        besti = i;
+                        break;
+                    }
+                }
+                if (besti != -1) {
+                    int i = besti;
+                    HistorySpec const &spec = *specs[i];
+                    unsigned int hashed_idx = getIndex(tid, bi, spec, i);
+                    int counter = tables[i][hashed_idx];
+                    bool sign =
+                        sign_bits[i][hashed_idx][bi.getHPC() % n_sign_bits];
+                    if (counter > 1) {
+                        counter--;
+                        tables[i][hashed_idx] = counter;
+                    }
+                    int weight = ((spec.width == 5) ?
+                            xlat4[counter] : xlat[counter]);
+                    int signed_weight = sign ? -weight : weight;
+                    int out = pout + signed_weight;
+                    round_counter += 1;
+                    if ((out >= 1) != taken) {
+                        found = true;
+                    }
+                }
+            } while (found && round_counter < extra_rounds);
+        }
+    }
+}
+
+void
+MultiperspectivePerceptron::uncondBranch(ThreadID tid, Addr pc,
+                                         void * &bp_history)
+{
+    MPPBranchInfo *bi = new MPPBranchInfo(pc, pcshift, false);
+    std::vector<unsigned int> &ghist_words = threadData[tid]->ghist_words;
+
+    bp_history = (void *)bi;
+    unsigned short int pc2 = pc >> 2;
+    bool ab = !(pc & (1<<pcbit));
+    for (int i = 0; i < ghist_length / blockSize + 1; i += 1) {
+        bool ab_new = (ghist_words[i] >> (blockSize - 1)) & 1;
+        ghist_words[i] <<= 1;
+        ghist_words[i] |= ab;
+        ghist_words[i] &= (1 << blockSize) - 1;
+        ab = ab_new;
+    }
+    memmove(&threadData[tid]->path_history[1],
+            &threadData[tid]->path_history[0],
+            sizeof(unsigned short int) * (path_length - 1));
+    threadData[tid]->path_history[0] = pc2;
+}
+
+bool
+MultiperspectivePerceptron::lookup(ThreadID tid, Addr instPC,
+                                   void * &bp_history)
+{
+    MPPBranchInfo *bi = new MPPBranchInfo(instPC, pcshift, true);
+    bp_history = (void *)bi;
+
+    bool use_static = false;
+
+    if (!threadData[tid]->filterTable.empty()) {
+        unsigned int findex =
+            bi->getHashFilter(threadData[tid]->last_ghist_bit) %
+            threadData[tid]->filterTable.size();
+        FilterEntry &f = threadData[tid]->filterTable[findex];
+        if (f.alwaysNotTakenSoFar()) {
+            bi->filtered = true;
+            bi->prediction = false;
+            return false;
+        } else if (f.alwaysTakenSoFar()) {
+            bi->filtered = true;
+            bi->prediction = true;
+            return true;
+        }
+        if (f.neverSeen()) {
+            use_static = true;
+        }
+    }
+
+    int bestval = computeOutput(tid, *bi);
+    if (use_static) {
+        bi->prediction = false;
+    } else {
+        if (abs(bi->yout) <= threshold) {
+            bi->prediction = (bestval >= 1);
+        } else {
+            bi->prediction = (bi->yout >= 1);
+        }
+    }
+
+    return bi->prediction;
+}
+
+void
+MultiperspectivePerceptron::update(ThreadID tid, Addr instPC, bool taken,
+                                   void *bp_history, bool squashed,
+                                   const StaticInstPtr & inst,
+                                   Addr corrTarget)
+{
+    assert(bp_history);
+    MPPBranchInfo *bi = static_cast<MPPBranchInfo*>(bp_history);
+    assert(corrTarget != MaxAddr);
+    if (squashed) {
+        //delete bi;
+        return;
+    }
+
+    if (bi->isUnconditional()) {
+        delete bi;
+        return;
+    }
+
+    bool do_train = true;
+
+    if (!threadData[tid]->filterTable.empty()) {
+        int findex = bi->getHashFilter(threadData[tid]->last_ghist_bit) %
+                                       threadData[tid]->filterTable.size();
+        FilterEntry &f = threadData[tid]->filterTable[findex];
+
+        // compute this first, so we don't not train on the
+        // first time a branch is seen.
+        bool transition = false;
+        if (f.alwaysNotTakenSoFar() || f.alwaysTakenSoFar()) {
+            do_train = false;
+        }
+        if (taken) {
+            if (f.alwaysNotTakenSoFar()) {
+                transition = true;
+            }
+            f.seenTaken = true;
+        } else {
+            if (f.alwaysTakenSoFar()) {
+                transition = true;
+            }
+            f.seenUntaken = true;
+        }
+        // is this the first time time the branch has gone both ways?
+        if (transition) {
+            threadData[tid]->occupancy += 1;
+        }
+        // for every new dynamic branch, when there ar
+        // more than 'decay' number of branches in the
+        // filter, blow a random filter entry away
+        if (decay && transition &&
+            ((threadData[tid]->occupancy > decay) || (decay == 1))) {
+            int rnd = rand_r(&randSeed) % threadData[tid]->filterTable.size();
+            FilterEntry &frand = threadData[tid]->filterTable[rnd];
+            if (frand.seenTaken && frand.seenUntaken) {
+                threadData[tid]->occupancy -= 1;
+            }
+            frand.seenTaken = false;
+            frand.seenUntaken = false;
+        }
+    }
+
+    if (do_train) {
+        train(tid, *bi, taken);
+    }
+
+#define RECORD_FILTERED_IMLI      1
+#define RECORD_FILTERED_GHIST     2
+#define RECORD_FILTERED_PATH      4
+#define RECORD_FILTERED_ACYCLIC   8
+#define RECORD_FILTERED_MOD      16
+#define RECORD_FILTERED_BLURRY   32
+// should never record a filtered local branch - duh!
+#define RECORD_FILTERED_LOCAL    64
+#define RECORD_FILTERED_RECENCY 128
+
+    // four different styles of IMLI
+    if (!bi->filtered || (record_mask & RECORD_FILTERED_IMLI)) {
+        unsigned int target = corrTarget;
+        if (target < bi->getPC()) {
+            if (taken) {
+                threadData[tid]->imli_counter[0] += 1;
+            } else {
+                threadData[tid]->imli_counter[0] = 0;
+            }
+            if (!taken) {
+                threadData[tid]->imli_counter[1] += 1;
+            } else {
+                threadData[tid]->imli_counter[1] = 0;
+            }
+        } else {
+            if (taken) {
+                threadData[tid]->imli_counter[2] += 1;
+            } else {
+                threadData[tid]->imli_counter[2] = 0;
+            }
+            if (!taken) {
+                threadData[tid]->imli_counter[3] += 1;
+            } else {
+                threadData[tid]->imli_counter[3] = 0;
+            }
+        }
+    }
+
+    bool hashed_taken = hash_taken ? (taken ^ !!(bi->getPC() & (1<<pcbit)))
+                                   : taken;
+    // record into ghist
+    if (!bi->filtered || (record_mask & RECORD_FILTERED_GHIST)) {
+        bool ab = hashed_taken;
+        assert(threadData[tid]->ghist_words.size() > 0);
+        for (int i = 0; i < ghist_length / blockSize + 1; i += 1) {
+            unsigned int a = threadData[tid]->ghist_words[i];
+            bool ab_new = (a >> (blockSize - 1)) & 1;
+            a <<= 1;
+            a |= ab;
+            ab = ab_new;
+            a &= (1 << blockSize) - 1;
+            threadData[tid]->ghist_words[i] = a;
+        }
+    }
+
+    // record into path history
+    if (!bi->filtered || (record_mask & RECORD_FILTERED_PATH)) {
+        assert(threadData[tid]->path_history.size() > 0);
+        memmove(&threadData[tid]->path_history[1],
+                &threadData[tid]->path_history[0],
+                sizeof(unsigned short int) * (path_length - 1));
+        threadData[tid]->path_history[0] = bi->getPC2();
+    }
+
+    // record into acyclic history
+    if (!bi->filtered || (record_mask & RECORD_FILTERED_ACYCLIC)) {
+        threadData[tid]->updateAcyclic(hashed_taken, bi->getHPC());
+    }
+
+    // record into modulo path history
+    if (!bi->filtered || (record_mask & RECORD_FILTERED_MOD)) {
+        for (int ii = 0; ii < modpath_indices.size(); ii += 1) {
+            int i = modpath_indices[ii];
+            if (bi->getHPC() % (i + 2) == 0) {
+                memmove(&threadData[tid]->modpath_histories[i][1],
+                        &threadData[tid]->modpath_histories[i][0],
+                        sizeof(unsigned short int) * (modpath_lengths[ii]-1));
+                threadData[tid]->modpath_histories[i][0] = bi->getPC2();
+            }
+        }
+    }
+
+    // update blurry history
+    if (!bi->filtered || (record_mask & RECORD_FILTERED_BLURRY)) {
+        std::vector<std::vector<unsigned int>> &blurrypath_histories =
+             threadData[tid]->blurrypath_histories;
+
+        for (int i = 0; i < blurrypath_histories.size(); i += 1)
+        {
+            if (blurrypath_histories[i].size() > 0) {
+                unsigned int z = bi->getPC() >> i;
+                if (blurrypath_histories[i][0] != z) {
+                    memmove(&blurrypath_histories[i][1],
+                            &blurrypath_histories[i][0],
+                            sizeof(unsigned int) *
+                            (blurrypath_histories[i].size() - 1));
+                    blurrypath_histories[i][0] = z;
+                }
+            }
+        }
+    }
+
+    // record into modulo pattern history
+    if (!bi->filtered || (record_mask & RECORD_FILTERED_MOD)) {
+        for (int ii = 0; ii < modhist_indices.size(); ii += 1) {
+            int i = modhist_indices[ii];
+            if (bi->getHPC() % (i + 2) == 0) {
+                for (int j = modhist_lengths[ii] - 1; j > 0; j -= 1) {
+                    threadData[tid]->mod_histories[i][j] =
+                        threadData[tid]->mod_histories[i][j-1];
+                }
+                threadData[tid]->mod_histories[i][0] = hashed_taken;
+            }
+        }
+    }
+
+    // insert this PC into the recency stack
+    if (doing_recency) {
+        if (!bi->filtered || (record_mask & RECORD_FILTERED_RECENCY)) {
+            threadData[tid]->insertRecency(bi->getPC2(), assoc);
+        }
+    }
+
+    // record into a local history
+    if (!bi->filtered || (record_mask & RECORD_FILTERED_LOCAL)) {
+        threadData[tid]->localHistories.update(bi->getPC(), hashed_taken);
+    }
+
+    // update last ghist bit, used to index filter
+    threadData[tid]->last_ghist_bit = taken;
+
+    delete bi;
+}
+
+void
+MultiperspectivePerceptron::btbUpdate(ThreadID tid, Addr branch_pc,
+                                      void* &bp_history)
+{
+}
+
+void
+MultiperspectivePerceptron::squash(ThreadID tid, void *bp_history)
+{
+    assert(bp_history);
+    MPPBranchInfo *bi = static_cast<MPPBranchInfo*>(bp_history);
+    delete bi;
+}
diff --git a/src/cpu/pred/multiperspective_perceptron.hh b/src/cpu/pred/multiperspective_perceptron.hh
new file mode 100644
index 0000000..e81bd8e
--- /dev/null
+++ b/src/cpu/pred/multiperspective_perceptron.hh
@@ -0,0 +1,1027 @@
+/*
+ * 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;
+    unsigned int randSeed;
+    int thresholdCounter;
+    int theta;
+    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
+     */
+    void computeBits(int num_filter_entries, int nlocal_histories,
+            int local_history_length);
+
+    /**
+     * 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);
+
+    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 = MaxAddr) override;
+    void btbUpdate(ThreadID tid, Addr branch_addr, void* &bp_history) override;
+};
+#endif//__CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_HH__
diff --git a/src/cpu/pred/multiperspective_perceptron_64KB.cc b/src/cpu/pred/multiperspective_perceptron_64KB.cc
new file mode 100644
index 0000000..a5d7241
--- /dev/null
+++ b/src/cpu/pred/multiperspective_perceptron_64KB.cc
@@ -0,0 +1,93 @@
+/*
+ * 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)
+ * - 64KB version
+ */
+
+#include "cpu/pred/multiperspective_perceptron_64KB.hh"
+
+MultiperspectivePerceptron64KB::MultiperspectivePerceptron64KB(
+        const MultiperspectivePerceptron64KBParams *p)
+    : MultiperspectivePerceptron(p)
+{
+}
+
+void
+MultiperspectivePerceptron64KB::createSpecs() {
+    addSpec(new ACYCLIC(10, -1, -1, 1.0, 0, 6, *this));
+    addSpec(new BLURRYPATH(10, 7, -1, 1.0, 0, 6, *this));
+    addSpec(new GHIST(0, 19, 1.3125, 0, 6, *this));
+    addSpec(new GHIST(0, 65, 0.85, 0, 6, *this));
+    addSpec(new GHIST(111, 222, 1.0, 0, 6, *this));
+    addSpec(new GHIST(115, 206, 1.0, 0, 6, *this));
+    addSpec(new GHIST(190, 336, 1.0, 0, 6, *this));
+    addSpec(new GHIST(21, 64, 1.0, 0, 6, *this));
+    addSpec(new GHIST(48, 119, 1.0, 0, 6, *this));
+    addSpec(new GHIST(67, 203, 0.75, 0, 6, *this));
+    addSpec(new GHIST(75, 150, 1.0, 0, 6, *this));
+    addSpec(new GHISTMODPATH(1, 5, 4, 1.45, 1913, 6, *this));
+    addSpec(new GHISTMODPATH(3, 13, 1, 1.0, 0, 6, *this));
+    addSpec(new GHISTPATH(105, 4, 0, 1.0, 0, 6, *this));
+    addSpec(new GHISTPATH(11, 2, -1, 1.25, 0, 6, *this));
+    addSpec(new GHISTPATH(15, 4, -1, 1.125, 0, 6, *this));
+    addSpec(new GHISTPATH(23, 4, -1, 1.0, 0, 6, *this));
+    addSpec(new GHISTPATH(31, 1, -1, 1.0, 0, 6, *this));
+    addSpec(new GHISTPATH(32, 2, -1, 1.0, 0, 6, *this));
+    addSpec(new GHISTPATH(36, 4, -1, 1.0, 0, 6, *this));
+    addSpec(new GHISTPATH(51, 1, 0, 1.0, 0, 6, *this));
+    addSpec(new GHISTPATH(7, 1, -1, 1.5, 0, 6, *this));
+    addSpec(new GHISTPATH(72, 1, -1, 1.0, 0, 6, *this));
+    addSpec(new GHISTPATH(86, 4, 0, 1.0, 0, 6, *this));
+    addSpec(new IMLI(1, 1.8125, 0, 6, *this));
+    addSpec(new IMLI(4, 1.78125, 1536, 6, *this));
+    addSpec(new LOCAL(-1, 1.0, 1024, 6, *this));
+    addSpec(new LOCAL(-1, 2.0, 3467, 6, *this));
+    addSpec(new MODHIST(1, 16, 0.9375, 0, 6, *this));
+    addSpec(new MODPATH(3, 20, 1, 1.0, 0, 6, *this));
+    addSpec(new PATH(13, 2, -1, 1.4375, 0, 6, *this));
+    addSpec(new PATH(27, 5, -1, 1.0, 0, 6, *this));
+    addSpec(new RECENCY(10, 3, -1, 0.55, 1024, 6, *this));
+    addSpec(new RECENCY(14, 4, -1, 1.3125, 0, 6, *this));
+    addSpec(new RECENCYPOS(31, 1.5, 0, 6, *this));
+    addSpec(new SGHISTPATH(1, 2, 5, 1.25, 768, 6, *this));
+    addSpec(new SGHISTPATH(1, 5, 2, 1.3125, 972, 6, *this));
+}
+
+    MultiperspectivePerceptron64KB*
+MultiperspectivePerceptron64KBParams::create()
+{
+    return new MultiperspectivePerceptron64KB(this);
+}
diff --git a/src/cpu/pred/multiperspective_perceptron_64KB.hh b/src/cpu/pred/multiperspective_perceptron_64KB.hh
new file mode 100644
index 0000000..a87020b
--- /dev/null
+++ b/src/cpu/pred/multiperspective_perceptron_64KB.hh
@@ -0,0 +1,53 @@
+/*
+ * 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)
+ * - 64KB version
+ */
+
+#ifndef __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_64KB_HH__
+#define __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_64KB_HH__
+
+#include "cpu/pred/multiperspective_perceptron.hh"
+#include "params/MultiperspectivePerceptron64KB.hh"
+
+class MultiperspectivePerceptron64KB : public MultiperspectivePerceptron {
+    void createSpecs() override;
+    public:
+    MultiperspectivePerceptron64KB(
+            const MultiperspectivePerceptron64KBParams *p);
+};
+
+#endif // __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_64KB_HH__
diff --git a/src/cpu/pred/multiperspective_perceptron_8KB.cc b/src/cpu/pred/multiperspective_perceptron_8KB.cc
new file mode 100644
index 0000000..832e172
--- /dev/null
+++ b/src/cpu/pred/multiperspective_perceptron_8KB.cc
@@ -0,0 +1,72 @@
+/*
+ * 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)
+ * - 8KB version
+ */
+
+#include "cpu/pred/multiperspective_perceptron_8KB.hh"
+
+MultiperspectivePerceptron8KB::MultiperspectivePerceptron8KB(
+        const MultiperspectivePerceptron8KBParams *p)
+    : MultiperspectivePerceptron(p)
+{
+}
+
+void
+MultiperspectivePerceptron8KB::createSpecs() {
+    addSpec(new BIAS(2.40625, 0, 6, *this));
+    addSpec(new GHIST(0, 19, 1.4375, 0, 6, *this));
+    addSpec(new GHIST(0, 65, 1.0, 0, 6, *this));
+    addSpec(new GHIST(21, 64, 1.0, 0, 6, *this));
+    addSpec(new GHIST(75, 150, 1.0625, 0, 6, *this));
+    addSpec(new GHISTMODPATH(0, 7, 3, 1.625, 0, 6, *this));
+    addSpec(new GHISTPATH(11, 2, -1, 1.25, 0, 6, *this));
+    addSpec(new GHISTPATH(15, 4, -1, 1.125, 0, 6, *this));
+    addSpec(new GHISTPATH(31, 1, -1, 1.40625, 0, 6, *this));
+    addSpec(new GHISTPATH(7, 1, -1, 1.5, 600, 6, *this));
+    addSpec(new IMLI(4, 1.28125, 375, 6, *this));
+    addSpec(new LOCAL(-1, 1.5625, 512, 6, *this));
+    addSpec(new RECENCY(14, 4, -1, 1.25, 0, 6, *this));
+    addSpec(new RECENCYPOS(31, 1.875, 0, 6, *this));
+    addSpec(new SGHISTPATH(0, 4, 3, 1.65625, 0, 6, *this));
+    addSpec(new SGHISTPATH(1, 2, 5, 2.53125, 0, 5, *this));
+}
+
+    MultiperspectivePerceptron8KB*
+MultiperspectivePerceptron8KBParams::create()
+{
+    return new MultiperspectivePerceptron8KB(this);
+}
diff --git a/src/cpu/pred/multiperspective_perceptron_8KB.hh b/src/cpu/pred/multiperspective_perceptron_8KB.hh
new file mode 100644
index 0000000..032ecdf
--- /dev/null
+++ b/src/cpu/pred/multiperspective_perceptron_8KB.hh
@@ -0,0 +1,53 @@
+/*
+ * 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)
+ * - 8KB version
+ */
+
+#ifndef __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_8KB_HH__
+#define __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_8KB_HH__
+
+#include "cpu/pred/multiperspective_perceptron.hh"
+#include "params/MultiperspectivePerceptron8KB.hh"
+
+class MultiperspectivePerceptron8KB : public MultiperspectivePerceptron {
+    void createSpecs() override;
+    public:
+    MultiperspectivePerceptron8KB(
+            const MultiperspectivePerceptron8KBParams *p);
+};
+
+#endif // __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_8KB_HH__
