btb.cc revision 6227
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" 346184SN/A 356184SN/ADefaultBTB::DefaultBTB(unsigned _numEntries, 366184SN/A unsigned _tagBits, 376184SN/A unsigned _instShiftAmt) 386184SN/A : numEntries(_numEntries), 396184SN/A tagBits(_tagBits), 406184SN/A instShiftAmt(_instShiftAmt) 416184SN/A{ 426184SN/A DPRINTF(Fetch, "BTB: Creating BTB object.\n"); 436184SN/A 446184SN/A if (!isPowerOf2(numEntries)) { 456184SN/A fatal("BTB entries is not a power of 2!"); 466184SN/A } 476184SN/A 486184SN/A btb.resize(numEntries); 496184SN/A 506227Snate@binkert.org for (unsigned i = 0; i < numEntries; ++i) { 516184SN/A btb[i].valid = false; 526184SN/A } 536184SN/A 546184SN/A idxMask = numEntries - 1; 556184SN/A 566184SN/A tagMask = (1 << tagBits) - 1; 576184SN/A 586184SN/A tagShiftAmt = instShiftAmt + floorLog2(numEntries); 596184SN/A} 606184SN/A 616184SN/Avoid 626184SN/ADefaultBTB::reset() 636184SN/A{ 646227Snate@binkert.org for (unsigned i = 0; i < numEntries; ++i) { 656184SN/A btb[i].valid = false; 666184SN/A } 676184SN/A} 686184SN/A 696184SN/Ainline 706184SN/Aunsigned 716184SN/ADefaultBTB::getIndex(const Addr &inst_PC) 726184SN/A{ 736184SN/A // Need to shift PC over by the word offset. 746184SN/A return (inst_PC >> instShiftAmt) & idxMask; 756184SN/A} 766184SN/A 776184SN/Ainline 786184SN/AAddr 796184SN/ADefaultBTB::getTag(const Addr &inst_PC) 806184SN/A{ 816184SN/A return (inst_PC >> tagShiftAmt) & tagMask; 826184SN/A} 836184SN/A 846184SN/Abool 856221SN/ADefaultBTB::valid(const Addr &inst_PC, ThreadID tid) 866184SN/A{ 876184SN/A unsigned btb_idx = getIndex(inst_PC); 886184SN/A 896184SN/A Addr inst_tag = getTag(inst_PC); 906184SN/A 916184SN/A assert(btb_idx < numEntries); 926184SN/A 936184SN/A if (btb[btb_idx].valid 946184SN/A && inst_tag == btb[btb_idx].tag 956184SN/A && btb[btb_idx].tid == tid) { 966184SN/A return true; 976184SN/A } else { 986184SN/A return false; 996184SN/A } 1006184SN/A} 1016184SN/A 1026184SN/A// @todo Create some sort of return struct that has both whether or not the 1036184SN/A// address is valid, and also the address. For now will just use addr = 0 to 1046184SN/A// represent invalid entry. 1056184SN/AAddr 1066221SN/ADefaultBTB::lookup(const Addr &inst_PC, ThreadID tid) 1076184SN/A{ 1086184SN/A unsigned btb_idx = getIndex(inst_PC); 1096184SN/A 1106184SN/A Addr inst_tag = getTag(inst_PC); 1116184SN/A 1126184SN/A assert(btb_idx < numEntries); 1136184SN/A 1146184SN/A if (btb[btb_idx].valid 1156184SN/A && inst_tag == btb[btb_idx].tag 1166184SN/A && btb[btb_idx].tid == tid) { 1176184SN/A return btb[btb_idx].target; 1186184SN/A } else { 1196184SN/A return 0; 1206184SN/A } 1216184SN/A} 1226184SN/A 1236184SN/Avoid 1246221SN/ADefaultBTB::update(const Addr &inst_PC, const Addr &target, ThreadID tid) 1256184SN/A{ 1266184SN/A unsigned btb_idx = getIndex(inst_PC); 1276184SN/A 1286184SN/A assert(btb_idx < numEntries); 1296184SN/A 1306184SN/A btb[btb_idx].tid = tid; 1316184SN/A btb[btb_idx].valid = true; 1326184SN/A btb[btb_idx].target = target; 1336184SN/A btb[btb_idx].tag = getTag(inst_PC); 1346184SN/A} 135