From: Nathan Binkert Date: Fri, 5 Jun 2009 04:50:20 +0000 (-0700) Subject: move: put predictor includes and cc files into the same place X-Git-Tag: Calvin_Submission~291 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4e3426624557b555c354035ee3961eab7554d81d;p=gem5.git move: put predictor includes and cc files into the same place --HG-- rename : src/cpu/2bit_local_pred.cc => src/cpu/pred/2bit_local.cc rename : src/cpu/o3/2bit_local_pred.hh => src/cpu/pred/2bit_local.hh rename : src/cpu/btb.cc => src/cpu/pred/btb.cc rename : src/cpu/o3/btb.hh => src/cpu/pred/btb.hh rename : src/cpu/ras.cc => src/cpu/pred/ras.cc rename : src/cpu/o3/ras.hh => src/cpu/pred/ras.hh rename : src/cpu/tournament_pred.cc => src/cpu/pred/tournament.cc rename : src/cpu/o3/tournament_pred.hh => src/cpu/pred/tournament.hh --- diff --git a/src/cpu/2bit_local_pred.cc b/src/cpu/2bit_local_pred.cc deleted file mode 100644 index 77a45ea26..000000000 --- a/src/cpu/2bit_local_pred.cc +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2004-2006 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Kevin Lim - */ - -#include "base/intmath.hh" -#include "base/misc.hh" -#include "base/trace.hh" -#include "cpu/o3/2bit_local_pred.hh" - -LocalBP::LocalBP(unsigned _localPredictorSize, - unsigned _localCtrBits, - unsigned _instShiftAmt) - : localPredictorSize(_localPredictorSize), - localCtrBits(_localCtrBits), - instShiftAmt(_instShiftAmt) -{ - if (!isPowerOf2(localPredictorSize)) { - fatal("Invalid local predictor size!\n"); - } - - localPredictorSets = localPredictorSize / localCtrBits; - - if (!isPowerOf2(localPredictorSets)) { - fatal("Invalid number of local predictor sets! Check localCtrBits.\n"); - } - - // Setup the index mask. - indexMask = localPredictorSets - 1; - - DPRINTF(Fetch, "Branch predictor: index mask: %#x\n", indexMask); - - // Setup the array of counters for the local predictor. - localCtrs.resize(localPredictorSets); - - for (int i = 0; i < localPredictorSets; ++i) - localCtrs[i].setBits(_localCtrBits); - - DPRINTF(Fetch, "Branch predictor: local predictor size: %i\n", - localPredictorSize); - - DPRINTF(Fetch, "Branch predictor: local counter bits: %i\n", localCtrBits); - - DPRINTF(Fetch, "Branch predictor: instruction shift amount: %i\n", - instShiftAmt); -} - -void -LocalBP::reset() -{ - for (int i = 0; i < localPredictorSets; ++i) { - localCtrs[i].reset(); - } -} - -bool -LocalBP::lookup(Addr &branch_addr, void * &bp_history) -{ - bool taken; - uint8_t counter_val; - unsigned local_predictor_idx = getLocalIndex(branch_addr); - - DPRINTF(Fetch, "Branch predictor: Looking up index %#x\n", - local_predictor_idx); - - counter_val = localCtrs[local_predictor_idx].read(); - - DPRINTF(Fetch, "Branch predictor: prediction is %i.\n", - (int)counter_val); - - taken = getPrediction(counter_val); - -#if 0 - // Speculative update. - if (taken) { - DPRINTF(Fetch, "Branch predictor: Branch updated as taken.\n"); - localCtrs[local_predictor_idx].increment(); - } else { - DPRINTF(Fetch, "Branch predictor: Branch updated as not taken.\n"); - localCtrs[local_predictor_idx].decrement(); - } -#endif - - return taken; -} - -void -LocalBP::update(Addr &branch_addr, bool taken, void *bp_history) -{ - assert(bp_history == NULL); - unsigned local_predictor_idx; - - // Update the local predictor. - local_predictor_idx = getLocalIndex(branch_addr); - - DPRINTF(Fetch, "Branch predictor: Looking up index %#x\n", - local_predictor_idx); - - if (taken) { - DPRINTF(Fetch, "Branch predictor: Branch updated as taken.\n"); - localCtrs[local_predictor_idx].increment(); - } else { - DPRINTF(Fetch, "Branch predictor: Branch updated as not taken.\n"); - localCtrs[local_predictor_idx].decrement(); - } -} - -inline -bool -LocalBP::getPrediction(uint8_t &count) -{ - // Get the MSB of the count - return (count >> (localCtrBits - 1)); -} - -inline -unsigned -LocalBP::getLocalIndex(Addr &branch_addr) -{ - return (branch_addr >> instShiftAmt) & indexMask; -} diff --git a/src/cpu/SConscript b/src/cpu/SConscript index 80bc0986e..44f8817ff 100644 --- a/src/cpu/SConscript +++ b/src/cpu/SConscript @@ -126,13 +126,6 @@ Source('simple_thread.cc') Source('thread_context.cc') Source('thread_state.cc') -if 'InOrderCPU' in env['CPU_MODELS'] or 'O3CPU' in env['CPU_MODELS']: - Source('btb.cc') - Source('tournament_pred.cc') - Source('2bit_local_pred.cc') - Source('ras.cc') - TraceFlag('FreeList') - if env['FULL_SYSTEM']: SimObject('IntrControl.py') diff --git a/src/cpu/btb.cc b/src/cpu/btb.cc deleted file mode 100644 index 4c1d441be..000000000 --- a/src/cpu/btb.cc +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2004-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Kevin Lim - */ - -#include "base/intmath.hh" -#include "base/trace.hh" -#include "cpu/o3/btb.hh" - -DefaultBTB::DefaultBTB(unsigned _numEntries, - unsigned _tagBits, - unsigned _instShiftAmt) - : numEntries(_numEntries), - tagBits(_tagBits), - instShiftAmt(_instShiftAmt) -{ - DPRINTF(Fetch, "BTB: Creating BTB object.\n"); - - if (!isPowerOf2(numEntries)) { - fatal("BTB entries is not a power of 2!"); - } - - btb.resize(numEntries); - - for (int i = 0; i < numEntries; ++i) { - btb[i].valid = false; - } - - idxMask = numEntries - 1; - - tagMask = (1 << tagBits) - 1; - - tagShiftAmt = instShiftAmt + floorLog2(numEntries); -} - -void -DefaultBTB::reset() -{ - for (int i = 0; i < numEntries; ++i) { - btb[i].valid = false; - } -} - -inline -unsigned -DefaultBTB::getIndex(const Addr &inst_PC) -{ - // Need to shift PC over by the word offset. - return (inst_PC >> instShiftAmt) & idxMask; -} - -inline -Addr -DefaultBTB::getTag(const Addr &inst_PC) -{ - return (inst_PC >> tagShiftAmt) & tagMask; -} - -bool -DefaultBTB::valid(const Addr &inst_PC, ThreadID tid) -{ - unsigned btb_idx = getIndex(inst_PC); - - Addr inst_tag = getTag(inst_PC); - - assert(btb_idx < numEntries); - - if (btb[btb_idx].valid - && inst_tag == btb[btb_idx].tag - && btb[btb_idx].tid == tid) { - return true; - } else { - return false; - } -} - -// @todo Create some sort of return struct that has both whether or not the -// address is valid, and also the address. For now will just use addr = 0 to -// represent invalid entry. -Addr -DefaultBTB::lookup(const Addr &inst_PC, ThreadID tid) -{ - unsigned btb_idx = getIndex(inst_PC); - - Addr inst_tag = getTag(inst_PC); - - assert(btb_idx < numEntries); - - if (btb[btb_idx].valid - && inst_tag == btb[btb_idx].tag - && btb[btb_idx].tid == tid) { - return btb[btb_idx].target; - } else { - return 0; - } -} - -void -DefaultBTB::update(const Addr &inst_PC, const Addr &target, ThreadID tid) -{ - unsigned btb_idx = getIndex(inst_PC); - - assert(btb_idx < numEntries); - - btb[btb_idx].tid = tid; - btb[btb_idx].valid = true; - btb[btb_idx].target = target; - btb[btb_idx].tag = getTag(inst_PC); -} diff --git a/src/cpu/inorder/resources/bpred_unit.hh b/src/cpu/inorder/resources/bpred_unit.hh index abbb70e0d..1571e3206 100644 --- a/src/cpu/inorder/resources/bpred_unit.hh +++ b/src/cpu/inorder/resources/bpred_unit.hh @@ -32,21 +32,18 @@ #ifndef __CPU_INORDER_BPRED_UNIT_HH__ #define __CPU_INORDER_BPRED_UNIT_HH__ -// For Addr type. +#include + #include "arch/isa_traits.hh" #include "base/statistics.hh" #include "cpu/inst_seq.hh" - -//#include "cpu/inorder/params.hh" -#include "cpu/o3/2bit_local_pred.hh" -#include "cpu/o3/btb.hh" -#include "cpu/o3/ras.hh" -#include "cpu/o3/tournament_pred.hh" -#include "params/InOrderCPU.hh" #include "cpu/inorder/inorder_dyn_inst.hh" #include "cpu/inorder/pipeline_traits.hh" - -#include +#include "cpu/pred/2bit_local.hh" +#include "cpu/pred/btb.hh" +#include "cpu/pred/ras.hh" +#include "cpu/pred/tournament.hh" +#include "params/InOrderCPU.hh" /** * Basically a wrapper class to hold both the branch predictor diff --git a/src/cpu/o3/2bit_local_pred.hh b/src/cpu/o3/2bit_local_pred.hh deleted file mode 100644 index 8b7bb8463..000000000 --- a/src/cpu/o3/2bit_local_pred.hh +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2004-2006 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Kevin Lim - */ - -#ifndef __CPU_O3_2BIT_LOCAL_PRED_HH__ -#define __CPU_O3_2BIT_LOCAL_PRED_HH__ - -#include - -#include "base/types.hh" -#include "cpu/o3/sat_counter.hh" - -/** - * Implements a local predictor that uses the PC to index into a table of - * counters. Note that any time a pointer to the bp_history is given, it - * should be NULL using this predictor because it does not have any branch - * predictor state that needs to be recorded or updated; the update can be - * determined solely by the branch being taken or not taken. - */ -class LocalBP -{ - public: - /** - * Default branch predictor constructor. - * @param localPredictorSize Size of the local predictor. - * @param localCtrBits Number of bits per counter. - * @param instShiftAmt Offset amount for instructions to ignore alignment. - */ - LocalBP(unsigned localPredictorSize, unsigned localCtrBits, - unsigned instShiftAmt); - - /** - * Looks up the given address in the branch predictor and returns - * a true/false value as to whether it is taken. - * @param branch_addr The address of the branch to look up. - * @param bp_history Pointer to any bp history state. - * @return Whether or not the branch is taken. - */ - bool lookup(Addr &branch_addr, void * &bp_history); - - /** - * Updates the branch predictor with the actual result of a branch. - * @param branch_addr The address of the branch to update. - * @param taken Whether or not the branch was taken. - */ - void update(Addr &branch_addr, bool taken, void *bp_history); - - void squash(void *bp_history) - { assert(bp_history == NULL); } - - void reset(); - - private: - /** - * Returns the taken/not taken prediction given the value of the - * counter. - * @param count The value of the counter. - * @return The prediction based on the counter value. - */ - inline bool getPrediction(uint8_t &count); - - /** Calculates the local index based on the PC. */ - inline unsigned getLocalIndex(Addr &PC); - - /** Array of counters that make up the local predictor. */ - std::vector localCtrs; - - /** Size of the local predictor. */ - unsigned localPredictorSize; - - /** Number of sets. */ - unsigned localPredictorSets; - - /** Number of bits of the local predictor's counters. */ - unsigned localCtrBits; - - /** Number of bits to shift the PC when calculating index. */ - unsigned instShiftAmt; - - /** Mask to get index bits. */ - unsigned indexMask; -}; - -#endif // __CPU_O3_2BIT_LOCAL_PRED_HH__ diff --git a/src/cpu/o3/bpred_unit.hh b/src/cpu/o3/bpred_unit.hh index 49cb4233b..f199bdd75 100644 --- a/src/cpu/o3/bpred_unit.hh +++ b/src/cpu/o3/bpred_unit.hh @@ -36,10 +36,10 @@ #include "base/statistics.hh" #include "base/types.hh" #include "cpu/inst_seq.hh" -#include "cpu/o3/2bit_local_pred.hh" -#include "cpu/o3/btb.hh" -#include "cpu/o3/ras.hh" -#include "cpu/o3/tournament_pred.hh" +#include "cpu/pred/2bit_local.hh" +#include "cpu/pred/btb.hh" +#include "cpu/pred/ras.hh" +#include "cpu/pred/tournament.hh" class DerivO3CPUParams; diff --git a/src/cpu/o3/btb.hh b/src/cpu/o3/btb.hh deleted file mode 100644 index 6557522e0..000000000 --- a/src/cpu/o3/btb.hh +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2004-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Kevin Lim - */ - -#ifndef __CPU_O3_BTB_HH__ -#define __CPU_O3_BTB_HH__ - -#include "base/misc.hh" -#include "base/types.hh" - -class DefaultBTB -{ - private: - struct BTBEntry - { - BTBEntry() - : tag(0), target(0), valid(false) - { - } - - /** The entry's tag. */ - Addr tag; - - /** The entry's target. */ - Addr target; - - /** The entry's thread id. */ - ThreadID tid; - - /** Whether or not the entry is valid. */ - bool valid; - }; - - public: - /** Creates a BTB with the given number of entries, number of bits per - * tag, and instruction offset amount. - * @param numEntries Number of entries for the BTB. - * @param tagBits Number of bits for each tag in the BTB. - * @param instShiftAmt Offset amount for instructions to ignore alignment. - */ - DefaultBTB(unsigned numEntries, unsigned tagBits, - unsigned instShiftAmt); - - void reset(); - - /** Looks up an address in the BTB. Must call valid() first on the address. - * @param inst_PC The address of the branch to look up. - * @param tid The thread id. - * @return Returns the target of the branch. - */ - Addr lookup(const Addr &inst_PC, ThreadID tid); - - /** Checks if a branch is in the BTB. - * @param inst_PC The address of the branch to look up. - * @param tid The thread id. - * @return Whether or not the branch exists in the BTB. - */ - bool valid(const Addr &inst_PC, ThreadID tid); - - /** Updates the BTB with the target of a branch. - * @param inst_PC The address of the branch being updated. - * @param target_PC The target address of the branch. - * @param tid The thread id. - */ - void update(const Addr &inst_PC, const Addr &target_PC, - ThreadID tid); - - private: - /** Returns the index into the BTB, based on the branch's PC. - * @param inst_PC The branch to look up. - * @return Returns the index into the BTB. - */ - inline unsigned getIndex(const Addr &inst_PC); - - /** Returns the tag bits of a given address. - * @param inst_PC The branch's address. - * @return Returns the tag bits. - */ - inline Addr getTag(const Addr &inst_PC); - - /** The actual BTB. */ - std::vector btb; - - /** The number of entries in the BTB. */ - unsigned numEntries; - - /** The index mask. */ - unsigned idxMask; - - /** The number of tag bits per entry. */ - unsigned tagBits; - - /** The tag mask. */ - unsigned tagMask; - - /** Number of bits to shift PC when calculating index. */ - unsigned instShiftAmt; - - /** Number of bits to shift PC when calculating tag. */ - unsigned tagShiftAmt; -}; - -#endif // __CPU_O3_BTB_HH__ diff --git a/src/cpu/o3/ras.hh b/src/cpu/o3/ras.hh deleted file mode 100644 index a36faf79a..000000000 --- a/src/cpu/o3/ras.hh +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2004-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Kevin Lim - */ - -#ifndef __CPU_O3_RAS_HH__ -#define __CPU_O3_RAS_HH__ - -#include - -#include "base/types.hh" - -/** Return address stack class, implements a simple RAS. */ -class ReturnAddrStack -{ - public: - /** Creates a return address stack, but init() must be called prior to - * use. - */ - ReturnAddrStack() {} - - /** Initializes RAS with a specified number of entries. - * @param numEntries Number of entries in the RAS. - */ - void init(unsigned numEntries); - - void reset(); - - /** Returns the top address on the RAS. */ - Addr top() - { return addrStack[tos]; } - - /** Returns the index of the top of the RAS. */ - unsigned topIdx() - { return tos; } - - /** Pushes an address onto the RAS. */ - void push(const Addr &return_addr); - - /** Pops the top address from the RAS. */ - void pop(); - - /** Changes index to the top of the RAS, and replaces the top address with - * a new target. - * @param top_entry_idx The index of the RAS that will now be the top. - * @param restored_target The new target address of the new top of the RAS. - */ - void restore(unsigned top_entry_idx, const Addr &restored_target); - - bool empty() { return usedEntries == 0; } - - bool full() { return usedEntries == numEntries; } - private: - /** Increments the top of stack index. */ - inline void incrTos() - { if (++tos == numEntries) tos = 0; } - - /** Decrements the top of stack index. */ - inline void decrTos() - { tos = (tos == 0 ? numEntries - 1 : tos - 1); } - - /** The RAS itself. */ - std::vector addrStack; - - /** The number of entries in the RAS. */ - unsigned numEntries; - - /** The number of used entries in the RAS. */ - unsigned usedEntries; - - /** The top of stack index. */ - unsigned tos; -}; - -#endif // __CPU_O3_RAS_HH__ diff --git a/src/cpu/o3/tournament_pred.hh b/src/cpu/o3/tournament_pred.hh deleted file mode 100644 index 96bd43ed6..000000000 --- a/src/cpu/o3/tournament_pred.hh +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) 2004-2006 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Kevin Lim - */ - -#ifndef __CPU_O3_TOURNAMENT_PRED_HH__ -#define __CPU_O3_TOURNAMENT_PRED_HH__ - -#include - -#include "base/types.hh" -#include "cpu/o3/sat_counter.hh" - -/** - * Implements a tournament branch predictor, hopefully identical to the one - * used in the 21264. It has a local predictor, which uses a local history - * table to index into a table of counters, and a global predictor, which - * uses a global history to index into a table of counters. A choice - * predictor chooses between the two. Only the global history register - * is speculatively updated, the rest are updated upon branches committing - * or misspeculating. - */ -class TournamentBP -{ - public: - /** - * Default branch predictor constructor. - */ - TournamentBP(unsigned localPredictorSize, - unsigned localCtrBits, - unsigned localHistoryTableSize, - unsigned localHistoryBits, - unsigned globalPredictorSize, - unsigned globalHistoryBits, - unsigned globalCtrBits, - unsigned choicePredictorSize, - unsigned choiceCtrBits, - unsigned instShiftAmt); - - /** - * Looks up the given address in the branch predictor and returns - * a true/false value as to whether it is taken. Also creates a - * BPHistory object to store any state it will need on squash/update. - * @param branch_addr The address of the branch to look up. - * @param bp_history Pointer that will be set to the BPHistory object. - * @return Whether or not the branch is taken. - */ - bool lookup(Addr &branch_addr, void * &bp_history); - - /** - * Records that there was an unconditional branch, and modifies - * the bp history to point to an object that has the previous - * global history stored in it. - * @param bp_history Pointer that will be set to the BPHistory object. - */ - void uncondBr(void * &bp_history); - - /** - * Updates the branch predictor with the actual result of a branch. - * @param branch_addr The address of the branch to update. - * @param taken Whether or not the branch was taken. - * @param bp_history Pointer to the BPHistory object that was created - * when the branch was predicted. - */ - void update(Addr &branch_addr, bool taken, void *bp_history); - - /** - * Restores the global branch history on a squash. - * @param bp_history Pointer to the BPHistory object that has the - * previous global branch history in it. - */ - void squash(void *bp_history); - - /** Returns the global history. */ - inline unsigned readGlobalHist() { return globalHistory; } - - private: - /** - * Returns if the branch should be taken or not, given a counter - * value. - * @param count The counter value. - */ - inline bool getPrediction(uint8_t &count); - - /** - * Returns the local history index, given a branch address. - * @param branch_addr The branch's PC address. - */ - inline unsigned calcLocHistIdx(Addr &branch_addr); - - /** Updates global history as taken. */ - inline void updateGlobalHistTaken(); - - /** Updates global history as not taken. */ - inline void updateGlobalHistNotTaken(); - - /** - * Updates local histories as taken. - * @param local_history_idx The local history table entry that - * will be updated. - */ - inline void updateLocalHistTaken(unsigned local_history_idx); - - /** - * Updates local histories as not taken. - * @param local_history_idx The local history table entry that - * will be updated. - */ - inline void updateLocalHistNotTaken(unsigned local_history_idx); - - /** - * The branch history information that is created upon predicting - * a branch. It will be passed back upon updating and squashing, - * when the BP can use this information to update/restore its - * state properly. - */ - struct BPHistory { -#ifdef DEBUG - BPHistory() - { newCount++; } - ~BPHistory() - { newCount--; } - - static int newCount; -#endif - unsigned globalHistory; - bool localPredTaken; - bool globalPredTaken; - bool globalUsed; - }; - - /** Local counters. */ - std::vector localCtrs; - - /** Size of the local predictor. */ - unsigned localPredictorSize; - - /** Mask to get the proper index bits into the predictor. */ - unsigned localPredictorMask; - - /** Number of bits of the local predictor's counters. */ - unsigned localCtrBits; - - /** Array of local history table entries. */ - std::vector localHistoryTable; - - /** Size of the local history table. */ - unsigned localHistoryTableSize; - - /** Number of bits for each entry of the local history table. - * @todo Doesn't this come from the size of the local predictor? - */ - unsigned localHistoryBits; - - /** Mask to get the proper local history. */ - unsigned localHistoryMask; - - /** Array of counters that make up the global predictor. */ - std::vector globalCtrs; - - /** Size of the global predictor. */ - unsigned globalPredictorSize; - - /** Number of bits of the global predictor's counters. */ - unsigned globalCtrBits; - - /** Global history register. */ - unsigned globalHistory; - - /** Number of bits for the global history. */ - unsigned globalHistoryBits; - - /** Mask to get the proper global history. */ - unsigned globalHistoryMask; - - /** Array of counters that make up the choice predictor. */ - std::vector choiceCtrs; - - /** Size of the choice predictor (identical to the global predictor). */ - unsigned choicePredictorSize; - - /** Number of bits of the choice predictor's counters. */ - unsigned choiceCtrBits; - - /** Number of bits to shift the instruction over to get rid of the word - * offset. - */ - unsigned instShiftAmt; - - /** Threshold for the counter value; above the threshold is taken, - * equal to or below the threshold is not taken. - */ - unsigned threshold; -}; - -#endif // __CPU_O3_TOURNAMENT_PRED_HH__ diff --git a/src/cpu/pred/2bit_local.cc b/src/cpu/pred/2bit_local.cc new file mode 100644 index 000000000..65925fe79 --- /dev/null +++ b/src/cpu/pred/2bit_local.cc @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2004-2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Kevin Lim + */ + +#include "base/intmath.hh" +#include "base/misc.hh" +#include "base/trace.hh" +#include "cpu/pred/2bit_local.hh" + +LocalBP::LocalBP(unsigned _localPredictorSize, + unsigned _localCtrBits, + unsigned _instShiftAmt) + : localPredictorSize(_localPredictorSize), + localCtrBits(_localCtrBits), + instShiftAmt(_instShiftAmt) +{ + if (!isPowerOf2(localPredictorSize)) { + fatal("Invalid local predictor size!\n"); + } + + localPredictorSets = localPredictorSize / localCtrBits; + + if (!isPowerOf2(localPredictorSets)) { + fatal("Invalid number of local predictor sets! Check localCtrBits.\n"); + } + + // Setup the index mask. + indexMask = localPredictorSets - 1; + + DPRINTF(Fetch, "Branch predictor: index mask: %#x\n", indexMask); + + // Setup the array of counters for the local predictor. + localCtrs.resize(localPredictorSets); + + for (int i = 0; i < localPredictorSets; ++i) + localCtrs[i].setBits(_localCtrBits); + + DPRINTF(Fetch, "Branch predictor: local predictor size: %i\n", + localPredictorSize); + + DPRINTF(Fetch, "Branch predictor: local counter bits: %i\n", localCtrBits); + + DPRINTF(Fetch, "Branch predictor: instruction shift amount: %i\n", + instShiftAmt); +} + +void +LocalBP::reset() +{ + for (int i = 0; i < localPredictorSets; ++i) { + localCtrs[i].reset(); + } +} + +bool +LocalBP::lookup(Addr &branch_addr, void * &bp_history) +{ + bool taken; + uint8_t counter_val; + unsigned local_predictor_idx = getLocalIndex(branch_addr); + + DPRINTF(Fetch, "Branch predictor: Looking up index %#x\n", + local_predictor_idx); + + counter_val = localCtrs[local_predictor_idx].read(); + + DPRINTF(Fetch, "Branch predictor: prediction is %i.\n", + (int)counter_val); + + taken = getPrediction(counter_val); + +#if 0 + // Speculative update. + if (taken) { + DPRINTF(Fetch, "Branch predictor: Branch updated as taken.\n"); + localCtrs[local_predictor_idx].increment(); + } else { + DPRINTF(Fetch, "Branch predictor: Branch updated as not taken.\n"); + localCtrs[local_predictor_idx].decrement(); + } +#endif + + return taken; +} + +void +LocalBP::update(Addr &branch_addr, bool taken, void *bp_history) +{ + assert(bp_history == NULL); + unsigned local_predictor_idx; + + // Update the local predictor. + local_predictor_idx = getLocalIndex(branch_addr); + + DPRINTF(Fetch, "Branch predictor: Looking up index %#x\n", + local_predictor_idx); + + if (taken) { + DPRINTF(Fetch, "Branch predictor: Branch updated as taken.\n"); + localCtrs[local_predictor_idx].increment(); + } else { + DPRINTF(Fetch, "Branch predictor: Branch updated as not taken.\n"); + localCtrs[local_predictor_idx].decrement(); + } +} + +inline +bool +LocalBP::getPrediction(uint8_t &count) +{ + // Get the MSB of the count + return (count >> (localCtrBits - 1)); +} + +inline +unsigned +LocalBP::getLocalIndex(Addr &branch_addr) +{ + return (branch_addr >> instShiftAmt) & indexMask; +} diff --git a/src/cpu/pred/2bit_local.hh b/src/cpu/pred/2bit_local.hh new file mode 100644 index 000000000..8b7bb8463 --- /dev/null +++ b/src/cpu/pred/2bit_local.hh @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2004-2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Kevin Lim + */ + +#ifndef __CPU_O3_2BIT_LOCAL_PRED_HH__ +#define __CPU_O3_2BIT_LOCAL_PRED_HH__ + +#include + +#include "base/types.hh" +#include "cpu/o3/sat_counter.hh" + +/** + * Implements a local predictor that uses the PC to index into a table of + * counters. Note that any time a pointer to the bp_history is given, it + * should be NULL using this predictor because it does not have any branch + * predictor state that needs to be recorded or updated; the update can be + * determined solely by the branch being taken or not taken. + */ +class LocalBP +{ + public: + /** + * Default branch predictor constructor. + * @param localPredictorSize Size of the local predictor. + * @param localCtrBits Number of bits per counter. + * @param instShiftAmt Offset amount for instructions to ignore alignment. + */ + LocalBP(unsigned localPredictorSize, unsigned localCtrBits, + unsigned instShiftAmt); + + /** + * Looks up the given address in the branch predictor and returns + * a true/false value as to whether it is taken. + * @param branch_addr The address of the branch to look up. + * @param bp_history Pointer to any bp history state. + * @return Whether or not the branch is taken. + */ + bool lookup(Addr &branch_addr, void * &bp_history); + + /** + * Updates the branch predictor with the actual result of a branch. + * @param branch_addr The address of the branch to update. + * @param taken Whether or not the branch was taken. + */ + void update(Addr &branch_addr, bool taken, void *bp_history); + + void squash(void *bp_history) + { assert(bp_history == NULL); } + + void reset(); + + private: + /** + * Returns the taken/not taken prediction given the value of the + * counter. + * @param count The value of the counter. + * @return The prediction based on the counter value. + */ + inline bool getPrediction(uint8_t &count); + + /** Calculates the local index based on the PC. */ + inline unsigned getLocalIndex(Addr &PC); + + /** Array of counters that make up the local predictor. */ + std::vector localCtrs; + + /** Size of the local predictor. */ + unsigned localPredictorSize; + + /** Number of sets. */ + unsigned localPredictorSets; + + /** Number of bits of the local predictor's counters. */ + unsigned localCtrBits; + + /** Number of bits to shift the PC when calculating index. */ + unsigned instShiftAmt; + + /** Mask to get index bits. */ + unsigned indexMask; +}; + +#endif // __CPU_O3_2BIT_LOCAL_PRED_HH__ diff --git a/src/cpu/pred/SConscript b/src/cpu/pred/SConscript new file mode 100644 index 000000000..ce1dab9e2 --- /dev/null +++ b/src/cpu/pred/SConscript @@ -0,0 +1,38 @@ +# -*- mode:python -*- + +# Copyright (c) 2006 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Steve Reinhardt + +Import('*') + +if 'InOrderCPU' in env['CPU_MODELS'] or 'O3CPU' in env['CPU_MODELS']: + Source('2bit_local.cc') + Source('btb.cc') + Source('ras.cc') + Source('tournament.cc') + TraceFlag('FreeList') diff --git a/src/cpu/pred/btb.cc b/src/cpu/pred/btb.cc new file mode 100644 index 000000000..81676aceb --- /dev/null +++ b/src/cpu/pred/btb.cc @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Kevin Lim + */ + +#include "base/intmath.hh" +#include "base/trace.hh" +#include "cpu/pred/btb.hh" + +DefaultBTB::DefaultBTB(unsigned _numEntries, + unsigned _tagBits, + unsigned _instShiftAmt) + : numEntries(_numEntries), + tagBits(_tagBits), + instShiftAmt(_instShiftAmt) +{ + DPRINTF(Fetch, "BTB: Creating BTB object.\n"); + + if (!isPowerOf2(numEntries)) { + fatal("BTB entries is not a power of 2!"); + } + + btb.resize(numEntries); + + for (int i = 0; i < numEntries; ++i) { + btb[i].valid = false; + } + + idxMask = numEntries - 1; + + tagMask = (1 << tagBits) - 1; + + tagShiftAmt = instShiftAmt + floorLog2(numEntries); +} + +void +DefaultBTB::reset() +{ + for (int i = 0; i < numEntries; ++i) { + btb[i].valid = false; + } +} + +inline +unsigned +DefaultBTB::getIndex(const Addr &inst_PC) +{ + // Need to shift PC over by the word offset. + return (inst_PC >> instShiftAmt) & idxMask; +} + +inline +Addr +DefaultBTB::getTag(const Addr &inst_PC) +{ + return (inst_PC >> tagShiftAmt) & tagMask; +} + +bool +DefaultBTB::valid(const Addr &inst_PC, ThreadID tid) +{ + unsigned btb_idx = getIndex(inst_PC); + + Addr inst_tag = getTag(inst_PC); + + assert(btb_idx < numEntries); + + if (btb[btb_idx].valid + && inst_tag == btb[btb_idx].tag + && btb[btb_idx].tid == tid) { + return true; + } else { + return false; + } +} + +// @todo Create some sort of return struct that has both whether or not the +// address is valid, and also the address. For now will just use addr = 0 to +// represent invalid entry. +Addr +DefaultBTB::lookup(const Addr &inst_PC, ThreadID tid) +{ + unsigned btb_idx = getIndex(inst_PC); + + Addr inst_tag = getTag(inst_PC); + + assert(btb_idx < numEntries); + + if (btb[btb_idx].valid + && inst_tag == btb[btb_idx].tag + && btb[btb_idx].tid == tid) { + return btb[btb_idx].target; + } else { + return 0; + } +} + +void +DefaultBTB::update(const Addr &inst_PC, const Addr &target, ThreadID tid) +{ + unsigned btb_idx = getIndex(inst_PC); + + assert(btb_idx < numEntries); + + btb[btb_idx].tid = tid; + btb[btb_idx].valid = true; + btb[btb_idx].target = target; + btb[btb_idx].tag = getTag(inst_PC); +} diff --git a/src/cpu/pred/btb.hh b/src/cpu/pred/btb.hh new file mode 100644 index 000000000..6557522e0 --- /dev/null +++ b/src/cpu/pred/btb.hh @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Kevin Lim + */ + +#ifndef __CPU_O3_BTB_HH__ +#define __CPU_O3_BTB_HH__ + +#include "base/misc.hh" +#include "base/types.hh" + +class DefaultBTB +{ + private: + struct BTBEntry + { + BTBEntry() + : tag(0), target(0), valid(false) + { + } + + /** The entry's tag. */ + Addr tag; + + /** The entry's target. */ + Addr target; + + /** The entry's thread id. */ + ThreadID tid; + + /** Whether or not the entry is valid. */ + bool valid; + }; + + public: + /** Creates a BTB with the given number of entries, number of bits per + * tag, and instruction offset amount. + * @param numEntries Number of entries for the BTB. + * @param tagBits Number of bits for each tag in the BTB. + * @param instShiftAmt Offset amount for instructions to ignore alignment. + */ + DefaultBTB(unsigned numEntries, unsigned tagBits, + unsigned instShiftAmt); + + void reset(); + + /** Looks up an address in the BTB. Must call valid() first on the address. + * @param inst_PC The address of the branch to look up. + * @param tid The thread id. + * @return Returns the target of the branch. + */ + Addr lookup(const Addr &inst_PC, ThreadID tid); + + /** Checks if a branch is in the BTB. + * @param inst_PC The address of the branch to look up. + * @param tid The thread id. + * @return Whether or not the branch exists in the BTB. + */ + bool valid(const Addr &inst_PC, ThreadID tid); + + /** Updates the BTB with the target of a branch. + * @param inst_PC The address of the branch being updated. + * @param target_PC The target address of the branch. + * @param tid The thread id. + */ + void update(const Addr &inst_PC, const Addr &target_PC, + ThreadID tid); + + private: + /** Returns the index into the BTB, based on the branch's PC. + * @param inst_PC The branch to look up. + * @return Returns the index into the BTB. + */ + inline unsigned getIndex(const Addr &inst_PC); + + /** Returns the tag bits of a given address. + * @param inst_PC The branch's address. + * @return Returns the tag bits. + */ + inline Addr getTag(const Addr &inst_PC); + + /** The actual BTB. */ + std::vector btb; + + /** The number of entries in the BTB. */ + unsigned numEntries; + + /** The index mask. */ + unsigned idxMask; + + /** The number of tag bits per entry. */ + unsigned tagBits; + + /** The tag mask. */ + unsigned tagMask; + + /** Number of bits to shift PC when calculating index. */ + unsigned instShiftAmt; + + /** Number of bits to shift PC when calculating tag. */ + unsigned tagShiftAmt; +}; + +#endif // __CPU_O3_BTB_HH__ diff --git a/src/cpu/pred/ras.cc b/src/cpu/pred/ras.cc new file mode 100644 index 000000000..5af188749 --- /dev/null +++ b/src/cpu/pred/ras.cc @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Kevin Lim + */ + +#include "cpu/pred/ras.hh" + +void +ReturnAddrStack::init(unsigned _numEntries) +{ + numEntries = _numEntries; + usedEntries = 0; + tos = 0; + + addrStack.resize(numEntries); + + for (int i = 0; i < numEntries; ++i) + addrStack[i] = 0; +} + +void +ReturnAddrStack::reset() +{ + usedEntries = 0; + tos = 0; + for (int i = 0; i < numEntries; ++i) + addrStack[i] = 0; +} + +void +ReturnAddrStack::push(const Addr &return_addr) +{ + incrTos(); + + addrStack[tos] = return_addr; + + if (usedEntries != numEntries) { + ++usedEntries; + } +} + +void +ReturnAddrStack::pop() +{ + if (usedEntries > 0) { + --usedEntries; + } + + decrTos(); +} + +void +ReturnAddrStack::restore(unsigned top_entry_idx, + const Addr &restored_target) +{ + tos = top_entry_idx; + + addrStack[tos] = restored_target; +} diff --git a/src/cpu/pred/ras.hh b/src/cpu/pred/ras.hh new file mode 100644 index 000000000..a36faf79a --- /dev/null +++ b/src/cpu/pred/ras.hh @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Kevin Lim + */ + +#ifndef __CPU_O3_RAS_HH__ +#define __CPU_O3_RAS_HH__ + +#include + +#include "base/types.hh" + +/** Return address stack class, implements a simple RAS. */ +class ReturnAddrStack +{ + public: + /** Creates a return address stack, but init() must be called prior to + * use. + */ + ReturnAddrStack() {} + + /** Initializes RAS with a specified number of entries. + * @param numEntries Number of entries in the RAS. + */ + void init(unsigned numEntries); + + void reset(); + + /** Returns the top address on the RAS. */ + Addr top() + { return addrStack[tos]; } + + /** Returns the index of the top of the RAS. */ + unsigned topIdx() + { return tos; } + + /** Pushes an address onto the RAS. */ + void push(const Addr &return_addr); + + /** Pops the top address from the RAS. */ + void pop(); + + /** Changes index to the top of the RAS, and replaces the top address with + * a new target. + * @param top_entry_idx The index of the RAS that will now be the top. + * @param restored_target The new target address of the new top of the RAS. + */ + void restore(unsigned top_entry_idx, const Addr &restored_target); + + bool empty() { return usedEntries == 0; } + + bool full() { return usedEntries == numEntries; } + private: + /** Increments the top of stack index. */ + inline void incrTos() + { if (++tos == numEntries) tos = 0; } + + /** Decrements the top of stack index. */ + inline void decrTos() + { tos = (tos == 0 ? numEntries - 1 : tos - 1); } + + /** The RAS itself. */ + std::vector addrStack; + + /** The number of entries in the RAS. */ + unsigned numEntries; + + /** The number of used entries in the RAS. */ + unsigned usedEntries; + + /** The top of stack index. */ + unsigned tos; +}; + +#endif // __CPU_O3_RAS_HH__ diff --git a/src/cpu/pred/tournament.cc b/src/cpu/pred/tournament.cc new file mode 100644 index 000000000..223e45333 --- /dev/null +++ b/src/cpu/pred/tournament.cc @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2004-2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Kevin Lim + */ + +#include "base/intmath.hh" +#include "cpu/pred/tournament.hh" + +TournamentBP::TournamentBP(unsigned _localPredictorSize, + unsigned _localCtrBits, + unsigned _localHistoryTableSize, + unsigned _localHistoryBits, + unsigned _globalPredictorSize, + unsigned _globalCtrBits, + unsigned _globalHistoryBits, + unsigned _choicePredictorSize, + unsigned _choiceCtrBits, + unsigned _instShiftAmt) + : localPredictorSize(_localPredictorSize), + localCtrBits(_localCtrBits), + localHistoryTableSize(_localHistoryTableSize), + localHistoryBits(_localHistoryBits), + globalPredictorSize(_globalPredictorSize), + globalCtrBits(_globalCtrBits), + globalHistoryBits(_globalHistoryBits), + choicePredictorSize(_globalPredictorSize), + choiceCtrBits(_choiceCtrBits), + instShiftAmt(_instShiftAmt) +{ + if (!isPowerOf2(localPredictorSize)) { + fatal("Invalid local predictor size!\n"); + } + + //Setup the array of counters for the local predictor + localCtrs.resize(localPredictorSize); + + for (int i = 0; i < localPredictorSize; ++i) + localCtrs[i].setBits(localCtrBits); + + localPredictorMask = floorPow2(localPredictorSize) - 1; + + if (!isPowerOf2(localHistoryTableSize)) { + fatal("Invalid local history table size!\n"); + } + + //Setup the history table for the local table + localHistoryTable.resize(localHistoryTableSize); + + for (int i = 0; i < localHistoryTableSize; ++i) + localHistoryTable[i] = 0; + + // Setup the local history mask + localHistoryMask = (1 << localHistoryBits) - 1; + + if (!isPowerOf2(globalPredictorSize)) { + fatal("Invalid global predictor size!\n"); + } + + //Setup the array of counters for the global predictor + globalCtrs.resize(globalPredictorSize); + + for (int i = 0; i < globalPredictorSize; ++i) + globalCtrs[i].setBits(globalCtrBits); + + //Clear the global history + globalHistory = 0; + // Setup the global history mask + globalHistoryMask = (1 << globalHistoryBits) - 1; + + if (!isPowerOf2(choicePredictorSize)) { + fatal("Invalid choice predictor size!\n"); + } + + //Setup the array of counters for the choice predictor + choiceCtrs.resize(choicePredictorSize); + + for (int i = 0; i < choicePredictorSize; ++i) + choiceCtrs[i].setBits(choiceCtrBits); + + // @todo: Allow for different thresholds between the predictors. + threshold = (1 << (localCtrBits - 1)) - 1; + threshold = threshold / 2; +} + +inline +unsigned +TournamentBP::calcLocHistIdx(Addr &branch_addr) +{ + // Get low order bits after removing instruction offset. + return (branch_addr >> instShiftAmt) & (localHistoryTableSize - 1); +} + +inline +void +TournamentBP::updateGlobalHistTaken() +{ + globalHistory = (globalHistory << 1) | 1; + globalHistory = globalHistory & globalHistoryMask; +} + +inline +void +TournamentBP::updateGlobalHistNotTaken() +{ + globalHistory = (globalHistory << 1); + globalHistory = globalHistory & globalHistoryMask; +} + +inline +void +TournamentBP::updateLocalHistTaken(unsigned local_history_idx) +{ + localHistoryTable[local_history_idx] = + (localHistoryTable[local_history_idx] << 1) | 1; +} + +inline +void +TournamentBP::updateLocalHistNotTaken(unsigned local_history_idx) +{ + localHistoryTable[local_history_idx] = + (localHistoryTable[local_history_idx] << 1); +} + +bool +TournamentBP::lookup(Addr &branch_addr, void * &bp_history) +{ + bool local_prediction; + unsigned local_history_idx; + unsigned local_predictor_idx; + + bool global_prediction; + bool choice_prediction; + + //Lookup in the local predictor to get its branch prediction + local_history_idx = calcLocHistIdx(branch_addr); + local_predictor_idx = localHistoryTable[local_history_idx] + & localPredictorMask; + local_prediction = localCtrs[local_predictor_idx].read() > threshold; + + //Lookup in the global predictor to get its branch prediction + global_prediction = globalCtrs[globalHistory].read() > threshold; + + //Lookup in the choice predictor to see which one to use + choice_prediction = choiceCtrs[globalHistory].read() > threshold; + + // Create BPHistory and pass it back to be recorded. + BPHistory *history = new BPHistory; + history->globalHistory = globalHistory; + history->localPredTaken = local_prediction; + history->globalPredTaken = global_prediction; + history->globalUsed = choice_prediction; + bp_history = (void *)history; + + assert(globalHistory < globalPredictorSize && + local_history_idx < localHistoryTableSize && + local_predictor_idx < localPredictorSize); + + // Commented code is for doing speculative update of counters and + // all histories. + if (choice_prediction) { + if (global_prediction) { +// updateHistoriesTaken(local_history_idx); +// globalCtrs[globalHistory].increment(); +// localCtrs[local_history_idx].increment(); + updateGlobalHistTaken(); + return true; + } else { +// updateHistoriesNotTaken(local_history_idx); +// globalCtrs[globalHistory].decrement(); +// localCtrs[local_history_idx].decrement(); + updateGlobalHistNotTaken(); + return false; + } + } else { + if (local_prediction) { +// updateHistoriesTaken(local_history_idx); +// globalCtrs[globalHistory].increment(); +// localCtrs[local_history_idx].increment(); + updateGlobalHistTaken(); + return true; + } else { +// updateHistoriesNotTaken(local_history_idx); +// globalCtrs[globalHistory].decrement(); +// localCtrs[local_history_idx].decrement(); + updateGlobalHistNotTaken(); + return false; + } + } +} + +void +TournamentBP::uncondBr(void * &bp_history) +{ + // Create BPHistory and pass it back to be recorded. + BPHistory *history = new BPHistory; + history->globalHistory = globalHistory; + history->localPredTaken = true; + history->globalPredTaken = true; + bp_history = static_cast(history); + + updateGlobalHistTaken(); +} + +void +TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history) +{ + unsigned local_history_idx; + unsigned local_predictor_idx; + unsigned local_predictor_hist; + + // Get the local predictor's current prediction + local_history_idx = calcLocHistIdx(branch_addr); + local_predictor_hist = localHistoryTable[local_history_idx]; + local_predictor_idx = local_predictor_hist & localPredictorMask; + + // Update the choice predictor to tell it which one was correct if + // there was a prediction. + if (bp_history) { + BPHistory *history = static_cast(bp_history); + if (history->localPredTaken != history->globalPredTaken) { + // If the local prediction matches the actual outcome, + // decerement the counter. Otherwise increment the + // counter. + if (history->localPredTaken == taken) { + choiceCtrs[globalHistory].decrement(); + } else if (history->globalPredTaken == taken){ + choiceCtrs[globalHistory].increment(); + } + } + + // We're done with this history, now delete it. + delete history; + } + + assert(globalHistory < globalPredictorSize && + local_history_idx < localHistoryTableSize && + local_predictor_idx < localPredictorSize); + + // Update the counters and local history with the proper + // resolution of the branch. Global history is updated + // speculatively and restored upon squash() calls, so it does not + // need to be updated. + if (taken) { + localCtrs[local_predictor_idx].increment(); + globalCtrs[globalHistory].increment(); + + updateLocalHistTaken(local_history_idx); + } else { + localCtrs[local_predictor_idx].decrement(); + globalCtrs[globalHistory].decrement(); + + updateLocalHistNotTaken(local_history_idx); + } +} + +void +TournamentBP::squash(void *bp_history) +{ + BPHistory *history = static_cast(bp_history); + + // Restore global history to state prior to this branch. + globalHistory = history->globalHistory; + + // Delete this BPHistory now that we're done with it. + delete history; +} + +#ifdef DEBUG +int +TournamentBP::BPHistory::newCount = 0; +#endif diff --git a/src/cpu/pred/tournament.hh b/src/cpu/pred/tournament.hh new file mode 100644 index 000000000..96bd43ed6 --- /dev/null +++ b/src/cpu/pred/tournament.hh @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2004-2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Kevin Lim + */ + +#ifndef __CPU_O3_TOURNAMENT_PRED_HH__ +#define __CPU_O3_TOURNAMENT_PRED_HH__ + +#include + +#include "base/types.hh" +#include "cpu/o3/sat_counter.hh" + +/** + * Implements a tournament branch predictor, hopefully identical to the one + * used in the 21264. It has a local predictor, which uses a local history + * table to index into a table of counters, and a global predictor, which + * uses a global history to index into a table of counters. A choice + * predictor chooses between the two. Only the global history register + * is speculatively updated, the rest are updated upon branches committing + * or misspeculating. + */ +class TournamentBP +{ + public: + /** + * Default branch predictor constructor. + */ + TournamentBP(unsigned localPredictorSize, + unsigned localCtrBits, + unsigned localHistoryTableSize, + unsigned localHistoryBits, + unsigned globalPredictorSize, + unsigned globalHistoryBits, + unsigned globalCtrBits, + unsigned choicePredictorSize, + unsigned choiceCtrBits, + unsigned instShiftAmt); + + /** + * Looks up the given address in the branch predictor and returns + * a true/false value as to whether it is taken. Also creates a + * BPHistory object to store any state it will need on squash/update. + * @param branch_addr The address of the branch to look up. + * @param bp_history Pointer that will be set to the BPHistory object. + * @return Whether or not the branch is taken. + */ + bool lookup(Addr &branch_addr, void * &bp_history); + + /** + * Records that there was an unconditional branch, and modifies + * the bp history to point to an object that has the previous + * global history stored in it. + * @param bp_history Pointer that will be set to the BPHistory object. + */ + void uncondBr(void * &bp_history); + + /** + * Updates the branch predictor with the actual result of a branch. + * @param branch_addr The address of the branch to update. + * @param taken Whether or not the branch was taken. + * @param bp_history Pointer to the BPHistory object that was created + * when the branch was predicted. + */ + void update(Addr &branch_addr, bool taken, void *bp_history); + + /** + * Restores the global branch history on a squash. + * @param bp_history Pointer to the BPHistory object that has the + * previous global branch history in it. + */ + void squash(void *bp_history); + + /** Returns the global history. */ + inline unsigned readGlobalHist() { return globalHistory; } + + private: + /** + * Returns if the branch should be taken or not, given a counter + * value. + * @param count The counter value. + */ + inline bool getPrediction(uint8_t &count); + + /** + * Returns the local history index, given a branch address. + * @param branch_addr The branch's PC address. + */ + inline unsigned calcLocHistIdx(Addr &branch_addr); + + /** Updates global history as taken. */ + inline void updateGlobalHistTaken(); + + /** Updates global history as not taken. */ + inline void updateGlobalHistNotTaken(); + + /** + * Updates local histories as taken. + * @param local_history_idx The local history table entry that + * will be updated. + */ + inline void updateLocalHistTaken(unsigned local_history_idx); + + /** + * Updates local histories as not taken. + * @param local_history_idx The local history table entry that + * will be updated. + */ + inline void updateLocalHistNotTaken(unsigned local_history_idx); + + /** + * The branch history information that is created upon predicting + * a branch. It will be passed back upon updating and squashing, + * when the BP can use this information to update/restore its + * state properly. + */ + struct BPHistory { +#ifdef DEBUG + BPHistory() + { newCount++; } + ~BPHistory() + { newCount--; } + + static int newCount; +#endif + unsigned globalHistory; + bool localPredTaken; + bool globalPredTaken; + bool globalUsed; + }; + + /** Local counters. */ + std::vector localCtrs; + + /** Size of the local predictor. */ + unsigned localPredictorSize; + + /** Mask to get the proper index bits into the predictor. */ + unsigned localPredictorMask; + + /** Number of bits of the local predictor's counters. */ + unsigned localCtrBits; + + /** Array of local history table entries. */ + std::vector localHistoryTable; + + /** Size of the local history table. */ + unsigned localHistoryTableSize; + + /** Number of bits for each entry of the local history table. + * @todo Doesn't this come from the size of the local predictor? + */ + unsigned localHistoryBits; + + /** Mask to get the proper local history. */ + unsigned localHistoryMask; + + /** Array of counters that make up the global predictor. */ + std::vector globalCtrs; + + /** Size of the global predictor. */ + unsigned globalPredictorSize; + + /** Number of bits of the global predictor's counters. */ + unsigned globalCtrBits; + + /** Global history register. */ + unsigned globalHistory; + + /** Number of bits for the global history. */ + unsigned globalHistoryBits; + + /** Mask to get the proper global history. */ + unsigned globalHistoryMask; + + /** Array of counters that make up the choice predictor. */ + std::vector choiceCtrs; + + /** Size of the choice predictor (identical to the global predictor). */ + unsigned choicePredictorSize; + + /** Number of bits of the choice predictor's counters. */ + unsigned choiceCtrBits; + + /** Number of bits to shift the instruction over to get rid of the word + * offset. + */ + unsigned instShiftAmt; + + /** Threshold for the counter value; above the threshold is taken, + * equal to or below the threshold is not taken. + */ + unsigned threshold; +}; + +#endif // __CPU_O3_TOURNAMENT_PRED_HH__ diff --git a/src/cpu/ras.cc b/src/cpu/ras.cc deleted file mode 100644 index f9939259a..000000000 --- a/src/cpu/ras.cc +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2004-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Kevin Lim - */ - -#include "cpu/o3/ras.hh" - -void -ReturnAddrStack::init(unsigned _numEntries) -{ - numEntries = _numEntries; - usedEntries = 0; - tos = 0; - - addrStack.resize(numEntries); - - for (int i = 0; i < numEntries; ++i) - addrStack[i] = 0; -} - -void -ReturnAddrStack::reset() -{ - usedEntries = 0; - tos = 0; - for (int i = 0; i < numEntries; ++i) - addrStack[i] = 0; -} - -void -ReturnAddrStack::push(const Addr &return_addr) -{ - incrTos(); - - addrStack[tos] = return_addr; - - if (usedEntries != numEntries) { - ++usedEntries; - } -} - -void -ReturnAddrStack::pop() -{ - if (usedEntries > 0) { - --usedEntries; - } - - decrTos(); -} - -void -ReturnAddrStack::restore(unsigned top_entry_idx, - const Addr &restored_target) -{ - tos = top_entry_idx; - - addrStack[tos] = restored_target; -} diff --git a/src/cpu/tournament_pred.cc b/src/cpu/tournament_pred.cc deleted file mode 100644 index ffb941c77..000000000 --- a/src/cpu/tournament_pred.cc +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (c) 2004-2006 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Kevin Lim - */ - -#include "base/intmath.hh" -#include "cpu/o3/tournament_pred.hh" - -TournamentBP::TournamentBP(unsigned _localPredictorSize, - unsigned _localCtrBits, - unsigned _localHistoryTableSize, - unsigned _localHistoryBits, - unsigned _globalPredictorSize, - unsigned _globalCtrBits, - unsigned _globalHistoryBits, - unsigned _choicePredictorSize, - unsigned _choiceCtrBits, - unsigned _instShiftAmt) - : localPredictorSize(_localPredictorSize), - localCtrBits(_localCtrBits), - localHistoryTableSize(_localHistoryTableSize), - localHistoryBits(_localHistoryBits), - globalPredictorSize(_globalPredictorSize), - globalCtrBits(_globalCtrBits), - globalHistoryBits(_globalHistoryBits), - choicePredictorSize(_globalPredictorSize), - choiceCtrBits(_choiceCtrBits), - instShiftAmt(_instShiftAmt) -{ - if (!isPowerOf2(localPredictorSize)) { - fatal("Invalid local predictor size!\n"); - } - - //Setup the array of counters for the local predictor - localCtrs.resize(localPredictorSize); - - for (int i = 0; i < localPredictorSize; ++i) - localCtrs[i].setBits(localCtrBits); - - localPredictorMask = floorPow2(localPredictorSize) - 1; - - if (!isPowerOf2(localHistoryTableSize)) { - fatal("Invalid local history table size!\n"); - } - - //Setup the history table for the local table - localHistoryTable.resize(localHistoryTableSize); - - for (int i = 0; i < localHistoryTableSize; ++i) - localHistoryTable[i] = 0; - - // Setup the local history mask - localHistoryMask = (1 << localHistoryBits) - 1; - - if (!isPowerOf2(globalPredictorSize)) { - fatal("Invalid global predictor size!\n"); - } - - //Setup the array of counters for the global predictor - globalCtrs.resize(globalPredictorSize); - - for (int i = 0; i < globalPredictorSize; ++i) - globalCtrs[i].setBits(globalCtrBits); - - //Clear the global history - globalHistory = 0; - // Setup the global history mask - globalHistoryMask = (1 << globalHistoryBits) - 1; - - if (!isPowerOf2(choicePredictorSize)) { - fatal("Invalid choice predictor size!\n"); - } - - //Setup the array of counters for the choice predictor - choiceCtrs.resize(choicePredictorSize); - - for (int i = 0; i < choicePredictorSize; ++i) - choiceCtrs[i].setBits(choiceCtrBits); - - // @todo: Allow for different thresholds between the predictors. - threshold = (1 << (localCtrBits - 1)) - 1; - threshold = threshold / 2; -} - -inline -unsigned -TournamentBP::calcLocHistIdx(Addr &branch_addr) -{ - // Get low order bits after removing instruction offset. - return (branch_addr >> instShiftAmt) & (localHistoryTableSize - 1); -} - -inline -void -TournamentBP::updateGlobalHistTaken() -{ - globalHistory = (globalHistory << 1) | 1; - globalHistory = globalHistory & globalHistoryMask; -} - -inline -void -TournamentBP::updateGlobalHistNotTaken() -{ - globalHistory = (globalHistory << 1); - globalHistory = globalHistory & globalHistoryMask; -} - -inline -void -TournamentBP::updateLocalHistTaken(unsigned local_history_idx) -{ - localHistoryTable[local_history_idx] = - (localHistoryTable[local_history_idx] << 1) | 1; -} - -inline -void -TournamentBP::updateLocalHistNotTaken(unsigned local_history_idx) -{ - localHistoryTable[local_history_idx] = - (localHistoryTable[local_history_idx] << 1); -} - -bool -TournamentBP::lookup(Addr &branch_addr, void * &bp_history) -{ - bool local_prediction; - unsigned local_history_idx; - unsigned local_predictor_idx; - - bool global_prediction; - bool choice_prediction; - - //Lookup in the local predictor to get its branch prediction - local_history_idx = calcLocHistIdx(branch_addr); - local_predictor_idx = localHistoryTable[local_history_idx] - & localPredictorMask; - local_prediction = localCtrs[local_predictor_idx].read() > threshold; - - //Lookup in the global predictor to get its branch prediction - global_prediction = globalCtrs[globalHistory].read() > threshold; - - //Lookup in the choice predictor to see which one to use - choice_prediction = choiceCtrs[globalHistory].read() > threshold; - - // Create BPHistory and pass it back to be recorded. - BPHistory *history = new BPHistory; - history->globalHistory = globalHistory; - history->localPredTaken = local_prediction; - history->globalPredTaken = global_prediction; - history->globalUsed = choice_prediction; - bp_history = (void *)history; - - assert(globalHistory < globalPredictorSize && - local_history_idx < localHistoryTableSize && - local_predictor_idx < localPredictorSize); - - // Commented code is for doing speculative update of counters and - // all histories. - if (choice_prediction) { - if (global_prediction) { -// updateHistoriesTaken(local_history_idx); -// globalCtrs[globalHistory].increment(); -// localCtrs[local_history_idx].increment(); - updateGlobalHistTaken(); - return true; - } else { -// updateHistoriesNotTaken(local_history_idx); -// globalCtrs[globalHistory].decrement(); -// localCtrs[local_history_idx].decrement(); - updateGlobalHistNotTaken(); - return false; - } - } else { - if (local_prediction) { -// updateHistoriesTaken(local_history_idx); -// globalCtrs[globalHistory].increment(); -// localCtrs[local_history_idx].increment(); - updateGlobalHistTaken(); - return true; - } else { -// updateHistoriesNotTaken(local_history_idx); -// globalCtrs[globalHistory].decrement(); -// localCtrs[local_history_idx].decrement(); - updateGlobalHistNotTaken(); - return false; - } - } -} - -void -TournamentBP::uncondBr(void * &bp_history) -{ - // Create BPHistory and pass it back to be recorded. - BPHistory *history = new BPHistory; - history->globalHistory = globalHistory; - history->localPredTaken = true; - history->globalPredTaken = true; - bp_history = static_cast(history); - - updateGlobalHistTaken(); -} - -void -TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history) -{ - unsigned local_history_idx; - unsigned local_predictor_idx; - unsigned local_predictor_hist; - - // Get the local predictor's current prediction - local_history_idx = calcLocHistIdx(branch_addr); - local_predictor_hist = localHistoryTable[local_history_idx]; - local_predictor_idx = local_predictor_hist & localPredictorMask; - - // Update the choice predictor to tell it which one was correct if - // there was a prediction. - if (bp_history) { - BPHistory *history = static_cast(bp_history); - if (history->localPredTaken != history->globalPredTaken) { - // If the local prediction matches the actual outcome, - // decerement the counter. Otherwise increment the - // counter. - if (history->localPredTaken == taken) { - choiceCtrs[globalHistory].decrement(); - } else if (history->globalPredTaken == taken){ - choiceCtrs[globalHistory].increment(); - } - } - - // We're done with this history, now delete it. - delete history; - } - - assert(globalHistory < globalPredictorSize && - local_history_idx < localHistoryTableSize && - local_predictor_idx < localPredictorSize); - - // Update the counters and local history with the proper - // resolution of the branch. Global history is updated - // speculatively and restored upon squash() calls, so it does not - // need to be updated. - if (taken) { - localCtrs[local_predictor_idx].increment(); - globalCtrs[globalHistory].increment(); - - updateLocalHistTaken(local_history_idx); - } else { - localCtrs[local_predictor_idx].decrement(); - globalCtrs[globalHistory].decrement(); - - updateLocalHistNotTaken(local_history_idx); - } -} - -void -TournamentBP::squash(void *bp_history) -{ - BPHistory *history = static_cast(bp_history); - - // Restore global history to state prior to this branch. - globalHistory = history->globalHistory; - - // Delete this BPHistory now that we're done with it. - delete history; -} - -#ifdef DEBUG -int -TournamentBP::BPHistory::newCount = 0; -#endif