tage_base.cc revision 13626
113626Sjairo.balart@metempsy.com/* 213626Sjairo.balart@metempsy.com * Copyright (c) 2014 The University of Wisconsin 313626Sjairo.balart@metempsy.com * 413626Sjairo.balart@metempsy.com * Copyright (c) 2006 INRIA (Institut National de Recherche en 513626Sjairo.balart@metempsy.com * Informatique et en Automatique / French National Research Institute 613626Sjairo.balart@metempsy.com * for Computer Science and Applied Mathematics) 713626Sjairo.balart@metempsy.com * 813626Sjairo.balart@metempsy.com * All rights reserved. 913626Sjairo.balart@metempsy.com * 1013626Sjairo.balart@metempsy.com * Redistribution and use in source and binary forms, with or without 1113626Sjairo.balart@metempsy.com * modification, are permitted provided that the following conditions are 1213626Sjairo.balart@metempsy.com * met: redistributions of source code must retain the above copyright 1313626Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer; 1413626Sjairo.balart@metempsy.com * redistributions in binary form must reproduce the above copyright 1513626Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer in the 1613626Sjairo.balart@metempsy.com * documentation and/or other materials provided with the distribution; 1713626Sjairo.balart@metempsy.com * neither the name of the copyright holders nor the names of its 1813626Sjairo.balart@metempsy.com * contributors may be used to endorse or promote products derived from 1913626Sjairo.balart@metempsy.com * this software without specific prior written permission. 2013626Sjairo.balart@metempsy.com * 2113626Sjairo.balart@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2213626Sjairo.balart@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2313626Sjairo.balart@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2413626Sjairo.balart@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2513626Sjairo.balart@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2613626Sjairo.balart@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2713626Sjairo.balart@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2813626Sjairo.balart@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2913626Sjairo.balart@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3013626Sjairo.balart@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3113626Sjairo.balart@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3213626Sjairo.balart@metempsy.com * 3313626Sjairo.balart@metempsy.com * Authors: Vignyan Reddy, Dibakar Gope and Arthur Perais, 3413626Sjairo.balart@metempsy.com * from André Seznec's code. 3513626Sjairo.balart@metempsy.com */ 3613626Sjairo.balart@metempsy.com 3713626Sjairo.balart@metempsy.com/* @file 3813626Sjairo.balart@metempsy.com * Implementation of a TAGE branch predictor 3913626Sjairo.balart@metempsy.com */ 4013626Sjairo.balart@metempsy.com 4113626Sjairo.balart@metempsy.com#include "cpu/pred/tage_base.hh" 4213626Sjairo.balart@metempsy.com 4313626Sjairo.balart@metempsy.com#include "base/intmath.hh" 4413626Sjairo.balart@metempsy.com#include "base/logging.hh" 4513626Sjairo.balart@metempsy.com#include "base/random.hh" 4613626Sjairo.balart@metempsy.com#include "debug/Fetch.hh" 4713626Sjairo.balart@metempsy.com#include "debug/Tage.hh" 4813626Sjairo.balart@metempsy.com 4913626Sjairo.balart@metempsy.comTAGEBase::TAGEBase(const TAGEBaseParams *p) 5013626Sjairo.balart@metempsy.com : SimObject(p), 5113626Sjairo.balart@metempsy.com logRatioBiModalHystEntries(p->logRatioBiModalHystEntries), 5213626Sjairo.balart@metempsy.com nHistoryTables(p->nHistoryTables), 5313626Sjairo.balart@metempsy.com tagTableCounterBits(p->tagTableCounterBits), 5413626Sjairo.balart@metempsy.com tagTableUBits(p->tagTableUBits), 5513626Sjairo.balart@metempsy.com histBufferSize(p->histBufferSize), 5613626Sjairo.balart@metempsy.com minHist(p->minHist), 5713626Sjairo.balart@metempsy.com maxHist(p->maxHist), 5813626Sjairo.balart@metempsy.com pathHistBits(p->pathHistBits), 5913626Sjairo.balart@metempsy.com tagTableTagWidths(p->tagTableTagWidths), 6013626Sjairo.balart@metempsy.com logTagTableSizes(p->logTagTableSizes), 6113626Sjairo.balart@metempsy.com threadHistory(p->numThreads), 6213626Sjairo.balart@metempsy.com logUResetPeriod(p->logUResetPeriod), 6313626Sjairo.balart@metempsy.com numUseAltOnNa(p->numUseAltOnNa), 6413626Sjairo.balart@metempsy.com useAltOnNaBits(p->useAltOnNaBits), 6513626Sjairo.balart@metempsy.com maxNumAlloc(p->maxNumAlloc), 6613626Sjairo.balart@metempsy.com noSkip(p->noSkip), 6713626Sjairo.balart@metempsy.com speculativeHistUpdate(p->speculativeHistUpdate), 6813626Sjairo.balart@metempsy.com instShiftAmt(p->instShiftAmt) 6913626Sjairo.balart@metempsy.com{ 7013626Sjairo.balart@metempsy.com if (noSkip.empty()) { 7113626Sjairo.balart@metempsy.com // Set all the table to enabled by default 7213626Sjairo.balart@metempsy.com noSkip.resize(nHistoryTables + 1, true); 7313626Sjairo.balart@metempsy.com } 7413626Sjairo.balart@metempsy.com} 7513626Sjairo.balart@metempsy.com 7613626Sjairo.balart@metempsy.comTAGEBase::BranchInfo* 7713626Sjairo.balart@metempsy.comTAGEBase::makeBranchInfo() { 7813626Sjairo.balart@metempsy.com return new BranchInfo(*this); 7913626Sjairo.balart@metempsy.com} 8013626Sjairo.balart@metempsy.com 8113626Sjairo.balart@metempsy.comvoid 8213626Sjairo.balart@metempsy.comTAGEBase::init() 8313626Sjairo.balart@metempsy.com{ 8413626Sjairo.balart@metempsy.com // Current method for periodically resetting the u counter bits only 8513626Sjairo.balart@metempsy.com // works for 1 or 2 bits 8613626Sjairo.balart@metempsy.com // Also make sure that it is not 0 8713626Sjairo.balart@metempsy.com assert(tagTableUBits <= 2 && (tagTableUBits > 0)); 8813626Sjairo.balart@metempsy.com 8913626Sjairo.balart@metempsy.com // we use int type for the path history, so it cannot be more than 9013626Sjairo.balart@metempsy.com // its size 9113626Sjairo.balart@metempsy.com assert(pathHistBits <= (sizeof(int)*8)); 9213626Sjairo.balart@metempsy.com 9313626Sjairo.balart@metempsy.com // initialize the counter to half of the period 9413626Sjairo.balart@metempsy.com assert(logUResetPeriod != 0); 9513626Sjairo.balart@metempsy.com tCounter = ULL(1) << (logUResetPeriod - 1); 9613626Sjairo.balart@metempsy.com 9713626Sjairo.balart@metempsy.com assert(histBufferSize > maxHist * 2); 9813626Sjairo.balart@metempsy.com 9913626Sjairo.balart@metempsy.com useAltPredForNewlyAllocated.resize(numUseAltOnNa, 0); 10013626Sjairo.balart@metempsy.com 10113626Sjairo.balart@metempsy.com for (auto& history : threadHistory) { 10213626Sjairo.balart@metempsy.com history.pathHist = 0; 10313626Sjairo.balart@metempsy.com history.globalHistory = new uint8_t[histBufferSize]; 10413626Sjairo.balart@metempsy.com history.gHist = history.globalHistory; 10513626Sjairo.balart@metempsy.com memset(history.gHist, 0, histBufferSize); 10613626Sjairo.balart@metempsy.com history.ptGhist = 0; 10713626Sjairo.balart@metempsy.com } 10813626Sjairo.balart@metempsy.com 10913626Sjairo.balart@metempsy.com histLengths = new int [nHistoryTables+1]; 11013626Sjairo.balart@metempsy.com 11113626Sjairo.balart@metempsy.com calculateParameters(); 11213626Sjairo.balart@metempsy.com 11313626Sjairo.balart@metempsy.com assert(tagTableTagWidths.size() == (nHistoryTables+1)); 11413626Sjairo.balart@metempsy.com assert(logTagTableSizes.size() == (nHistoryTables+1)); 11513626Sjairo.balart@metempsy.com 11613626Sjairo.balart@metempsy.com // First entry is for the Bimodal table and it is untagged in this 11713626Sjairo.balart@metempsy.com // implementation 11813626Sjairo.balart@metempsy.com assert(tagTableTagWidths[0] == 0); 11913626Sjairo.balart@metempsy.com 12013626Sjairo.balart@metempsy.com for (auto& history : threadHistory) { 12113626Sjairo.balart@metempsy.com history.computeIndices = new FoldedHistory[nHistoryTables+1]; 12213626Sjairo.balart@metempsy.com history.computeTags[0] = new FoldedHistory[nHistoryTables+1]; 12313626Sjairo.balart@metempsy.com history.computeTags[1] = new FoldedHistory[nHistoryTables+1]; 12413626Sjairo.balart@metempsy.com 12513626Sjairo.balart@metempsy.com initFoldedHistories(history); 12613626Sjairo.balart@metempsy.com } 12713626Sjairo.balart@metempsy.com 12813626Sjairo.balart@metempsy.com const uint64_t bimodalTableSize = ULL(1) << logTagTableSizes[0]; 12913626Sjairo.balart@metempsy.com btablePrediction.resize(bimodalTableSize, false); 13013626Sjairo.balart@metempsy.com btableHysteresis.resize(bimodalTableSize >> logRatioBiModalHystEntries, 13113626Sjairo.balart@metempsy.com true); 13213626Sjairo.balart@metempsy.com 13313626Sjairo.balart@metempsy.com gtable = new TageEntry*[nHistoryTables + 1]; 13413626Sjairo.balart@metempsy.com buildTageTables(); 13513626Sjairo.balart@metempsy.com 13613626Sjairo.balart@metempsy.com tableIndices = new int [nHistoryTables+1]; 13713626Sjairo.balart@metempsy.com tableTags = new int [nHistoryTables+1]; 13813626Sjairo.balart@metempsy.com} 13913626Sjairo.balart@metempsy.com 14013626Sjairo.balart@metempsy.comvoid 14113626Sjairo.balart@metempsy.comTAGEBase::initFoldedHistories(ThreadHistory & history) 14213626Sjairo.balart@metempsy.com{ 14313626Sjairo.balart@metempsy.com for (int i = 1; i <= nHistoryTables; i++) { 14413626Sjairo.balart@metempsy.com history.computeIndices[i].init( 14513626Sjairo.balart@metempsy.com histLengths[i], (logTagTableSizes[i])); 14613626Sjairo.balart@metempsy.com history.computeTags[0][i].init( 14713626Sjairo.balart@metempsy.com history.computeIndices[i].origLength, tagTableTagWidths[i]); 14813626Sjairo.balart@metempsy.com history.computeTags[1][i].init( 14913626Sjairo.balart@metempsy.com history.computeIndices[i].origLength, tagTableTagWidths[i]-1); 15013626Sjairo.balart@metempsy.com DPRINTF(Tage, "HistLength:%d, TTSize:%d, TTTWidth:%d\n", 15113626Sjairo.balart@metempsy.com histLengths[i], logTagTableSizes[i], tagTableTagWidths[i]); 15213626Sjairo.balart@metempsy.com } 15313626Sjairo.balart@metempsy.com} 15413626Sjairo.balart@metempsy.com 15513626Sjairo.balart@metempsy.comvoid 15613626Sjairo.balart@metempsy.comTAGEBase::buildTageTables() 15713626Sjairo.balart@metempsy.com{ 15813626Sjairo.balart@metempsy.com for (int i = 1; i <= nHistoryTables; i++) { 15913626Sjairo.balart@metempsy.com gtable[i] = new TageEntry[1<<(logTagTableSizes[i])]; 16013626Sjairo.balart@metempsy.com } 16113626Sjairo.balart@metempsy.com} 16213626Sjairo.balart@metempsy.com 16313626Sjairo.balart@metempsy.comvoid 16413626Sjairo.balart@metempsy.comTAGEBase::calculateParameters() 16513626Sjairo.balart@metempsy.com{ 16613626Sjairo.balart@metempsy.com histLengths[1] = minHist; 16713626Sjairo.balart@metempsy.com histLengths[nHistoryTables] = maxHist; 16813626Sjairo.balart@metempsy.com 16913626Sjairo.balart@metempsy.com for (int i = 2; i <= nHistoryTables; i++) { 17013626Sjairo.balart@metempsy.com histLengths[i] = (int) (((double) minHist * 17113626Sjairo.balart@metempsy.com pow ((double) (maxHist) / (double) minHist, 17213626Sjairo.balart@metempsy.com (double) (i - 1) / (double) ((nHistoryTables- 1)))) 17313626Sjairo.balart@metempsy.com + 0.5); 17413626Sjairo.balart@metempsy.com } 17513626Sjairo.balart@metempsy.com} 17613626Sjairo.balart@metempsy.com 17713626Sjairo.balart@metempsy.comvoid 17813626Sjairo.balart@metempsy.comTAGEBase::btbUpdate(ThreadID tid, Addr branch_pc, BranchInfo* &bi) 17913626Sjairo.balart@metempsy.com{ 18013626Sjairo.balart@metempsy.com if (speculativeHistUpdate) { 18113626Sjairo.balart@metempsy.com ThreadHistory& tHist = threadHistory[tid]; 18213626Sjairo.balart@metempsy.com DPRINTF(Tage, "BTB miss resets prediction: %lx\n", branch_pc); 18313626Sjairo.balart@metempsy.com assert(tHist.gHist == &tHist.globalHistory[tHist.ptGhist]); 18413626Sjairo.balart@metempsy.com tHist.gHist[0] = 0; 18513626Sjairo.balart@metempsy.com for (int i = 1; i <= nHistoryTables; i++) { 18613626Sjairo.balart@metempsy.com tHist.computeIndices[i].comp = bi->ci[i]; 18713626Sjairo.balart@metempsy.com tHist.computeTags[0][i].comp = bi->ct0[i]; 18813626Sjairo.balart@metempsy.com tHist.computeTags[1][i].comp = bi->ct1[i]; 18913626Sjairo.balart@metempsy.com tHist.computeIndices[i].update(tHist.gHist); 19013626Sjairo.balart@metempsy.com tHist.computeTags[0][i].update(tHist.gHist); 19113626Sjairo.balart@metempsy.com tHist.computeTags[1][i].update(tHist.gHist); 19213626Sjairo.balart@metempsy.com } 19313626Sjairo.balart@metempsy.com } 19413626Sjairo.balart@metempsy.com} 19513626Sjairo.balart@metempsy.com 19613626Sjairo.balart@metempsy.comint 19713626Sjairo.balart@metempsy.comTAGEBase::bindex(Addr pc_in) const 19813626Sjairo.balart@metempsy.com{ 19913626Sjairo.balart@metempsy.com return ((pc_in >> instShiftAmt) & ((ULL(1) << (logTagTableSizes[0])) - 1)); 20013626Sjairo.balart@metempsy.com} 20113626Sjairo.balart@metempsy.com 20213626Sjairo.balart@metempsy.comint 20313626Sjairo.balart@metempsy.comTAGEBase::F(int A, int size, int bank) const 20413626Sjairo.balart@metempsy.com{ 20513626Sjairo.balart@metempsy.com int A1, A2; 20613626Sjairo.balart@metempsy.com 20713626Sjairo.balart@metempsy.com A = A & ((ULL(1) << size) - 1); 20813626Sjairo.balart@metempsy.com A1 = (A & ((ULL(1) << logTagTableSizes[bank]) - 1)); 20913626Sjairo.balart@metempsy.com A2 = (A >> logTagTableSizes[bank]); 21013626Sjairo.balart@metempsy.com A2 = ((A2 << bank) & ((ULL(1) << logTagTableSizes[bank]) - 1)) 21113626Sjairo.balart@metempsy.com + (A2 >> (logTagTableSizes[bank] - bank)); 21213626Sjairo.balart@metempsy.com A = A1 ^ A2; 21313626Sjairo.balart@metempsy.com A = ((A << bank) & ((ULL(1) << logTagTableSizes[bank]) - 1)) 21413626Sjairo.balart@metempsy.com + (A >> (logTagTableSizes[bank] - bank)); 21513626Sjairo.balart@metempsy.com return (A); 21613626Sjairo.balart@metempsy.com} 21713626Sjairo.balart@metempsy.com 21813626Sjairo.balart@metempsy.com// gindex computes a full hash of pc, ghist and pathHist 21913626Sjairo.balart@metempsy.comint 22013626Sjairo.balart@metempsy.comTAGEBase::gindex(ThreadID tid, Addr pc, int bank) const 22113626Sjairo.balart@metempsy.com{ 22213626Sjairo.balart@metempsy.com int index; 22313626Sjairo.balart@metempsy.com int hlen = (histLengths[bank] > pathHistBits) ? pathHistBits : 22413626Sjairo.balart@metempsy.com histLengths[bank]; 22513626Sjairo.balart@metempsy.com const unsigned int shiftedPc = pc >> instShiftAmt; 22613626Sjairo.balart@metempsy.com index = 22713626Sjairo.balart@metempsy.com shiftedPc ^ 22813626Sjairo.balart@metempsy.com (shiftedPc >> ((int) abs(logTagTableSizes[bank] - bank) + 1)) ^ 22913626Sjairo.balart@metempsy.com threadHistory[tid].computeIndices[bank].comp ^ 23013626Sjairo.balart@metempsy.com F(threadHistory[tid].pathHist, hlen, bank); 23113626Sjairo.balart@metempsy.com 23213626Sjairo.balart@metempsy.com return (index & ((ULL(1) << (logTagTableSizes[bank])) - 1)); 23313626Sjairo.balart@metempsy.com} 23413626Sjairo.balart@metempsy.com 23513626Sjairo.balart@metempsy.com 23613626Sjairo.balart@metempsy.com// Tag computation 23713626Sjairo.balart@metempsy.comuint16_t 23813626Sjairo.balart@metempsy.comTAGEBase::gtag(ThreadID tid, Addr pc, int bank) const 23913626Sjairo.balart@metempsy.com{ 24013626Sjairo.balart@metempsy.com int tag = (pc >> instShiftAmt) ^ 24113626Sjairo.balart@metempsy.com threadHistory[tid].computeTags[0][bank].comp ^ 24213626Sjairo.balart@metempsy.com (threadHistory[tid].computeTags[1][bank].comp << 1); 24313626Sjairo.balart@metempsy.com 24413626Sjairo.balart@metempsy.com return (tag & ((ULL(1) << tagTableTagWidths[bank]) - 1)); 24513626Sjairo.balart@metempsy.com} 24613626Sjairo.balart@metempsy.com 24713626Sjairo.balart@metempsy.com 24813626Sjairo.balart@metempsy.com// Up-down saturating counter 24913626Sjairo.balart@metempsy.comtemplate<typename T> 25013626Sjairo.balart@metempsy.comvoid 25113626Sjairo.balart@metempsy.comTAGEBase::ctrUpdate(T & ctr, bool taken, int nbits) 25213626Sjairo.balart@metempsy.com{ 25313626Sjairo.balart@metempsy.com assert(nbits <= sizeof(T) << 3); 25413626Sjairo.balart@metempsy.com if (taken) { 25513626Sjairo.balart@metempsy.com if (ctr < ((1 << (nbits - 1)) - 1)) 25613626Sjairo.balart@metempsy.com ctr++; 25713626Sjairo.balart@metempsy.com } else { 25813626Sjairo.balart@metempsy.com if (ctr > -(1 << (nbits - 1))) 25913626Sjairo.balart@metempsy.com ctr--; 26013626Sjairo.balart@metempsy.com } 26113626Sjairo.balart@metempsy.com} 26213626Sjairo.balart@metempsy.com 26313626Sjairo.balart@metempsy.com// int8_t and int versions of this function may be needed 26413626Sjairo.balart@metempsy.comtemplate void TAGEBase::ctrUpdate(int8_t & ctr, bool taken, int nbits); 26513626Sjairo.balart@metempsy.comtemplate void TAGEBase::ctrUpdate(int & ctr, bool taken, int nbits); 26613626Sjairo.balart@metempsy.com 26713626Sjairo.balart@metempsy.com// Up-down unsigned saturating counter 26813626Sjairo.balart@metempsy.comvoid 26913626Sjairo.balart@metempsy.comTAGEBase::unsignedCtrUpdate(uint8_t & ctr, bool up, unsigned nbits) 27013626Sjairo.balart@metempsy.com{ 27113626Sjairo.balart@metempsy.com assert(nbits <= sizeof(uint8_t) << 3); 27213626Sjairo.balart@metempsy.com if (up) { 27313626Sjairo.balart@metempsy.com if (ctr < ((1 << nbits) - 1)) 27413626Sjairo.balart@metempsy.com ctr++; 27513626Sjairo.balart@metempsy.com } else { 27613626Sjairo.balart@metempsy.com if (ctr) 27713626Sjairo.balart@metempsy.com ctr--; 27813626Sjairo.balart@metempsy.com } 27913626Sjairo.balart@metempsy.com} 28013626Sjairo.balart@metempsy.com 28113626Sjairo.balart@metempsy.com// Bimodal prediction 28213626Sjairo.balart@metempsy.combool 28313626Sjairo.balart@metempsy.comTAGEBase::getBimodePred(Addr pc, BranchInfo* bi) const 28413626Sjairo.balart@metempsy.com{ 28513626Sjairo.balart@metempsy.com return btablePrediction[bi->bimodalIndex]; 28613626Sjairo.balart@metempsy.com} 28713626Sjairo.balart@metempsy.com 28813626Sjairo.balart@metempsy.com 28913626Sjairo.balart@metempsy.com// Update the bimodal predictor: a hysteresis bit is shared among N prediction 29013626Sjairo.balart@metempsy.com// bits (N = 2 ^ logRatioBiModalHystEntries) 29113626Sjairo.balart@metempsy.comvoid 29213626Sjairo.balart@metempsy.comTAGEBase::baseUpdate(Addr pc, bool taken, BranchInfo* bi) 29313626Sjairo.balart@metempsy.com{ 29413626Sjairo.balart@metempsy.com int inter = (btablePrediction[bi->bimodalIndex] << 1) 29513626Sjairo.balart@metempsy.com + btableHysteresis[bi->bimodalIndex >> logRatioBiModalHystEntries]; 29613626Sjairo.balart@metempsy.com if (taken) { 29713626Sjairo.balart@metempsy.com if (inter < 3) 29813626Sjairo.balart@metempsy.com inter++; 29913626Sjairo.balart@metempsy.com } else if (inter > 0) { 30013626Sjairo.balart@metempsy.com inter--; 30113626Sjairo.balart@metempsy.com } 30213626Sjairo.balart@metempsy.com const bool pred = inter >> 1; 30313626Sjairo.balart@metempsy.com const bool hyst = inter & 1; 30413626Sjairo.balart@metempsy.com btablePrediction[bi->bimodalIndex] = pred; 30513626Sjairo.balart@metempsy.com btableHysteresis[bi->bimodalIndex >> logRatioBiModalHystEntries] = hyst; 30613626Sjairo.balart@metempsy.com DPRINTF(Tage, "Updating branch %lx, pred:%d, hyst:%d\n", pc, pred, hyst); 30713626Sjairo.balart@metempsy.com} 30813626Sjairo.balart@metempsy.com 30913626Sjairo.balart@metempsy.com// shifting the global history: we manage the history in a big table in order 31013626Sjairo.balart@metempsy.com// to reduce simulation time 31113626Sjairo.balart@metempsy.comvoid 31213626Sjairo.balart@metempsy.comTAGEBase::updateGHist(uint8_t * &h, bool dir, uint8_t * tab, int &pt) 31313626Sjairo.balart@metempsy.com{ 31413626Sjairo.balart@metempsy.com if (pt == 0) { 31513626Sjairo.balart@metempsy.com DPRINTF(Tage, "Rolling over the histories\n"); 31613626Sjairo.balart@metempsy.com // Copy beginning of globalHistoryBuffer to end, such that 31713626Sjairo.balart@metempsy.com // the last maxHist outcomes are still reachable 31813626Sjairo.balart@metempsy.com // through pt[0 .. maxHist - 1]. 31913626Sjairo.balart@metempsy.com for (int i = 0; i < maxHist; i++) 32013626Sjairo.balart@metempsy.com tab[histBufferSize - maxHist + i] = tab[i]; 32113626Sjairo.balart@metempsy.com pt = histBufferSize - maxHist; 32213626Sjairo.balart@metempsy.com h = &tab[pt]; 32313626Sjairo.balart@metempsy.com } 32413626Sjairo.balart@metempsy.com pt--; 32513626Sjairo.balart@metempsy.com h--; 32613626Sjairo.balart@metempsy.com h[0] = (dir) ? 1 : 0; 32713626Sjairo.balart@metempsy.com} 32813626Sjairo.balart@metempsy.com 32913626Sjairo.balart@metempsy.comvoid 33013626Sjairo.balart@metempsy.comTAGEBase::calculateIndicesAndTags(ThreadID tid, Addr branch_pc, 33113626Sjairo.balart@metempsy.com BranchInfo* bi) 33213626Sjairo.balart@metempsy.com{ 33313626Sjairo.balart@metempsy.com // computes the table addresses and the partial tags 33413626Sjairo.balart@metempsy.com for (int i = 1; i <= nHistoryTables; i++) { 33513626Sjairo.balart@metempsy.com tableIndices[i] = gindex(tid, branch_pc, i); 33613626Sjairo.balart@metempsy.com bi->tableIndices[i] = tableIndices[i]; 33713626Sjairo.balart@metempsy.com tableTags[i] = gtag(tid, branch_pc, i); 33813626Sjairo.balart@metempsy.com bi->tableTags[i] = tableTags[i]; 33913626Sjairo.balart@metempsy.com } 34013626Sjairo.balart@metempsy.com} 34113626Sjairo.balart@metempsy.com 34213626Sjairo.balart@metempsy.comunsigned 34313626Sjairo.balart@metempsy.comTAGEBase::getUseAltIdx(BranchInfo* bi) 34413626Sjairo.balart@metempsy.com{ 34513626Sjairo.balart@metempsy.com // There is only 1 counter on the base TAGE implementation 34613626Sjairo.balart@metempsy.com return 0; 34713626Sjairo.balart@metempsy.com} 34813626Sjairo.balart@metempsy.com 34913626Sjairo.balart@metempsy.combool 35013626Sjairo.balart@metempsy.comTAGEBase::tagePredict(ThreadID tid, Addr branch_pc, 35113626Sjairo.balart@metempsy.com bool cond_branch, BranchInfo* bi) 35213626Sjairo.balart@metempsy.com{ 35313626Sjairo.balart@metempsy.com Addr pc = branch_pc; 35413626Sjairo.balart@metempsy.com bool pred_taken = true; 35513626Sjairo.balart@metempsy.com 35613626Sjairo.balart@metempsy.com if (cond_branch) { 35713626Sjairo.balart@metempsy.com // TAGE prediction 35813626Sjairo.balart@metempsy.com 35913626Sjairo.balart@metempsy.com calculateIndicesAndTags(tid, pc, bi); 36013626Sjairo.balart@metempsy.com 36113626Sjairo.balart@metempsy.com bi->bimodalIndex = bindex(pc); 36213626Sjairo.balart@metempsy.com 36313626Sjairo.balart@metempsy.com bi->hitBank = 0; 36413626Sjairo.balart@metempsy.com bi->altBank = 0; 36513626Sjairo.balart@metempsy.com //Look for the bank with longest matching history 36613626Sjairo.balart@metempsy.com for (int i = nHistoryTables; i > 0; i--) { 36713626Sjairo.balart@metempsy.com if (noSkip[i] && 36813626Sjairo.balart@metempsy.com gtable[i][tableIndices[i]].tag == tableTags[i]) { 36913626Sjairo.balart@metempsy.com bi->hitBank = i; 37013626Sjairo.balart@metempsy.com bi->hitBankIndex = tableIndices[bi->hitBank]; 37113626Sjairo.balart@metempsy.com break; 37213626Sjairo.balart@metempsy.com } 37313626Sjairo.balart@metempsy.com } 37413626Sjairo.balart@metempsy.com //Look for the alternate bank 37513626Sjairo.balart@metempsy.com for (int i = bi->hitBank - 1; i > 0; i--) { 37613626Sjairo.balart@metempsy.com if (noSkip[i] && 37713626Sjairo.balart@metempsy.com gtable[i][tableIndices[i]].tag == tableTags[i]) { 37813626Sjairo.balart@metempsy.com bi->altBank = i; 37913626Sjairo.balart@metempsy.com bi->altBankIndex = tableIndices[bi->altBank]; 38013626Sjairo.balart@metempsy.com break; 38113626Sjairo.balart@metempsy.com } 38213626Sjairo.balart@metempsy.com } 38313626Sjairo.balart@metempsy.com //computes the prediction and the alternate prediction 38413626Sjairo.balart@metempsy.com if (bi->hitBank > 0) { 38513626Sjairo.balart@metempsy.com if (bi->altBank > 0) { 38613626Sjairo.balart@metempsy.com bi->altTaken = 38713626Sjairo.balart@metempsy.com gtable[bi->altBank][tableIndices[bi->altBank]].ctr >= 0; 38813626Sjairo.balart@metempsy.com extraAltCalc(bi); 38913626Sjairo.balart@metempsy.com }else { 39013626Sjairo.balart@metempsy.com bi->altTaken = getBimodePred(pc, bi); 39113626Sjairo.balart@metempsy.com } 39213626Sjairo.balart@metempsy.com 39313626Sjairo.balart@metempsy.com bi->longestMatchPred = 39413626Sjairo.balart@metempsy.com gtable[bi->hitBank][tableIndices[bi->hitBank]].ctr >= 0; 39513626Sjairo.balart@metempsy.com bi->pseudoNewAlloc = 39613626Sjairo.balart@metempsy.com abs(2 * gtable[bi->hitBank][bi->hitBankIndex].ctr + 1) <= 1; 39713626Sjairo.balart@metempsy.com 39813626Sjairo.balart@metempsy.com //if the entry is recognized as a newly allocated entry and 39913626Sjairo.balart@metempsy.com //useAltPredForNewlyAllocated is positive use the alternate 40013626Sjairo.balart@metempsy.com //prediction 40113626Sjairo.balart@metempsy.com if ((useAltPredForNewlyAllocated[getUseAltIdx(bi)] < 0) || 40213626Sjairo.balart@metempsy.com ! bi->pseudoNewAlloc) { 40313626Sjairo.balart@metempsy.com bi->tagePred = bi->longestMatchPred; 40413626Sjairo.balart@metempsy.com bi->provider = TAGE_LONGEST_MATCH; 40513626Sjairo.balart@metempsy.com } else { 40613626Sjairo.balart@metempsy.com bi->tagePred = bi->altTaken; 40713626Sjairo.balart@metempsy.com bi->provider = bi->altBank ? TAGE_ALT_MATCH 40813626Sjairo.balart@metempsy.com : BIMODAL_ALT_MATCH; 40913626Sjairo.balart@metempsy.com } 41013626Sjairo.balart@metempsy.com } else { 41113626Sjairo.balart@metempsy.com bi->altTaken = getBimodePred(pc, bi); 41213626Sjairo.balart@metempsy.com bi->tagePred = bi->altTaken; 41313626Sjairo.balart@metempsy.com bi->longestMatchPred = bi->altTaken; 41413626Sjairo.balart@metempsy.com bi->provider = BIMODAL_ONLY; 41513626Sjairo.balart@metempsy.com } 41613626Sjairo.balart@metempsy.com //end TAGE prediction 41713626Sjairo.balart@metempsy.com 41813626Sjairo.balart@metempsy.com pred_taken = (bi->tagePred); 41913626Sjairo.balart@metempsy.com DPRINTF(Tage, "Predict for %lx: taken?:%d, tagePred:%d, altPred:%d\n", 42013626Sjairo.balart@metempsy.com branch_pc, pred_taken, bi->tagePred, bi->altTaken); 42113626Sjairo.balart@metempsy.com } 42213626Sjairo.balart@metempsy.com bi->branchPC = branch_pc; 42313626Sjairo.balart@metempsy.com bi->condBranch = cond_branch; 42413626Sjairo.balart@metempsy.com return pred_taken; 42513626Sjairo.balart@metempsy.com} 42613626Sjairo.balart@metempsy.com 42713626Sjairo.balart@metempsy.comvoid 42813626Sjairo.balart@metempsy.comTAGEBase::adjustAlloc(bool & alloc, bool taken) 42913626Sjairo.balart@metempsy.com{ 43013626Sjairo.balart@metempsy.com // Nothing for this base class implementation 43113626Sjairo.balart@metempsy.com} 43213626Sjairo.balart@metempsy.com 43313626Sjairo.balart@metempsy.comvoid 43413626Sjairo.balart@metempsy.comTAGEBase::handleAllocAndUReset(bool alloc, bool taken, BranchInfo* bi, 43513626Sjairo.balart@metempsy.com int nrand) 43613626Sjairo.balart@metempsy.com{ 43713626Sjairo.balart@metempsy.com if (alloc) { 43813626Sjairo.balart@metempsy.com // is there some "unuseful" entry to allocate 43913626Sjairo.balart@metempsy.com uint8_t min = 1; 44013626Sjairo.balart@metempsy.com for (int i = nHistoryTables; i > bi->hitBank; i--) { 44113626Sjairo.balart@metempsy.com if (gtable[i][bi->tableIndices[i]].u < min) { 44213626Sjairo.balart@metempsy.com min = gtable[i][bi->tableIndices[i]].u; 44313626Sjairo.balart@metempsy.com } 44413626Sjairo.balart@metempsy.com } 44513626Sjairo.balart@metempsy.com 44613626Sjairo.balart@metempsy.com // we allocate an entry with a longer history 44713626Sjairo.balart@metempsy.com // to avoid ping-pong, we do not choose systematically the next 44813626Sjairo.balart@metempsy.com // entry, but among the 3 next entries 44913626Sjairo.balart@metempsy.com int Y = nrand & 45013626Sjairo.balart@metempsy.com ((ULL(1) << (nHistoryTables - bi->hitBank - 1)) - 1); 45113626Sjairo.balart@metempsy.com int X = bi->hitBank + 1; 45213626Sjairo.balart@metempsy.com if (Y & 1) { 45313626Sjairo.balart@metempsy.com X++; 45413626Sjairo.balart@metempsy.com if (Y & 2) 45513626Sjairo.balart@metempsy.com X++; 45613626Sjairo.balart@metempsy.com } 45713626Sjairo.balart@metempsy.com // No entry available, forces one to be available 45813626Sjairo.balart@metempsy.com if (min > 0) { 45913626Sjairo.balart@metempsy.com gtable[X][bi->tableIndices[X]].u = 0; 46013626Sjairo.balart@metempsy.com } 46113626Sjairo.balart@metempsy.com 46213626Sjairo.balart@metempsy.com 46313626Sjairo.balart@metempsy.com //Allocate entries 46413626Sjairo.balart@metempsy.com unsigned numAllocated = 0; 46513626Sjairo.balart@metempsy.com for (int i = X; i <= nHistoryTables; i++) { 46613626Sjairo.balart@metempsy.com if ((gtable[i][bi->tableIndices[i]].u == 0)) { 46713626Sjairo.balart@metempsy.com gtable[i][bi->tableIndices[i]].tag = bi->tableTags[i]; 46813626Sjairo.balart@metempsy.com gtable[i][bi->tableIndices[i]].ctr = (taken) ? 0 : -1; 46913626Sjairo.balart@metempsy.com ++numAllocated; 47013626Sjairo.balart@metempsy.com if (numAllocated == maxNumAlloc) { 47113626Sjairo.balart@metempsy.com break; 47213626Sjairo.balart@metempsy.com } 47313626Sjairo.balart@metempsy.com } 47413626Sjairo.balart@metempsy.com } 47513626Sjairo.balart@metempsy.com } 47613626Sjairo.balart@metempsy.com 47713626Sjairo.balart@metempsy.com tCounter++; 47813626Sjairo.balart@metempsy.com 47913626Sjairo.balart@metempsy.com handleUReset(); 48013626Sjairo.balart@metempsy.com} 48113626Sjairo.balart@metempsy.com 48213626Sjairo.balart@metempsy.comvoid 48313626Sjairo.balart@metempsy.comTAGEBase::handleUReset() 48413626Sjairo.balart@metempsy.com{ 48513626Sjairo.balart@metempsy.com //periodic reset of u: reset is not complete but bit by bit 48613626Sjairo.balart@metempsy.com if ((tCounter & ((ULL(1) << logUResetPeriod) - 1)) == 0) { 48713626Sjairo.balart@metempsy.com // reset least significant bit 48813626Sjairo.balart@metempsy.com // most significant bit becomes least significant bit 48913626Sjairo.balart@metempsy.com for (int i = 1; i <= nHistoryTables; i++) { 49013626Sjairo.balart@metempsy.com for (int j = 0; j < (ULL(1) << logTagTableSizes[i]); j++) { 49113626Sjairo.balart@metempsy.com resetUctr(gtable[i][j].u); 49213626Sjairo.balart@metempsy.com } 49313626Sjairo.balart@metempsy.com } 49413626Sjairo.balart@metempsy.com } 49513626Sjairo.balart@metempsy.com} 49613626Sjairo.balart@metempsy.com 49713626Sjairo.balart@metempsy.comvoid 49813626Sjairo.balart@metempsy.comTAGEBase::resetUctr(uint8_t & u) 49913626Sjairo.balart@metempsy.com{ 50013626Sjairo.balart@metempsy.com u >>= 1; 50113626Sjairo.balart@metempsy.com} 50213626Sjairo.balart@metempsy.com 50313626Sjairo.balart@metempsy.comvoid 50413626Sjairo.balart@metempsy.comTAGEBase::condBranchUpdate(ThreadID tid, Addr branch_pc, bool taken, 50513626Sjairo.balart@metempsy.com BranchInfo* bi, int nrand, Addr corrTarget) 50613626Sjairo.balart@metempsy.com{ 50713626Sjairo.balart@metempsy.com // TAGE UPDATE 50813626Sjairo.balart@metempsy.com // try to allocate a new entries only if prediction was wrong 50913626Sjairo.balart@metempsy.com bool alloc = (bi->tagePred != taken) && (bi->hitBank < nHistoryTables); 51013626Sjairo.balart@metempsy.com if (bi->hitBank > 0) { 51113626Sjairo.balart@metempsy.com // Manage the selection between longest matching and alternate 51213626Sjairo.balart@metempsy.com // matching for "pseudo"-newly allocated longest matching entry 51313626Sjairo.balart@metempsy.com bool PseudoNewAlloc = bi->pseudoNewAlloc; 51413626Sjairo.balart@metempsy.com // an entry is considered as newly allocated if its prediction 51513626Sjairo.balart@metempsy.com // counter is weak 51613626Sjairo.balart@metempsy.com if (PseudoNewAlloc) { 51713626Sjairo.balart@metempsy.com if (bi->longestMatchPred == taken) { 51813626Sjairo.balart@metempsy.com alloc = false; 51913626Sjairo.balart@metempsy.com } 52013626Sjairo.balart@metempsy.com // if it was delivering the correct prediction, no need to 52113626Sjairo.balart@metempsy.com // allocate new entry even if the overall prediction was false 52213626Sjairo.balart@metempsy.com if (bi->longestMatchPred != bi->altTaken) { 52313626Sjairo.balart@metempsy.com ctrUpdate(useAltPredForNewlyAllocated[getUseAltIdx(bi)], 52413626Sjairo.balart@metempsy.com bi->altTaken == taken, useAltOnNaBits); 52513626Sjairo.balart@metempsy.com } 52613626Sjairo.balart@metempsy.com } 52713626Sjairo.balart@metempsy.com } 52813626Sjairo.balart@metempsy.com 52913626Sjairo.balart@metempsy.com adjustAlloc(alloc, taken); 53013626Sjairo.balart@metempsy.com 53113626Sjairo.balart@metempsy.com handleAllocAndUReset(alloc, taken, bi, nrand); 53213626Sjairo.balart@metempsy.com 53313626Sjairo.balart@metempsy.com handleTAGEUpdate(branch_pc, taken, bi); 53413626Sjairo.balart@metempsy.com} 53513626Sjairo.balart@metempsy.com 53613626Sjairo.balart@metempsy.comvoid 53713626Sjairo.balart@metempsy.comTAGEBase::handleTAGEUpdate(Addr branch_pc, bool taken, BranchInfo* bi) 53813626Sjairo.balart@metempsy.com{ 53913626Sjairo.balart@metempsy.com if (bi->hitBank > 0) { 54013626Sjairo.balart@metempsy.com DPRINTF(Tage, "Updating tag table entry (%d,%d) for branch %lx\n", 54113626Sjairo.balart@metempsy.com bi->hitBank, bi->hitBankIndex, branch_pc); 54213626Sjairo.balart@metempsy.com ctrUpdate(gtable[bi->hitBank][bi->hitBankIndex].ctr, taken, 54313626Sjairo.balart@metempsy.com tagTableCounterBits); 54413626Sjairo.balart@metempsy.com // if the provider entry is not certified to be useful also update 54513626Sjairo.balart@metempsy.com // the alternate prediction 54613626Sjairo.balart@metempsy.com if (gtable[bi->hitBank][bi->hitBankIndex].u == 0) { 54713626Sjairo.balart@metempsy.com if (bi->altBank > 0) { 54813626Sjairo.balart@metempsy.com ctrUpdate(gtable[bi->altBank][bi->altBankIndex].ctr, taken, 54913626Sjairo.balart@metempsy.com tagTableCounterBits); 55013626Sjairo.balart@metempsy.com DPRINTF(Tage, "Updating tag table entry (%d,%d) for" 55113626Sjairo.balart@metempsy.com " branch %lx\n", bi->hitBank, bi->hitBankIndex, 55213626Sjairo.balart@metempsy.com branch_pc); 55313626Sjairo.balart@metempsy.com } 55413626Sjairo.balart@metempsy.com if (bi->altBank == 0) { 55513626Sjairo.balart@metempsy.com baseUpdate(branch_pc, taken, bi); 55613626Sjairo.balart@metempsy.com } 55713626Sjairo.balart@metempsy.com } 55813626Sjairo.balart@metempsy.com 55913626Sjairo.balart@metempsy.com // update the u counter 56013626Sjairo.balart@metempsy.com if (bi->tagePred != bi->altTaken) { 56113626Sjairo.balart@metempsy.com unsignedCtrUpdate(gtable[bi->hitBank][bi->hitBankIndex].u, 56213626Sjairo.balart@metempsy.com bi->tagePred == taken, tagTableUBits); 56313626Sjairo.balart@metempsy.com } 56413626Sjairo.balart@metempsy.com } else { 56513626Sjairo.balart@metempsy.com baseUpdate(branch_pc, taken, bi); 56613626Sjairo.balart@metempsy.com } 56713626Sjairo.balart@metempsy.com} 56813626Sjairo.balart@metempsy.com 56913626Sjairo.balart@metempsy.comvoid 57013626Sjairo.balart@metempsy.comTAGEBase::updateHistories(ThreadID tid, Addr branch_pc, bool taken, 57113626Sjairo.balart@metempsy.com BranchInfo* bi, bool speculative, 57213626Sjairo.balart@metempsy.com const StaticInstPtr &inst, Addr target) 57313626Sjairo.balart@metempsy.com{ 57413626Sjairo.balart@metempsy.com if (speculative != speculativeHistUpdate) { 57513626Sjairo.balart@metempsy.com return; 57613626Sjairo.balart@metempsy.com } 57713626Sjairo.balart@metempsy.com ThreadHistory& tHist = threadHistory[tid]; 57813626Sjairo.balart@metempsy.com // UPDATE HISTORIES 57913626Sjairo.balart@metempsy.com bool pathbit = ((branch_pc >> instShiftAmt) & 1); 58013626Sjairo.balart@metempsy.com //on a squash, return pointers to this and recompute indices. 58113626Sjairo.balart@metempsy.com //update user history 58213626Sjairo.balart@metempsy.com updateGHist(tHist.gHist, taken, tHist.globalHistory, tHist.ptGhist); 58313626Sjairo.balart@metempsy.com tHist.pathHist = (tHist.pathHist << 1) + pathbit; 58413626Sjairo.balart@metempsy.com tHist.pathHist = (tHist.pathHist & ((ULL(1) << pathHistBits) - 1)); 58513626Sjairo.balart@metempsy.com 58613626Sjairo.balart@metempsy.com if (speculative) { 58713626Sjairo.balart@metempsy.com bi->ptGhist = tHist.ptGhist; 58813626Sjairo.balart@metempsy.com bi->pathHist = tHist.pathHist; 58913626Sjairo.balart@metempsy.com } 59013626Sjairo.balart@metempsy.com 59113626Sjairo.balart@metempsy.com //prepare next index and tag computations for user branchs 59213626Sjairo.balart@metempsy.com for (int i = 1; i <= nHistoryTables; i++) 59313626Sjairo.balart@metempsy.com { 59413626Sjairo.balart@metempsy.com if (speculative) { 59513626Sjairo.balart@metempsy.com bi->ci[i] = tHist.computeIndices[i].comp; 59613626Sjairo.balart@metempsy.com bi->ct0[i] = tHist.computeTags[0][i].comp; 59713626Sjairo.balart@metempsy.com bi->ct1[i] = tHist.computeTags[1][i].comp; 59813626Sjairo.balart@metempsy.com } 59913626Sjairo.balart@metempsy.com tHist.computeIndices[i].update(tHist.gHist); 60013626Sjairo.balart@metempsy.com tHist.computeTags[0][i].update(tHist.gHist); 60113626Sjairo.balart@metempsy.com tHist.computeTags[1][i].update(tHist.gHist); 60213626Sjairo.balart@metempsy.com } 60313626Sjairo.balart@metempsy.com DPRINTF(Tage, "Updating global histories with branch:%lx; taken?:%d, " 60413626Sjairo.balart@metempsy.com "path Hist: %x; pointer:%d\n", branch_pc, taken, tHist.pathHist, 60513626Sjairo.balart@metempsy.com tHist.ptGhist); 60613626Sjairo.balart@metempsy.com assert(threadHistory[tid].gHist == 60713626Sjairo.balart@metempsy.com &threadHistory[tid].globalHistory[threadHistory[tid].ptGhist]); 60813626Sjairo.balart@metempsy.com} 60913626Sjairo.balart@metempsy.com 61013626Sjairo.balart@metempsy.comvoid 61113626Sjairo.balart@metempsy.comTAGEBase::squash(ThreadID tid, bool taken, TAGEBase::BranchInfo *bi, 61213626Sjairo.balart@metempsy.com Addr target) 61313626Sjairo.balart@metempsy.com{ 61413626Sjairo.balart@metempsy.com if (!speculativeHistUpdate) { 61513626Sjairo.balart@metempsy.com /* If there are no speculative updates, no actions are needed */ 61613626Sjairo.balart@metempsy.com return; 61713626Sjairo.balart@metempsy.com } 61813626Sjairo.balart@metempsy.com 61913626Sjairo.balart@metempsy.com ThreadHistory& tHist = threadHistory[tid]; 62013626Sjairo.balart@metempsy.com DPRINTF(Tage, "Restoring branch info: %lx; taken? %d; PathHistory:%x, " 62113626Sjairo.balart@metempsy.com "pointer:%d\n", bi->branchPC,taken, bi->pathHist, bi->ptGhist); 62213626Sjairo.balart@metempsy.com tHist.pathHist = bi->pathHist; 62313626Sjairo.balart@metempsy.com tHist.ptGhist = bi->ptGhist; 62413626Sjairo.balart@metempsy.com tHist.gHist = &(tHist.globalHistory[tHist.ptGhist]); 62513626Sjairo.balart@metempsy.com tHist.gHist[0] = (taken ? 1 : 0); 62613626Sjairo.balart@metempsy.com for (int i = 1; i <= nHistoryTables; i++) { 62713626Sjairo.balart@metempsy.com tHist.computeIndices[i].comp = bi->ci[i]; 62813626Sjairo.balart@metempsy.com tHist.computeTags[0][i].comp = bi->ct0[i]; 62913626Sjairo.balart@metempsy.com tHist.computeTags[1][i].comp = bi->ct1[i]; 63013626Sjairo.balart@metempsy.com tHist.computeIndices[i].update(tHist.gHist); 63113626Sjairo.balart@metempsy.com tHist.computeTags[0][i].update(tHist.gHist); 63213626Sjairo.balart@metempsy.com tHist.computeTags[1][i].update(tHist.gHist); 63313626Sjairo.balart@metempsy.com } 63413626Sjairo.balart@metempsy.com} 63513626Sjairo.balart@metempsy.com 63613626Sjairo.balart@metempsy.comvoid 63713626Sjairo.balart@metempsy.comTAGEBase::extraAltCalc(BranchInfo* bi) 63813626Sjairo.balart@metempsy.com{ 63913626Sjairo.balart@metempsy.com // do nothing. This is only used in some derived classes 64013626Sjairo.balart@metempsy.com return; 64113626Sjairo.balart@metempsy.com} 64213626Sjairo.balart@metempsy.com 64313626Sjairo.balart@metempsy.comint 64413626Sjairo.balart@metempsy.comTAGEBase::getRandom() 64513626Sjairo.balart@metempsy.com{ 64613626Sjairo.balart@metempsy.com return random_mt.random<int>(); 64713626Sjairo.balart@metempsy.com} 64813626Sjairo.balart@metempsy.com 64913626Sjairo.balart@metempsy.comvoid 65013626Sjairo.balart@metempsy.comTAGEBase::updateStats(bool taken, BranchInfo* bi) 65113626Sjairo.balart@metempsy.com{ 65213626Sjairo.balart@metempsy.com if (taken == bi->tagePred) { 65313626Sjairo.balart@metempsy.com // correct prediction 65413626Sjairo.balart@metempsy.com switch (bi->provider) { 65513626Sjairo.balart@metempsy.com case BIMODAL_ONLY: tageBimodalProviderCorrect++; break; 65613626Sjairo.balart@metempsy.com case TAGE_LONGEST_MATCH: tageLongestMatchProviderCorrect++; break; 65713626Sjairo.balart@metempsy.com case BIMODAL_ALT_MATCH: bimodalAltMatchProviderCorrect++; break; 65813626Sjairo.balart@metempsy.com case TAGE_ALT_MATCH: tageAltMatchProviderCorrect++; break; 65913626Sjairo.balart@metempsy.com } 66013626Sjairo.balart@metempsy.com } else { 66113626Sjairo.balart@metempsy.com // wrong prediction 66213626Sjairo.balart@metempsy.com switch (bi->provider) { 66313626Sjairo.balart@metempsy.com case BIMODAL_ONLY: tageBimodalProviderWrong++; break; 66413626Sjairo.balart@metempsy.com case TAGE_LONGEST_MATCH: 66513626Sjairo.balart@metempsy.com tageLongestMatchProviderWrong++; 66613626Sjairo.balart@metempsy.com if (bi->altTaken == taken) { 66713626Sjairo.balart@metempsy.com tageAltMatchProviderWouldHaveHit++; 66813626Sjairo.balart@metempsy.com } 66913626Sjairo.balart@metempsy.com break; 67013626Sjairo.balart@metempsy.com case BIMODAL_ALT_MATCH: 67113626Sjairo.balart@metempsy.com bimodalAltMatchProviderWrong++; 67213626Sjairo.balart@metempsy.com break; 67313626Sjairo.balart@metempsy.com case TAGE_ALT_MATCH: 67413626Sjairo.balart@metempsy.com tageAltMatchProviderWrong++; 67513626Sjairo.balart@metempsy.com break; 67613626Sjairo.balart@metempsy.com } 67713626Sjairo.balart@metempsy.com 67813626Sjairo.balart@metempsy.com switch (bi->provider) { 67913626Sjairo.balart@metempsy.com case BIMODAL_ALT_MATCH: 68013626Sjairo.balart@metempsy.com case TAGE_ALT_MATCH: 68113626Sjairo.balart@metempsy.com if (bi->longestMatchPred == taken) { 68213626Sjairo.balart@metempsy.com tageLongestMatchProviderWouldHaveHit++; 68313626Sjairo.balart@metempsy.com } 68413626Sjairo.balart@metempsy.com } 68513626Sjairo.balart@metempsy.com } 68613626Sjairo.balart@metempsy.com 68713626Sjairo.balart@metempsy.com switch (bi->provider) { 68813626Sjairo.balart@metempsy.com case TAGE_LONGEST_MATCH: 68913626Sjairo.balart@metempsy.com case TAGE_ALT_MATCH: 69013626Sjairo.balart@metempsy.com tageLongestMatchProvider[bi->hitBank]++; 69113626Sjairo.balart@metempsy.com tageAltMatchProvider[bi->altBank]++; 69213626Sjairo.balart@metempsy.com break; 69313626Sjairo.balart@metempsy.com } 69413626Sjairo.balart@metempsy.com} 69513626Sjairo.balart@metempsy.com 69613626Sjairo.balart@metempsy.comunsigned 69713626Sjairo.balart@metempsy.comTAGEBase::getGHR(ThreadID tid, BranchInfo *bi) const 69813626Sjairo.balart@metempsy.com{ 69913626Sjairo.balart@metempsy.com unsigned val = 0; 70013626Sjairo.balart@metempsy.com for (unsigned i = 0; i < 32; i++) { 70113626Sjairo.balart@metempsy.com // Make sure we don't go out of bounds 70213626Sjairo.balart@metempsy.com int gh_offset = bi->ptGhist + i; 70313626Sjairo.balart@metempsy.com assert(&(threadHistory[tid].globalHistory[gh_offset]) < 70413626Sjairo.balart@metempsy.com threadHistory[tid].globalHistory + histBufferSize); 70513626Sjairo.balart@metempsy.com val |= ((threadHistory[tid].globalHistory[gh_offset] & 0x1) << i); 70613626Sjairo.balart@metempsy.com } 70713626Sjairo.balart@metempsy.com 70813626Sjairo.balart@metempsy.com return val; 70913626Sjairo.balart@metempsy.com} 71013626Sjairo.balart@metempsy.com 71113626Sjairo.balart@metempsy.comvoid 71213626Sjairo.balart@metempsy.comTAGEBase::regStats() 71313626Sjairo.balart@metempsy.com{ 71413626Sjairo.balart@metempsy.com tageLongestMatchProviderCorrect 71513626Sjairo.balart@metempsy.com .name(name() + ".tageLongestMatchProviderCorrect") 71613626Sjairo.balart@metempsy.com .desc("Number of times TAGE Longest Match is the provider and " 71713626Sjairo.balart@metempsy.com "the prediction is correct"); 71813626Sjairo.balart@metempsy.com 71913626Sjairo.balart@metempsy.com tageAltMatchProviderCorrect 72013626Sjairo.balart@metempsy.com .name(name() + ".tageAltMatchProviderCorrect") 72113626Sjairo.balart@metempsy.com .desc("Number of times TAGE Alt Match is the provider and " 72213626Sjairo.balart@metempsy.com "the prediction is correct"); 72313626Sjairo.balart@metempsy.com 72413626Sjairo.balart@metempsy.com bimodalAltMatchProviderCorrect 72513626Sjairo.balart@metempsy.com .name(name() + ".bimodalAltMatchProviderCorrect") 72613626Sjairo.balart@metempsy.com .desc("Number of times TAGE Alt Match is the bimodal and it is the " 72713626Sjairo.balart@metempsy.com "provider and the prediction is correct"); 72813626Sjairo.balart@metempsy.com 72913626Sjairo.balart@metempsy.com tageBimodalProviderCorrect 73013626Sjairo.balart@metempsy.com .name(name() + ".tageBimodalProviderCorrect") 73113626Sjairo.balart@metempsy.com .desc("Number of times there are no hits on the TAGE tables " 73213626Sjairo.balart@metempsy.com "and the bimodal prediction is correct"); 73313626Sjairo.balart@metempsy.com 73413626Sjairo.balart@metempsy.com tageLongestMatchProviderWrong 73513626Sjairo.balart@metempsy.com .name(name() + ".tageLongestMatchProviderWrong") 73613626Sjairo.balart@metempsy.com .desc("Number of times TAGE Longest Match is the provider and " 73713626Sjairo.balart@metempsy.com "the prediction is wrong"); 73813626Sjairo.balart@metempsy.com 73913626Sjairo.balart@metempsy.com tageAltMatchProviderWrong 74013626Sjairo.balart@metempsy.com .name(name() + ".tageAltMatchProviderWrong") 74113626Sjairo.balart@metempsy.com .desc("Number of times TAGE Alt Match is the provider and " 74213626Sjairo.balart@metempsy.com "the prediction is wrong"); 74313626Sjairo.balart@metempsy.com 74413626Sjairo.balart@metempsy.com bimodalAltMatchProviderWrong 74513626Sjairo.balart@metempsy.com .name(name() + ".bimodalAltMatchProviderWrong") 74613626Sjairo.balart@metempsy.com .desc("Number of times TAGE Alt Match is the bimodal and it is the " 74713626Sjairo.balart@metempsy.com "provider and the prediction is wrong"); 74813626Sjairo.balart@metempsy.com 74913626Sjairo.balart@metempsy.com tageBimodalProviderWrong 75013626Sjairo.balart@metempsy.com .name(name() + ".tageBimodalProviderWrong") 75113626Sjairo.balart@metempsy.com .desc("Number of times there are no hits on the TAGE tables " 75213626Sjairo.balart@metempsy.com "and the bimodal prediction is wrong"); 75313626Sjairo.balart@metempsy.com 75413626Sjairo.balart@metempsy.com tageAltMatchProviderWouldHaveHit 75513626Sjairo.balart@metempsy.com .name(name() + ".tageAltMatchProviderWouldHaveHit") 75613626Sjairo.balart@metempsy.com .desc("Number of times TAGE Longest Match is the provider, " 75713626Sjairo.balart@metempsy.com "the prediction is wrong and Alt Match prediction was correct"); 75813626Sjairo.balart@metempsy.com 75913626Sjairo.balart@metempsy.com tageLongestMatchProviderWouldHaveHit 76013626Sjairo.balart@metempsy.com .name(name() + ".tageLongestMatchProviderWouldHaveHit") 76113626Sjairo.balart@metempsy.com .desc("Number of times TAGE Alt Match is the provider, the " 76213626Sjairo.balart@metempsy.com "prediction is wrong and Longest Match prediction was correct"); 76313626Sjairo.balart@metempsy.com 76413626Sjairo.balart@metempsy.com tageLongestMatchProvider 76513626Sjairo.balart@metempsy.com .init(nHistoryTables + 1) 76613626Sjairo.balart@metempsy.com .name(name() + ".tageLongestMatchProvider") 76713626Sjairo.balart@metempsy.com .desc("TAGE provider for longest match"); 76813626Sjairo.balart@metempsy.com 76913626Sjairo.balart@metempsy.com tageAltMatchProvider 77013626Sjairo.balart@metempsy.com .init(nHistoryTables + 1) 77113626Sjairo.balart@metempsy.com .name(name() + ".tageAltMatchProvider") 77213626Sjairo.balart@metempsy.com .desc("TAGE provider for alt match"); 77313626Sjairo.balart@metempsy.com} 77413626Sjairo.balart@metempsy.com 77513626Sjairo.balart@metempsy.comint8_t 77613626Sjairo.balart@metempsy.comTAGEBase::getCtr(int hitBank, int hitBankIndex) const 77713626Sjairo.balart@metempsy.com{ 77813626Sjairo.balart@metempsy.com return gtable[hitBank][hitBankIndex].ctr; 77913626Sjairo.balart@metempsy.com} 78013626Sjairo.balart@metempsy.com 78113626Sjairo.balart@metempsy.comunsigned 78213626Sjairo.balart@metempsy.comTAGEBase::getTageCtrBits() const 78313626Sjairo.balart@metempsy.com{ 78413626Sjairo.balart@metempsy.com return tagTableCounterBits; 78513626Sjairo.balart@metempsy.com} 78613626Sjairo.balart@metempsy.com 78713626Sjairo.balart@metempsy.comint 78813626Sjairo.balart@metempsy.comTAGEBase::getPathHist(ThreadID tid) const 78913626Sjairo.balart@metempsy.com{ 79013626Sjairo.balart@metempsy.com return threadHistory[tid].pathHist; 79113626Sjairo.balart@metempsy.com} 79213626Sjairo.balart@metempsy.com 79313626Sjairo.balart@metempsy.combool 79413626Sjairo.balart@metempsy.comTAGEBase::isSpeculativeUpdateEnabled() const 79513626Sjairo.balart@metempsy.com{ 79613626Sjairo.balart@metempsy.com return speculativeHistUpdate; 79713626Sjairo.balart@metempsy.com} 79813626Sjairo.balart@metempsy.com 79913626Sjairo.balart@metempsy.comTAGEBase* 80013626Sjairo.balart@metempsy.comTAGEBaseParams::create() 80113626Sjairo.balart@metempsy.com{ 80213626Sjairo.balart@metempsy.com return new TAGEBase(this); 80313626Sjairo.balart@metempsy.com} 804