btb.cc revision 11432
16184SN/A/* 26184SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 36184SN/A * All rights reserved. 46184SN/A * 56184SN/A * Redistribution and use in source and binary forms, with or without 66184SN/A * modification, are permitted provided that the following conditions are 76184SN/A * met: redistributions of source code must retain the above copyright 86184SN/A * notice, this list of conditions and the following disclaimer; 96184SN/A * redistributions in binary form must reproduce the above copyright 106184SN/A * notice, this list of conditions and the following disclaimer in the 116184SN/A * documentation and/or other materials provided with the distribution; 126184SN/A * neither the name of the copyright holders nor the names of its 136184SN/A * contributors may be used to endorse or promote products derived from 146184SN/A * this software without specific prior written permission. 156184SN/A * 166184SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176184SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186184SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196184SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206184SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216184SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226184SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236184SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246184SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256184SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266184SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276184SN/A * 286184SN/A * Authors: Kevin Lim 296184SN/A */ 306184SN/A 316184SN/A#include "base/intmath.hh" 326184SN/A#include "base/trace.hh" 336226Snate@binkert.org#include "cpu/pred/btb.hh" 348232Snate@binkert.org#include "debug/Fetch.hh" 356184SN/A 366184SN/ADefaultBTB::DefaultBTB(unsigned _numEntries, 376184SN/A unsigned _tagBits, 3811432Smitch.hayenga@arm.com unsigned _instShiftAmt, 3911432Smitch.hayenga@arm.com unsigned _num_threads) 406184SN/A : numEntries(_numEntries), 416184SN/A tagBits(_tagBits), 4211432Smitch.hayenga@arm.com instShiftAmt(_instShiftAmt), 4311432Smitch.hayenga@arm.com log2NumThreads(floorLog2(_num_threads)) 446184SN/A{ 456184SN/A DPRINTF(Fetch, "BTB: Creating BTB object.\n"); 466184SN/A 476184SN/A if (!isPowerOf2(numEntries)) { 486184SN/A fatal("BTB entries is not a power of 2!"); 496184SN/A } 506184SN/A 516184SN/A btb.resize(numEntries); 526184SN/A 536227Snate@binkert.org for (unsigned i = 0; i < numEntries; ++i) { 546184SN/A btb[i].valid = false; 556184SN/A } 566184SN/A 576184SN/A idxMask = numEntries - 1; 586184SN/A 596184SN/A tagMask = (1 << tagBits) - 1; 606184SN/A 616184SN/A tagShiftAmt = instShiftAmt + floorLog2(numEntries); 626184SN/A} 636184SN/A 646184SN/Avoid 656184SN/ADefaultBTB::reset() 666184SN/A{ 676227Snate@binkert.org for (unsigned i = 0; i < numEntries; ++i) { 686184SN/A btb[i].valid = false; 696184SN/A } 706184SN/A} 716184SN/A 726184SN/Ainline 736184SN/Aunsigned 7411432Smitch.hayenga@arm.comDefaultBTB::getIndex(Addr instPC, ThreadID tid) 756184SN/A{ 766184SN/A // Need to shift PC over by the word offset. 7711432Smitch.hayenga@arm.com return ((instPC >> instShiftAmt) 7811432Smitch.hayenga@arm.com ^ (tid << (tagShiftAmt - instShiftAmt - log2NumThreads))) 7911432Smitch.hayenga@arm.com & idxMask; 806184SN/A} 816184SN/A 826184SN/Ainline 836184SN/AAddr 847720Sgblack@eecs.umich.eduDefaultBTB::getTag(Addr instPC) 856184SN/A{ 867720Sgblack@eecs.umich.edu return (instPC >> tagShiftAmt) & tagMask; 876184SN/A} 886184SN/A 896184SN/Abool 907720Sgblack@eecs.umich.eduDefaultBTB::valid(Addr instPC, ThreadID tid) 916184SN/A{ 9211432Smitch.hayenga@arm.com unsigned btb_idx = getIndex(instPC, tid); 936184SN/A 947720Sgblack@eecs.umich.edu Addr inst_tag = getTag(instPC); 956184SN/A 966184SN/A assert(btb_idx < numEntries); 976184SN/A 986184SN/A if (btb[btb_idx].valid 996184SN/A && inst_tag == btb[btb_idx].tag 1006184SN/A && btb[btb_idx].tid == tid) { 1016184SN/A return true; 1026184SN/A } else { 1036184SN/A return false; 1046184SN/A } 1056184SN/A} 1066184SN/A 1076184SN/A// @todo Create some sort of return struct that has both whether or not the 1086184SN/A// address is valid, and also the address. For now will just use addr = 0 to 1096184SN/A// represent invalid entry. 1107720Sgblack@eecs.umich.eduTheISA::PCState 1117720Sgblack@eecs.umich.eduDefaultBTB::lookup(Addr instPC, ThreadID tid) 1126184SN/A{ 11311432Smitch.hayenga@arm.com unsigned btb_idx = getIndex(instPC, tid); 1146184SN/A 1157720Sgblack@eecs.umich.edu Addr inst_tag = getTag(instPC); 1166184SN/A 1176184SN/A assert(btb_idx < numEntries); 1186184SN/A 1196184SN/A if (btb[btb_idx].valid 1206184SN/A && inst_tag == btb[btb_idx].tag 1216184SN/A && btb[btb_idx].tid == tid) { 1226184SN/A return btb[btb_idx].target; 1236184SN/A } else { 1246184SN/A return 0; 1256184SN/A } 1266184SN/A} 1276184SN/A 1286184SN/Avoid 1297720Sgblack@eecs.umich.eduDefaultBTB::update(Addr instPC, const TheISA::PCState &target, ThreadID tid) 1306184SN/A{ 13111432Smitch.hayenga@arm.com unsigned btb_idx = getIndex(instPC, tid); 1326184SN/A 1336184SN/A assert(btb_idx < numEntries); 1346184SN/A 1356184SN/A btb[btb_idx].tid = tid; 1366184SN/A btb[btb_idx].valid = true; 1376184SN/A btb[btb_idx].target = target; 1387720Sgblack@eecs.umich.edu btb[btb_idx].tag = getTag(instPC); 1396184SN/A} 140