2bit_local.cc revision 13626
12440SN/A/*
22440SN/A * Copyright (c) 2004-2006 The Regents of The University of Michigan
32440SN/A * All rights reserved.
42440SN/A *
52440SN/A * Redistribution and use in source and binary forms, with or without
62440SN/A * modification, are permitted provided that the following conditions are
72440SN/A * met: redistributions of source code must retain the above copyright
82440SN/A * notice, this list of conditions and the following disclaimer;
92440SN/A * redistributions in binary form must reproduce the above copyright
102440SN/A * notice, this list of conditions and the following disclaimer in the
112440SN/A * documentation and/or other materials provided with the distribution;
122440SN/A * neither the name of the copyright holders nor the names of its
132440SN/A * contributors may be used to endorse or promote products derived from
142440SN/A * this software without specific prior written permission.
152440SN/A *
162440SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172440SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182440SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192440SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202440SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212440SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222440SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232440SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242440SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252440SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262440SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665SN/A *
282665SN/A * Authors: Kevin Lim
292440SN/A */
302440SN/A
316329Sgblack@eecs.umich.edu#include "cpu/pred/2bit_local.hh"
326329Sgblack@eecs.umich.edu
332440SN/A#include "base/intmath.hh"
348961Sgblack@eecs.umich.edu#include "base/logging.hh"
356327SN/A#include "base/trace.hh"
366329Sgblack@eecs.umich.edu#include "debug/Fetch.hh"
372440SN/A
385569SN/ALocalBP::LocalBP(const LocalBPParams *params)
392972SN/A    : BPredUnit(params),
406329Sgblack@eecs.umich.edu      localPredictorSize(params->localPredictorSize),
416329Sgblack@eecs.umich.edu      localCtrBits(params->localCtrBits)
426327SN/A{
439046SAli.Saidi@ARM.com    if (!isPowerOf2(localPredictorSize)) {
449046SAli.Saidi@ARM.com        fatal("Invalid local predictor size!\n");
459046SAli.Saidi@ARM.com    }
466329Sgblack@eecs.umich.edu
476329Sgblack@eecs.umich.edu    localPredictorSets = localPredictorSize / localCtrBits;
486327SN/A
496329Sgblack@eecs.umich.edu    if (!isPowerOf2(localPredictorSets)) {
506329Sgblack@eecs.umich.edu        fatal("Invalid number of local predictor sets! Check localCtrBits.\n");
516329Sgblack@eecs.umich.edu    }
526327SN/A
536329Sgblack@eecs.umich.edu    // Setup the index mask.
546329Sgblack@eecs.umich.edu    indexMask = localPredictorSets - 1;
556327SN/A
566329Sgblack@eecs.umich.edu    DPRINTF(Fetch, "index mask: %#x\n", indexMask);
576329Sgblack@eecs.umich.edu
586329Sgblack@eecs.umich.edu    // Setup the array of counters for the local predictor.
596329Sgblack@eecs.umich.edu    localCtrs.resize(localPredictorSets);
606329Sgblack@eecs.umich.edu
616329Sgblack@eecs.umich.edu    for (unsigned i = 0; i < localPredictorSets; ++i)
626321SN/A        localCtrs[i].setBits(localCtrBits);
636329Sgblack@eecs.umich.edu
646329Sgblack@eecs.umich.edu    DPRINTF(Fetch, "local predictor size: %i\n",
656329Sgblack@eecs.umich.edu            localPredictorSize);
666329Sgblack@eecs.umich.edu
676329Sgblack@eecs.umich.edu    DPRINTF(Fetch, "local counter bits: %i\n", localCtrBits);
686329Sgblack@eecs.umich.edu
697699Sgblack@eecs.umich.edu    DPRINTF(Fetch, "instruction shift amount: %i\n",
707699Sgblack@eecs.umich.edu            instShiftAmt);
716329Sgblack@eecs.umich.edu}
725569SN/A
736329Sgblack@eecs.umich.eduvoid
746329Sgblack@eecs.umich.eduLocalBP::reset()
756329Sgblack@eecs.umich.edu{
766329Sgblack@eecs.umich.edu    for (unsigned i = 0; i < localPredictorSets; ++i) {
776329Sgblack@eecs.umich.edu        localCtrs[i].reset();
786329Sgblack@eecs.umich.edu    }
796329Sgblack@eecs.umich.edu}
806329Sgblack@eecs.umich.edu
816329Sgblack@eecs.umich.eduvoid
826329Sgblack@eecs.umich.eduLocalBP::btbUpdate(ThreadID tid, Addr branch_addr, void * &bp_history)
836329Sgblack@eecs.umich.edu{
846329Sgblack@eecs.umich.edu// Place holder for a function that is called to update predictor history when
856329Sgblack@eecs.umich.edu// a BTB entry is invalid or not found.
866329Sgblack@eecs.umich.edu}
876329Sgblack@eecs.umich.edu
886329Sgblack@eecs.umich.edu
896329Sgblack@eecs.umich.edubool
906329Sgblack@eecs.umich.eduLocalBP::lookup(ThreadID tid, Addr branch_addr, void * &bp_history)
917699Sgblack@eecs.umich.edu{
926329Sgblack@eecs.umich.edu    bool taken;
936329Sgblack@eecs.umich.edu    uint8_t counter_val;
946329Sgblack@eecs.umich.edu    unsigned local_predictor_idx = getLocalIndex(branch_addr);
956329Sgblack@eecs.umich.edu
966329Sgblack@eecs.umich.edu    DPRINTF(Fetch, "Looking up index %#x\n",
976329Sgblack@eecs.umich.edu            local_predictor_idx);
987699Sgblack@eecs.umich.edu
996329Sgblack@eecs.umich.edu    counter_val = localCtrs[local_predictor_idx].read();
1006329Sgblack@eecs.umich.edu
1016329Sgblack@eecs.umich.edu    DPRINTF(Fetch, "prediction is %i.\n",
1026329Sgblack@eecs.umich.edu            (int)counter_val);
1036329Sgblack@eecs.umich.edu
1046329Sgblack@eecs.umich.edu    taken = getPrediction(counter_val);
1056329Sgblack@eecs.umich.edu
1066329Sgblack@eecs.umich.edu#if 0
1077649Sminkyu.jeong@arm.com    // Speculative update.
1087649Sminkyu.jeong@arm.com    if (taken) {
1096329Sgblack@eecs.umich.edu        DPRINTF(Fetch, "Branch updated as taken.\n");
1105569SN/A        localCtrs[local_predictor_idx].increment();
1112440SN/A    } else {
1122440SN/A        DPRINTF(Fetch, "Branch updated as not taken.\n");
1135569SN/A        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, const StaticInstPtr & inst, Addr corrTarget)
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