2bit_local.cc revision 8232
16184SN/A/*
26184SN/A * Copyright (c) 2004-2006 The Regents of The University of Michigan
36184SN/A * All rights reserved.
46184SN/A *
56184SN/A * Redistribution and use in source and binary forms, with or without
66184SN/A * modification, are permitted provided that the following conditions are
76184SN/A * met: redistributions of source code must retain the above copyright
86184SN/A * notice, this list of conditions and the following disclaimer;
96184SN/A * redistributions in binary form must reproduce the above copyright
106184SN/A * notice, this list of conditions and the following disclaimer in the
116184SN/A * documentation and/or other materials provided with the distribution;
126184SN/A * neither the name of the copyright holders nor the names of its
136184SN/A * contributors may be used to endorse or promote products derived from
146184SN/A * this software without specific prior written permission.
156184SN/A *
166184SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176184SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186184SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196184SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206184SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216184SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226184SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236184SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246184SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256184SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266184SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276184SN/A *
286184SN/A * Authors: Kevin Lim
296184SN/A */
306184SN/A
316184SN/A#include "base/intmath.hh"
326184SN/A#include "base/misc.hh"
336184SN/A#include "base/trace.hh"
346226Snate@binkert.org#include "cpu/pred/2bit_local.hh"
358232Snate@binkert.org#include "debug/Fetch.hh"
366184SN/A
376184SN/ALocalBP::LocalBP(unsigned _localPredictorSize,
386184SN/A                 unsigned _localCtrBits,
396184SN/A                 unsigned _instShiftAmt)
406184SN/A    : localPredictorSize(_localPredictorSize),
416184SN/A      localCtrBits(_localCtrBits),
426184SN/A      instShiftAmt(_instShiftAmt)
436184SN/A{
446184SN/A    if (!isPowerOf2(localPredictorSize)) {
456184SN/A        fatal("Invalid local predictor size!\n");
466184SN/A    }
476184SN/A
486184SN/A    localPredictorSets = localPredictorSize / localCtrBits;
496184SN/A
506184SN/A    if (!isPowerOf2(localPredictorSets)) {
516184SN/A        fatal("Invalid number of local predictor sets! Check localCtrBits.\n");
526184SN/A    }
536184SN/A
546184SN/A    // Setup the index mask.
556184SN/A    indexMask = localPredictorSets - 1;
566184SN/A
576184SN/A    DPRINTF(Fetch, "Branch predictor: index mask: %#x\n", indexMask);
586184SN/A
596184SN/A    // Setup the array of counters for the local predictor.
606184SN/A    localCtrs.resize(localPredictorSets);
616184SN/A
626227Snate@binkert.org    for (unsigned i = 0; i < localPredictorSets; ++i)
636184SN/A        localCtrs[i].setBits(_localCtrBits);
646184SN/A
656184SN/A    DPRINTF(Fetch, "Branch predictor: local predictor size: %i\n",
666184SN/A            localPredictorSize);
676184SN/A
686184SN/A    DPRINTF(Fetch, "Branch predictor: local counter bits: %i\n", localCtrBits);
696184SN/A
706184SN/A    DPRINTF(Fetch, "Branch predictor: instruction shift amount: %i\n",
716184SN/A            instShiftAmt);
726184SN/A}
736184SN/A
746184SN/Avoid
756184SN/ALocalBP::reset()
766184SN/A{
776227Snate@binkert.org    for (unsigned i = 0; i < localPredictorSets; ++i) {
786184SN/A        localCtrs[i].reset();
796184SN/A    }
806184SN/A}
816184SN/A
826184SN/Abool
836184SN/ALocalBP::lookup(Addr &branch_addr, void * &bp_history)
846184SN/A{
856184SN/A    bool taken;
866184SN/A    uint8_t counter_val;
876184SN/A    unsigned local_predictor_idx = getLocalIndex(branch_addr);
886184SN/A
896184SN/A    DPRINTF(Fetch, "Branch predictor: Looking up index %#x\n",
906184SN/A            local_predictor_idx);
916184SN/A
926184SN/A    counter_val = localCtrs[local_predictor_idx].read();
936184SN/A
946184SN/A    DPRINTF(Fetch, "Branch predictor: prediction is %i.\n",
956184SN/A            (int)counter_val);
966184SN/A
976184SN/A    taken = getPrediction(counter_val);
986184SN/A
996184SN/A#if 0
1006184SN/A    // Speculative update.
1016184SN/A    if (taken) {
1026184SN/A        DPRINTF(Fetch, "Branch predictor: Branch updated as taken.\n");
1036184SN/A        localCtrs[local_predictor_idx].increment();
1046184SN/A    } else {
1056184SN/A        DPRINTF(Fetch, "Branch predictor: Branch updated as not taken.\n");
1066184SN/A        localCtrs[local_predictor_idx].decrement();
1076184SN/A    }
1086184SN/A#endif
1096184SN/A
1106184SN/A    return taken;
1116184SN/A}
1126184SN/A
1136184SN/Avoid
1146184SN/ALocalBP::update(Addr &branch_addr, bool taken, void *bp_history)
1156184SN/A{
1166184SN/A    assert(bp_history == NULL);
1176184SN/A    unsigned local_predictor_idx;
1186184SN/A
1196184SN/A    // Update the local predictor.
1206184SN/A    local_predictor_idx = getLocalIndex(branch_addr);
1216184SN/A
1226184SN/A    DPRINTF(Fetch, "Branch predictor: Looking up index %#x\n",
1236184SN/A            local_predictor_idx);
1246184SN/A
1256184SN/A    if (taken) {
1266184SN/A        DPRINTF(Fetch, "Branch predictor: Branch updated as taken.\n");
1276184SN/A        localCtrs[local_predictor_idx].increment();
1286184SN/A    } else {
1296184SN/A        DPRINTF(Fetch, "Branch predictor: Branch updated as not taken.\n");
1306184SN/A        localCtrs[local_predictor_idx].decrement();
1316184SN/A    }
1326184SN/A}
1336184SN/A
1346184SN/Ainline
1356184SN/Abool
1366184SN/ALocalBP::getPrediction(uint8_t &count)
1376184SN/A{
1386184SN/A    // Get the MSB of the count
1396184SN/A    return (count >> (localCtrBits - 1));
1406184SN/A}
1416184SN/A
1426184SN/Ainline
1436184SN/Aunsigned
1446184SN/ALocalBP::getLocalIndex(Addr &branch_addr)
1456184SN/A{
1466184SN/A    return (branch_addr >> instShiftAmt) & indexMask;
1476184SN/A}
148