/*
 * Copyright (c) 2018 Metempsy Technology Consulting
 * All rights reserved.
 *
 * Copyright (c) 2006 INRIA (Institut National de Recherche en
 * Informatique et en Automatique  / French National Research Institute
 * for Computer Science and Applied Mathematics)
 *
 * 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.
 *
 * Author: André Seznec, Pau Cabre, Javier Bueno
 *
 */

/*
 * 8KB TAGE-SC-L branch predictor (devised by Andre Seznec)
 */

#include "cpu/pred/tage_sc_l_8KB.hh"

#include "base/random.hh"
#include "debug/TageSCL.hh"

TAGE_SC_L_8KB_StatisticalCorrector::TAGE_SC_L_8KB_StatisticalCorrector(
    const TAGE_SC_L_8KB_StatisticalCorrectorParams &p)
  : StatisticalCorrector(p),
    gnb(p.gnb),
    logGnb(p.logGnb),
    gm(p.gm)
{
    initGEHLTable(gnb, gm, ggehl, logGnb, wg, 7);
}

TAGE_SC_L_8KB_StatisticalCorrector::SCThreadHistory *
TAGE_SC_L_8KB_StatisticalCorrector::makeThreadHistory()
{
    SC_8KB_ThreadHistory *sh = new SC_8KB_ThreadHistory();
    sh->setNumOrdinalHistories(1);
    sh->initLocalHistory(1, numEntriesFirstLocalHistories, 2);
    return sh;
}

unsigned
TAGE_SC_L_8KB_StatisticalCorrector::getIndBiasBank(Addr branch_pc,
        BranchInfo* bi, int hitBank, int altBank) const
{
    return (bi->predBeforeSC + (((hitBank+1)/4)<<4) + (bi->highConf<<1) +
            (bi->lowConf <<2) +((altBank!=0)<<3)) & ((1<<logBias) -1);
}

int
TAGE_SC_L_8KB_StatisticalCorrector::gPredictions(
    ThreadID tid, Addr branch_pc, BranchInfo* bi, int & lsum, int64_t phist)
{
    SC_8KB_ThreadHistory *sh = static_cast<SC_8KB_ThreadHistory *>(scHistory);
    lsum += gPredict(
        branch_pc, sh->globalHist, gm, ggehl, gnb, logGnb, wg);

    lsum += gPredict(
        branch_pc, sh->bwHist, bwm, bwgehl, bwnb, logBwnb, wbw);

    // only 1 local history here
    lsum += gPredict(
        branch_pc, sh->getLocalHistory(1, branch_pc), lm,
        lgehl, lnb, logLnb, wl);

    lsum += gPredict(
        branch_pc, sh->imliCount, im, igehl, inb, logInb, wi);

    int thres = (updateThreshold>>3)+pUpdateThreshold[getIndUpd(branch_pc)];

    return thres;
}

int TAGE_SC_L_8KB_StatisticalCorrector::gIndexLogsSubstr(int nbr, int i)
{
    return 0;
}

void
TAGE_SC_L_8KB_StatisticalCorrector::scHistoryUpdate(Addr branch_pc,
    const StaticInstPtr &inst, bool taken, BranchInfo *tage_bi,
    Addr corrTarget)
{
    int brtype = inst->isDirectCtrl() ? 0 : 2;
    if (! inst->isUncondCtrl()) {
        ++brtype;
    }
    // Non speculative SC histories update
    if (brtype & 1) {
        SC_8KB_ThreadHistory *sh =
            static_cast<SC_8KB_ThreadHistory *>(scHistory);
        sh->globalHist = (sh->globalHist << 1) + taken;
    }

    StatisticalCorrector::scHistoryUpdate(branch_pc, inst, taken, tage_bi,
                                          corrTarget);
}

void
TAGE_SC_L_8KB_StatisticalCorrector::gUpdates(ThreadID tid, Addr pc, bool taken,
        BranchInfo* bi, int64_t phist)
{
    SC_8KB_ThreadHistory *sh = static_cast<SC_8KB_ThreadHistory *>(scHistory);
    gUpdate(pc, taken, sh->globalHist, gm, ggehl, gnb, logGnb, wg, bi);
    gUpdate(pc, taken, sh->bwHist, bwm, bwgehl, bwnb, logBwnb, wbw, bi);
    gUpdate(pc, taken, sh->getLocalHistory(1, pc), lm, lgehl, lnb, logLnb, wl,
            bi);
    gUpdate(pc, taken, sh->imliCount, im, igehl, inb, logInb, wi, bi);
}

TAGE_SC_L_8KB::TAGE_SC_L_8KB(const TAGE_SC_L_8KBParams &params)
  : TAGE_SC_L(params)
{
}

void
TAGE_SC_L_TAGE_8KB::initFoldedHistories(ThreadHistory & history)
{
    // Some hardcoded values are used here
    // (they do not seem to depend on any parameter)
    for (int i = 1; i <= nHistoryTables; i++) {
        history.computeIndices[i].init(
            histLengths[i], 17 + (2 * ((i - 1) / 2) % 4));
        history.computeTags[0][i].init(
            history.computeIndices[i].origLength, 13);
        history.computeTags[1][i].init(
            history.computeIndices[i].origLength, 11);
        DPRINTF(TageSCL, "HistLength:%d, TTSize:%d, TTTWidth:%d\n",
                histLengths[i], logTagTableSizes[i], tagTableTagWidths[i]);
    }
}

int
TAGE_SC_L_TAGE_8KB::gindex_ext(int index, int bank) const
{
    return (index ^ (index >> logTagTableSizes[bank])
                  ^ (index >> 2 * logTagTableSizes[bank]));
}

uint16_t
TAGE_SC_L_TAGE_8KB::gtag(ThreadID tid, Addr pc, int bank) const
{
    int tag = (threadHistory[tid].computeIndices[bank - 1].comp << 2) ^ pc ^
              (pc >> instShiftAmt) ^
              threadHistory[tid].computeIndices[bank].comp;
    int hlen = (histLengths[bank] > pathHistBits) ? pathHistBits :
                                                    histLengths[bank];

    tag = (tag >> 1) ^ ((tag & 1) << 10) ^
           F(threadHistory[tid].pathHist, hlen, bank);
    tag ^= threadHistory[tid].computeTags[0][bank].comp ^
           (threadHistory[tid].computeTags[1][bank].comp << 1);

    return ((tag ^ (tag >> tagTableTagWidths[bank]))
            & ((ULL(1) << tagTableTagWidths[bank]) - 1));
}

void
TAGE_SC_L_TAGE_8KB::handleAllocAndUReset(
    bool alloc, bool taken, TAGEBase::BranchInfo* bi, int nrand)
{
    if (!alloc) {
        return;
    }

    int penalty = 0;
    int truePen = 0;
    int numAllocated = 0;
    bool maxAllocReached = false;

    for (int I = calcDep(bi); I < nHistoryTables; I += 2) {
        // Handle the 2-way associativity for allocation
        for (int j = 0; j < 2; ++j) {
            int i = ((j == 0) ? I : (I ^ 1)) + 1;
            if (i > nHistoryTables) {
                break;
            }
            if (noSkip[i]) {
                if (gtable[i][bi->tableIndices[i]].u == 0) {
                    gtable[i][bi->tableIndices[i]].u =
                        ((random_mt.random<int>() & 31) == 0);
                    // protect randomly from fast replacement
                    gtable[i][bi->tableIndices[i]].tag = bi->tableTags[i];
                    gtable[i][bi->tableIndices[i]].ctr = taken ? 0 : -1;
                    numAllocated++;

                    if (numAllocated == maxNumAlloc) {
                        maxAllocReached = true;
                        break;
                    }
                    I += 2;
                } else {
                    int8_t ctr = gtable[i][bi->tableIndices[i]].ctr;
                    if ((gtable[i][bi->tableIndices[i]].u == 1) &
                        (abs (2 * ctr + 1) == 1)) {
                        if ((random_mt.random<int>() & 7) == 0) {
                            gtable[i][bi->tableIndices[i]].u = 0;
                        }
                    } else {
                        truePen++;
                    }
                    penalty++;
                }
            } else {
                break;
            }
        }
        if (maxAllocReached) {
            break;
        }
    }

    tCounter += (truePen + penalty - 5 * numAllocated);

    handleUReset();
}

void
TAGE_SC_L_TAGE_8KB::resetUctr(uint8_t & u)
{
    // On real HW it should be u >>= 1 instead of if > 0 then u--
    if (u > 0) {
        u--;
    }
}

void
TAGE_SC_L_TAGE_8KB::handleTAGEUpdate(Addr branch_pc, bool taken,
                                     TAGEBase::BranchInfo* bi)
{
    if (bi->hitBank > 0) {
        if (abs (2 * gtable[bi->hitBank][bi->hitBankIndex].ctr + 1) == 1) {
            if (bi->longestMatchPred != taken) { // acts as a protection
                if (bi->altBank > 0) {
                    int8_t ctr = gtable[bi->altBank][bi->altBankIndex].ctr;
                    if (abs (2 * ctr + 1) == 1) {
                        gtable[bi->altBank][bi->altBankIndex].u = 0;
                    }

                    //just mute from protected to unprotected
                    ctrUpdate(gtable[bi->altBank][bi->altBankIndex].ctr, taken,
                              tagTableCounterBits);
                    ctr = gtable[bi->altBank][bi->altBankIndex].ctr;
                    if (abs (2 * ctr + 1) == 1) {
                        gtable[bi->altBank][bi->altBankIndex].u = 0;
                    }
                }
                if (bi->altBank == 0) {
                    baseUpdate(branch_pc, taken, bi);
                }
            }
        }

        //just mute from protected to unprotected
        if (abs (2 * gtable[bi->hitBank][bi->hitBankIndex].ctr + 1) == 1) {
            gtable[bi->hitBank][bi->hitBankIndex].u = 0;
        }

        ctrUpdate(gtable[bi->hitBank][bi->hitBankIndex].ctr, taken,
                  tagTableCounterBits);

        //sign changes: no way it can have been useful
        if (abs (2 * gtable[bi->hitBank][bi->hitBankIndex].ctr + 1) == 1) {
            gtable[bi->hitBank][bi->hitBankIndex].u = 0;
        }

        if (bi->altTaken == taken) {
            if (bi->altBank > 0) {
                int8_t ctr = gtable[bi->altBank][bi->altBankIndex].ctr;
                if (abs (2*ctr + 1) == 7) {
                    if (gtable[bi->hitBank][bi->hitBankIndex].u == 1) {
                        if (bi->longestMatchPred == taken) {
                            gtable[bi->hitBank][bi->hitBankIndex].u = 0;
                        }
                    }
                }
            }
        }
    } else {
        baseUpdate(branch_pc, taken, bi);
    }

    if ((bi->longestMatchPred != bi->altTaken) &&
        (bi->longestMatchPred == taken) &&
        (gtable[bi->hitBank][bi->hitBankIndex].u < (1 << tagTableUBits) -1)) {
            gtable[bi->hitBank][bi->hitBankIndex].u++;
    }
}
