 src/cpu/pred/BranchPredictor.py |  9 ++++
 src/cpu/pred/SConscript         |  3 +-
 src/cpu/pred/gshare.cc          | 48 +++++++++++++++++++++
 src/cpu/pred/gshare.hh          | 93 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 152 insertions(+), 1 deletion(-)

diff --git a/src/cpu/pred/BranchPredictor.py b/src/cpu/pred/BranchPredictor.py
index a10b2c2cef..2d01f589b1 100644
--- a/src/cpu/pred/BranchPredictor.py
+++ b/src/cpu/pred/BranchPredictor.py
@@ -157,6 +157,15 @@ class BranchPredictor(SimObject):
     )
 
 
+class GShareBP(BranchPredictor):
+    type = "GShareBP"
+    cxx_class = "gem5::branch_prediction::GShareBP"
+    cxx_header = "cpu/pred/gshare.hh"
+
+    localPredictorSize = Param.Unsigned(2048, "Size of local predictor")
+    localCtrBits = Param.Unsigned(2, "Bits per counter")
+
+
 class LocalBP(BranchPredictor):
     type = "LocalBP"
     cxx_class = "gem5::branch_prediction::LocalBP"
diff --git a/src/cpu/pred/SConscript b/src/cpu/pred/SConscript
index ec3102cada..7eb94bdf39 100644
--- a/src/cpu/pred/SConscript
+++ b/src/cpu/pred/SConscript
@@ -58,11 +58,12 @@ SimObject('BranchPredictor.py',
     'MultiperspectivePerceptronTAGE', 'MPP_StatisticalCorrector_64KB',
     'MultiperspectivePerceptronTAGE64KB', 'MPP_TAGE_8KB',
     'MPP_LoopPredictor_8KB', 'MPP_StatisticalCorrector_8KB',
-    'MultiperspectivePerceptronTAGE8KB'],
+    'MultiperspectivePerceptronTAGE8KB', 'GShareBP'],
     enums=['BranchType', 'TargetProvider'])
 
 Source('bpred_unit.cc')
 Source('2bit_local.cc')
+Source('gshare.cc')
 Source('simple_indirect.cc')
 Source('indirect.cc')
 Source('ras.cc')
diff --git a/src/cpu/pred/gshare.cc b/src/cpu/pred/gshare.cc
new file mode 100644
index 0000000000..72c0598ebf
--- /dev/null
+++ b/src/cpu/pred/gshare.cc
@@ -0,0 +1,48 @@
+#include "cpu/pred/gshare.hh"
+
+#include "base/intmath.hh"
+#include "base/logging.hh"
+#include "base/trace.hh"
+#include "debug/Fetch.hh"
+
+namespace gem5
+{
+
+namespace branch_prediction
+{
+
+GShareBP::GShareBP(const GShareBPParams &params)
+    : BPredUnit(params)
+{
+
+}
+
+void
+GShareBP::updateHistories(ThreadID tid, Addr pc, bool uncond,
+                         bool taken, Addr target, void * &bp_history)
+{
+// Place holder for a function that is called to update predictor history
+}
+
+
+bool
+GShareBP::lookup(ThreadID tid, Addr branch_addr, void * &bp_history)
+{
+    return false;
+}
+
+void
+GShareBP::update(ThreadID tid, Addr branch_addr, bool taken, void *&bp_history,
+                bool squashed, const StaticInstPtr & inst, Addr target)
+{
+
+}
+
+inline
+bool
+GShareBP::getPrediction(uint8_t &count)
+{
+    return false;
+}
+} // namespace branch_prediction
+} // namespace gem5
diff --git a/src/cpu/pred/gshare.hh b/src/cpu/pred/gshare.hh
new file mode 100644
index 0000000000..069fbc4151
--- /dev/null
+++ b/src/cpu/pred/gshare.hh
@@ -0,0 +1,93 @@
+#ifndef __CPU_PRED_GSHARE_PRED_HH__
+#define __CPU_PRED_GSHARE_PRED_HH__
+
+#include <vector>
+
+#include "base/sat_counter.hh"
+#include "base/types.hh"
+#include "cpu/pred/bpred_unit.hh"
+#include "params/GShareBP.hh"
+
+namespace gem5
+{
+
+namespace branch_prediction
+{
+
+/**
+ * Implements a gshare predictor, in which global history is XORed against
+ * bits from the PC. It uses the branch history to index into a table of
+ * counters. Global history is speculatively updated, and corrected during
+ * a squash.
+ */
+class GShareBP : public BPredUnit
+{
+  public:
+    /**
+     * Default branch predictor constructor.
+     */
+    GShareBP(const GShareBPParams &params);
+
+    // Overriding interface functions
+    /**
+     * Looks up the given address in the branch predictor and returns
+     * a true/false value as to whether it is taken.  Also creates a
+     * BPHistory object to store any state it will need on squash/update.
+     * @param branch_addr The address of the branch to look up.
+     * @param bp_history Pointer that will be set to the BPHistory object.
+     * @return Whether or not the branch is taken.
+     */
+    bool lookup(ThreadID tid, Addr pc, void * &bp_history) override;
+
+    /**
+     * Once done with the prediction, this funcion updates the path
+     * and global history. All branches call this function (including
+     * unconditional ones).
+     * @param tid The thread ID
+     * @param pc The branch PC to be updated
+     * @param uncond Is the branch unconditional?
+     * @param taken Did we take the branch?
+     * @param target The target of the branch
+     * @param bp_history The pointer set to an object
+     *   that has the branch predictor state associated
+     *   with the lookup
+     */
+    void updateHistories(ThreadID tid, Addr pc, bool uncond, bool taken,
+                         Addr target,  void * &bp_history) override;
+
+
+    /**
+     * Updates the branch predictor with the actual result of a branch.
+     * @param branch_addr The address of the branch to update.
+     * @param taken Whether or not the branch was taken.
+     * @param bp_history Pointer to the BPHistory object that was created
+     * when the branch was predicted.
+     * @param squashed is set when this function is called during a squash
+     * operation.
+     */
+    void update(ThreadID tid, Addr pc, bool taken,
+                void * &bp_history, bool squashed,
+                const StaticInstPtr & inst, Addr target) override;
+
+    /**
+     * Restores the global branch history on a squash.
+     * @param bp_history Pointer to the BPHistory object that has the
+     * previous global branch history in it.
+     */
+    void squash(ThreadID tid, void * &bp_history) override
+    { assert(bp_history == NULL); }
+
+  private:
+    /**
+     *  Returns the taken/not taken prediction given the value of the
+     *  counter.
+     *  @param count The value of the counter.
+     *  @return The prediction based on the counter value.
+     */
+    inline bool getPrediction(uint8_t &count);
+};
+
+} // namespace branch_prediction
+} // namespace gem5
+
+#endif // __CPU_PRED_GSHARE_PRED_HH__
