2bit_local.cc revision 11793
16145SN/A/*
26145SN/A * Copyright (c) 2004-2006 The Regents of The University of Michigan
36145SN/A * All rights reserved.
46145SN/A *
56145SN/A * Redistribution and use in source and binary forms, with or without
66145SN/A * modification, are permitted provided that the following conditions are
76145SN/A * met: redistributions of source code must retain the above copyright
86145SN/A * notice, this list of conditions and the following disclaimer;
96145SN/A * redistributions in binary form must reproduce the above copyright
106145SN/A * notice, this list of conditions and the following disclaimer in the
116145SN/A * documentation and/or other materials provided with the distribution;
126145SN/A * neither the name of the copyright holders nor the names of its
136145SN/A * contributors may be used to endorse or promote products derived from
146145SN/A * this software without specific prior written permission.
156145SN/A *
166145SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176145SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186145SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196145SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206145SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216145SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226145SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236145SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246145SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256145SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266145SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276145SN/A *
286145SN/A * Authors: Kevin Lim
296145SN/A */
307054SN/A
317054SN/A#include "cpu/pred/2bit_local.hh"
327054SN/A
337054SN/A#include "base/intmath.hh"
347054SN/A#include "base/misc.hh"
357054SN/A#include "base/trace.hh"
367054SN/A#include "debug/Fetch.hh"
377054SN/A
387054SN/ALocalBP::LocalBP(const LocalBPParams *params)
396145SN/A    : BPredUnit(params),
409594Snilay@cs.wisc.edu      localPredictorSize(params->localPredictorSize),
419594Snilay@cs.wisc.edu      localCtrBits(params->localCtrBits)
426145SN/A{
437002SN/A    if (!isPowerOf2(localPredictorSize)) {
447002SN/A        fatal("Invalid local predictor size!\n");
457454SN/A    }
467002SN/A
478257SBrad.Beckmann@amd.com    localPredictorSets = localPredictorSize / localCtrBits;
488608Snilay@cs.wisc.edu
499594Snilay@cs.wisc.edu    if (!isPowerOf2(localPredictorSets)) {
506145SN/A        fatal("Invalid number of local predictor sets! Check localCtrBits.\n");
518257SBrad.Beckmann@amd.com    }
526145SN/A
536145SN/A    // Setup the index mask.
547454SN/A    indexMask = localPredictorSets - 1;
556145SN/A
568257SBrad.Beckmann@amd.com    DPRINTF(Fetch, "index mask: %#x\n", indexMask);
577054SN/A
588257SBrad.Beckmann@amd.com    // Setup the array of counters for the local predictor.
598257SBrad.Beckmann@amd.com    localCtrs.resize(localPredictorSets);
606879SN/A
616879SN/A    for (unsigned i = 0; i < localPredictorSets; ++i)
6210005Snilay@cs.wisc.edu        localCtrs[i].setBits(localCtrBits);
636879SN/A
649594Snilay@cs.wisc.edu    DPRINTF(Fetch, "local predictor size: %i\n",
657054SN/A            localPredictorSize);
667054SN/A
6711096Snilay@cs.wisc.edu    DPRINTF(Fetch, "local counter bits: %i\n", localCtrBits);
6811096Snilay@cs.wisc.edu
696145SN/A    DPRINTF(Fetch, "instruction shift amount: %i\n",
709594Snilay@cs.wisc.edu            instShiftAmt);
719799Snilay@cs.wisc.edu}
727054SN/A
736881SN/Avoid
7411096Snilay@cs.wisc.eduLocalBP::reset()
758257SBrad.Beckmann@amd.com{
768257SBrad.Beckmann@amd.com    for (unsigned i = 0; i < localPredictorSets; ++i) {
777054SN/A        localCtrs[i].reset();
789799Snilay@cs.wisc.edu    }
796145SN/A}
8011096Snilay@cs.wisc.edu
8111096Snilay@cs.wisc.eduvoid
8211096Snilay@cs.wisc.eduLocalBP::btbUpdate(ThreadID tid, Addr branch_addr, void * &bp_history)
8311096Snilay@cs.wisc.edu{
8411096Snilay@cs.wisc.edu// Place holder for a function that is called to update predictor history when
8511096Snilay@cs.wisc.edu// a BTB entry is invalid or not found.
8611096Snilay@cs.wisc.edu}
8711096Snilay@cs.wisc.edu
8811096Snilay@cs.wisc.edu
8911096Snilay@cs.wisc.edubool
9011096Snilay@cs.wisc.eduLocalBP::lookup(ThreadID tid, Addr branch_addr, void * &bp_history)
9111096Snilay@cs.wisc.edu{
9211096Snilay@cs.wisc.edu    bool taken;
9311096Snilay@cs.wisc.edu    uint8_t counter_val;
9411096Snilay@cs.wisc.edu    unsigned local_predictor_idx = getLocalIndex(branch_addr);
956145SN/A
968257SBrad.Beckmann@amd.com    DPRINTF(Fetch, "Looking up index %#x\n",
978257SBrad.Beckmann@amd.com            local_predictor_idx);
986881SN/A
998257SBrad.Beckmann@amd.com    counter_val = localCtrs[local_predictor_idx].read();
1006145SN/A
1016145SN/A    DPRINTF(Fetch, "prediction is %i.\n",
1027054SN/A            (int)counter_val);
1037054SN/A
1046145SN/A    taken = getPrediction(counter_val);
1057054SN/A
1067054SN/A#if 0
1077054SN/A    // Speculative update.
1086145SN/A    if (taken) {
1096145SN/A        DPRINTF(Fetch, "Branch updated as taken.\n");
1109594Snilay@cs.wisc.edu        localCtrs[local_predictor_idx].increment();
111    } else {
112        DPRINTF(Fetch, "Branch updated as not taken.\n");
113        localCtrs[local_predictor_idx].decrement();
114    }
115#endif
116
117    return taken;
118}
119
120void
121LocalBP::update(ThreadID tid, Addr branch_addr, bool taken, void *bp_history,
122                bool squashed)
123{
124    assert(bp_history == NULL);
125    unsigned local_predictor_idx;
126
127    // No state to restore, and we do not update on the wrong
128    // path.
129    if (squashed) {
130        return;
131    }
132
133    // Update the local predictor.
134    local_predictor_idx = getLocalIndex(branch_addr);
135
136    DPRINTF(Fetch, "Looking up index %#x\n", local_predictor_idx);
137
138    if (taken) {
139        DPRINTF(Fetch, "Branch updated as taken.\n");
140        localCtrs[local_predictor_idx].increment();
141    } else {
142        DPRINTF(Fetch, "Branch updated as not taken.\n");
143        localCtrs[local_predictor_idx].decrement();
144    }
145}
146
147inline
148bool
149LocalBP::getPrediction(uint8_t &count)
150{
151    // Get the MSB of the count
152    return (count >> (localCtrBits - 1));
153}
154
155inline
156unsigned
157LocalBP::getLocalIndex(Addr &branch_addr)
158{
159    return (branch_addr >> instShiftAmt) & indexMask;
160}
161
162void
163LocalBP::uncondBranch(ThreadID tid, Addr pc, void *&bp_history)
164{
165}
166
167LocalBP*
168LocalBPParams::create()
169{
170    return new LocalBP(this);
171}
172