cpu: Fix the usage of const DynInstPtr
[gem5.git] / src / cpu / o3 / decode_impl.hh
index 3def971e989545f063a00fcf8852a3f7971ab91b..51c1b9de161e296625b43f1e19513ad9a0e56200 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2012, 2014 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2004-2006 The Regents of The University of Michigan
  * All rights reserved.
  *
@@ -28,6 +40,9 @@
  * Authors: Kevin Lim
  */
 
+#ifndef __CPU_O3_DECODE_IMPL_HH__
+#define __CPU_O3_DECODE_IMPL_HH__
+
 #include "arch/types.hh"
 #include "base/trace.hh"
 #include "config/the_isa.hh"
 #include "cpu/inst_seq.hh"
 #include "debug/Activity.hh"
 #include "debug/Decode.hh"
+#include "debug/O3PipeView.hh"
 #include "params/DerivO3CPU.hh"
 #include "sim/full_system.hh"
 
-using namespace std;
+// clang complains about std::set being overloaded with Packet::set if
+// we open up the entire namespace std
+using std::list;
 
 template<class Impl>
 DefaultDecode<Impl>::DefaultDecode(O3CPU *_cpu, DerivO3CPUParams *params)
@@ -49,6 +67,26 @@ DefaultDecode<Impl>::DefaultDecode(O3CPU *_cpu, DerivO3CPUParams *params)
       fetchToDecodeDelay(params->fetchToDecodeDelay),
       decodeWidth(params->decodeWidth),
       numThreads(params->numThreads)
+{
+    if (decodeWidth > Impl::MaxWidth)
+        fatal("decodeWidth (%d) is larger than compiled limit (%d),\n"
+             "\tincrease MaxWidth in src/cpu/o3/impl.hh\n",
+             decodeWidth, static_cast<int>(Impl::MaxWidth));
+
+    // @todo: Make into a parameter
+    skidBufferMax = (fetchToDecodeDelay + 1) *  params->fetchWidth;
+}
+
+template<class Impl>
+void
+DefaultDecode<Impl>::startupStage()
+{
+    resetStage();
+}
+
+template<class Impl>
+void
+DefaultDecode<Impl>::resetStage()
 {
     _status = Inactive;
 
@@ -57,12 +95,7 @@ DefaultDecode<Impl>::DefaultDecode(O3CPU *_cpu, DerivO3CPUParams *params)
         decodeStatus[tid] = Idle;
 
         stalls[tid].rename = false;
-        stalls[tid].iew = false;
-        stalls[tid].commit = false;
     }
-
-    // @todo: Make into a parameter
-    skidBufferMax = (fetchToDecodeDelay * params->fetchWidth) + decodeWidth;
 }
 
 template <class Impl>
@@ -162,34 +195,25 @@ DefaultDecode<Impl>::setActiveThreads(std::list<ThreadID> *at_ptr)
 }
 
 template <class Impl>
-bool
-DefaultDecode<Impl>::drain()
+void
+DefaultDecode<Impl>::drainSanityCheck() const
 {
-    // Decode is done draining at any time.
-    cpu->signalDrained();
-    return true;
+    for (ThreadID tid = 0; tid < numThreads; ++tid) {
+        assert(insts[tid].empty());
+        assert(skidBuffer[tid].empty());
+    }
 }
 
 template <class Impl>
-void
-DefaultDecode<Impl>::takeOverFrom()
+bool
+DefaultDecode<Impl>::isDrained() const
 {
-    _status = Inactive;
-
-    // Be sure to reset state and clear out any old instructions.
     for (ThreadID tid = 0; tid < numThreads; ++tid) {
-        decodeStatus[tid] = Idle;
-
-        stalls[tid].rename = false;
-        stalls[tid].iew = false;
-        stalls[tid].commit = false;
-        while (!insts[tid].empty())
-            insts[tid].pop();
-        while (!skidBuffer[tid].empty())
-            skidBuffer[tid].pop();
-        branchCount[tid] = 0;
+        if (!insts[tid].empty() || !skidBuffer[tid].empty() ||
+                (decodeStatus[tid] != Running && decodeStatus[tid] != Idle))
+            return false;
     }
-    wroteToTimeBuffer = false;
+    return true;
 }
 
 template<class Impl>
@@ -201,12 +225,6 @@ DefaultDecode<Impl>::checkStall(ThreadID tid) const
     if (stalls[tid].rename) {
         DPRINTF(Decode,"[tid:%i]: Stall fom Rename stage detected.\n", tid);
         ret_val = true;
-    } else if (stalls[tid].iew) {
-        DPRINTF(Decode,"[tid:%i]: Stall fom IEW stage detected.\n", tid);
-        ret_val = true;
-    } else if (stalls[tid].commit) {
-        DPRINTF(Decode,"[tid:%i]: Stall fom Commit stage detected.\n", tid);
-        ret_val = true;
     }
 
     return ret_val;
@@ -236,7 +254,9 @@ DefaultDecode<Impl>::block(ThreadID tid)
         // Set the status to Blocked.
         decodeStatus[tid] = Blocked;
 
-        if (decodeStatus[tid] != Unblocking) {
+        if (toFetch->decodeUnblock[tid]) {
+            toFetch->decodeUnblock[tid] = false;
+        } else {
             toFetch->decodeBlock[tid] = true;
             wroteToTimeBuffer = true;
         }
@@ -268,7 +288,7 @@ DefaultDecode<Impl>::unblock(ThreadID tid)
 
 template<class Impl>
 void
-DefaultDecode<Impl>::squash(DynInstPtr &inst, ThreadID tid)
+DefaultDecode<Impl>::squash(const DynInstPtr &inst, ThreadID tid)
 {
     DPRINTF(Decode, "[tid:%i]: [sn:%i] Squashing due to incorrect branch "
             "prediction detected at decode.\n", tid, inst->seqNum);
@@ -276,11 +296,15 @@ DefaultDecode<Impl>::squash(DynInstPtr &inst, ThreadID tid)
     // Send back mispredict information.
     toFetch->decodeInfo[tid].branchMispredict = true;
     toFetch->decodeInfo[tid].predIncorrect = true;
+    toFetch->decodeInfo[tid].mispredictInst = inst;
     toFetch->decodeInfo[tid].squash = true;
     toFetch->decodeInfo[tid].doneSeqNum = inst->seqNum;
     toFetch->decodeInfo[tid].nextPC = inst->branchTarget();
     toFetch->decodeInfo[tid].branchTaken = inst->pcState().branching();
     toFetch->decodeInfo[tid].squashInst = inst;
+    if (toFetch->decodeInfo[tid].mispredictInst->isUncondCtrl()) {
+            toFetch->decodeInfo[tid].branchTaken = true;
+    }
 
     InstSeqNum squash_seq_num = inst->seqNum;
 
@@ -375,10 +399,10 @@ DefaultDecode<Impl>::skidInsert(ThreadID tid)
 
         assert(tid == inst->threadNumber);
 
-        DPRINTF(Decode,"Inserting [sn:%lli] PC: %s into decode skidBuffer %i\n",
-                inst->seqNum, inst->pcState(), inst->threadNumber);
-
         skidBuffer[tid].push(inst);
+
+        DPRINTF(Decode,"Inserting [tid:%d][sn:%lli] PC: %s into decode skidBuffer %i\n",
+                inst->threadNumber, inst->seqNum, inst->pcState(), skidBuffer[tid].size());
     }
 
     // @todo: Eventually need to enforce this by not letting a thread
@@ -446,10 +470,6 @@ void
 DefaultDecode<Impl>::sortInsts()
 {
     int insts_from_fetch = fromFetch->size;
-#ifdef DEBUG
-    for (ThreadID tid = 0; tid < numThreads; tid++)
-        assert(insts[tid].empty());
-#endif
     for (int i = 0; i < insts_from_fetch; ++i) {
         insts[fromFetch->insts[i]->threadNumber].push(fromFetch->insts[i]);
     }
@@ -467,24 +487,6 @@ DefaultDecode<Impl>::readStallSignals(ThreadID tid)
         assert(stalls[tid].rename);
         stalls[tid].rename = false;
     }
-
-    if (fromIEW->iewBlock[tid]) {
-        stalls[tid].iew = true;
-    }
-
-    if (fromIEW->iewUnblock[tid]) {
-        assert(stalls[tid].iew);
-        stalls[tid].iew = false;
-    }
-
-    if (fromCommit->commitBlock[tid]) {
-        stalls[tid].commit = true;
-    }
-
-    if (fromCommit->commitUnblock[tid]) {
-        assert(stalls[tid].commit);
-        stalls[tid].commit = false;
-    }
 }
 
 template <class Impl>
@@ -513,16 +515,6 @@ DefaultDecode<Impl>::checkSignalsAndUpdate(ThreadID tid)
         return true;
     }
 
-    // Check ROB squash signals from commit.
-    if (fromCommit->commitInfo[tid].robSquashing) {
-        DPRINTF(Decode, "[tid:%u]: ROB is still squashing.\n", tid);
-
-        // Continue to squash.
-        decodeStatus[tid] = Squashing;
-
-        return true;
-    }
-
     if (checkStall(tid)) {
         return block(tid);
     }
@@ -658,8 +650,6 @@ DefaultDecode<Impl>::decodeInsts(ThreadID tid)
         ++decodeRunCycles;
     }
 
-    DynInstPtr inst;
-
     std::queue<DynInstPtr>
         &insts_to_decode = decodeStatus[tid] == Unblocking ?
         skidBuffer[tid] : insts[tid];
@@ -669,7 +659,7 @@ DefaultDecode<Impl>::decodeInsts(ThreadID tid)
     while (insts_available > 0 && toRenameIndex < decodeWidth) {
         assert(!insts_to_decode.empty());
 
-        inst = insts_to_decode.front();
+        DynInstPtr inst = std::move(insts_to_decode.front());
 
         insts_to_decode.pop();
 
@@ -707,7 +697,9 @@ DefaultDecode<Impl>::decodeInsts(ThreadID tid)
         --insts_available;
 
 #if TRACING_ON
-        inst->decodeTick = curTick();
+        if (DTRACE(O3PipeView)) {
+            inst->decodeTick = curTick() - inst->fetchTick;
+        }
 #endif
 
         // Ensure that if it was predicted as a branch, it really is a
@@ -725,7 +717,11 @@ DefaultDecode<Impl>::decodeInsts(ThreadID tid)
         }
 
         // Go ahead and compute any PC-relative branches.
-        if (inst->isDirectCtrl() && inst->isUncondCtrl()) {
+        // This includes direct unconditional control and
+        // direct conditional control that is predicted taken.
+        if (inst->isDirectCtrl() &&
+           (inst->isUncondCtrl() || inst->readPredTaken()))
+        {
             ++decodeBranchResolved;
 
             if (!(inst->branchTarget() == inst->readPredTarg())) {
@@ -757,3 +753,5 @@ DefaultDecode<Impl>::decodeInsts(ThreadID tid)
         wroteToTimeBuffer = true;
     }
 }
+
+#endif//__CPU_O3_DECODE_IMPL_HH__