cpu, fastmodel: Remove the old getDTBPtr/getITBPtr virtual methods
[gem5.git] / src / cpu / o3 / decode_impl.hh
index 8b851c032810327f4fb8f3f0aa0891dacb55f404..76cc2cf1045565f4abf0f04226e9d53f2359eca3 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.
  *
  * 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_DECODE_IMPL_HH__
+#define __CPU_O3_DECODE_IMPL_HH__
+
+#include "arch/types.hh"
+#include "base/trace.hh"
+#include "config/the_isa.hh"
 #include "cpu/o3/decode.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"
+
+// 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, const DerivO3CPUParams &params)
+    : cpu(_cpu),
+      renameToDecodeDelay(params.renameToDecodeDelay),
+      iewToDecodeDelay(params.iewToDecodeDelay),
+      commitToDecodeDelay(params.commitToDecodeDelay),
+      fetchToDecodeDelay(params.fetchToDecodeDelay),
+      decodeWidth(params.decodeWidth),
+      numThreads(params.numThreads),
+      stats(_cpu)
+{
+    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;
+    for (int tid = 0; tid < Impl::MaxThreads; tid++) {
+        stalls[tid] = {false};
+        decodeStatus[tid] = Idle;
+        bdelayDoneSeqNum[tid] = 0;
+        squashInst[tid] = nullptr;
+        squashAfterDelaySlot[tid] = 0;
+    }
+}
 
-using namespace std;
+template<class Impl>
+void
+DefaultDecode<Impl>::startupStage()
+{
+    resetStage();
+}
 
 template<class Impl>
-DefaultDecode<Impl>::DefaultDecode(Params *params)
-    : renameToDecodeDelay(params->renameToDecodeDelay),
-      iewToDecodeDelay(params->iewToDecodeDelay),
-      commitToDecodeDelay(params->commitToDecodeDelay),
-      fetchToDecodeDelay(params->fetchToDecodeDelay),
-      decodeWidth(params->decodeWidth),
-      numThreads(params->numberOfThreads)
+void
+DefaultDecode<Impl>::clearStates(ThreadID tid)
+{
+    decodeStatus[tid] = Idle;
+    stalls[tid].rename = false;
+}
+
+template<class Impl>
+void
+DefaultDecode<Impl>::resetStage()
 {
     _status = Inactive;
 
     // Setup status, make sure stall signals are clear.
-    for (int i = 0; i < numThreads; ++i) {
-        decodeStatus[i] = Idle;
+    for (ThreadID tid = 0; tid < numThreads; ++tid) {
+        decodeStatus[tid] = Idle;
 
-        stalls[i].rename = false;
-        stalls[i].iew = false;
-        stalls[i].commit = false;
+        stalls[tid].rename = false;
     }
-
-    // @todo: Make into a parameter
-    skidBufferMax = (fetchToDecodeDelay * params->fetchWidth) + decodeWidth;
 }
 
 template <class Impl>
@@ -64,65 +120,39 @@ DefaultDecode<Impl>::name() const
 }
 
 template <class Impl>
-void
-DefaultDecode<Impl>::regStats()
+DefaultDecode<Impl>::DecodeStats::DecodeStats(O3CPU *cpu)
+    : Stats::Group(cpu, "decode"),
+      ADD_STAT(idleCycles, "Number of cycles decode is idle"),
+      ADD_STAT(blockedCycles, "Number of cycles decode is blocked"),
+      ADD_STAT(runCycles, "Number of cycles decode is running"),
+      ADD_STAT(unblockCycles, "Number of cycles decode is unblocking"),
+      ADD_STAT(squashCycles, "Number of cycles decode is squashing"),
+      ADD_STAT(branchResolved, "Number of times decode resolved a "
+          " branch"),
+      ADD_STAT(branchMispred, "Number of times decode detected a branch"
+          " misprediction"),
+      ADD_STAT(controlMispred,"Number of times decode detected an"
+          " instruction incorrectly predicted as a control"),
+      ADD_STAT(decodedInsts, "Number of instructions handled by decode"),
+      ADD_STAT(squashedInsts, "Number of squashed instructions handled"
+          " by decode")
 {
-    decodeIdleCycles
-        .name(name() + ".DECODE:IdleCycles")
-        .desc("Number of cycles decode is idle")
-        .prereq(decodeIdleCycles);
-    decodeBlockedCycles
-        .name(name() + ".DECODE:BlockedCycles")
-        .desc("Number of cycles decode is blocked")
-        .prereq(decodeBlockedCycles);
-    decodeRunCycles
-        .name(name() + ".DECODE:RunCycles")
-        .desc("Number of cycles decode is running")
-        .prereq(decodeRunCycles);
-    decodeUnblockCycles
-        .name(name() + ".DECODE:UnblockCycles")
-        .desc("Number of cycles decode is unblocking")
-        .prereq(decodeUnblockCycles);
-    decodeSquashCycles
-        .name(name() + ".DECODE:SquashCycles")
-        .desc("Number of cycles decode is squashing")
-        .prereq(decodeSquashCycles);
-    decodeBranchResolved
-        .name(name() + ".DECODE:BranchResolved")
-        .desc("Number of times decode resolved a branch")
-        .prereq(decodeBranchResolved);
-    decodeBranchMispred
-        .name(name() + ".DECODE:BranchMispred")
-        .desc("Number of times decode detected a branch misprediction")
-        .prereq(decodeBranchMispred);
-    decodeControlMispred
-        .name(name() + ".DECODE:ControlMispred")
-        .desc("Number of times decode detected an instruction incorrectly"
-              " predicted as a control")
-        .prereq(decodeControlMispred);
-    decodeDecodedInsts
-        .name(name() + ".DECODE:DecodedInsts")
-        .desc("Number of instructions handled by decode")
-        .prereq(decodeDecodedInsts);
-    decodeSquashedInsts
-        .name(name() + ".DECODE:SquashedInsts")
-        .desc("Number of squashed instructions handled by decode")
-        .prereq(decodeSquashedInsts);
-}
-
-template<class Impl>
-void
-DefaultDecode<Impl>::setCPU(O3CPU *cpu_ptr)
-{
-    DPRINTF(Decode, "Setting CPU pointer.\n");
-    cpu = cpu_ptr;
+    idleCycles.prereq(idleCycles);
+    blockedCycles.prereq(blockedCycles);
+    runCycles.prereq(runCycles);
+    unblockCycles.prereq(unblockCycles);
+    squashCycles.prereq(squashCycles);
+    branchResolved.prereq(branchResolved);
+    branchMispred.prereq(branchMispred);
+    controlMispred.prereq(controlMispred);
+    decodedInsts.prereq(decodedInsts);
+    squashedInsts.prereq(squashedInsts);
 }
 
 template<class Impl>
 void
 DefaultDecode<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
 {
-    DPRINTF(Decode, "Setting time buffer pointer.\n");
     timeBuffer = tb_ptr;
 
     // Setup wire to write information back to fetch.
@@ -138,7 +168,6 @@ template<class Impl>
 void
 DefaultDecode<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr)
 {
-    DPRINTF(Decode, "Setting decode queue pointer.\n");
     decodeQueue = dq_ptr;
 
     // Setup wire to write information to proper place in decode queue.
@@ -149,7 +178,6 @@ template<class Impl>
 void
 DefaultDecode<Impl>::setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr)
 {
-    DPRINTF(Decode, "Setting fetch queue pointer.\n");
     fetchQueue = fq_ptr;
 
     // Setup wire to read information from fetch queue.
@@ -158,57 +186,41 @@ DefaultDecode<Impl>::setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr)
 
 template<class Impl>
 void
-DefaultDecode<Impl>::setActiveThreads(list<unsigned> *at_ptr)
+DefaultDecode<Impl>::setActiveThreads(std::list<ThreadID> *at_ptr)
 {
-    DPRINTF(Decode, "Setting active threads list pointer.\n");
     activeThreads = 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 (int i = 0; i < numThreads; ++i) {
-        decodeStatus[i] = Idle;
-
-        stalls[i].rename = false;
-        stalls[i].iew = false;
-        stalls[i].commit = false;
-        while (!insts[i].empty())
-            insts[i].pop();
-        while (!skidBuffer[i].empty())
-            skidBuffer[i].pop();
-        branchCount[i] = 0;
+    for (ThreadID tid = 0; tid < numThreads; ++tid) {
+        if (!insts[tid].empty() || !skidBuffer[tid].empty() ||
+                (decodeStatus[tid] != Running && decodeStatus[tid] != Idle))
+            return false;
     }
-    wroteToTimeBuffer = false;
+    return true;
 }
 
 template<class Impl>
 bool
-DefaultDecode<Impl>::checkStall(unsigned tid) const
+DefaultDecode<Impl>::checkStall(ThreadID tid) const
 {
     bool ret_val = false;
 
     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);
+        DPRINTF(Decode,"[tid:%i] Stall fom Rename stage detected.\n", tid);
         ret_val = true;
     }
 
@@ -224,9 +236,9 @@ DefaultDecode<Impl>::fetchInstsValid()
 
 template<class Impl>
 bool
-DefaultDecode<Impl>::block(unsigned tid)
+DefaultDecode<Impl>::block(ThreadID tid)
 {
-    DPRINTF(Decode, "[tid:%u]: Blocking.\n", tid);
+    DPRINTF(Decode, "[tid:%i] Blocking.\n", tid);
 
     // Add the current inputs to the skid buffer so they can be
     // reprocessed when this stage unblocks.
@@ -239,7 +251,9 @@ DefaultDecode<Impl>::block(unsigned 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;
         }
@@ -252,11 +266,11 @@ DefaultDecode<Impl>::block(unsigned tid)
 
 template<class Impl>
 bool
-DefaultDecode<Impl>::unblock(unsigned tid)
+DefaultDecode<Impl>::unblock(ThreadID tid)
 {
     // Decode is done unblocking only if the skid buffer is empty.
     if (skidBuffer[tid].empty()) {
-        DPRINTF(Decode, "[tid:%u]: Done unblocking.\n", tid);
+        DPRINTF(Decode, "[tid:%i] Done unblocking.\n", tid);
         toFetch->decodeUnblock[tid] = true;
         wroteToTimeBuffer = true;
 
@@ -264,26 +278,32 @@ DefaultDecode<Impl>::unblock(unsigned tid)
         return true;
     }
 
-    DPRINTF(Decode, "[tid:%u]: Currently unblocking.\n", tid);
+    DPRINTF(Decode, "[tid:%i] Currently unblocking.\n", tid);
 
     return false;
 }
 
 template<class Impl>
 void
-DefaultDecode<Impl>::squash(DynInstPtr &inst, unsigned tid)
+DefaultDecode<Impl>::squash(const DynInstPtr &inst, ThreadID tid)
 {
-    DPRINTF(Decode, "[tid:%i]: Squashing due to incorrect branch prediction "
-            "detected at decode.\n", tid);
+    DPRINTF(Decode, "[tid:%i] [sn:%llu] Squashing due to incorrect branch "
+            "prediction detected at decode.\n", tid, inst->seqNum);
 
     // Send back mispredict information.
     toFetch->decodeInfo[tid].branchMispredict = true;
-    toFetch->decodeInfo[tid].doneSeqNum = inst->seqNum;
     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->readNextPC() != (inst->readPC() + sizeof(TheISA::MachInst));
+    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;
 
     // Might have to tell fetch to unblock.
     if (decodeStatus[tid] == Blocked ||
@@ -296,7 +316,7 @@ DefaultDecode<Impl>::squash(DynInstPtr &inst, unsigned tid)
 
     for (int i=0; i<fromFetch->size; i++) {
         if (fromFetch->insts[i]->threadNumber == tid &&
-            fromFetch->insts[i]->seqNum > inst->seqNum) {
+            fromFetch->insts[i]->seqNum > squash_seq_num) {
             fromFetch->insts[i]->setSquashed();
         }
     }
@@ -312,30 +332,29 @@ DefaultDecode<Impl>::squash(DynInstPtr &inst, unsigned tid)
     }
 
     // Squash instructions up until this one
-    cpu->removeInstsUntil(inst->seqNum, tid);
+    cpu->removeInstsUntil(squash_seq_num, tid);
 }
 
 template<class Impl>
 unsigned
-DefaultDecode<Impl>::squash(unsigned tid)
+DefaultDecode<Impl>::squash(ThreadID tid)
 {
-    DPRINTF(Decode, "[tid:%i]: Squashing.\n",tid);
+    DPRINTF(Decode, "[tid:%i] Squashing.\n",tid);
 
     if (decodeStatus[tid] == Blocked ||
         decodeStatus[tid] == Unblocking) {
-#if !FULL_SYSTEM
-        // In syscall emulation, we can have both a block and a squash due
-        // to a syscall in the same cycle.  This would cause both signals to
-        // be high.  This shouldn't happen in full system.
-        // @todo: Determine if this still happens.
-        if (toFetch->decodeBlock[tid]) {
-            toFetch->decodeBlock[tid] = 0;
-        } else {
+        if (FullSystem) {
             toFetch->decodeUnblock[tid] = 1;
+        } else {
+            // In syscall emulation, we can have both a block and a squash due
+            // to a syscall in the same cycle.  This would cause both signals
+            // to be high.  This shouldn't happen in full system.
+            // @todo: Determine if this still happens.
+            if (toFetch->decodeBlock[tid])
+                toFetch->decodeBlock[tid] = 0;
+            else
+                toFetch->decodeUnblock[tid] = 1;
         }
-#else
-        toFetch->decodeUnblock[tid] = 1;
-#endif
     }
 
     // Set status to squashing.
@@ -366,7 +385,7 @@ DefaultDecode<Impl>::squash(unsigned tid)
 
 template<class Impl>
 void
-DefaultDecode<Impl>::skidInsert(unsigned tid)
+DefaultDecode<Impl>::skidInsert(ThreadID tid)
 {
     DynInstPtr inst = NULL;
 
@@ -377,10 +396,10 @@ DefaultDecode<Impl>::skidInsert(unsigned tid)
 
         assert(tid == inst->threadNumber);
 
-        DPRINTF(Decode,"Inserting [sn:%lli] PC:%#x into decode skidBuffer %i\n",
-                inst->seqNum, inst->readPC(), 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
@@ -392,10 +411,12 @@ template<class Impl>
 bool
 DefaultDecode<Impl>::skidsEmpty()
 {
-    list<unsigned>::iterator threads = (*activeThreads).begin();
+    list<ThreadID>::iterator threads = activeThreads->begin();
+    list<ThreadID>::iterator end = activeThreads->end();
 
-    while (threads != (*activeThreads).end()) {
-        if (!skidBuffer[*threads++].empty())
+    while (threads != end) {
+        ThreadID tid = *threads++;
+        if (!skidBuffer[tid].empty())
             return false;
     }
 
@@ -408,12 +429,11 @@ DefaultDecode<Impl>::updateStatus()
 {
     bool any_unblocking = false;
 
-    list<unsigned>::iterator threads = (*activeThreads).begin();
+    list<ThreadID>::iterator threads = activeThreads->begin();
+    list<ThreadID>::iterator end = activeThreads->end();
 
-    threads = (*activeThreads).begin();
-
-    while (threads != (*activeThreads).end()) {
-        unsigned tid = *threads++;
+    while (threads != end) {
+        ThreadID tid = *threads++;
 
         if (decodeStatus[tid] == Unblocking) {
             any_unblocking = true;
@@ -447,10 +467,6 @@ void
 DefaultDecode<Impl>::sortInsts()
 {
     int insts_from_fetch = fromFetch->size;
-#ifdef DEBUG
-    for (int i=0; i < numThreads; i++)
-        assert(insts[i].empty());
-#endif
     for (int i = 0; i < insts_from_fetch; ++i) {
         insts[fromFetch->insts[i]->threadNumber].push(fromFetch->insts[i]);
     }
@@ -458,7 +474,7 @@ DefaultDecode<Impl>::sortInsts()
 
 template<class Impl>
 void
-DefaultDecode<Impl>::readStallSignals(unsigned tid)
+DefaultDecode<Impl>::readStallSignals(ThreadID tid)
 {
     if (fromRename->renameBlock[tid]) {
         stalls[tid].rename = true;
@@ -468,29 +484,11 @@ DefaultDecode<Impl>::readStallSignals(unsigned 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>
 bool
-DefaultDecode<Impl>::checkSignalsAndUpdate(unsigned tid)
+DefaultDecode<Impl>::checkSignalsAndUpdate(ThreadID tid)
 {
     // Check if there's a squash signal, squash if there is.
     // Check stall signals, block if necessary.
@@ -506,7 +504,7 @@ DefaultDecode<Impl>::checkSignalsAndUpdate(unsigned tid)
     // Check squash signals from commit.
     if (fromCommit->commitInfo[tid].squash) {
 
-        DPRINTF(Decode, "[tid:%u]: Squashing instructions due to squash "
+        DPRINTF(Decode, "[tid:%i] Squashing instructions due to squash "
                 "from commit.\n", tid);
 
         squash(tid);
@@ -514,22 +512,12 @@ DefaultDecode<Impl>::checkSignalsAndUpdate(unsigned 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);
     }
 
     if (decodeStatus[tid] == Blocked) {
-        DPRINTF(Decode, "[tid:%u]: Done blocking, switching to unblocking.\n",
+        DPRINTF(Decode, "[tid:%i] Done blocking, switching to unblocking.\n",
                 tid);
 
         decodeStatus[tid] = Unblocking;
@@ -542,7 +530,7 @@ DefaultDecode<Impl>::checkSignalsAndUpdate(unsigned tid)
     if (decodeStatus[tid] == Squashing) {
         // Switch status to running if decode isn't being told to block or
         // squash this cycle.
-        DPRINTF(Decode, "[tid:%u]: Done squashing, switching to running.\n",
+        DPRINTF(Decode, "[tid:%i] Done squashing, switching to running.\n",
                 tid);
 
         decodeStatus[tid] = Running;
@@ -565,13 +553,14 @@ DefaultDecode<Impl>::tick()
 
     toRenameIndex = 0;
 
-    list<unsigned>::iterator threads = (*activeThreads).begin();
+    list<ThreadID>::iterator threads = activeThreads->begin();
+    list<ThreadID>::iterator end = activeThreads->end();
 
     sortInsts();
 
     //Check stall and squash signals.
-    while (threads != (*activeThreads).end()) {
-    unsigned tid = *threads++;
+    while (threads != end) {
+        ThreadID tid = *threads++;
 
         DPRINTF(Decode,"Processing [tid:%i]\n",tid);
         status_change =  checkSignalsAndUpdate(tid) || status_change;
@@ -592,7 +581,7 @@ DefaultDecode<Impl>::tick()
 
 template<class Impl>
 void
-DefaultDecode<Impl>::decode(bool &status_change, unsigned tid)
+DefaultDecode<Impl>::decode(bool &status_change, ThreadID tid)
 {
     // If status is Running or idle,
     //     call decodeInsts()
@@ -602,16 +591,16 @@ DefaultDecode<Impl>::decode(bool &status_change, unsigned tid)
     //     check if stall conditions have passed
 
     if (decodeStatus[tid] == Blocked) {
-        ++decodeBlockedCycles;
+        ++stats.blockedCycles;
     } else if (decodeStatus[tid] == Squashing) {
-        ++decodeSquashCycles;
+        ++stats.squashCycles;
     }
 
     // Decode should try to decode as many instructions as its bandwidth
     // will allow, as long as it is not currently blocked.
     if (decodeStatus[tid] == Running ||
         decodeStatus[tid] == Idle) {
-        DPRINTF(Decode, "[tid:%u] Not blocked, so attempting to run "
+        DPRINTF(Decode, "[tid:%i] Not blocked, so attempting to run "
                 "stage.\n",tid);
 
         decodeInsts(tid);
@@ -637,7 +626,7 @@ DefaultDecode<Impl>::decode(bool &status_change, unsigned tid)
 
 template <class Impl>
 void
-DefaultDecode<Impl>::decodeInsts(unsigned tid)
+DefaultDecode<Impl>::decodeInsts(ThreadID tid)
 {
     // Instructions can come either from the skid buffer or the list of
     // instructions coming from fetch, depending on decode's status.
@@ -645,44 +634,41 @@ DefaultDecode<Impl>::decodeInsts(unsigned tid)
         skidBuffer[tid].size() : insts[tid].size();
 
     if (insts_available == 0) {
-        DPRINTF(Decode, "[tid:%u] Nothing to do, breaking out"
+        DPRINTF(Decode, "[tid:%i] Nothing to do, breaking out"
                 " early.\n",tid);
         // Should I change the status to idle?
-        ++decodeIdleCycles;
+        ++stats.idleCycles;
         return;
     } else if (decodeStatus[tid] == Unblocking) {
-        DPRINTF(Decode, "[tid:%u] Unblocking, removing insts from skid "
+        DPRINTF(Decode, "[tid:%i] Unblocking, removing insts from skid "
                 "buffer.\n",tid);
-        ++decodeUnblockCycles;
+        ++stats.unblockCycles;
     } else if (decodeStatus[tid] == Running) {
-        ++decodeRunCycles;
+        ++stats.runCycles;
     }
 
-    DynInstPtr inst;
-
     std::queue<DynInstPtr>
         &insts_to_decode = decodeStatus[tid] == Unblocking ?
         skidBuffer[tid] : insts[tid];
 
-    DPRINTF(Decode, "[tid:%u]: Sending instruction to rename.\n",tid);
+    DPRINTF(Decode, "[tid:%i] Sending instruction to rename.\n",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();
 
-        DPRINTF(Decode, "[tid:%u]: Processing instruction [sn:%lli] with "
-                "PC %#x\n",
-                tid, inst->seqNum, inst->readPC());
+        DPRINTF(Decode, "[tid:%i] Processing instruction [sn:%lli] with "
+                "PC %s\n", tid, inst->seqNum, inst->pcState());
 
         if (inst->isSquashed()) {
-            DPRINTF(Decode, "[tid:%u]: Instruction %i with PC %#x is "
+            DPRINTF(Decode, "[tid:%i] Instruction %i with PC %s is "
                     "squashed, skipping.\n",
-                    tid, inst->seqNum, inst->readPC());
+                    tid, inst->seqNum, inst->pcState());
 
-            ++decodeSquashedInsts;
+            ++stats.squashedInsts;
 
             --insts_available;
 
@@ -704,15 +690,21 @@ DefaultDecode<Impl>::decodeInsts(unsigned tid)
 
         ++(toRename->size);
         ++toRenameIndex;
-        ++decodeDecodedInsts;
+        ++stats.decodedInsts;
         --insts_available;
 
+#if TRACING_ON
+        if (DTRACE(O3PipeView)) {
+            inst->decodeTick = curTick() - inst->fetchTick;
+        }
+#endif
+
         // Ensure that if it was predicted as a branch, it really is a
         // branch.
-        if (inst->predTaken() && !inst->isControl()) {
+        if (inst->readPredTaken() && !inst->isControl()) {
             panic("Instruction predicted as a branch!");
 
-            ++decodeControlMispred;
+            ++stats.controlMispred;
 
             // Might want to set some sort of boolean and just do
             // a check at the end
@@ -722,17 +714,28 @@ DefaultDecode<Impl>::decodeInsts(unsigned tid)
         }
 
         // Go ahead and compute any PC-relative branches.
-        if (inst->isDirectCtrl() && inst->isUncondCtrl()) {
-            ++decodeBranchResolved;
+        // This includes direct unconditional control and
+        // direct conditional control that is predicted taken.
+        if (inst->isDirectCtrl() &&
+           (inst->isUncondCtrl() || inst->readPredTaken()))
+        {
+            ++stats.branchResolved;
 
-            if (inst->branchTarget() != inst->readPredTarg()) {
-                ++decodeBranchMispred;
+            if (!(inst->branchTarget() == inst->readPredTarg())) {
+                ++stats.branchMispred;
 
                 // Might want to set some sort of boolean and just do
                 // a check at the end
                 squash(inst, inst->threadNumber);
-                inst->setPredTarg(inst->branchTarget());
-
+                TheISA::PCState target = inst->branchTarget();
+
+                DPRINTF(Decode,
+                        "[tid:%i] [sn:%llu] "
+                        "Updating predictions: Wrong predicted target: %s \
+                        PredPC: %s\n",
+                        tid, inst->seqNum, inst->readPredTarg(), target);
+                //The micro pc after an instruction level branch should be 0
+                inst->setPredTarg(target);
                 break;
             }
         }
@@ -750,3 +753,5 @@ DefaultDecode<Impl>::decodeInsts(unsigned tid)
         wroteToTimeBuffer = true;
     }
 }
+
+#endif//__CPU_O3_DECODE_IMPL_HH__