Minor format tweaks on config file documentation.
[gem5.git] / cpu / beta_cpu / decode_impl.hh
index 9d88f94acfb1db31d97ebb2e1afe5c4dc0e0da28..af848341d5aa7e4d7ae73fdb812f4b5cb422278d 100644 (file)
@@ -1,3 +1,31 @@
+/*
+ * 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.
+ */
+
 #include "cpu/beta_cpu/decode.hh"
 
 template<class Impl>
@@ -98,6 +126,13 @@ SimpleDecode<Impl>::setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr)
     fromFetch = fetchQueue->getWire(-fetchToDecodeDelay);
 }
 
+template<class Impl>
+inline bool
+SimpleDecode<Impl>::fetchInstsValid()
+{
+    return fromFetch->size > 0;
+}
+
 template<class Impl>
 void
 SimpleDecode<Impl>::block()
@@ -156,14 +191,14 @@ SimpleDecode<Impl>::squash(DynInstPtr &inst)
     // Set status to squashing.
     _status = Squashing;
 
-    // Maybe advance the time buffer?  Not sure what to do in the normal
-    // case.
-
     // Clear the skid buffer in case it has any data in it.
-    while (!skidBuffer.empty())
-    {
+    while (!skidBuffer.empty()) {
         skidBuffer.pop();
     }
+
+    // Squash instructions up until this one
+    // Slightly unrealistic!
+    cpu->removeInstsUntil(inst->seqNum);
 }
 
 template<class Impl>
@@ -205,7 +240,7 @@ SimpleDecode<Impl>::tick()
         if (_status == Unblocking) {
             ++decodeUnblockCycles;
 
-            if (fromFetch->size > 0) {
+            if (fetchInstsValid()) {
                 // Add the current inputs to the skid buffer so they can be
                 // reprocessed when this stage unblocks.
                 skidBuffer.push(*fromFetch);
@@ -216,7 +251,7 @@ SimpleDecode<Impl>::tick()
     } else if (_status == Blocked) {
         ++decodeBlockedCycles;
 
-        if (fromFetch->size > 0) {
+        if (fetchInstsValid()) {
             block();
         }
 
@@ -240,12 +275,12 @@ SimpleDecode<Impl>::tick()
             squash();
         }
     } else if (_status == Squashing) {
-        ++decodeSquashCycles;
-
         if (!fromCommit->commitInfo.squash &&
             !fromCommit->commitInfo.robSquashing) {
             _status = Running;
         } else if (fromCommit->commitInfo.squash) {
+            ++decodeSquashCycles;
+
             squash();
         }
     }
@@ -264,8 +299,7 @@ SimpleDecode<Impl>::decode()
     // Check time buffer if being told to stall.
     if (fromRename->renameInfo.stall ||
         fromIEW->iewInfo.stall ||
-        fromCommit->commitInfo.stall)
-    {
+        fromCommit->commitInfo.stall) {
         block();
         return;
     }
@@ -273,7 +307,7 @@ SimpleDecode<Impl>::decode()
     // Check fetch queue to see if instructions are available.
     // If no available instructions, do nothing, unless this stage is
     // currently unblocking.
-    if (fromFetch->size == 0 && _status != Unblocking) {
+    if (!fetchInstsValid() && _status != Unblocking) {
         DPRINTF(Decode, "Decode: Nothing to do, breaking out early.\n");
         // Should I change the status to idle?
         ++decodeIdleCycles;
@@ -286,7 +320,7 @@ SimpleDecode<Impl>::decode()
     unsigned to_rename_index = 0;
 
     int insts_available = _status == Unblocking ?
-        skidBuffer.front().size :
+        skidBuffer.front().size - numInst :
         fromFetch->size;
 
     // Debug block...
@@ -308,8 +342,8 @@ SimpleDecode<Impl>::decode()
     }
 #endif
 
-     while (insts_available > 0)
-     {
+    while (insts_available > 0)
+    {
         DPRINTF(Decode, "Decode: Sending instruction to rename.\n");
 
         inst = _status == Unblocking ? skidBuffer.front().insts[numInst] :
@@ -331,6 +365,16 @@ SimpleDecode<Impl>::decode()
             continue;
         }
 
+
+        // Also check if instructions have no source registers.  Mark
+        // them as ready to issue at any time.  Not sure if this check
+        // should exist here or at a later stage; however it doesn't matter
+        // too much for function correctness.
+        // Isn't this handled by the inst queue?
+        if (inst->numSrcRegs() == 0) {
+            inst->setCanIssue();
+        }
+
         // This current instruction is valid, so add it into the decode
         // queue.  The next instruction may not be valid, so check to
         // see if branches were predicted correctly.
@@ -369,16 +413,6 @@ SimpleDecode<Impl>::decode()
         // addr (either the immediate, or the branch PC + 4) and redirect
         // fetch if it's incorrect.
 
-
-        // Also check if instructions have no source registers.  Mark
-        // them as ready to issue at any time.  Not sure if this check
-        // should exist here or at a later stage; however it doesn't matter
-        // too much for function correctness.
-        // Isn't this handled by the inst queue?
-        if (inst->numSrcRegs() == 0) {
-            inst->setCanIssue();
-        }
-
         // Increment which instruction we're looking at.
         ++numInst;
         ++to_rename_index;