diff options
Diffstat (limited to 'cpu/o3/rob_impl.hh')
-rw-r--r-- | cpu/o3/rob_impl.hh | 312 |
1 files changed, 0 insertions, 312 deletions
diff --git a/cpu/o3/rob_impl.hh b/cpu/o3/rob_impl.hh deleted file mode 100644 index e7a5671d9..000000000 --- a/cpu/o3/rob_impl.hh +++ /dev/null @@ -1,312 +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. - */ - -#ifndef __CPU_O3_CPU_ROB_IMPL_HH__ -#define __CPU_O3_CPU_ROB_IMPL_HH__ - -#include "config/full_system.hh" -#include "cpu/o3/rob.hh" - -template <class Impl> -ROB<Impl>::ROB(unsigned _numEntries, unsigned _squashWidth) - : numEntries(_numEntries), - squashWidth(_squashWidth), - numInstsInROB(0), - squashedSeqNum(0) -{ - doneSquashing = true; -} - -template <class Impl> -void -ROB<Impl>::setCPU(FullCPU *cpu_ptr) -{ - cpu = cpu_ptr; - - // Set the tail to the beginning of the CPU instruction list so that - // upon the first instruction being inserted into the ROB, the tail - // iterator can simply be incremented. - tail = cpu->instList.begin(); - - // Set the squash iterator to the end of the instruction list. - squashIt = cpu->instList.end(); -} - -template <class Impl> -int -ROB<Impl>::countInsts() -{ - // Start at 1; if the tail matches cpu->instList.begin(), then there is - // one inst in the ROB. - int return_val = 1; - - // There are quite a few special cases. Do not use this function other - // than for debugging purposes. - if (cpu->instList.begin() == cpu->instList.end()) { - // In this case there are no instructions in the list. The ROB - // must be empty. - return 0; - } else if (tail == cpu->instList.end()) { - // In this case, the tail is not yet pointing to anything valid. - // The ROB must be empty. - return 0; - } - - // Iterate through the ROB from the head to the tail, counting the - // entries. - for (InstIt_t i = cpu->instList.begin(); i != tail; ++i) - { - assert(i != cpu->instList.end()); - ++return_val; - } - - return return_val; - - // Because the head won't be tracked properly until the ROB gets the - // first instruction, and any time that the ROB is empty and has not - // yet gotten the instruction, this function doesn't work. -// return numInstsInROB; -} - -template <class Impl> -void -ROB<Impl>::insertInst(DynInstPtr &inst) -{ - // Make sure we have the right number of instructions. - assert(numInstsInROB == countInsts()); - // Make sure the instruction is valid. - assert(inst); - - DPRINTF(ROB, "ROB: Adding inst PC %#x to the ROB.\n", inst->readPC()); - - // If the ROB is full then exit. - assert(numInstsInROB != numEntries); - - ++numInstsInROB; - - // Increment the tail iterator, moving it one instruction back. - // There is a special case if the ROB was empty prior to this insertion, - // in which case the tail will be pointing at instList.end(). If that - // happens, then reset the tail to the beginning of the list. - if (tail != cpu->instList.end()) { - ++tail; - } else { - tail = cpu->instList.begin(); - } - - // Make sure the tail iterator is actually pointing at the instruction - // added. - assert((*tail) == inst); - - DPRINTF(ROB, "ROB: Now has %d instructions.\n", numInstsInROB); - -} - -// Whatever calls this function needs to ensure that it properly frees up -// registers prior to this function. -template <class Impl> -void -ROB<Impl>::retireHead() -{ - assert(numInstsInROB == countInsts()); - assert(numInstsInROB > 0); - - // Get the head ROB instruction. - DynInstPtr head_inst = cpu->instList.front(); - - // Make certain this can retire. - assert(head_inst->readyToCommit()); - - DPRINTF(ROB, "ROB: Retiring head instruction of the ROB, " - "instruction PC %#x, seq num %i\n", head_inst->readPC(), - head_inst->seqNum); - - // Keep track of how many instructions are in the ROB. - --numInstsInROB; - - // Tell CPU to remove the instruction from the list of instructions. - // A special case is needed if the instruction being retired is the - // only instruction in the ROB; otherwise the tail iterator will become - // invalidated. - cpu->removeFrontInst(head_inst); - - if (numInstsInROB == 0) { - tail = cpu->instList.end(); - } -} - -template <class Impl> -bool -ROB<Impl>::isHeadReady() -{ - if (numInstsInROB != 0) { - return cpu->instList.front()->readyToCommit(); - } - - return false; -} - -template <class Impl> -unsigned -ROB<Impl>::numFreeEntries() -{ - assert(numInstsInROB == countInsts()); - - return numEntries - numInstsInROB; -} - -template <class Impl> -void -ROB<Impl>::doSquash() -{ - DPRINTF(ROB, "ROB: Squashing instructions.\n"); - - assert(squashIt != cpu->instList.end()); - - for (int numSquashed = 0; - numSquashed < squashWidth && (*squashIt)->seqNum != squashedSeqNum; - ++numSquashed) - { - // Ensure that the instruction is younger. - assert((*squashIt)->seqNum > squashedSeqNum); - - DPRINTF(ROB, "ROB: Squashing instruction PC %#x, seq num %i.\n", - (*squashIt)->readPC(), (*squashIt)->seqNum); - - // Mark the instruction as squashed, and ready to commit so that - // it can drain out of the pipeline. - (*squashIt)->setSquashed(); - - (*squashIt)->setCanCommit(); - - // Special case for when squashing due to a syscall. It's possible - // that the squash happened after the head instruction was already - // committed, meaning that (*squashIt)->seqNum != squashedSeqNum - // will never be false. Normally the squash would never be able - // to go past the head of the ROB; in this case it might, so it - // must be handled otherwise it will segfault. -#if !FULL_SYSTEM - if (squashIt == cpu->instList.begin()) { - DPRINTF(ROB, "ROB: Reached head of instruction list while " - "squashing.\n"); - - squashIt = cpu->instList.end(); - - doneSquashing = true; - - return; - } -#endif - - // Move the tail iterator to the next instruction. - squashIt--; - } - - - // Check if ROB is done squashing. - if ((*squashIt)->seqNum == squashedSeqNum) { - DPRINTF(ROB, "ROB: Done squashing instructions.\n"); - - squashIt = cpu->instList.end(); - - doneSquashing = true; - } -} - -template <class Impl> -void -ROB<Impl>::squash(InstSeqNum squash_num) -{ - DPRINTF(ROB, "ROB: Starting to squash within the ROB.\n"); - doneSquashing = false; - - squashedSeqNum = squash_num; - - assert(tail != cpu->instList.end()); - - squashIt = tail; - - doSquash(); -} - -template <class Impl> -uint64_t -ROB<Impl>::readHeadPC() -{ - assert(numInstsInROB == countInsts()); - - DynInstPtr head_inst = cpu->instList.front(); - - return head_inst->readPC(); -} - -template <class Impl> -uint64_t -ROB<Impl>::readHeadNextPC() -{ - assert(numInstsInROB == countInsts()); - - DynInstPtr head_inst = cpu->instList.front(); - - return head_inst->readNextPC(); -} - -template <class Impl> -InstSeqNum -ROB<Impl>::readHeadSeqNum() -{ - // Return the last sequence number that has not been squashed. Other - // stages can use it to squash any instructions younger than the current - // tail. - DynInstPtr head_inst = cpu->instList.front(); - - return head_inst->seqNum; -} - -template <class Impl> -uint64_t -ROB<Impl>::readTailPC() -{ - assert(numInstsInROB == countInsts()); - - assert(tail != cpu->instList.end()); - - return (*tail)->readPC(); -} - -template <class Impl> -InstSeqNum -ROB<Impl>::readTailSeqNum() -{ - // Return the last sequence number that has not been squashed. Other - // stages can use it to squash any instructions younger than the current - // tail. - return (*tail)->seqNum; -} - -#endif // __CPU_O3_CPU_ROB_IMPL_HH__ |