/*
 * Copyright (c) 2004-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "cpu/o3/tournament_pred.hh"

TournamentBP::TournamentBP(unsigned _local_predictor_size,
                           unsigned _local_ctr_bits,
                           unsigned _local_history_table_size,
                           unsigned _local_history_bits,
                           unsigned _global_predictor_size,
                           unsigned _global_ctr_bits,
                           unsigned _global_history_bits,
                           unsigned _choice_predictor_size,
                           unsigned _choice_ctr_bits,
                           unsigned _instShiftAmt)
    : localPredictorSize(_local_predictor_size),
      localCtrBits(_local_ctr_bits),
      localHistoryTableSize(_local_history_table_size),
      localHistoryBits(_local_history_bits),
      globalPredictorSize(_global_predictor_size),
      globalCtrBits(_global_ctr_bits),
      globalHistoryBits(_global_history_bits),
      choicePredictorSize(_global_predictor_size),
      choiceCtrBits(_choice_ctr_bits),
      instShiftAmt(_instShiftAmt)
{
    //Should do checks here to make sure sizes are correct (powers of 2)

    //Setup the array of counters for the local predictor
    localCtrs = new SatCounter[localPredictorSize];

    for (int i = 0; i < localPredictorSize; ++i)
        localCtrs[i].setBits(localCtrBits);

    //Setup the history table for the local table
    localHistoryTable = new unsigned[localHistoryTableSize];

    for (int i = 0; i < localHistoryTableSize; ++i)
        localHistoryTable[i] = 0;

    // Setup the local history mask
    localHistoryMask = (1 << localHistoryBits) - 1;

    //Setup the array of counters for the global predictor
    globalCtrs = new SatCounter[globalPredictorSize];

    for (int i = 0; i < globalPredictorSize; ++i)
        globalCtrs[i].setBits(globalCtrBits);

    //Clear the global history
    globalHistory = 0;
    // Setup the global history mask
    globalHistoryMask = (1 << globalHistoryBits) - 1;

    //Setup the array of counters for the choice predictor
    choiceCtrs = new SatCounter[choicePredictorSize];

    for (int i = 0; i < choicePredictorSize; ++i)
        choiceCtrs[i].setBits(choiceCtrBits);

    threshold = (1 << (localCtrBits - 1)) - 1;
    threshold = threshold / 2;
}

inline
unsigned
TournamentBP::calcLocHistIdx(Addr &branch_addr)
{
    return (branch_addr >> instShiftAmt) & (localHistoryTableSize - 1);
}

inline
void
TournamentBP::updateHistoriesTaken(unsigned local_history_idx)
{
    globalHistory = (globalHistory << 1) | 1;
    globalHistory = globalHistory & globalHistoryMask;

    localHistoryTable[local_history_idx] =
        (localHistoryTable[local_history_idx] << 1) | 1;
}

inline
void
TournamentBP::updateHistoriesNotTaken(unsigned local_history_idx)
{
    globalHistory = (globalHistory << 1);
    globalHistory = globalHistory & globalHistoryMask;

    localHistoryTable[local_history_idx] =
        (localHistoryTable[local_history_idx] << 1);
}

bool
TournamentBP::lookup(Addr &branch_addr)
{
    uint8_t local_prediction;
    unsigned local_history_idx;
    unsigned local_predictor_idx;

    uint8_t global_prediction;
    uint8_t choice_prediction;

    //Lookup in the local predictor to get its branch prediction
    local_history_idx = calcLocHistIdx(branch_addr);
    local_predictor_idx = localHistoryTable[local_history_idx]
        & localHistoryMask;
    local_prediction = localCtrs[local_predictor_idx].read();

    //Lookup in the global predictor to get its branch prediction
    global_prediction = globalCtrs[globalHistory].read();

    //Lookup in the choice predictor to see which one to use
    choice_prediction = choiceCtrs[globalHistory].read();

    //@todo Put a threshold value in for the three predictors that can
    // be set through the constructor (so this isn't hard coded).
    //Also should put some of this code into functions.
    if (choice_prediction > threshold) {
        if (global_prediction > threshold) {
            updateHistoriesTaken(local_history_idx);

            assert(globalHistory < globalPredictorSize &&
                   local_history_idx < localPredictorSize);

            globalCtrs[globalHistory].increment();
            localCtrs[local_history_idx].increment();

            return true;
        } else {
            updateHistoriesNotTaken(local_history_idx);

            assert(globalHistory < globalPredictorSize &&
                   local_history_idx < localPredictorSize);

            globalCtrs[globalHistory].decrement();
            localCtrs[local_history_idx].decrement();

            return false;
        }
    } else {
        if (local_prediction > threshold) {
            updateHistoriesTaken(local_history_idx);

            assert(globalHistory < globalPredictorSize &&
                   local_history_idx < localPredictorSize);

            globalCtrs[globalHistory].increment();
            localCtrs[local_history_idx].increment();

            return true;
        } else {
            updateHistoriesNotTaken(local_history_idx);

            assert(globalHistory < globalPredictorSize &&
                   local_history_idx < localPredictorSize);

            globalCtrs[globalHistory].decrement();
            localCtrs[local_history_idx].decrement();

            return false;
        }
    }
}

// Update the branch predictor if it predicted a branch wrong.
void
TournamentBP::update(Addr &branch_addr, unsigned correct_gh, bool taken)
{

    uint8_t local_prediction;
    unsigned local_history_idx;
    unsigned local_predictor_idx;
    bool local_pred_taken;

    uint8_t global_prediction;
    bool global_pred_taken;

    // Load the correct global history into the register.
    globalHistory = correct_gh;

    // Get the local predictor's current prediction, remove the incorrect
    // update, and update the local predictor
    local_history_idx = calcLocHistIdx(branch_addr);
    local_predictor_idx = localHistoryTable[local_history_idx];
    local_predictor_idx = (local_predictor_idx >> 1) & localHistoryMask;

    local_prediction = localCtrs[local_predictor_idx].read();
    local_pred_taken = local_prediction > threshold;

    //Get the global predictor's current prediction, and update the
    //global predictor
    global_prediction = globalCtrs[globalHistory].read();
    global_pred_taken = global_prediction > threshold;

    //Update the choice predictor to tell it which one was correct
    if (local_pred_taken != global_pred_taken) {
        //If the local prediction matches the actual outcome, decerement
        //the counter.  Otherwise increment the counter.
        if (local_pred_taken == taken) {
            choiceCtrs[globalHistory].decrement();
        } else {
            choiceCtrs[globalHistory].increment();
        }
    }

    if (taken) {
        assert(globalHistory < globalPredictorSize &&
               local_predictor_idx < localPredictorSize);

        localCtrs[local_predictor_idx].increment();
        globalCtrs[globalHistory].increment();

        globalHistory = (globalHistory << 1) | 1;
        globalHistory = globalHistory & globalHistoryMask;

        localHistoryTable[local_history_idx] |= 1;
    }
    else {
        assert(globalHistory < globalPredictorSize &&
               local_predictor_idx < localPredictorSize);

        localCtrs[local_predictor_idx].decrement();
        globalCtrs[globalHistory].decrement();

        globalHistory = (globalHistory << 1);
        globalHistory = globalHistory & globalHistoryMask;

        localHistoryTable[local_history_idx] &= ~1;
    }
}
