2bit_local.cc revision 12334
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
3111793Sbrandon.potter@amd.com#include "cpu/pred/2bit_local.hh"
3211793Sbrandon.potter@amd.com
336184SN/A#include "base/intmath.hh"
3412334Sgabeblack@google.com#include "base/logging.hh"
356184SN/A#include "base/trace.hh"
368232Snate@binkert.org#include "debug/Fetch.hh"
376184SN/A
3810785Sgope@wisc.eduLocalBP::LocalBP(const LocalBPParams *params)
399480Snilay@cs.wisc.edu    : BPredUnit(params),
409480Snilay@cs.wisc.edu      localPredictorSize(params->localPredictorSize),
4110785Sgope@wisc.edu      localCtrBits(params->localCtrBits)
426184SN/A{
436184SN/A    if (!isPowerOf2(localPredictorSize)) {
446184SN/A        fatal("Invalid local predictor size!\n");
456184SN/A    }
466184SN/A
476184SN/A    localPredictorSets = localPredictorSize / localCtrBits;
486184SN/A
496184SN/A    if (!isPowerOf2(localPredictorSets)) {
506184SN/A        fatal("Invalid number of local predictor sets! Check localCtrBits.\n");
516184SN/A    }
526184SN/A
536184SN/A    // Setup the index mask.
546184SN/A    indexMask = localPredictorSets - 1;
556184SN/A
569480Snilay@cs.wisc.edu    DPRINTF(Fetch, "index mask: %#x\n", indexMask);
576184SN/A
586184SN/A    // Setup the array of counters for the local predictor.
596184SN/A    localCtrs.resize(localPredictorSets);
606184SN/A
616227Snate@binkert.org    for (unsigned i = 0; i < localPredictorSets; ++i)
629480Snilay@cs.wisc.edu        localCtrs[i].setBits(localCtrBits);
636184SN/A
649480Snilay@cs.wisc.edu    DPRINTF(Fetch, "local predictor size: %i\n",
656184SN/A            localPredictorSize);
666184SN/A
679480Snilay@cs.wisc.edu    DPRINTF(Fetch, "local counter bits: %i\n", localCtrBits);
686184SN/A
699480Snilay@cs.wisc.edu    DPRINTF(Fetch, "instruction shift amount: %i\n",
706184SN/A            instShiftAmt);
716184SN/A}
726184SN/A
736184SN/Avoid
746184SN/ALocalBP::reset()
756184SN/A{
766227Snate@binkert.org    for (unsigned i = 0; i < localPredictorSets; ++i) {
776184SN/A        localCtrs[i].reset();
786184SN/A    }
796184SN/A}
806184SN/A
818842Smrinmoy.ghosh@arm.comvoid
8211434Smitch.hayenga@arm.comLocalBP::btbUpdate(ThreadID tid, Addr branch_addr, void * &bp_history)
838842Smrinmoy.ghosh@arm.com{
848842Smrinmoy.ghosh@arm.com// Place holder for a function that is called to update predictor history when
858842Smrinmoy.ghosh@arm.com// a BTB entry is invalid or not found.
868842Smrinmoy.ghosh@arm.com}
878842Smrinmoy.ghosh@arm.com
888842Smrinmoy.ghosh@arm.com
896184SN/Abool
9011434Smitch.hayenga@arm.comLocalBP::lookup(ThreadID tid, Addr branch_addr, void * &bp_history)
916184SN/A{
926184SN/A    bool taken;
936184SN/A    uint8_t counter_val;
946184SN/A    unsigned local_predictor_idx = getLocalIndex(branch_addr);
956184SN/A
969480Snilay@cs.wisc.edu    DPRINTF(Fetch, "Looking up index %#x\n",
976184SN/A            local_predictor_idx);
986184SN/A
996184SN/A    counter_val = localCtrs[local_predictor_idx].read();
1006184SN/A
1019480Snilay@cs.wisc.edu    DPRINTF(Fetch, "prediction is %i.\n",
1026184SN/A            (int)counter_val);
1036184SN/A
1046184SN/A    taken = getPrediction(counter_val);
1056184SN/A
1066184SN/A#if 0
1076184SN/A    // Speculative update.
1086184SN/A    if (taken) {
1099480Snilay@cs.wisc.edu        DPRINTF(Fetch, "Branch updated as taken.\n");
1106184SN/A        localCtrs[local_predictor_idx].increment();
1116184SN/A    } else {
1129480Snilay@cs.wisc.edu        DPRINTF(Fetch, "Branch updated as not taken.\n");
1136184SN/A        localCtrs[local_predictor_idx].decrement();
1146184SN/A    }
1156184SN/A#endif
1166184SN/A
1176184SN/A    return taken;
1186184SN/A}
1196184SN/A
1206184SN/Avoid
12111434Smitch.hayenga@arm.comLocalBP::update(ThreadID tid, Addr branch_addr, bool taken, void *bp_history,
12211434Smitch.hayenga@arm.com                bool squashed)
1236184SN/A{
1246184SN/A    assert(bp_history == NULL);
1256184SN/A    unsigned local_predictor_idx;
1266184SN/A
12711783Sarthur.perais@inria.fr    // No state to restore, and we do not update on the wrong
12811783Sarthur.perais@inria.fr    // path.
12911783Sarthur.perais@inria.fr    if (squashed) {
13011783Sarthur.perais@inria.fr        return;
13111783Sarthur.perais@inria.fr    }
13211783Sarthur.perais@inria.fr
1336184SN/A    // Update the local predictor.
1346184SN/A    local_predictor_idx = getLocalIndex(branch_addr);
1356184SN/A
1369480Snilay@cs.wisc.edu    DPRINTF(Fetch, "Looking up index %#x\n", local_predictor_idx);
1376184SN/A
1386184SN/A    if (taken) {
1399480Snilay@cs.wisc.edu        DPRINTF(Fetch, "Branch updated as taken.\n");
1406184SN/A        localCtrs[local_predictor_idx].increment();
1416184SN/A    } else {
1429480Snilay@cs.wisc.edu        DPRINTF(Fetch, "Branch updated as not taken.\n");
1436184SN/A        localCtrs[local_predictor_idx].decrement();
1446184SN/A    }
1456184SN/A}
1466184SN/A
1476184SN/Ainline
1486184SN/Abool
1496184SN/ALocalBP::getPrediction(uint8_t &count)
1506184SN/A{
1516184SN/A    // Get the MSB of the count
1526184SN/A    return (count >> (localCtrBits - 1));
1536184SN/A}
1546184SN/A
1556184SN/Ainline
1566184SN/Aunsigned
1576184SN/ALocalBP::getLocalIndex(Addr &branch_addr)
1586184SN/A{
1596184SN/A    return (branch_addr >> instShiftAmt) & indexMask;
1606184SN/A}
1619480Snilay@cs.wisc.edu
1629480Snilay@cs.wisc.eduvoid
16311434Smitch.hayenga@arm.comLocalBP::uncondBranch(ThreadID tid, Addr pc, void *&bp_history)
1649480Snilay@cs.wisc.edu{
1659480Snilay@cs.wisc.edu}
16610785Sgope@wisc.edu
16710785Sgope@wisc.eduLocalBP*
16810785Sgope@wisc.eduLocalBPParams::create()
16910785Sgope@wisc.edu{
17010785Sgope@wisc.edu    return new LocalBP(this);
17110785Sgope@wisc.edu}
172