btb.cc revision 11793
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 3111793Sbrandon.potter@amd.com#include "cpu/pred/btb.hh" 3211793Sbrandon.potter@amd.com 336184SN/A#include "base/intmath.hh" 346184SN/A#include "base/trace.hh" 358232Snate@binkert.org#include "debug/Fetch.hh" 366184SN/A 376184SN/ADefaultBTB::DefaultBTB(unsigned _numEntries, 386184SN/A unsigned _tagBits, 3911432Smitch.hayenga@arm.com unsigned _instShiftAmt, 4011432Smitch.hayenga@arm.com unsigned _num_threads) 416184SN/A : numEntries(_numEntries), 426184SN/A tagBits(_tagBits), 4311432Smitch.hayenga@arm.com instShiftAmt(_instShiftAmt), 4411432Smitch.hayenga@arm.com log2NumThreads(floorLog2(_num_threads)) 456184SN/A{ 466184SN/A DPRINTF(Fetch, "BTB: Creating BTB object.\n"); 476184SN/A 486184SN/A if (!isPowerOf2(numEntries)) { 496184SN/A fatal("BTB entries is not a power of 2!"); 506184SN/A } 516184SN/A 526184SN/A btb.resize(numEntries); 536184SN/A 546227Snate@binkert.org for (unsigned i = 0; i < numEntries; ++i) { 556184SN/A btb[i].valid = false; 566184SN/A } 576184SN/A 586184SN/A idxMask = numEntries - 1; 596184SN/A 606184SN/A tagMask = (1 << tagBits) - 1; 616184SN/A 626184SN/A tagShiftAmt = instShiftAmt + floorLog2(numEntries); 636184SN/A} 646184SN/A 656184SN/Avoid 666184SN/ADefaultBTB::reset() 676184SN/A{ 686227Snate@binkert.org for (unsigned i = 0; i < numEntries; ++i) { 696184SN/A btb[i].valid = false; 706184SN/A } 716184SN/A} 726184SN/A 736184SN/Ainline 746184SN/Aunsigned 7511432Smitch.hayenga@arm.comDefaultBTB::getIndex(Addr instPC, ThreadID tid) 766184SN/A{ 776184SN/A // Need to shift PC over by the word offset. 7811432Smitch.hayenga@arm.com return ((instPC >> instShiftAmt) 7911432Smitch.hayenga@arm.com ^ (tid << (tagShiftAmt - instShiftAmt - log2NumThreads))) 8011432Smitch.hayenga@arm.com & idxMask; 816184SN/A} 826184SN/A 836184SN/Ainline 846184SN/AAddr 857720Sgblack@eecs.umich.eduDefaultBTB::getTag(Addr instPC) 866184SN/A{ 877720Sgblack@eecs.umich.edu return (instPC >> tagShiftAmt) & tagMask; 886184SN/A} 896184SN/A 906184SN/Abool 917720Sgblack@eecs.umich.eduDefaultBTB::valid(Addr instPC, ThreadID tid) 926184SN/A{ 9311432Smitch.hayenga@arm.com unsigned btb_idx = getIndex(instPC, tid); 946184SN/A 957720Sgblack@eecs.umich.edu Addr inst_tag = getTag(instPC); 966184SN/A 976184SN/A assert(btb_idx < numEntries); 986184SN/A 996184SN/A if (btb[btb_idx].valid 1006184SN/A && inst_tag == btb[btb_idx].tag 1016184SN/A && btb[btb_idx].tid == tid) { 1026184SN/A return true; 1036184SN/A } else { 1046184SN/A return false; 1056184SN/A } 1066184SN/A} 1076184SN/A 1086184SN/A// @todo Create some sort of return struct that has both whether or not the 1096184SN/A// address is valid, and also the address. For now will just use addr = 0 to 1106184SN/A// represent invalid entry. 1117720Sgblack@eecs.umich.eduTheISA::PCState 1127720Sgblack@eecs.umich.eduDefaultBTB::lookup(Addr instPC, ThreadID tid) 1136184SN/A{ 11411432Smitch.hayenga@arm.com unsigned btb_idx = getIndex(instPC, tid); 1156184SN/A 1167720Sgblack@eecs.umich.edu Addr inst_tag = getTag(instPC); 1176184SN/A 1186184SN/A assert(btb_idx < numEntries); 1196184SN/A 1206184SN/A if (btb[btb_idx].valid 1216184SN/A && inst_tag == btb[btb_idx].tag 1226184SN/A && btb[btb_idx].tid == tid) { 1236184SN/A return btb[btb_idx].target; 1246184SN/A } else { 1256184SN/A return 0; 1266184SN/A } 1276184SN/A} 1286184SN/A 1296184SN/Avoid 1307720Sgblack@eecs.umich.eduDefaultBTB::update(Addr instPC, const TheISA::PCState &target, ThreadID tid) 1316184SN/A{ 13211432Smitch.hayenga@arm.com unsigned btb_idx = getIndex(instPC, tid); 1336184SN/A 1346184SN/A assert(btb_idx < numEntries); 1356184SN/A 1366184SN/A btb[btb_idx].tid = tid; 1376184SN/A btb[btb_idx].valid = true; 1386184SN/A btb[btb_idx].target = target; 1397720Sgblack@eecs.umich.edu btb[btb_idx].tag = getTag(instPC); 1406184SN/A} 141