syscall_emul: [patch 13/22] add system call retry capability
[gem5.git] / src / cpu / o3 / commit_impl.hh
index 46c4158f6eb4d5c016bb28d8b4eb9c96c43e85e7..ea77f18fb54613c916130c09c55284f70aec3aba 100644 (file)
@@ -1,4 +1,17 @@
 /*
+ * Copyright 2014 Google, Inc.
+ * Copyright (c) 2010-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.
  *
  * Authors: Kevin Lim
  *          Korey Sewell
  */
-
-#include "config/full_system.hh"
-#include "config/use_checker.hh"
+#ifndef __CPU_O3_COMMIT_IMPL_HH__
+#define __CPU_O3_COMMIT_IMPL_HH__
 
 #include <algorithm>
+#include <set>
 #include <string>
 
 #include "arch/utility.hh"
 #include "base/loader/symtab.hh"
-#include "base/timebuf.hh"
-#include "cpu/exetrace.hh"
+#include "base/cp_annotate.hh"
+#include "config/the_isa.hh"
+#include "cpu/checker/cpu.hh"
 #include "cpu/o3/commit.hh"
 #include "cpu/o3/thread_state.hh"
-
-#if USE_CHECKER
-#include "cpu/checker/cpu.hh"
-#endif
-
+#include "cpu/base.hh"
+#include "cpu/exetrace.hh"
+#include "cpu/timebuf.hh"
+#include "debug/Activity.hh"
+#include "debug/Commit.hh"
+#include "debug/CommitRate.hh"
+#include "debug/Drain.hh"
+#include "debug/ExecFaulting.hh"
+#include "debug/O3PipeView.hh"
 #include "params/DerivO3CPU.hh"
+#include "sim/faults.hh"
+#include "sim/full_system.hh"
+
+using namespace std;
 
 template <class Impl>
 DefaultCommit<Impl>::TrapEvent::TrapEvent(DefaultCommit<Impl> *_commit,
-                                          unsigned _tid)
-    : Event(CPU_Tick_Pri), commit(_commit), tid(_tid)
+                                          ThreadID _tid)
+    : Event(CPU_Tick_Pri, AutoDelete), commit(_commit), tid(_tid)
 {
-    this->setFlags(Event::AutoDelete);
 }
 
 template <class Impl>
@@ -75,7 +96,6 @@ DefaultCommit<Impl>::TrapEvent::description() const
 template <class Impl>
 DefaultCommit<Impl>::DefaultCommit(O3CPU *_cpu, DerivO3CPUParams *params)
     : cpu(_cpu),
-      squashCounter(0),
       iewToCommitDelay(params->iewToCommitDelay),
       commitToIEWDelay(params->commitToIEWDelay),
       renameToROBDelay(params->renameToROBDelay),
@@ -84,9 +104,16 @@ DefaultCommit<Impl>::DefaultCommit(O3CPU *_cpu, DerivO3CPUParams *params)
       commitWidth(params->commitWidth),
       numThreads(params->numThreads),
       drainPending(false),
-      switchedOut(false),
-      trapLatency(params->trapLatency)
+      drainImminent(false),
+      trapLatency(params->trapLatency),
+      canHandleInterrupts(true),
+      avoidQuiesceLiveLock(false)
 {
+    if (commitWidth > Impl::MaxWidth)
+        fatal("commitWidth (%d) is larger than compiled limit (%d),\n"
+             "\tincrease MaxWidth in src/cpu/o3/impl.hh\n",
+             commitWidth, static_cast<int>(Impl::MaxWidth));
+
     _status = Active;
     _nextStatus = Inactive;
     std::string policy = params->smtCommitPolicy;
@@ -99,16 +126,16 @@ DefaultCommit<Impl>::DefaultCommit(O3CPU *_cpu, DerivO3CPUParams *params)
     if (policy == "aggressive"){
         commitPolicy = Aggressive;
 
-        DPRINTF(Commit,"Commit Policy set to Aggressive.");
+        DPRINTF(Commit,"Commit Policy set to Aggressive.\n");
     } else if (policy == "roundrobin"){
         commitPolicy = RoundRobin;
 
         //Set-Up Priority List
-        for (int tid=0; tid < numThreads; tid++) {
+        for (ThreadID tid = 0; tid < numThreads; tid++) {
             priority_list.push_back(tid);
         }
 
-        DPRINTF(Commit,"Commit Policy set to Round Robin.");
+        DPRINTF(Commit,"Commit Policy set to Round Robin.\n");
     } else if (policy == "oldestready"){
         commitPolicy = OldestReady;
 
@@ -118,19 +145,19 @@ DefaultCommit<Impl>::DefaultCommit(O3CPU *_cpu, DerivO3CPUParams *params)
                "RoundRobin,OldestReady}");
     }
 
-    for (int i=0; i < numThreads; i++) {
-        commitStatus[i] = Idle;
-        changedROBNumEntries[i] = false;
-        checkEmptyROB[i] = false;
-        trapInFlight[i] = false;
-        committedStores[i] = false;
-        trapSquash[i] = false;
-        tcSquash[i] = false;
-        microPC[i] = nextMicroPC[i] = PC[i] = nextPC[i] = nextNPC[i] = 0;
+    for (ThreadID tid = 0; tid < numThreads; tid++) {
+        commitStatus[tid] = Idle;
+        changedROBNumEntries[tid] = false;
+        checkEmptyROB[tid] = false;
+        trapInFlight[tid] = false;
+        committedStores[tid] = false;
+        trapSquash[tid] = false;
+        tcSquash[tid] = false;
+        pc[tid].set(0);
+        lastCommitedSeqNum[tid] = 0;
+        squashAfterInst[tid] = NULL;
     }
-#if FULL_SYSTEM
     interrupt = NoFault;
-#endif
 }
 
 template <class Impl>
@@ -140,90 +167,123 @@ DefaultCommit<Impl>::name() const
     return cpu->name() + ".commit";
 }
 
+template <class Impl>
+void
+DefaultCommit<Impl>::regProbePoints()
+{
+    ppCommit = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Commit");
+    ppCommitStall = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "CommitStall");
+    ppSquash = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Squash");
+}
+
 template <class Impl>
 void
 DefaultCommit<Impl>::regStats()
 {
     using namespace Stats;
-    commitCommittedInsts
-        .name(name() + ".commitCommittedInsts")
-        .desc("The number of committed instructions")
-        .prereq(commitCommittedInsts);
     commitSquashedInsts
         .name(name() + ".commitSquashedInsts")
         .desc("The number of squashed insts skipped by commit")
         .prereq(commitSquashedInsts);
-    commitSquashEvents
-        .name(name() + ".commitSquashEvents")
-        .desc("The number of times commit is told to squash")
-        .prereq(commitSquashEvents);
+
     commitNonSpecStalls
         .name(name() + ".commitNonSpecStalls")
         .desc("The number of times commit has been forced to stall to "
               "communicate backwards")
         .prereq(commitNonSpecStalls);
+
     branchMispredicts
         .name(name() + ".branchMispredicts")
         .desc("The number of times a branch was mispredicted")
         .prereq(branchMispredicts);
+
     numCommittedDist
         .init(0,commitWidth,1)
-        .name(name() + ".COM:committed_per_cycle")
+        .name(name() + ".committed_per_cycle")
         .desc("Number of insts commited each cycle")
         .flags(Stats::pdf)
         ;
 
-    statComInst
-        .init(cpu->number_of_threads)
-        .name(name() + ".COM:count")
+    instsCommitted
+        .init(cpu->numThreads)
+        .name(name() + ".committedInsts")
         .desc("Number of instructions committed")
         .flags(total)
         ;
 
+    opsCommitted
+        .init(cpu->numThreads)
+        .name(name() + ".committedOps")
+        .desc("Number of ops (including micro ops) committed")
+        .flags(total)
+        ;
+
     statComSwp
-        .init(cpu->number_of_threads)
-        .name(name() + ".COM:swp_count")
+        .init(cpu->numThreads)
+        .name(name() + ".swp_count")
         .desc("Number of s/w prefetches committed")
         .flags(total)
         ;
 
     statComRefs
-        .init(cpu->number_of_threads)
-        .name(name() +  ".COM:refs")
+        .init(cpu->numThreads)
+        .name(name() +  ".refs")
         .desc("Number of memory references committed")
         .flags(total)
         ;
 
     statComLoads
-        .init(cpu->number_of_threads)
-        .name(name() +  ".COM:loads")
+        .init(cpu->numThreads)
+        .name(name() +  ".loads")
         .desc("Number of loads committed")
         .flags(total)
         ;
 
     statComMembars
-        .init(cpu->number_of_threads)
-        .name(name() +  ".COM:membars")
+        .init(cpu->numThreads)
+        .name(name() +  ".membars")
         .desc("Number of memory barriers committed")
         .flags(total)
         ;
 
     statComBranches
-        .init(cpu->number_of_threads)
-        .name(name() + ".COM:branches")
+        .init(cpu->numThreads)
+        .name(name() + ".branches")
         .desc("Number of branches committed")
         .flags(total)
         ;
 
-    commitEligible
-        .init(cpu->number_of_threads)
-        .name(name() + ".COM:bw_limited")
-        .desc("number of insts not committed due to BW limits")
+    statComFloating
+        .init(cpu->numThreads)
+        .name(name() + ".fp_insts")
+        .desc("Number of committed floating point instructions.")
+        .flags(total)
+        ;
+
+    statComInteger
+        .init(cpu->numThreads)
+        .name(name()+".int_insts")
+        .desc("Number of committed integer instructions.")
+        .flags(total)
+        ;
+
+    statComFunctionCalls
+        .init(cpu->numThreads)
+        .name(name()+".function_calls")
+        .desc("Number of function calls committed.")
         .flags(total)
         ;
 
+    statCommittedInstType
+        .init(numThreads,Enums::Num_OpClass)
+        .name(name() + ".op_class")
+        .desc("Class of committed instruction")
+        .flags(total | pdf | dist)
+        ;
+    statCommittedInstType.ysubnames(Enums::OpClassStrings);
+
     commitEligibleSamples
-        .name(name() + ".COM:bw_lim_events")
+        .name(name() + ".bw_lim_events")
         .desc("number cycles where commit BW limit reached")
         ;
 }
@@ -287,7 +347,7 @@ DefaultCommit<Impl>::setIEWStage(IEW *iew_stage)
 
 template<class Impl>
 void
-DefaultCommit<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
+DefaultCommit<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
 {
     activeThreads = at_ptr;
 }
@@ -296,9 +356,8 @@ template <class Impl>
 void
 DefaultCommit<Impl>::setRenameMap(RenameMap rm_ptr[])
 {
-    for (int i=0; i < numThreads; i++) {
-        renameMap[i] = &rm_ptr[i];
-    }
+    for (ThreadID tid = 0; tid < numThreads; tid++)
+        renameMap[tid] = &rm_ptr[tid];
 }
 
 template <class Impl>
@@ -310,16 +369,16 @@ DefaultCommit<Impl>::setROB(ROB *rob_ptr)
 
 template <class Impl>
 void
-DefaultCommit<Impl>::initStage()
+DefaultCommit<Impl>::startupStage()
 {
     rob->setActiveThreads(activeThreads);
     rob->resetEntries();
 
     // Broadcast the number of free entries.
-    for (int i=0; i < numThreads; i++) {
-        toIEW->commitInfo[i].usedROB = true;
-        toIEW->commitInfo[i].freeROBEntries = rob->numFreeEntries(i);
-        toIEW->commitInfo[i].emptyROB = true;
+    for (ThreadID tid = 0; tid < numThreads; tid++) {
+        toIEW->commitInfo[tid].usedROB = true;
+        toIEW->commitInfo[tid].freeROBEntries = rob->numFreeEntries(tid);
+        toIEW->commitInfo[tid].emptyROB = true;
     }
 
     // Commit must broadcast the number of free entries it has at the
@@ -327,61 +386,98 @@ DefaultCommit<Impl>::initStage()
     cpu->activateStage(O3CPU::CommitIdx);
 
     cpu->activityThisCycle();
-    trapLatency = cpu->ticks(trapLatency);
 }
 
 template <class Impl>
-bool
+void
 DefaultCommit<Impl>::drain()
 {
     drainPending = true;
-
-    return false;
 }
 
 template <class Impl>
 void
-DefaultCommit<Impl>::switchOut()
+DefaultCommit<Impl>::drainResume()
 {
-    switchedOut = true;
     drainPending = false;
-    rob->switchOut();
+    drainImminent = false;
 }
 
 template <class Impl>
 void
-DefaultCommit<Impl>::resume()
+DefaultCommit<Impl>::drainSanityCheck() const
 {
-    drainPending = false;
+    assert(isDrained());
+    rob->drainSanityCheck();
+}
+
+template <class Impl>
+bool
+DefaultCommit<Impl>::isDrained() const
+{
+    /* Make sure no one is executing microcode. There are two reasons
+     * for this:
+     * - Hardware virtualized CPUs can't switch into the middle of a
+     *   microcode sequence.
+     * - The current fetch implementation will most likely get very
+     *   confused if it tries to start fetching an instruction that
+     *   is executing in the middle of a ucode sequence that changes
+     *   address mappings. This can happen on for example x86.
+     */
+    for (ThreadID tid = 0; tid < numThreads; tid++) {
+        if (pc[tid].microPC() != 0)
+            return false;
+    }
+
+    /* Make sure that all instructions have finished committing before
+     * declaring the system as drained. We want the pipeline to be
+     * completely empty when we declare the CPU to be drained. This
+     * makes debugging easier since CPU handover and restoring from a
+     * checkpoint with a different CPU should have the same timing.
+     */
+    return rob->isEmpty() &&
+        interrupt == NoFault;
 }
 
 template <class Impl>
 void
 DefaultCommit<Impl>::takeOverFrom()
 {
-    switchedOut = false;
     _status = Active;
     _nextStatus = Inactive;
-    for (int i=0; i < numThreads; i++) {
-        commitStatus[i] = Idle;
-        changedROBNumEntries[i] = false;
-        trapSquash[i] = false;
-        tcSquash[i] = false;
+    for (ThreadID tid = 0; tid < numThreads; tid++) {
+        commitStatus[tid] = Idle;
+        changedROBNumEntries[tid] = false;
+        trapSquash[tid] = false;
+        tcSquash[tid] = false;
+        squashAfterInst[tid] = NULL;
     }
-    squashCounter = 0;
     rob->takeOverFrom();
 }
 
+template <class Impl>
+void
+DefaultCommit<Impl>::deactivateThread(ThreadID tid)
+{
+    list<ThreadID>::iterator thread_it = std::find(priority_list.begin(),
+            priority_list.end(), tid);
+
+    if (thread_it != priority_list.end()) {
+        priority_list.erase(thread_it);
+    }
+}
+
+
 template <class Impl>
 void
 DefaultCommit<Impl>::updateStatus()
 {
     // reset ROB changed variable
-    std::list<unsigned>::iterator threads = activeThreads->begin();
-    std::list<unsigned>::iterator end = activeThreads->end();
+    list<ThreadID>::iterator threads = activeThreads->begin();
+    list<ThreadID>::iterator end = activeThreads->end();
 
     while (threads != end) {
-        unsigned tid = *threads++;
+        ThreadID tid = *threads++;
 
         changedROBNumEntries[tid] = false;
 
@@ -403,41 +499,15 @@ DefaultCommit<Impl>::updateStatus()
     _status = _nextStatus;
 }
 
-template <class Impl>
-void
-DefaultCommit<Impl>::setNextStatus()
-{
-    int squashes = 0;
-
-    std::list<unsigned>::iterator threads = activeThreads->begin();
-    std::list<unsigned>::iterator end = activeThreads->end();
-
-    while (threads != end) {
-        unsigned tid = *threads++;
-
-        if (commitStatus[tid] == ROBSquashing) {
-            squashes++;
-        }
-    }
-
-    squashCounter = squashes;
-
-    // If commit is currently squashing, then it will have activity for the
-    // next cycle. Set its next status as active.
-    if (squashCounter) {
-        _nextStatus = Active;
-    }
-}
-
 template <class Impl>
 bool
 DefaultCommit<Impl>::changedROBEntries()
 {
-    std::list<unsigned>::iterator threads = activeThreads->begin();
-    std::list<unsigned>::iterator end = activeThreads->end();
+    list<ThreadID>::iterator threads = activeThreads->begin();
+    list<ThreadID>::iterator end = activeThreads->end();
 
     while (threads != end) {
-        unsigned tid = *threads++;
+        ThreadID tid = *threads++;
 
         if (changedROBNumEntries[tid]) {
             return true;
@@ -448,27 +518,31 @@ DefaultCommit<Impl>::changedROBEntries()
 }
 
 template <class Impl>
-unsigned
-DefaultCommit<Impl>::numROBFreeEntries(unsigned tid)
+size_t
+DefaultCommit<Impl>::numROBFreeEntries(ThreadID tid)
 {
     return rob->numFreeEntries(tid);
 }
 
 template <class Impl>
 void
-DefaultCommit<Impl>::generateTrapEvent(unsigned tid)
+DefaultCommit<Impl>::generateTrapEvent(ThreadID tid, Fault inst_fault)
 {
     DPRINTF(Commit, "Generating trap event for [tid:%i]\n", tid);
 
     TrapEvent *trap = new TrapEvent(this, tid);
 
-    cpu->schedule(trap, curTick + trapLatency);
+    Cycles latency = dynamic_pointer_cast<SyscallRetryFault>(inst_fault) ?
+                     cpu->syscallRetryLatency : trapLatency;
+
+    cpu->schedule(trap, cpu->clockEdge(latency));
     trapInFlight[tid] = true;
+    thread[tid]->trapPending = true;
 }
 
 template <class Impl>
 void
-DefaultCommit<Impl>::generateTCEvent(unsigned tid)
+DefaultCommit<Impl>::generateTCEvent(ThreadID tid)
 {
     assert(!trapInFlight[tid]);
     DPRINTF(Commit, "Generating TC squash event for [tid:%i]\n", tid);
@@ -478,19 +552,19 @@ DefaultCommit<Impl>::generateTCEvent(unsigned tid)
 
 template <class Impl>
 void
-DefaultCommit<Impl>::squashAll(unsigned tid)
+DefaultCommit<Impl>::squashAll(ThreadID tid)
 {
     // If we want to include the squashing instruction in the squash,
     // then use one older sequence number.
     // Hopefully this doesn't mess things up.  Basically I want to squash
     // all instructions of this thread.
-    InstSeqNum squashed_inst = rob->isEmpty() ?
-        0 : rob->readHeadInst(tid)->seqNum - 1;
+    InstSeqNum squashed_inst = rob->isEmpty(tid) ?
+        lastCommitedSeqNum[tid] : rob->readHeadInst(tid)->seqNum - 1;
 
     // All younger instructions will be squashed. Set the sequence
     // number as the youngest instruction in the ROB (0 in this case.
     // Hopefully nothing breaks.)
-    youngestSeqNum[tid] = 0;
+    youngestSeqNum[tid] = lastCommitedSeqNum[tid];
 
     rob->squash(squashed_inst, tid);
     changedROBNumEntries[tid] = true;
@@ -506,23 +580,22 @@ DefaultCommit<Impl>::squashAll(unsigned tid)
     // the ROB is in the process of squashing.
     toIEW->commitInfo[tid].robSquashing = true;
 
-    toIEW->commitInfo[tid].branchMispredict = false;
+    toIEW->commitInfo[tid].mispredictInst = NULL;
+    toIEW->commitInfo[tid].squashInst = NULL;
 
-    toIEW->commitInfo[tid].nextPC = PC[tid];
-    toIEW->commitInfo[tid].nextNPC = nextPC[tid];
-    toIEW->commitInfo[tid].nextMicroPC = nextMicroPC[tid];
+    toIEW->commitInfo[tid].pc = pc[tid];
 }
 
 template <class Impl>
 void
-DefaultCommit<Impl>::squashFromTrap(unsigned tid)
+DefaultCommit<Impl>::squashFromTrap(ThreadID tid)
 {
     squashAll(tid);
 
-    DPRINTF(Commit, "Squashing from trap, restarting at PC %#x\n", PC[tid]);
+    DPRINTF(Commit, "Squashing from trap, restarting at PC %s\n", pc[tid]);
 
     thread[tid]->trapPending = false;
-    thread[tid]->inSyscall = false;
+    thread[tid]->noSquashFromTC = false;
     trapInFlight[tid] = false;
 
     trapSquash[tid] = false;
@@ -533,13 +606,13 @@ DefaultCommit<Impl>::squashFromTrap(unsigned tid)
 
 template <class Impl>
 void
-DefaultCommit<Impl>::squashFromTC(unsigned tid)
+DefaultCommit<Impl>::squashFromTC(ThreadID tid)
 {
     squashAll(tid);
 
-    DPRINTF(Commit, "Squashing from TC, restarting at PC %#x\n", PC[tid]);
+    DPRINTF(Commit, "Squashing from TC, restarting at PC %s\n", pc[tid]);
 
-    thread[tid]->inSyscall = false;
+    thread[tid]->noSquashFromTC = false;
     assert(!thread[tid]->trapPending);
 
     commitStatus[tid] = ROBSquashing;
@@ -548,6 +621,36 @@ DefaultCommit<Impl>::squashFromTC(unsigned tid)
     tcSquash[tid] = false;
 }
 
+template <class Impl>
+void
+DefaultCommit<Impl>::squashFromSquashAfter(ThreadID tid)
+{
+    DPRINTF(Commit, "Squashing after squash after request, "
+            "restarting at PC %s\n", pc[tid]);
+
+    squashAll(tid);
+    // Make sure to inform the fetch stage of which instruction caused
+    // the squash. It'll try to re-fetch an instruction executing in
+    // microcode unless this is set.
+    toIEW->commitInfo[tid].squashInst = squashAfterInst[tid];
+    squashAfterInst[tid] = NULL;
+
+    commitStatus[tid] = ROBSquashing;
+    cpu->activityThisCycle();
+}
+
+template <class Impl>
+void
+DefaultCommit<Impl>::squashAfter(ThreadID tid, DynInstPtr &head_inst)
+{
+    DPRINTF(Commit, "Executing squash after for [tid:%i] inst [sn:%lli]\n",
+            tid, head_inst->seqNum);
+
+    assert(!squashAfterInst[tid] || squashAfterInst[tid] == head_inst);
+    commitStatus[tid] = SquashAfterPending;
+    squashAfterInst[tid] = head_inst;
+}
+
 template <class Impl>
 void
 DefaultCommit<Impl>::tick()
@@ -555,22 +658,16 @@ DefaultCommit<Impl>::tick()
     wroteToTimeBuffer = false;
     _nextStatus = Inactive;
 
-    if (drainPending && rob->isEmpty() && !iewStage->hasStoresToWB()) {
-        cpu->signalDrained();
-        drainPending = false;
-        return;
-    }
-
     if (activeThreads->empty())
         return;
 
-    std::list<unsigned>::iterator threads = activeThreads->begin();
-    std::list<unsigned>::iterator end = activeThreads->end();
+    list<ThreadID>::iterator threads = activeThreads->begin();
+    list<ThreadID>::iterator end = activeThreads->end();
 
     // Check if any of the threads are done squashing.  Change the
     // status if they are done.
     while (threads != end) {
-        unsigned tid = *threads++;
+        ThreadID tid = *threads++;
 
         // Clear the bit saying if the thread has committed stores
         // this cycle.
@@ -597,7 +694,7 @@ DefaultCommit<Impl>::tick()
     threads = activeThreads->begin();
 
     while (threads != end) {
-        unsigned tid = *threads++;
+        ThreadID tid = *threads++;
 
         if (!rob->isEmpty(tid) && rob->readHeadInst(tid)->readyToCommit()) {
             // The ROB has more instructions it can commit. Its next status
@@ -606,16 +703,18 @@ DefaultCommit<Impl>::tick()
 
             DynInstPtr inst = rob->readHeadInst(tid);
 
-            DPRINTF(Commit,"[tid:%i]: Instruction [sn:%lli] PC %#x is head of"
+            DPRINTF(Commit,"[tid:%i]: Instruction [sn:%lli] PC %s is head of"
                     " ROB and ready to commit\n",
-                    tid, inst->seqNum, inst->readPC());
+                    tid, inst->seqNum, inst->pcState());
 
         } else if (!rob->isEmpty(tid)) {
             DynInstPtr inst = rob->readHeadInst(tid);
 
+            ppCommitStall->notify(inst);
+
             DPRINTF(Commit,"[tid:%i]: Can't commit, Instruction [sn:%lli] PC "
-                    "%#x is head of ROB and not ready\n",
-                    tid, inst->seqNum, inst->readPC());
+                    "%s is head of ROB and not ready\n",
+                    tid, inst->seqNum, inst->pcState());
         }
 
         DPRINTF(Commit, "[tid:%i]: ROB has %d insts & %d free entries.\n",
@@ -631,92 +730,119 @@ DefaultCommit<Impl>::tick()
     updateStatus();
 }
 
-#if FULL_SYSTEM
 template <class Impl>
 void
 DefaultCommit<Impl>::handleInterrupt()
 {
-    if (interrupt != NoFault) {
-        // Wait until the ROB is empty and all stores have drained in
-        // order to enter the interrupt.
-        if (rob->isEmpty() && !iewStage->hasStoresToWB()) {
-            // Squash or record that I need to squash this cycle if
-            // an interrupt needed to be handled.
-            DPRINTF(Commit, "Interrupt detected.\n");
+    // Verify that we still have an interrupt to handle
+    if (!cpu->checkInterrupts(cpu->tcBase(0))) {
+        DPRINTF(Commit, "Pending interrupt is cleared by master before "
+                "it got handled. Restart fetching from the orig path.\n");
+        toIEW->commitInfo[0].clearInterrupt = true;
+        interrupt = NoFault;
+        avoidQuiesceLiveLock = true;
+        return;
+    }
 
-            // Clear the interrupt now that it's going to be handled
-            toIEW->commitInfo[0].clearInterrupt = true;
+    // Wait until all in flight instructions are finished before enterring
+    // the interrupt.
+    if (canHandleInterrupts && cpu->instList.empty()) {
+        // Squash or record that I need to squash this cycle if
+        // an interrupt needed to be handled.
+        DPRINTF(Commit, "Interrupt detected.\n");
 
-            assert(!thread[0]->inSyscall);
-            thread[0]->inSyscall = true;
+        // Clear the interrupt now that it's going to be handled
+        toIEW->commitInfo[0].clearInterrupt = true;
 
-            // CPU will handle interrupt.
-            cpu->processInterrupts(interrupt);
+        assert(!thread[0]->noSquashFromTC);
+        thread[0]->noSquashFromTC = true;
 
-            thread[0]->inSyscall = false;
+        if (cpu->checker) {
+            cpu->checker->handlePendingInt();
+        }
 
-            commitStatus[0] = TrapPending;
+        // CPU will handle interrupt. Note that we ignore the local copy of
+        // interrupt. This is because the local copy may no longer be the
+        // interrupt that the interrupt controller thinks is being handled.
+        cpu->processInterrupts(cpu->getInterrupts());
 
-            // Generate trap squash event.
-            generateTrapEvent(0);
+        thread[0]->noSquashFromTC = false;
 
-            interrupt = NoFault;
-        } else {
-            DPRINTF(Commit, "Interrupt pending, waiting for ROB to empty.\n");
-        }
-    } else if (commitStatus[0] != TrapPending &&
-               cpu->checkInterrupts(cpu->tcBase(0)) &&
-               !trapSquash[0] &&
-               !tcSquash[0]) {
-        // Process interrupts if interrupts are enabled, not in PAL
-        // mode, and no other traps or external squashes are currently
-        // pending.
-        // @todo: Allow other threads to handle interrupts.
-
-        // Get any interrupt that happened
-        interrupt = cpu->getInterrupts();
-
-        if (interrupt != NoFault) {
-            // Tell fetch that there is an interrupt pending.  This
-            // will make fetch wait until it sees a non PAL-mode PC,
-            // at which point it stops fetching instructions.
-            toIEW->commitInfo[0].interruptPending = true;
-        }
+        commitStatus[0] = TrapPending;
+
+        interrupt = NoFault;
+
+        // Generate trap squash event.
+        generateTrapEvent(0, interrupt);
+
+        avoidQuiesceLiveLock = false;
+    } else {
+        DPRINTF(Commit, "Interrupt pending: instruction is %sin "
+                "flight, ROB is %sempty\n",
+                canHandleInterrupts ? "not " : "",
+                cpu->instList.empty() ? "" : "not " );
     }
 }
-#endif // FULL_SYSTEM
 
 template <class Impl>
 void
-DefaultCommit<Impl>::commit()
+DefaultCommit<Impl>::propagateInterrupt()
 {
+    // Don't propagate intterupts if we are currently handling a trap or
+    // in draining and the last observable instruction has been committed.
+    if (commitStatus[0] == TrapPending || interrupt || trapSquash[0] ||
+            tcSquash[0] || drainImminent)
+        return;
+
+    // Process interrupts if interrupts are enabled, not in PAL
+    // mode, and no other traps or external squashes are currently
+    // pending.
+    // @todo: Allow other threads to handle interrupts.
+
+    // Get any interrupt that happened
+    interrupt = cpu->getInterrupts();
+
+    // Tell fetch that there is an interrupt pending.  This
+    // will make fetch wait until it sees a non PAL-mode PC,
+    // at which point it stops fetching instructions.
+    if (interrupt != NoFault)
+        toIEW->commitInfo[0].interruptPending = true;
+}
 
-#if FULL_SYSTEM
-    // Check for any interrupt, and start processing it.  Or if we
-    // have an outstanding interrupt and are at a point when it is
-    // valid to take an interrupt, process it.
-    if (cpu->checkInterrupts(cpu->tcBase(0))) {
-        handleInterrupt();
+template <class Impl>
+void
+DefaultCommit<Impl>::commit()
+{
+    if (FullSystem) {
+        // Check if we have a interrupt and get read to handle it
+        if (cpu->checkInterrupts(cpu->tcBase(0)))
+            propagateInterrupt();
     }
-#endif // FULL_SYSTEM
 
     ////////////////////////////////////
     // Check for any possible squashes, handle them first
     ////////////////////////////////////
-    std::list<unsigned>::iterator threads = activeThreads->begin();
-    std::list<unsigned>::iterator end = activeThreads->end();
+    list<ThreadID>::iterator threads = activeThreads->begin();
+    list<ThreadID>::iterator end = activeThreads->end();
+
+    int num_squashing_threads = 0;
 
     while (threads != end) {
-        unsigned tid = *threads++;
+        ThreadID tid = *threads++;
 
         // Not sure which one takes priority.  I think if we have
         // both, that's a bad sign.
-        if (trapSquash[tid] == true) {
+        if (trapSquash[tid]) {
             assert(!tcSquash[tid]);
             squashFromTrap(tid);
-        } else if (tcSquash[tid] == true) {
+        } else if (tcSquash[tid]) {
             assert(commitStatus[tid] != TrapPending);
             squashFromTC(tid);
+        } else if (commitStatus[tid] == SquashAfterPending) {
+            // A squash from the previous cycle of the commit stage (i.e.,
+            // commitInsts() called squashAfter) is pending. Squash the
+            // thread now.
+            squashFromSquashAfter(tid);
         }
 
         // Squashed sequence number must be older than youngest valid
@@ -726,14 +852,21 @@ DefaultCommit<Impl>::commit()
             commitStatus[tid] != TrapPending &&
             fromIEW->squashedSeqNum[tid] <= youngestSeqNum[tid]) {
 
-            DPRINTF(Commit, "[tid:%i]: Squashing due to PC %#x [sn:%i]\n",
+            if (fromIEW->mispredictInst[tid]) {
+                DPRINTF(Commit,
+                    "[tid:%i]: Squashing due to branch mispred PC:%#x [sn:%i]\n",
                     tid,
-                    fromIEW->mispredPC[tid],
+                    fromIEW->mispredictInst[tid]->instAddr(),
                     fromIEW->squashedSeqNum[tid]);
+            } else {
+                DPRINTF(Commit,
+                    "[tid:%i]: Squashing due to order violation [sn:%i]\n",
+                    tid, fromIEW->squashedSeqNum[tid]);
+            }
 
             DPRINTF(Commit, "[tid:%i]: Redirecting to PC %#x\n",
                     tid,
-                    fromIEW->nextPC[tid]);
+                    fromIEW->pc[tid].nextInstAddr());
 
             commitStatus[tid] = ROBSquashing;
 
@@ -741,7 +874,7 @@ DefaultCommit<Impl>::commit()
             // then use one older sequence number.
             InstSeqNum squashed_inst = fromIEW->squashedSeqNum[tid];
 
-            if (fromIEW->includeSquashInst[tid] == true) {
+            if (fromIEW->includeSquashInst[tid]) {
                 squashed_inst--;
             }
 
@@ -760,28 +893,34 @@ DefaultCommit<Impl>::commit()
             // the ROB is in the process of squashing.
             toIEW->commitInfo[tid].robSquashing = true;
 
-            toIEW->commitInfo[tid].branchMispredict =
-                fromIEW->branchMispredict[tid];
-
+            toIEW->commitInfo[tid].mispredictInst =
+                fromIEW->mispredictInst[tid];
             toIEW->commitInfo[tid].branchTaken =
                 fromIEW->branchTaken[tid];
-
-            toIEW->commitInfo[tid].nextPC = fromIEW->nextPC[tid];
-            toIEW->commitInfo[tid].nextNPC = fromIEW->nextNPC[tid];
-            toIEW->commitInfo[tid].nextMicroPC = fromIEW->nextMicroPC[tid];
-
-            toIEW->commitInfo[tid].mispredPC = fromIEW->mispredPC[tid];
-
-            if (toIEW->commitInfo[tid].branchMispredict) {
+            toIEW->commitInfo[tid].squashInst =
+                                    rob->findInst(tid, squashed_inst);
+            if (toIEW->commitInfo[tid].mispredictInst) {
+                if (toIEW->commitInfo[tid].mispredictInst->isUncondCtrl()) {
+                     toIEW->commitInfo[tid].branchTaken = true;
+                }
                 ++branchMispredicts;
             }
+
+            toIEW->commitInfo[tid].pc = fromIEW->pc[tid];
         }
 
+        if (commitStatus[tid] == ROBSquashing) {
+            num_squashing_threads++;
+        }
     }
 
-    setNextStatus();
+    // If commit is currently squashing, then it will have activity for the
+    // next cycle. Set its next status as active.
+    if (num_squashing_threads) {
+        _nextStatus = Active;
+    }
 
-    if (squashCounter != numThreads) {
+    if (num_squashing_threads != numThreads) {
         // If we're not currently squashing, then get instructions.
         getInsts();
 
@@ -793,7 +932,7 @@ DefaultCommit<Impl>::commit()
     threads = activeThreads->begin();
 
     while (threads != end) {
-        unsigned tid = *threads++;
+        ThreadID tid = *threads++;
 
         if (changedROBNumEntries[tid]) {
             toIEW->commitInfo[tid].usedROB = true;
@@ -847,14 +986,19 @@ DefaultCommit<Impl>::commitInsts()
     // Commit as many instructions as possible until the commit bandwidth
     // limit is reached, or it becomes impossible to commit any more.
     while (num_committed < commitWidth) {
-        int commit_thread = getCommittingThread();
+        // Check for any interrupt that we've already squashed for
+        // and start processing it.
+        if (interrupt != NoFault)
+            handleInterrupt();
+
+        ThreadID commit_thread = getCommittingThread();
 
         if (commit_thread == -1 || !rob->isHeadReady(commit_thread))
             break;
 
         head_inst = rob->readHeadInst(commit_thread);
 
-        int tid = head_inst->threadNumber;
+        ThreadID tid = head_inst->threadNumber;
 
         assert(tid == commit_thread);
 
@@ -871,14 +1015,13 @@ DefaultCommit<Impl>::commitInsts()
             rob->retireHead(commit_thread);
 
             ++commitSquashedInsts;
+            // Notify potential listeners that this instruction is squashed
+            ppSquash->notify(head_inst);
 
             // Record that the number of ROB entries has changed.
             changedROBNumEntries[tid] = true;
         } else {
-            PC[tid] = head_inst->readPC();
-            nextPC[tid] = head_inst->readNextPC();
-            nextNPC[tid] = head_inst->readNextNPC();
-            nextMicroPC[tid] = head_inst->readNextMicroPC();
+            pc[tid] = head_inst->pcState();
 
             // Increment the total number of non-speculative instructions
             // executed.
@@ -892,45 +1035,91 @@ DefaultCommit<Impl>::commitInsts()
 
             if (commit_success) {
                 ++num_committed;
+                statCommittedInstType[tid][head_inst->opClass()]++;
+                ppCommit->notify(head_inst);
 
                 changedROBNumEntries[tid] = true;
 
                 // Set the doneSeqNum to the youngest committed instruction.
                 toIEW->commitInfo[tid].doneSeqNum = head_inst->seqNum;
 
-                ++commitCommittedInsts;
+                if (tid == 0) {
+                    canHandleInterrupts =  (!head_inst->isDelayedCommit()) &&
+                                           ((THE_ISA != ALPHA_ISA) ||
+                                             (!(pc[0].instAddr() & 0x3)));
+                }
+
+                // Updates misc. registers.
+                head_inst->updateMiscRegs();
 
-                // To match the old model, don't count nops and instruction
-                // prefetches towards the total commit count.
-                if (!head_inst->isNop() && !head_inst->isInstPrefetch()) {
-                    cpu->instDone(tid);
+                // Check instruction execution if it successfully commits and
+                // is not carrying a fault.
+                if (cpu->checker) {
+                    cpu->checker->verify(head_inst);
                 }
 
-                PC[tid] = nextPC[tid];
-                nextPC[tid] = nextNPC[tid];
-                nextNPC[tid] = nextNPC[tid] + sizeof(TheISA::MachInst);
-                microPC[tid] = nextMicroPC[tid];
-                nextMicroPC[tid] = microPC[tid] + 1;
-
-                int count = 0;
-                Addr oldpc;
-                // Debug statement.  Checks to make sure we're not
-                // currently updating state while handling PC events.
-                assert(!thread[tid]->inSyscall && !thread[tid]->trapPending);
-                do {
-                    oldpc = PC[tid];
-                    cpu->system->pcEventQueue.service(thread[tid]->getTC());
-                    count++;
-                } while (oldpc != PC[tid]);
-                if (count > 1) {
-                    DPRINTF(Commit,
-                            "PC skip function event, stopping commit\n");
-                    break;
+                cpu->traceFunctions(pc[tid].instAddr());
+
+                TheISA::advancePC(pc[tid], head_inst->staticInst);
+
+                // Keep track of the last sequence number commited
+                lastCommitedSeqNum[tid] = head_inst->seqNum;
+
+                // If this is an instruction that doesn't play nicely with
+                // others squash everything and restart fetch
+                if (head_inst->isSquashAfter())
+                    squashAfter(tid, head_inst);
+
+                if (drainPending) {
+                    if (pc[tid].microPC() == 0 && interrupt == NoFault &&
+                        !thread[tid]->trapPending) {
+                        // Last architectually committed instruction.
+                        // Squash the pipeline, stall fetch, and use
+                        // drainImminent to disable interrupts
+                        DPRINTF(Drain, "Draining: %i:%s\n", tid, pc[tid]);
+                        squashAfter(tid, head_inst);
+                        cpu->commitDrained(tid);
+                        drainImminent = true;
+                    }
                 }
+
+                bool onInstBoundary = !head_inst->isMicroop() ||
+                                      head_inst->isLastMicroop() ||
+                                      !head_inst->isDelayedCommit();
+
+                if (onInstBoundary) {
+                    int count = 0;
+                    Addr oldpc;
+                    // Make sure we're not currently updating state while
+                    // handling PC events.
+                    assert(!thread[tid]->noSquashFromTC &&
+                           !thread[tid]->trapPending);
+                    do {
+                        oldpc = pc[tid].instAddr();
+                        cpu->system->pcEventQueue.service(thread[tid]->getTC());
+                        count++;
+                    } while (oldpc != pc[tid].instAddr());
+                    if (count > 1) {
+                        DPRINTF(Commit,
+                                "PC skip function event, stopping commit\n");
+                        break;
+                    }
+                }
+
+                // Check if an instruction just enabled interrupts and we've
+                // previously had an interrupt pending that was not handled
+                // because interrupts were subsequently disabled before the
+                // pipeline reached a place to handle the interrupt. In that
+                // case squash now to make sure the interrupt is handled.
+                //
+                // If we don't do this, we might end up in a live lock situation
+                if (!interrupt && avoidQuiesceLiveLock &&
+                    onInstBoundary && cpu->checkInterrupts(cpu->tcBase(0)))
+                    squashAfter(tid, head_inst);
             } else {
-                DPRINTF(Commit, "Unable to commit head instruction PC:%#x "
+                DPRINTF(Commit, "Unable to commit head instruction PC:%s "
                         "[tid:%i] [sn:%i].\n",
-                        head_inst->readPC(), tid ,head_inst->seqNum);
+                        head_inst->pcState(), tid ,head_inst->seqNum);
                 break;
             }
         }
@@ -950,7 +1139,7 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
 {
     assert(head_inst);
 
-    int tid = head_inst->threadNumber;
+    ThreadID tid = head_inst->threadNumber;
 
     // If the instruction is not executed yet, then it will need extra
     // handling.  Signal backwards that it should be executed.
@@ -959,52 +1148,37 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
         // and committed this instruction.
         thread[tid]->funcExeInst--;
 
-        if (head_inst->isNonSpeculative() ||
-            head_inst->isStoreConditional() ||
-            head_inst->isMemBarrier() ||
-            head_inst->isWriteBarrier()) {
+        // Make sure we are only trying to commit un-executed instructions we
+        // think are possible.
+        assert(head_inst->isNonSpeculative() || head_inst->isStoreConditional()
+               || head_inst->isMemBarrier() || head_inst->isWriteBarrier() ||
+               (head_inst->isLoad() && head_inst->strictlyOrdered()));
 
-            DPRINTF(Commit, "Encountered a barrier or non-speculative "
-                    "instruction [sn:%lli] at the head of the ROB, PC %#x.\n",
-                    head_inst->seqNum, head_inst->readPC());
-
-            if (inst_num > 0 || iewStage->hasStoresToWB(tid)) {
-                DPRINTF(Commit, "Waiting for all stores to writeback.\n");
-                return false;
-            }
-
-            toIEW->commitInfo[tid].nonSpecSeqNum = head_inst->seqNum;
-
-            // Change the instruction so it won't try to commit again until
-            // it is executed.
-            head_inst->clearCanCommit();
-
-            ++commitNonSpecStalls;
+        DPRINTF(Commit, "Encountered a barrier or non-speculative "
+                "instruction [sn:%lli] at the head of the ROB, PC %s.\n",
+                head_inst->seqNum, head_inst->pcState());
 
+        if (inst_num > 0 || iewStage->hasStoresToWB(tid)) {
+            DPRINTF(Commit, "Waiting for all stores to writeback.\n");
             return false;
-        } else if (head_inst->isLoad()) {
-            if (inst_num > 0 || iewStage->hasStoresToWB(tid)) {
-                DPRINTF(Commit, "Waiting for all stores to writeback.\n");
-                return false;
-            }
-
-            assert(head_inst->uncacheable());
-            DPRINTF(Commit, "[sn:%lli]: Uncached load, PC %#x.\n",
-                    head_inst->seqNum, head_inst->readPC());
+        }
 
-            // Send back the non-speculative instruction's sequence
-            // number.  Tell the lsq to re-execute the load.
-            toIEW->commitInfo[tid].nonSpecSeqNum = head_inst->seqNum;
-            toIEW->commitInfo[tid].uncached = true;
-            toIEW->commitInfo[tid].uncachedLoad = head_inst;
+        toIEW->commitInfo[tid].nonSpecSeqNum = head_inst->seqNum;
 
-            head_inst->clearCanCommit();
+        // Change the instruction so it won't try to commit again until
+        // it is executed.
+        head_inst->clearCanCommit();
 
-            return false;
+        if (head_inst->isLoad() && head_inst->strictlyOrdered()) {
+            DPRINTF(Commit, "[sn:%lli]: Strictly ordered load, PC %s.\n",
+                    head_inst->seqNum, head_inst->pcState());
+            toIEW->commitInfo[tid].strictlyOrdered = true;
+            toIEW->commitInfo[tid].strictlyOrderedLoad = head_inst;
         } else {
-            panic("Trying to commit un-executed instruction "
-                  "of unknown type!\n");
+            ++commitNonSpecStalls;
         }
+
+        return false;
     }
 
     if (head_inst->isThreadSync()) {
@@ -1020,23 +1194,9 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
         head_inst->setCompleted();
     }
 
-#if USE_CHECKER
-    // Use checker prior to updating anything due to traps or PC
-    // based events.
-    if (cpu->checker) {
-        cpu->checker->verify(head_inst);
-    }
-#endif
-
-    // DTB will sometimes need the machine instruction for when
-    // faults happen.  So we will set it here, prior to the DTB
-    // possibly needing it for its fault.
-    thread[tid]->setInst(
-        static_cast<TheISA::MachInst>(head_inst->staticInst->machInst));
-
     if (inst_fault != NoFault) {
-        DPRINTF(Commit, "Inst [sn:%lli] PC %#x has a fault\n",
-                head_inst->seqNum, head_inst->readPC());
+        DPRINTF(Commit, "Inst [sn:%lli] PC %s has a fault\n",
+                head_inst->seqNum, head_inst->pcState());
 
         if (iewStage->hasStoresToWB(tid) || inst_num > 0) {
             DPRINTF(Commit, "Stores outstanding, fault must wait.\n");
@@ -1045,17 +1205,18 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
 
         head_inst->setCompleted();
 
-#if USE_CHECKER
-        if (cpu->checker && head_inst->isStore()) {
+        // If instruction has faulted, let the checker execute it and
+        // check if it sees the same fault and control flow.
+        if (cpu->checker) {
+            // Need to check the instruction before its fault is processed
             cpu->checker->verify(head_inst);
         }
-#endif
 
-        assert(!thread[tid]->inSyscall);
+        assert(!thread[tid]->noSquashFromTC);
 
         // Mark that we're in state update mode so that the trap's
         // execution doesn't generate extra squashes.
-        thread[tid]->inSyscall = true;
+        thread[tid]->noSquashFromTC = true;
 
         // Execute the trap.  Although it's slightly unrealistic in
         // terms of timing (as it doesn't wait for the full timing of
@@ -1063,49 +1224,61 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
         // needed to update the state as soon as possible.  This
         // prevents external agents from changing any specific state
         // that the trap need.
-        cpu->trap(inst_fault, tid);
+        cpu->trap(inst_fault, tid, head_inst->staticInst);
 
         // Exit state update mode to avoid accidental updating.
-        thread[tid]->inSyscall = false;
+        thread[tid]->noSquashFromTC = false;
 
         commitStatus[tid] = TrapPending;
 
+        DPRINTF(Commit, "Committing instruction with fault [sn:%lli]\n",
+            head_inst->seqNum);
         if (head_inst->traceData) {
-            head_inst->traceData->setFetchSeq(head_inst->seqNum);
-            head_inst->traceData->setCPSeq(thread[tid]->numInst);
-            head_inst->traceData->dump();
+            if (DTRACE(ExecFaulting)) {
+                head_inst->traceData->setFetchSeq(head_inst->seqNum);
+                head_inst->traceData->setCPSeq(thread[tid]->numOp);
+                head_inst->traceData->dump();
+            }
             delete head_inst->traceData;
             head_inst->traceData = NULL;
         }
 
         // Generate trap squash event.
-        generateTrapEvent(tid);
-//        warn("%lli fault (%d) handled @ PC %08p", curTick, inst_fault->name(), head_inst->readPC());
+        generateTrapEvent(tid, inst_fault);
         return false;
     }
 
     updateComInstStats(head_inst);
 
-#if FULL_SYSTEM
-    if (thread[tid]->profile) {
-//        bool usermode = TheISA::inUserMode(thread[tid]->getTC());
-//        thread[tid]->profilePC = usermode ? 1 : head_inst->readPC();
-        thread[tid]->profilePC = head_inst->readPC();
-        ProfileNode *node = thread[tid]->profile->consume(thread[tid]->getTC(),
-                                                          head_inst->staticInst);
+    if (FullSystem) {
+        if (thread[tid]->profile) {
+            thread[tid]->profilePC = head_inst->instAddr();
+            ProfileNode *node = thread[tid]->profile->consume(
+                    thread[tid]->getTC(), head_inst->staticInst);
 
-        if (node)
-            thread[tid]->profileNode = node;
+            if (node)
+                thread[tid]->profileNode = node;
+        }
+        if (CPA::available()) {
+            if (head_inst->isControl()) {
+                ThreadContext *tc = thread[tid]->getTC();
+                CPA::cpa()->swAutoBegin(tc, head_inst->nextInstAddr());
+            }
+        }
     }
-#endif
-
+    DPRINTF(Commit, "Committing instruction with [sn:%lli] PC %s\n",
+            head_inst->seqNum, head_inst->pcState());
     if (head_inst->traceData) {
         head_inst->traceData->setFetchSeq(head_inst->seqNum);
-        head_inst->traceData->setCPSeq(thread[tid]->numInst);
+        head_inst->traceData->setCPSeq(thread[tid]->numOp);
         head_inst->traceData->dump();
         delete head_inst->traceData;
         head_inst->traceData = NULL;
     }
+    if (head_inst->isReturn()) {
+        DPRINTF(Commit,"Return Instruction Committed [sn:%lli] PC %s \n",
+                        head_inst->seqNum, head_inst->pcState());
+    }
 
     // Update the commit rename map
     for (int i = 0; i < head_inst->numDestRegs(); i++) {
@@ -1113,12 +1286,15 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
                                  head_inst->renamedDestRegIdx(i));
     }
 
-    if (head_inst->isCopy())
-        panic("Should not commit any copy instructions!");
-
     // Finally clear the head ROB entry.
     rob->retireHead(tid);
 
+#if TRACING_ON
+    if (DTRACE(O3PipeView)) {
+        head_inst->commitTick = curTick() - head_inst->fetchTick;
+    }
+#endif
+
     // If this was a store, record it for this cycle.
     if (head_inst->isStore())
         committedStores[tid] = true;
@@ -1140,15 +1316,15 @@ DefaultCommit<Impl>::getInsts()
         DynInstPtr inst;
 
         inst = fromRename->insts[inst_num];
-        int tid = inst->threadNumber;
+        ThreadID tid = inst->threadNumber;
 
         if (!inst->isSquashed() &&
             commitStatus[tid] != ROBSquashing &&
             commitStatus[tid] != TrapPending) {
             changedROBNumEntries[tid] = true;
 
-            DPRINTF(Commit, "Inserting PC %#x [sn:%i] [tid:%i] into ROB.\n",
-                    inst->readPC(), inst->seqNum, tid);
+            DPRINTF(Commit, "Inserting PC %s [sn:%i] [tid:%i] into ROB.\n",
+                    inst->pcState(), inst->seqNum, tid);
 
             rob->insertInst(inst);
 
@@ -1156,32 +1332,9 @@ DefaultCommit<Impl>::getInsts()
 
             youngestSeqNum[tid] = inst->seqNum;
         } else {
-            DPRINTF(Commit, "Instruction PC %#x [sn:%i] [tid:%i] was "
-                    "squashed, skipping.\n",
-                    inst->readPC(), inst->seqNum, tid);
-        }
-    }
-}
-
-template <class Impl>
-void
-DefaultCommit<Impl>::skidInsert()
-{
-    DPRINTF(Commit, "Attempting to any instructions from rename into "
-            "skidBuffer.\n");
-
-    for (int inst_num = 0; inst_num < fromRename->size; ++inst_num) {
-        DynInstPtr inst = fromRename->insts[inst_num];
-
-        if (!inst->isSquashed()) {
-            DPRINTF(Commit, "Inserting PC %#x [sn:%i] [tid:%i] into ",
-                    "skidBuffer.\n", inst->readPC(), inst->seqNum,
-                    inst->threadNumber);
-            skidBuffer.push(inst);
-        } else {
-            DPRINTF(Commit, "Instruction PC %#x [sn:%i] [tid:%i] was "
+            DPRINTF(Commit, "Instruction PC %s [sn:%i] [tid:%i] was "
                     "squashed, skipping.\n",
-                    inst->readPC(), inst->seqNum, inst->threadNumber);
+                    inst->pcState(), inst->seqNum, tid);
         }
     }
 }
@@ -1192,15 +1345,13 @@ DefaultCommit<Impl>::markCompletedInsts()
 {
     // Grab completed insts out of the IEW instruction queue, and mark
     // instructions completed within the ROB.
-    for (int inst_num = 0;
-         inst_num < fromIEW->size && fromIEW->insts[inst_num];
-         ++inst_num)
-    {
+    for (int inst_num = 0; inst_num < fromIEW->size; ++inst_num) {
+        assert(fromIEW->insts[inst_num]);
         if (!fromIEW->insts[inst_num]->isSquashed()) {
-            DPRINTF(Commit, "[tid:%i]: Marking PC %#x, [sn:%lli] ready "
+            DPRINTF(Commit, "[tid:%i]: Marking PC %s, [sn:%lli] ready "
                     "within ROB.\n",
                     fromIEW->insts[inst_num]->threadNumber,
-                    fromIEW->insts[inst_num]->readPC(),
+                    fromIEW->insts[inst_num]->pcState(),
                     fromIEW->insts[inst_num]->seqNum);
 
             // Mark the instruction as ready to commit.
@@ -1209,62 +1360,55 @@ DefaultCommit<Impl>::markCompletedInsts()
     }
 }
 
-template <class Impl>
-bool
-DefaultCommit<Impl>::robDoneSquashing()
-{
-    std::list<unsigned>::iterator threads = activeThreads->begin();
-    std::list<unsigned>::iterator end = activeThreads->end();
-
-    while (threads != end) {
-        unsigned tid = *threads++;
-
-        if (!rob->isDoneSquashing(tid))
-            return false;
-    }
-
-    return true;
-}
-
 template <class Impl>
 void
 DefaultCommit<Impl>::updateComInstStats(DynInstPtr &inst)
 {
-    unsigned thread = inst->threadNumber;
+    ThreadID tid = inst->threadNumber;
 
-    //
-    //  Pick off the software prefetches
-    //
-#ifdef TARGET_ALPHA
-    if (inst->isDataPrefetch()) {
-        statComSwp[thread]++;
-    } else {
-        statComInst[thread]++;
+    if (!inst->isMicroop() || inst->isLastMicroop())
+        instsCommitted[tid]++;
+    opsCommitted[tid]++;
+
+    // To match the old model, don't count nops and instruction
+    // prefetches towards the total commit count.
+    if (!inst->isNop() && !inst->isInstPrefetch()) {
+        cpu->instDone(tid, inst);
     }
-#else
-    statComInst[thread]++;
-#endif
 
     //
     //  Control Instructions
     //
     if (inst->isControl())
-        statComBranches[thread]++;
+        statComBranches[tid]++;
 
     //
     //  Memory references
     //
     if (inst->isMemRef()) {
-        statComRefs[thread]++;
+        statComRefs[tid]++;
 
         if (inst->isLoad()) {
-            statComLoads[thread]++;
+            statComLoads[tid]++;
         }
     }
 
     if (inst->isMemBarrier()) {
-        statComMembars[thread]++;
+        statComMembars[tid]++;
     }
+
+    // Integer Instruction
+    if (inst->isInteger())
+        statComInteger[tid]++;
+
+    // Floating Point Instruction
+    if (inst->isFloating())
+        statComFloating[tid]++;
+
+    // Function Calls
+    if (inst->isCall())
+        statComFunctionCalls[tid]++;
+
 }
 
 ////////////////////////////////////////
@@ -1273,7 +1417,7 @@ DefaultCommit<Impl>::updateComInstStats(DynInstPtr &inst)
 //                                    //
 ////////////////////////////////////////
 template <class Impl>
-int
+ThreadID
 DefaultCommit<Impl>::getCommittingThread()
 {
     if (numThreads > 1) {
@@ -1292,31 +1436,31 @@ DefaultCommit<Impl>::getCommittingThread()
             return oldestReady();
 
           default:
-            return -1;
+            return InvalidThreadID;
         }
     } else {
         assert(!activeThreads->empty());
-        int tid = activeThreads->front();
+        ThreadID tid = activeThreads->front();
 
         if (commitStatus[tid] == Running ||
             commitStatus[tid] == Idle ||
             commitStatus[tid] == FetchTrapPending) {
             return tid;
         } else {
-            return -1;
+            return InvalidThreadID;
         }
     }
 }
 
 template<class Impl>
-int
+ThreadID
 DefaultCommit<Impl>::roundRobin()
 {
-    std::list<unsigned>::iterator pri_iter = priority_list.begin();
-    std::list<unsigned>::iterator end      = priority_list.end();
+    list<ThreadID>::iterator pri_iter = priority_list.begin();
+    list<ThreadID>::iterator end      = priority_list.end();
 
     while (pri_iter != end) {
-        unsigned tid = *pri_iter;
+        ThreadID tid = *pri_iter;
 
         if (commitStatus[tid] == Running ||
             commitStatus[tid] == Idle ||
@@ -1333,21 +1477,21 @@ DefaultCommit<Impl>::roundRobin()
         pri_iter++;
     }
 
-    return -1;
+    return InvalidThreadID;
 }
 
 template<class Impl>
-int
+ThreadID
 DefaultCommit<Impl>::oldestReady()
 {
     unsigned oldest = 0;
     bool first = true;
 
-    std::list<unsigned>::iterator threads = activeThreads->begin();
-    std::list<unsigned>::iterator end = activeThreads->end();
+    list<ThreadID>::iterator threads = activeThreads->begin();
+    list<ThreadID>::iterator end = activeThreads->end();
 
     while (threads != end) {
-        unsigned tid = *threads++;
+        ThreadID tid = *threads++;
 
         if (!rob->isEmpty(tid) &&
             (commitStatus[tid] == Running ||
@@ -1371,6 +1515,8 @@ DefaultCommit<Impl>::oldestReady()
     if (!first) {
         return oldest;
     } else {
-        return -1;
+        return InvalidThreadID;
     }
 }
+
+#endif//__CPU_O3_COMMIT_IMPL_HH__