summaryrefslogtreecommitdiff
path: root/cpu/beta_cpu/rob_impl.hh
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/beta_cpu/rob_impl.hh')
-rw-r--r--cpu/beta_cpu/rob_impl.hh311
1 files changed, 0 insertions, 311 deletions
diff --git a/cpu/beta_cpu/rob_impl.hh b/cpu/beta_cpu/rob_impl.hh
deleted file mode 100644
index dd3ffe7e6..000000000
--- a/cpu/beta_cpu/rob_impl.hh
+++ /dev/null
@@ -1,311 +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_BETA_CPU_ROB_IMPL_HH__
-#define __CPU_BETA_CPU_ROB_IMPL_HH__
-
-#include "cpu/beta_cpu/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.
-#ifndef 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_BETA_CPU_ROB_IMPL_HH__