tage_sc_l.cc revision 14081
113685Sjavier.bueno@metempsy.com/* 213685Sjavier.bueno@metempsy.com * Copyright (c) 2018 Metempsy Technology Consulting 313685Sjavier.bueno@metempsy.com * All rights reserved. 413685Sjavier.bueno@metempsy.com * 513685Sjavier.bueno@metempsy.com * Copyright (c) 2006 INRIA (Institut National de Recherche en 613685Sjavier.bueno@metempsy.com * Informatique et en Automatique / French National Research Institute 713685Sjavier.bueno@metempsy.com * for Computer Science and Applied Mathematics) 813685Sjavier.bueno@metempsy.com * 913685Sjavier.bueno@metempsy.com * All rights reserved. 1013685Sjavier.bueno@metempsy.com * 1113685Sjavier.bueno@metempsy.com * Redistribution and use in source and binary forms, with or without 1213685Sjavier.bueno@metempsy.com * modification, are permitted provided that the following conditions are 1313685Sjavier.bueno@metempsy.com * met: redistributions of source code must retain the above copyright 1413685Sjavier.bueno@metempsy.com * notice, this list of conditions and the following disclaimer; 1513685Sjavier.bueno@metempsy.com * redistributions in binary form must reproduce the above copyright 1613685Sjavier.bueno@metempsy.com * notice, this list of conditions and the following disclaimer in the 1713685Sjavier.bueno@metempsy.com * documentation and/or other materials provided with the distribution; 1813685Sjavier.bueno@metempsy.com * neither the name of the copyright holders nor the names of its 1913685Sjavier.bueno@metempsy.com * contributors may be used to endorse or promote products derived from 2013685Sjavier.bueno@metempsy.com * this software without specific prior written permission. 2113685Sjavier.bueno@metempsy.com * 2213685Sjavier.bueno@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2313685Sjavier.bueno@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2413685Sjavier.bueno@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2513685Sjavier.bueno@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2613685Sjavier.bueno@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2713685Sjavier.bueno@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2813685Sjavier.bueno@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2913685Sjavier.bueno@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3013685Sjavier.bueno@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3113685Sjavier.bueno@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3213685Sjavier.bueno@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3313685Sjavier.bueno@metempsy.com * 3413685Sjavier.bueno@metempsy.com * Author: André Seznec, Pau Cabre, Javier Bueno 3513685Sjavier.bueno@metempsy.com * 3613685Sjavier.bueno@metempsy.com */ 3713685Sjavier.bueno@metempsy.com 3813685Sjavier.bueno@metempsy.com/* 3913685Sjavier.bueno@metempsy.com * TAGE-SC-L branch predictor base class (devised by Andre Seznec) 4013685Sjavier.bueno@metempsy.com * It consits of a TAGE + a statistical corrector (SC) + a loop predictor (L) 4113685Sjavier.bueno@metempsy.com */ 4213685Sjavier.bueno@metempsy.com 4313685Sjavier.bueno@metempsy.com#include "cpu/pred/tage_sc_l.hh" 4413685Sjavier.bueno@metempsy.com 4513685Sjavier.bueno@metempsy.com#include "base/random.hh" 4613685Sjavier.bueno@metempsy.com#include "debug/TageSCL.hh" 4713685Sjavier.bueno@metempsy.com 4813685Sjavier.bueno@metempsy.combool 4913685Sjavier.bueno@metempsy.comTAGE_SC_L_LoopPredictor::calcConf(int index) const 5013685Sjavier.bueno@metempsy.com{ 5113685Sjavier.bueno@metempsy.com return LoopPredictor::calcConf(index) || 5213685Sjavier.bueno@metempsy.com (ltable[index].confidence * ltable[index].numIter > 128); 5313685Sjavier.bueno@metempsy.com} 5413685Sjavier.bueno@metempsy.com 5513685Sjavier.bueno@metempsy.combool 5613685Sjavier.bueno@metempsy.comTAGE_SC_L_LoopPredictor::optionalAgeInc() const 5713685Sjavier.bueno@metempsy.com{ 5813685Sjavier.bueno@metempsy.com return (random_mt.random<int>() & 7) == 0; 5913685Sjavier.bueno@metempsy.com} 6013685Sjavier.bueno@metempsy.com 6113685Sjavier.bueno@metempsy.comTAGE_SC_L_LoopPredictor * 6213685Sjavier.bueno@metempsy.comTAGE_SC_L_LoopPredictorParams::create() 6313685Sjavier.bueno@metempsy.com{ 6413685Sjavier.bueno@metempsy.com return new TAGE_SC_L_LoopPredictor(this); 6513685Sjavier.bueno@metempsy.com} 6613685Sjavier.bueno@metempsy.com 6713685Sjavier.bueno@metempsy.comTAGE_SC_L::TAGE_SC_L(const TAGE_SC_LParams *p) 6813685Sjavier.bueno@metempsy.com : LTAGE(p), statisticalCorrector(p->statistical_corrector) 6913685Sjavier.bueno@metempsy.com{ 7013685Sjavier.bueno@metempsy.com} 7113685Sjavier.bueno@metempsy.com 7213685Sjavier.bueno@metempsy.comTAGEBase::BranchInfo* 7313685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::makeBranchInfo() 7413685Sjavier.bueno@metempsy.com{ 7513685Sjavier.bueno@metempsy.com return new BranchInfo(*this); 7613685Sjavier.bueno@metempsy.com} 7713685Sjavier.bueno@metempsy.comvoid 7813685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::calculateParameters() 7913685Sjavier.bueno@metempsy.com{ 8013685Sjavier.bueno@metempsy.com unsigned numHistLengths = nHistoryTables/2; 8113685Sjavier.bueno@metempsy.com histLengths[1] = minHist; 8213685Sjavier.bueno@metempsy.com histLengths[numHistLengths] = maxHist; 8313685Sjavier.bueno@metempsy.com 8413685Sjavier.bueno@metempsy.com // This calculates the different history lenghts 8513685Sjavier.bueno@metempsy.com // there are only numHistLengths different lengths 8613685Sjavier.bueno@metempsy.com // They are initially set to the lower half of histLengths 8713685Sjavier.bueno@metempsy.com for (int i = 2; i <= numHistLengths; i++) { 8813685Sjavier.bueno@metempsy.com histLengths[i] = (int) (((double) minHist * 8913685Sjavier.bueno@metempsy.com pow ((double) (maxHist) / (double) minHist, 9013685Sjavier.bueno@metempsy.com (double) (i - 1) / (double) ((numHistLengths - 1)))) 9113685Sjavier.bueno@metempsy.com + 0.5); 9213685Sjavier.bueno@metempsy.com } 9313685Sjavier.bueno@metempsy.com 9413685Sjavier.bueno@metempsy.com // This copies and duplicates the values from the lower half of the table 9513685Sjavier.bueno@metempsy.com // Ex: 4, 6, 9, 13 would get exanded to 4, 4, 6, 6, 9, 9, 13, 13 9613685Sjavier.bueno@metempsy.com for (int i = nHistoryTables; i > 1; i--) 9713685Sjavier.bueno@metempsy.com { 9813685Sjavier.bueno@metempsy.com histLengths[i] = histLengths[(i + 1) / 2]; 9913685Sjavier.bueno@metempsy.com } 10013685Sjavier.bueno@metempsy.com 10113685Sjavier.bueno@metempsy.com for (int i = 1; i <= nHistoryTables; i++) 10213685Sjavier.bueno@metempsy.com { 10313685Sjavier.bueno@metempsy.com tagTableTagWidths.push_back( 10413685Sjavier.bueno@metempsy.com (i < firstLongTagTable) ? shortTagsSize : longTagsSize); 10513685Sjavier.bueno@metempsy.com 10613685Sjavier.bueno@metempsy.com logTagTableSizes.push_back(logTagTableSize); 10713685Sjavier.bueno@metempsy.com } 10813685Sjavier.bueno@metempsy.com} 10913685Sjavier.bueno@metempsy.com 11013685Sjavier.bueno@metempsy.comvoid 11113685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::buildTageTables() 11213685Sjavier.bueno@metempsy.com{ 11313685Sjavier.bueno@metempsy.com // Trick! We only allocate entries for tables 1 and firstLongTagTable and 11413685Sjavier.bueno@metempsy.com // make the other tables point to these allocated entries 11513685Sjavier.bueno@metempsy.com 11613685Sjavier.bueno@metempsy.com gtable[1] = new TageEntry[shortTagsTageFactor * (1 << logTagTableSize)]; 11713685Sjavier.bueno@metempsy.com gtable[firstLongTagTable] = 11813685Sjavier.bueno@metempsy.com new TageEntry[longTagsTageFactor * (1 << logTagTableSize)]; 11913685Sjavier.bueno@metempsy.com for (int i = 2; i < firstLongTagTable; ++i) { 12013685Sjavier.bueno@metempsy.com gtable[i] = gtable[1]; 12113685Sjavier.bueno@metempsy.com } 12213685Sjavier.bueno@metempsy.com for (int i = firstLongTagTable + 1; i <= nHistoryTables; ++i) { 12313685Sjavier.bueno@metempsy.com gtable[i] = gtable[firstLongTagTable]; 12413685Sjavier.bueno@metempsy.com } 12513685Sjavier.bueno@metempsy.com} 12613685Sjavier.bueno@metempsy.com 12713685Sjavier.bueno@metempsy.comvoid 12813685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::calculateIndicesAndTags( 12913685Sjavier.bueno@metempsy.com ThreadID tid, Addr pc, TAGEBase::BranchInfo* bi) 13013685Sjavier.bueno@metempsy.com{ 13113685Sjavier.bueno@metempsy.com // computes the table addresses and the partial tags 13213685Sjavier.bueno@metempsy.com 13313685Sjavier.bueno@metempsy.com for (int i = 1; i <= nHistoryTables; i += 2) { 13413685Sjavier.bueno@metempsy.com tableIndices[i] = gindex(tid, pc, i); 13513685Sjavier.bueno@metempsy.com tableTags[i] = gtag(tid, pc, i); 13613685Sjavier.bueno@metempsy.com tableTags[i + 1] = tableTags[i]; 13713685Sjavier.bueno@metempsy.com tableIndices[i + 1] = tableIndices[i] ^ 13813685Sjavier.bueno@metempsy.com (tableTags[i] & ((1 << logTagTableSizes[i]) - 1)); 13913685Sjavier.bueno@metempsy.com 14013685Sjavier.bueno@metempsy.com bi->tableTags[i] = tableTags[i]; 14113685Sjavier.bueno@metempsy.com bi->tableTags[i+1] = tableTags[i+1]; 14213685Sjavier.bueno@metempsy.com } 14313685Sjavier.bueno@metempsy.com 14413685Sjavier.bueno@metempsy.com Addr t = (pc ^ (threadHistory[tid].pathHist & 14513685Sjavier.bueno@metempsy.com ((1 << histLengths[firstLongTagTable]) - 1))) 14613685Sjavier.bueno@metempsy.com % longTagsTageFactor; 14713685Sjavier.bueno@metempsy.com 14813685Sjavier.bueno@metempsy.com for (int i = firstLongTagTable; i <= nHistoryTables; i++) { 14913685Sjavier.bueno@metempsy.com if (noSkip[i]) { 15013685Sjavier.bueno@metempsy.com tableIndices[i] += (t << logTagTableSizes[i]); 15113685Sjavier.bueno@metempsy.com bi->tableIndices[i] = tableIndices[i]; 15213685Sjavier.bueno@metempsy.com t++; 15313685Sjavier.bueno@metempsy.com t = t % longTagsTageFactor; 15413685Sjavier.bueno@metempsy.com } 15513685Sjavier.bueno@metempsy.com } 15613685Sjavier.bueno@metempsy.com 15713685Sjavier.bueno@metempsy.com t = (pc ^ (threadHistory[tid].pathHist & ((1 << histLengths[1]) - 1))) 15813685Sjavier.bueno@metempsy.com % shortTagsTageFactor; 15913685Sjavier.bueno@metempsy.com 16013685Sjavier.bueno@metempsy.com for (int i = 1; i <= firstLongTagTable - 1; i++) { 16113685Sjavier.bueno@metempsy.com if (noSkip[i]) { 16213685Sjavier.bueno@metempsy.com tableIndices[i] += (t << logTagTableSizes[i]); 16313685Sjavier.bueno@metempsy.com bi->tableIndices[i] = tableIndices[i]; 16413685Sjavier.bueno@metempsy.com t++; 16513685Sjavier.bueno@metempsy.com t = t % shortTagsTageFactor; 16613685Sjavier.bueno@metempsy.com } 16713685Sjavier.bueno@metempsy.com } 16813685Sjavier.bueno@metempsy.com} 16913685Sjavier.bueno@metempsy.com 17013685Sjavier.bueno@metempsy.comunsigned 17114081Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::getUseAltIdx(TAGEBase::BranchInfo* bi, Addr branch_pc) 17213685Sjavier.bueno@metempsy.com{ 17313685Sjavier.bueno@metempsy.com BranchInfo *tbi = static_cast<BranchInfo *>(bi); 17413685Sjavier.bueno@metempsy.com unsigned idx; 17513685Sjavier.bueno@metempsy.com idx = ((((bi->hitBank-1)/8)<<1)+tbi->altConf) % (numUseAltOnNa-1); 17613685Sjavier.bueno@metempsy.com return idx; 17713685Sjavier.bueno@metempsy.com} 17813685Sjavier.bueno@metempsy.com 17913685Sjavier.bueno@metempsy.comint 18013685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::gindex(ThreadID tid, Addr pc, int bank) const 18113685Sjavier.bueno@metempsy.com{ 18213685Sjavier.bueno@metempsy.com int index; 18313685Sjavier.bueno@metempsy.com int hlen = (histLengths[bank] > pathHistBits) ? pathHistBits : 18413685Sjavier.bueno@metempsy.com histLengths[bank]; 18513685Sjavier.bueno@metempsy.com unsigned int shortPc = pc; 18613685Sjavier.bueno@metempsy.com 18713685Sjavier.bueno@metempsy.com // pc is not shifted by instShiftAmt in this implementation 18813685Sjavier.bueno@metempsy.com index = shortPc ^ 18913685Sjavier.bueno@metempsy.com (shortPc >> ((int) abs(logTagTableSizes[bank] - bank) + 1)) ^ 19013685Sjavier.bueno@metempsy.com threadHistory[tid].computeIndices[bank].comp ^ 19113685Sjavier.bueno@metempsy.com F(threadHistory[tid].pathHist, hlen, bank); 19213685Sjavier.bueno@metempsy.com 19313685Sjavier.bueno@metempsy.com index = gindex_ext(index, bank); 19413685Sjavier.bueno@metempsy.com 19513685Sjavier.bueno@metempsy.com return (index & ((ULL(1) << (logTagTableSizes[bank])) - 1)); 19613685Sjavier.bueno@metempsy.com} 19713685Sjavier.bueno@metempsy.com 19813685Sjavier.bueno@metempsy.comint 19913685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::F(int a, int size, int bank) const 20013685Sjavier.bueno@metempsy.com{ 20113685Sjavier.bueno@metempsy.com int a1, a2; 20213685Sjavier.bueno@metempsy.com 20313685Sjavier.bueno@metempsy.com a = a & ((ULL(1) << size) - 1); 20413685Sjavier.bueno@metempsy.com a1 = (a & ((ULL(1) << logTagTableSizes[bank]) - 1)); 20513685Sjavier.bueno@metempsy.com a2 = (a >> logTagTableSizes[bank]); 20613685Sjavier.bueno@metempsy.com 20713685Sjavier.bueno@metempsy.com if (bank < logTagTableSizes[bank]) { 20813685Sjavier.bueno@metempsy.com a2 = ((a2 << bank) & ((ULL(1) << logTagTableSizes[bank]) - 1)) 20913685Sjavier.bueno@metempsy.com + (a2 >> (logTagTableSizes[bank] - bank)); 21013685Sjavier.bueno@metempsy.com } 21113685Sjavier.bueno@metempsy.com 21213685Sjavier.bueno@metempsy.com a = a1 ^ a2; 21313685Sjavier.bueno@metempsy.com 21413685Sjavier.bueno@metempsy.com if (bank < logTagTableSizes[bank]) { 21513685Sjavier.bueno@metempsy.com a = ((a << bank) & ((ULL(1) << logTagTableSizes[bank]) - 1)) 21613685Sjavier.bueno@metempsy.com + (a >> (logTagTableSizes[bank] - bank)); 21713685Sjavier.bueno@metempsy.com } 21813685Sjavier.bueno@metempsy.com 21913685Sjavier.bueno@metempsy.com return a; 22013685Sjavier.bueno@metempsy.com} 22113685Sjavier.bueno@metempsy.com 22213685Sjavier.bueno@metempsy.comint 22313685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::bindex(Addr pc) const 22413685Sjavier.bueno@metempsy.com{ 22513685Sjavier.bueno@metempsy.com return ((pc ^ (pc >> instShiftAmt)) & 22613685Sjavier.bueno@metempsy.com ((ULL(1) << (logTagTableSizes[0])) - 1)); 22713685Sjavier.bueno@metempsy.com} 22813685Sjavier.bueno@metempsy.com 22913685Sjavier.bueno@metempsy.comvoid 23013685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::updatePathAndGlobalHistory( 23113685Sjavier.bueno@metempsy.com ThreadHistory& tHist, int brtype, bool taken, Addr branch_pc, Addr target) 23213685Sjavier.bueno@metempsy.com{ 23313685Sjavier.bueno@metempsy.com // TAGE update 23413685Sjavier.bueno@metempsy.com int tmp = ((branch_pc ^ (branch_pc >> instShiftAmt))) ^ taken; 23513685Sjavier.bueno@metempsy.com int path = branch_pc ^ (branch_pc >> instShiftAmt) 23613685Sjavier.bueno@metempsy.com ^ (branch_pc >> (instShiftAmt+2)); 23713685Sjavier.bueno@metempsy.com if ((brtype == 3) & taken) { 23813685Sjavier.bueno@metempsy.com tmp = (tmp ^ (target >> instShiftAmt)); 23913685Sjavier.bueno@metempsy.com path = path ^ (target >> instShiftAmt) ^ (target >> (instShiftAmt+2)); 24013685Sjavier.bueno@metempsy.com } 24113685Sjavier.bueno@metempsy.com 24213685Sjavier.bueno@metempsy.com // some branch types use 3 bits in global history, the others just 2 24313685Sjavier.bueno@metempsy.com int maxt = (brtype == 2) ? 3 : 2; 24413685Sjavier.bueno@metempsy.com 24513685Sjavier.bueno@metempsy.com for (int t = 0; t < maxt; t++) { 24613685Sjavier.bueno@metempsy.com bool dir = (tmp & 1); 24713685Sjavier.bueno@metempsy.com tmp >>= 1; 24813685Sjavier.bueno@metempsy.com int pathbit = (path & 127); 24913685Sjavier.bueno@metempsy.com path >>= 1; 25013685Sjavier.bueno@metempsy.com updateGHist(tHist.gHist, dir, tHist.globalHistory, tHist.ptGhist); 25113685Sjavier.bueno@metempsy.com tHist.pathHist = (tHist.pathHist << 1) ^ pathbit; 25213685Sjavier.bueno@metempsy.com if (truncatePathHist) { 25313685Sjavier.bueno@metempsy.com // The 8KB implementation does not do this truncation 25413685Sjavier.bueno@metempsy.com tHist.pathHist = (tHist.pathHist & ((ULL(1) << pathHistBits) - 1)); 25513685Sjavier.bueno@metempsy.com } 25613685Sjavier.bueno@metempsy.com for (int i = 1; i <= nHistoryTables; i++) { 25713685Sjavier.bueno@metempsy.com tHist.computeIndices[i].update(tHist.gHist); 25813685Sjavier.bueno@metempsy.com tHist.computeTags[0][i].update(tHist.gHist); 25913685Sjavier.bueno@metempsy.com tHist.computeTags[1][i].update(tHist.gHist); 26013685Sjavier.bueno@metempsy.com } 26113685Sjavier.bueno@metempsy.com } 26213685Sjavier.bueno@metempsy.com} 26313685Sjavier.bueno@metempsy.com 26413685Sjavier.bueno@metempsy.comvoid 26513685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::updateHistories( 26613685Sjavier.bueno@metempsy.com ThreadID tid, Addr branch_pc, bool taken, TAGEBase::BranchInfo* b, 26713685Sjavier.bueno@metempsy.com bool speculative, const StaticInstPtr &inst, Addr target) 26813685Sjavier.bueno@metempsy.com{ 26913685Sjavier.bueno@metempsy.com if (speculative != speculativeHistUpdate) { 27013685Sjavier.bueno@metempsy.com return; 27113685Sjavier.bueno@metempsy.com } 27213685Sjavier.bueno@metempsy.com // speculation is not implemented 27313685Sjavier.bueno@metempsy.com assert(! speculative); 27413685Sjavier.bueno@metempsy.com 27513685Sjavier.bueno@metempsy.com ThreadHistory& tHist = threadHistory[tid]; 27613685Sjavier.bueno@metempsy.com 27713685Sjavier.bueno@metempsy.com int brtype = inst->isDirectCtrl() ? 0 : 2; 27813685Sjavier.bueno@metempsy.com if (! inst->isUncondCtrl()) { 27913685Sjavier.bueno@metempsy.com ++brtype; 28013685Sjavier.bueno@metempsy.com } 28113685Sjavier.bueno@metempsy.com updatePathAndGlobalHistory(tHist, brtype, taken, branch_pc, target); 28213685Sjavier.bueno@metempsy.com 28313685Sjavier.bueno@metempsy.com DPRINTF(TageSCL, "Updating global histories with branch:%lx; taken?:%d, " 28413685Sjavier.bueno@metempsy.com "path Hist: %x; pointer:%d\n", branch_pc, taken, tHist.pathHist, 28513685Sjavier.bueno@metempsy.com tHist.ptGhist); 28613685Sjavier.bueno@metempsy.com} 28713685Sjavier.bueno@metempsy.com 28813685Sjavier.bueno@metempsy.comvoid 28913685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::squash(ThreadID tid, bool taken, TAGEBase::BranchInfo *bi, 29013685Sjavier.bueno@metempsy.com Addr target) 29113685Sjavier.bueno@metempsy.com{ 29213685Sjavier.bueno@metempsy.com fatal("Speculation is not implemented"); 29313685Sjavier.bueno@metempsy.com} 29413685Sjavier.bueno@metempsy.com 29513685Sjavier.bueno@metempsy.comvoid 29613685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::adjustAlloc(bool & alloc, bool taken, bool pred_taken) 29713685Sjavier.bueno@metempsy.com{ 29813685Sjavier.bueno@metempsy.com // Do not allocate too often if the prediction is ok 29913685Sjavier.bueno@metempsy.com if ((taken == pred_taken) && ((random_mt.random<int>() & 31) != 0)) { 30013685Sjavier.bueno@metempsy.com alloc = false; 30113685Sjavier.bueno@metempsy.com } 30213685Sjavier.bueno@metempsy.com} 30313685Sjavier.bueno@metempsy.com 30413685Sjavier.bueno@metempsy.comint 30513685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::calcDep(TAGEBase::BranchInfo* bi) 30613685Sjavier.bueno@metempsy.com{ 30713685Sjavier.bueno@metempsy.com int a = 1; 30813685Sjavier.bueno@metempsy.com if ((random_mt.random<int>() & 127) < 32) { 30913685Sjavier.bueno@metempsy.com a = 2; 31013685Sjavier.bueno@metempsy.com } 31113685Sjavier.bueno@metempsy.com return ((((bi->hitBank - 1 + 2 * a) & 0xffe)) ^ 31213685Sjavier.bueno@metempsy.com (random_mt.random<int>() & 1)); 31313685Sjavier.bueno@metempsy.com} 31413685Sjavier.bueno@metempsy.com 31513685Sjavier.bueno@metempsy.comvoid 31613685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::handleUReset() 31713685Sjavier.bueno@metempsy.com{ 31813685Sjavier.bueno@metempsy.com //just the best formula for the Championship: 31913685Sjavier.bueno@metempsy.com //In practice when one out of two entries are useful 32013685Sjavier.bueno@metempsy.com if (tCounter < 0) { 32113685Sjavier.bueno@metempsy.com tCounter = 0; 32213685Sjavier.bueno@metempsy.com } 32313685Sjavier.bueno@metempsy.com 32413685Sjavier.bueno@metempsy.com if (tCounter >= ((ULL(1) << logUResetPeriod))) { 32513685Sjavier.bueno@metempsy.com // Update the u bits for the short tags table 32613685Sjavier.bueno@metempsy.com for (int j = 0; j < (shortTagsTageFactor*(1<<logTagTableSize)); j++) { 32713685Sjavier.bueno@metempsy.com resetUctr(gtable[1][j].u); 32813685Sjavier.bueno@metempsy.com } 32913685Sjavier.bueno@metempsy.com 33013685Sjavier.bueno@metempsy.com // Update the u bits for the long tags table 33113685Sjavier.bueno@metempsy.com for (int j = 0; j < (longTagsTageFactor*(1<<logTagTableSize)); j++) { 33213685Sjavier.bueno@metempsy.com resetUctr(gtable[firstLongTagTable][j].u); 33313685Sjavier.bueno@metempsy.com } 33413685Sjavier.bueno@metempsy.com 33513685Sjavier.bueno@metempsy.com tCounter = 0; 33613685Sjavier.bueno@metempsy.com } 33713685Sjavier.bueno@metempsy.com} 33813685Sjavier.bueno@metempsy.com 33913685Sjavier.bueno@metempsy.combool 34013685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::getBimodePred(Addr pc, TAGEBase::BranchInfo* tage_bi) const 34113685Sjavier.bueno@metempsy.com{ 34213685Sjavier.bueno@metempsy.com TAGE_SC_L_TAGE::BranchInfo *bi = 34313685Sjavier.bueno@metempsy.com static_cast<TAGE_SC_L_TAGE::BranchInfo *>(tage_bi); 34413685Sjavier.bueno@metempsy.com 34513685Sjavier.bueno@metempsy.com int bim = (btablePrediction[bi->bimodalIndex] << 1) 34613685Sjavier.bueno@metempsy.com + btableHysteresis[bi->bimodalIndex >> logRatioBiModalHystEntries]; 34713685Sjavier.bueno@metempsy.com 34813685Sjavier.bueno@metempsy.com bi->highConf = (bim == 0) || (bim == 3); 34913685Sjavier.bueno@metempsy.com bi->lowConf = ! bi->highConf; 35013685Sjavier.bueno@metempsy.com bi->altConf = bi->highConf; 35113685Sjavier.bueno@metempsy.com bi->medConf = false; 35213685Sjavier.bueno@metempsy.com return TAGEBase::getBimodePred(pc, tage_bi); 35313685Sjavier.bueno@metempsy.com} 35413685Sjavier.bueno@metempsy.com 35513685Sjavier.bueno@metempsy.comvoid 35613685Sjavier.bueno@metempsy.comTAGE_SC_L_TAGE::extraAltCalc(TAGEBase::BranchInfo* bi) 35713685Sjavier.bueno@metempsy.com{ 35813685Sjavier.bueno@metempsy.com TAGE_SC_L_TAGE::BranchInfo *tage_scl_bi = 35913685Sjavier.bueno@metempsy.com static_cast<TAGE_SC_L_TAGE::BranchInfo *>(bi); 36013685Sjavier.bueno@metempsy.com int8_t ctr = gtable[bi->altBank][bi->altBankIndex].ctr; 36113685Sjavier.bueno@metempsy.com tage_scl_bi->altConf = (abs(2*ctr + 1) > 1); 36213685Sjavier.bueno@metempsy.com} 36313685Sjavier.bueno@metempsy.com 36413685Sjavier.bueno@metempsy.combool 36513685Sjavier.bueno@metempsy.comTAGE_SC_L::predict(ThreadID tid, Addr branch_pc, bool cond_branch, void* &b) 36613685Sjavier.bueno@metempsy.com{ 36713685Sjavier.bueno@metempsy.com TageSCLBranchInfo *bi = new TageSCLBranchInfo(*tage, 36813685Sjavier.bueno@metempsy.com *statisticalCorrector, 36913685Sjavier.bueno@metempsy.com *loopPredictor); 37013685Sjavier.bueno@metempsy.com b = (void*)(bi); 37113685Sjavier.bueno@metempsy.com 37213685Sjavier.bueno@metempsy.com bool pred_taken = tage->tagePredict(tid, branch_pc, cond_branch, 37313685Sjavier.bueno@metempsy.com bi->tageBranchInfo); 37413685Sjavier.bueno@metempsy.com pred_taken = loopPredictor->loopPredict(tid, branch_pc, cond_branch, 37513685Sjavier.bueno@metempsy.com bi->lpBranchInfo, pred_taken, 37613685Sjavier.bueno@metempsy.com instShiftAmt); 37713685Sjavier.bueno@metempsy.com 37813685Sjavier.bueno@metempsy.com if (bi->lpBranchInfo->loopPredUsed) { 37913685Sjavier.bueno@metempsy.com bi->tageBranchInfo->provider = LOOP; 38013685Sjavier.bueno@metempsy.com } 38113685Sjavier.bueno@metempsy.com 38213685Sjavier.bueno@metempsy.com TAGE_SC_L_TAGE::BranchInfo* tage_scl_bi = 38313685Sjavier.bueno@metempsy.com static_cast<TAGE_SC_L_TAGE::BranchInfo *>(bi->tageBranchInfo); 38413685Sjavier.bueno@metempsy.com 38513685Sjavier.bueno@metempsy.com // Copy the confidences computed by TAGE 38613685Sjavier.bueno@metempsy.com bi->scBranchInfo->lowConf = tage_scl_bi->lowConf; 38713685Sjavier.bueno@metempsy.com bi->scBranchInfo->highConf = tage_scl_bi->highConf; 38813685Sjavier.bueno@metempsy.com bi->scBranchInfo->altConf = tage_scl_bi->altConf; 38913685Sjavier.bueno@metempsy.com bi->scBranchInfo->medConf = tage_scl_bi->medConf; 39013685Sjavier.bueno@metempsy.com 39113685Sjavier.bueno@metempsy.com bool use_tage_ctr = bi->tageBranchInfo->hitBank > 0; 39213685Sjavier.bueno@metempsy.com int8_t tage_ctr = use_tage_ctr ? 39313685Sjavier.bueno@metempsy.com tage->getCtr(tage_scl_bi->hitBank, tage_scl_bi->hitBankIndex) : 0; 39413685Sjavier.bueno@metempsy.com bool bias = (bi->tageBranchInfo->longestMatchPred != 39513685Sjavier.bueno@metempsy.com bi->tageBranchInfo->altTaken); 39613685Sjavier.bueno@metempsy.com 39713685Sjavier.bueno@metempsy.com pred_taken = statisticalCorrector->scPredict(tid, branch_pc, cond_branch, 39813685Sjavier.bueno@metempsy.com bi->scBranchInfo, pred_taken, bias, use_tage_ctr, tage_ctr, 39913685Sjavier.bueno@metempsy.com tage->getTageCtrBits(), bi->tageBranchInfo->hitBank, 40013685Sjavier.bueno@metempsy.com bi->tageBranchInfo->altBank, tage->getPathHist(tid)); 40113685Sjavier.bueno@metempsy.com 40213685Sjavier.bueno@metempsy.com if (bi->scBranchInfo->usedScPred) { 40313685Sjavier.bueno@metempsy.com bi->tageBranchInfo->provider = SC; 40413685Sjavier.bueno@metempsy.com } 40513685Sjavier.bueno@metempsy.com 40613685Sjavier.bueno@metempsy.com // record final prediction 40713685Sjavier.bueno@metempsy.com bi->lpBranchInfo->predTaken = pred_taken; 40813685Sjavier.bueno@metempsy.com 40913685Sjavier.bueno@metempsy.com return pred_taken; 41013685Sjavier.bueno@metempsy.com} 41113685Sjavier.bueno@metempsy.com 41213685Sjavier.bueno@metempsy.comvoid 41313685Sjavier.bueno@metempsy.comTAGE_SC_L::update(ThreadID tid, Addr branch_pc, bool taken, void *bp_history, 41413685Sjavier.bueno@metempsy.com bool squashed, const StaticInstPtr & inst, Addr corrTarget) 41513685Sjavier.bueno@metempsy.com{ 41613685Sjavier.bueno@metempsy.com assert(bp_history); 41713685Sjavier.bueno@metempsy.com 41813685Sjavier.bueno@metempsy.com TageSCLBranchInfo* bi = static_cast<TageSCLBranchInfo*>(bp_history); 41913685Sjavier.bueno@metempsy.com TAGE_SC_L_TAGE::BranchInfo* tage_bi = 42013685Sjavier.bueno@metempsy.com static_cast<TAGE_SC_L_TAGE::BranchInfo *>(bi->tageBranchInfo); 42113685Sjavier.bueno@metempsy.com 42213685Sjavier.bueno@metempsy.com assert(corrTarget != MaxAddr); 42313685Sjavier.bueno@metempsy.com 42413685Sjavier.bueno@metempsy.com if (squashed) { 42513685Sjavier.bueno@metempsy.com if (tage->isSpeculativeUpdateEnabled()) { 42613685Sjavier.bueno@metempsy.com // This restores the global history, then update it 42713685Sjavier.bueno@metempsy.com // and recomputes the folded histories. 42813685Sjavier.bueno@metempsy.com tage->squash(tid, taken, tage_bi, corrTarget); 42913685Sjavier.bueno@metempsy.com if (bi->tageBranchInfo->condBranch) { 43013685Sjavier.bueno@metempsy.com loopPredictor->squashLoop(bi->lpBranchInfo); 43113685Sjavier.bueno@metempsy.com } 43213685Sjavier.bueno@metempsy.com } 43313685Sjavier.bueno@metempsy.com return; 43413685Sjavier.bueno@metempsy.com } 43513685Sjavier.bueno@metempsy.com 43613685Sjavier.bueno@metempsy.com int nrand = random_mt.random<int>() & 3; 43713685Sjavier.bueno@metempsy.com if (tage_bi->condBranch) { 43813685Sjavier.bueno@metempsy.com DPRINTF(TageSCL, "Updating tables for branch:%lx; taken?:%d\n", 43913685Sjavier.bueno@metempsy.com branch_pc, taken); 44013685Sjavier.bueno@metempsy.com tage->updateStats(taken, bi->tageBranchInfo); 44113685Sjavier.bueno@metempsy.com 44213685Sjavier.bueno@metempsy.com loopPredictor->updateStats(taken, bi->lpBranchInfo); 44313685Sjavier.bueno@metempsy.com 44413685Sjavier.bueno@metempsy.com statisticalCorrector->updateStats(taken, bi->scBranchInfo); 44513685Sjavier.bueno@metempsy.com 44613685Sjavier.bueno@metempsy.com bool bias = (bi->tageBranchInfo->longestMatchPred != 44713685Sjavier.bueno@metempsy.com bi->tageBranchInfo->altTaken); 44813685Sjavier.bueno@metempsy.com statisticalCorrector->condBranchUpdate(tid, branch_pc, taken, 44913685Sjavier.bueno@metempsy.com bi->scBranchInfo, corrTarget, bias, bi->tageBranchInfo->hitBank, 45013685Sjavier.bueno@metempsy.com bi->tageBranchInfo->altBank, tage->getPathHist(tid)); 45113685Sjavier.bueno@metempsy.com 45213685Sjavier.bueno@metempsy.com loopPredictor->condBranchUpdate(tid, branch_pc, taken, 45313685Sjavier.bueno@metempsy.com bi->tageBranchInfo->tagePred, bi->lpBranchInfo, instShiftAmt); 45413685Sjavier.bueno@metempsy.com 45513685Sjavier.bueno@metempsy.com tage->condBranchUpdate(tid, branch_pc, taken, bi->tageBranchInfo, 45613685Sjavier.bueno@metempsy.com nrand, corrTarget, bi->lpBranchInfo->predTaken); 45713685Sjavier.bueno@metempsy.com } 45813685Sjavier.bueno@metempsy.com 45913685Sjavier.bueno@metempsy.com if (!tage->isSpeculativeUpdateEnabled()) { 46014081Sjavier.bueno@metempsy.com statisticalCorrector->scHistoryUpdate(branch_pc, inst, taken, 46113685Sjavier.bueno@metempsy.com bi->scBranchInfo, corrTarget); 46213685Sjavier.bueno@metempsy.com 46313685Sjavier.bueno@metempsy.com tage->updateHistories(tid, branch_pc, taken, bi->tageBranchInfo, false, 46413685Sjavier.bueno@metempsy.com inst, corrTarget); 46513685Sjavier.bueno@metempsy.com } 46613685Sjavier.bueno@metempsy.com 46713685Sjavier.bueno@metempsy.com delete bi; 46813685Sjavier.bueno@metempsy.com} 46913685Sjavier.bueno@metempsy.com 47013685Sjavier.bueno@metempsy.comvoid 47113685Sjavier.bueno@metempsy.comTAGE_SC_L::regStats() 47213685Sjavier.bueno@metempsy.com{ 47313685Sjavier.bueno@metempsy.com LTAGE::regStats(); 47413685Sjavier.bueno@metempsy.com} 475