Replace curTick global variable with accessor functions.
[gem5.git] / src / cpu / o3 / commit_impl.hh
index f263383aef0ec13998d086c34ba8b9ab80bff263..2912cbb037ca54a533cabfa5337c1fdbb1a761f0 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2010 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.
  *
  *          Korey Sewell
  */
 
-#include "config/full_system.hh"
-#include "config/use_checker.hh"
-
 #include <algorithm>
 #include <string>
 
 #include "arch/utility.hh"
+#include "base/cp_annotate.hh"
 #include "base/loader/symtab.hh"
-#include "base/timebuf.hh"
+#include "cpu/timebuf.hh"
+#include "config/full_system.hh"
+#include "config/the_isa.hh"
+#include "config/use_checker.hh"
 #include "cpu/exetrace.hh"
 #include "cpu/o3/commit.hh"
 #include "cpu/o3/thread_state.hh"
+#include "params/DerivO3CPU.hh"
 
 #if USE_CHECKER
 #include "cpu/checker/cpu.hh"
 #endif
 
+using namespace std;
+
 template <class Impl>
 DefaultCommit<Impl>::TrapEvent::TrapEvent(DefaultCommit<Impl> *_commit,
-                                          unsigned _tid)
-    : Event(&mainEventQueue, CPU_Tick_Pri), commit(_commit), tid(_tid)
+                                          ThreadID _tid)
+    : Event(CPU_Tick_Pri), commit(_commit), tid(_tid)
 {
-    this->setFlags(Event::AutoDelete);
+    this->setFlags(AutoDelete);
 }
 
 template <class Impl>
@@ -65,13 +81,13 @@ DefaultCommit<Impl>::TrapEvent::process()
 
 template <class Impl>
 const char *
-DefaultCommit<Impl>::TrapEvent::description()
+DefaultCommit<Impl>::TrapEvent::description() const
 {
     return "Trap";
 }
 
 template <class Impl>
-DefaultCommit<Impl>::DefaultCommit(O3CPU *_cpu, Params *params)
+DefaultCommit<Impl>::DefaultCommit(O3CPU *_cpu, DerivO3CPUParams *params)
     : cpu(_cpu),
       squashCounter(0),
       iewToCommitDelay(params->iewToCommitDelay),
@@ -80,7 +96,7 @@ DefaultCommit<Impl>::DefaultCommit(O3CPU *_cpu, Params *params)
       fetchToCommitDelay(params->commitToFetchDelay),
       renameWidth(params->renameWidth),
       commitWidth(params->commitWidth),
-      numThreads(params->numberOfThreads),
+      numThreads(params->numThreads),
       drainPending(false),
       switchedOut(false),
       trapLatency(params->trapLatency)
@@ -102,7 +118,7 @@ DefaultCommit<Impl>::DefaultCommit(O3CPU *_cpu, Params *params)
         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);
         }
 
@@ -116,15 +132,15 @@ DefaultCommit<Impl>::DefaultCommit(O3CPU *_cpu, Params *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);
     }
 #if FULL_SYSTEM
     interrupt = NoFault;
@@ -172,49 +188,49 @@ DefaultCommit<Impl>::regStats()
         ;
 
     statComInst
-        .init(cpu->number_of_threads)
+        .init(cpu->numThreads)
         .name(name() + ".COM:count")
         .desc("Number of instructions committed")
         .flags(total)
         ;
 
     statComSwp
-        .init(cpu->number_of_threads)
+        .init(cpu->numThreads)
         .name(name() + ".COM:swp_count")
         .desc("Number of s/w prefetches committed")
         .flags(total)
         ;
 
     statComRefs
-        .init(cpu->number_of_threads)
+        .init(cpu->numThreads)
         .name(name() +  ".COM:refs")
         .desc("Number of memory references committed")
         .flags(total)
         ;
 
     statComLoads
-        .init(cpu->number_of_threads)
+        .init(cpu->numThreads)
         .name(name() +  ".COM:loads")
         .desc("Number of loads committed")
         .flags(total)
         ;
 
     statComMembars
-        .init(cpu->number_of_threads)
+        .init(cpu->numThreads)
         .name(name() +  ".COM:membars")
         .desc("Number of memory barriers committed")
         .flags(total)
         ;
 
     statComBranches
-        .init(cpu->number_of_threads)
+        .init(cpu->numThreads)
         .name(name() + ".COM:branches")
         .desc("Number of branches committed")
         .flags(total)
         ;
 
     commitEligible
-        .init(cpu->number_of_threads)
+        .init(cpu->numThreads)
         .name(name() + ".COM:bw_limited")
         .desc("number of insts not committed due to BW limits")
         .flags(total)
@@ -285,7 +301,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;
 }
@@ -294,9 +310,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>
@@ -314,10 +329,10 @@ DefaultCommit<Impl>::initStage()
     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
@@ -325,7 +340,7 @@ DefaultCommit<Impl>::initStage()
     cpu->activateStage(O3CPU::CommitIdx);
 
     cpu->activityThisCycle();
-    trapLatency = cpu->cycles(trapLatency);
+    trapLatency = cpu->ticks(trapLatency);
 }
 
 template <class Impl>
@@ -360,11 +375,11 @@ 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;
     }
     squashCounter = 0;
     rob->takeOverFrom();
@@ -375,11 +390,11 @@ 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;
 
@@ -407,11 +422,11 @@ DefaultCommit<Impl>::setNextStatus()
 {
     int squashes = 0;
 
-    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 (commitStatus[tid] == ROBSquashing) {
             squashes++;
@@ -431,11 +446,11 @@ 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;
@@ -446,27 +461,27 @@ 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)
 {
     DPRINTF(Commit, "Generating trap event for [tid:%i]\n", tid);
 
     TrapEvent *trap = new TrapEvent(this, tid);
 
-    trap->schedule(curTick + trapLatency);
+    cpu->schedule(trap, curTick() + trapLatency);
     trapInFlight[tid] = 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);
@@ -476,7 +491,7 @@ 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.
@@ -506,18 +521,16 @@ DefaultCommit<Impl>::squashAll(unsigned tid)
 
     toIEW->commitInfo[tid].branchMispredict = false;
 
-    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;
@@ -531,11 +544,11 @@ 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;
     assert(!thread[tid]->trapPending);
@@ -546,6 +559,33 @@ DefaultCommit<Impl>::squashFromTC(unsigned tid)
     tcSquash[tid] = false;
 }
 
+template <class Impl>
+void
+DefaultCommit<Impl>::squashAfter(ThreadID tid, uint64_t squash_after_seq_num)
+{
+    youngestSeqNum[tid] = squash_after_seq_num;
+
+    rob->squash(squash_after_seq_num, tid);
+    changedROBNumEntries[tid] = true;
+
+    // Send back the sequence number of the squashed instruction.
+    toIEW->commitInfo[tid].doneSeqNum = squash_after_seq_num;
+
+    // Send back the squash signal to tell stages that they should squash.
+    toIEW->commitInfo[tid].squash = true;
+
+    // Send back the rob squashing signal so other stages know that
+    // the ROB is in the process of squashing.
+    toIEW->commitInfo[tid].robSquashing = true;
+
+    toIEW->commitInfo[tid].branchMispredict = false;
+
+    toIEW->commitInfo[tid].pc = pc[tid];
+    DPRINTF(Commit, "Executing squash after for [tid:%i] inst [sn:%lli]\n",
+            tid, squash_after_seq_num);
+    commitStatus[tid] = ROBSquashing;
+}
+
 template <class Impl>
 void
 DefaultCommit<Impl>::tick()
@@ -562,13 +602,13 @@ DefaultCommit<Impl>::tick()
     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.
@@ -595,7 +635,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
@@ -604,16 +644,16 @@ 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);
 
             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",
@@ -663,7 +703,7 @@ DefaultCommit<Impl>::handleInterrupt()
             DPRINTF(Commit, "Interrupt pending, waiting for ROB to empty.\n");
         }
     } else if (commitStatus[0] != TrapPending &&
-               cpu->check_interrupts(cpu->tcBase(0)) &&
+               cpu->checkInterrupts(cpu->tcBase(0)) &&
                !trapSquash[0] &&
                !tcSquash[0]) {
         // Process interrupts if interrupts are enabled, not in PAL
@@ -693,7 +733,7 @@ DefaultCommit<Impl>::commit()
     // 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->check_interrupts(cpu->tcBase(0))) {
+    if (cpu->checkInterrupts(cpu->tcBase(0))) {
         handleInterrupt();
     }
 #endif // FULL_SYSTEM
@@ -701,11 +741,11 @@ DefaultCommit<Impl>::commit()
     ////////////////////////////////////
     // 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();
 
     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.
@@ -731,7 +771,7 @@ DefaultCommit<Impl>::commit()
 
             DPRINTF(Commit, "[tid:%i]: Redirecting to PC %#x\n",
                     tid,
-                    fromIEW->nextPC[tid]);
+                    fromIEW->pc[tid].nextInstAddr());
 
             commitStatus[tid] = ROBSquashing;
 
@@ -764,9 +804,7 @@ DefaultCommit<Impl>::commit()
             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].pc = fromIEW->pc[tid];
 
             toIEW->commitInfo[tid].mispredPC = fromIEW->mispredPC[tid];
 
@@ -791,7 +829,7 @@ DefaultCommit<Impl>::commit()
     threads = activeThreads->begin();
 
     while (threads != end) {
-        unsigned tid = *threads++;
+        ThreadID tid = *threads++;
 
         if (changedROBNumEntries[tid]) {
             toIEW->commitInfo[tid].usedROB = true;
@@ -812,7 +850,7 @@ DefaultCommit<Impl>::commit()
         // @todo: Make this handle multi-cycle communication between
         // commit and IEW.
         if (checkEmptyROB[tid] && rob->isEmpty(tid) &&
-            !iewStage->hasStoresToWB() && !committedStores[tid]) {
+            !iewStage->hasStoresToWB(tid) && !committedStores[tid]) {
             checkEmptyROB[tid] = false;
             toIEW->commitInfo[tid].usedROB = true;
             toIEW->commitInfo[tid].emptyROB = true;
@@ -852,7 +890,7 @@ DefaultCommit<Impl>::commitInsts()
 
         head_inst = rob->readHeadInst(commit_thread);
 
-        int tid = head_inst->threadNumber;
+        ThreadID tid = head_inst->threadNumber;
 
         assert(tid == commit_thread);
 
@@ -873,10 +911,7 @@ DefaultCommit<Impl>::commitInsts()
             // 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.
@@ -904,35 +939,35 @@ DefaultCommit<Impl>::commitInsts()
                     cpu->instDone(tid);
                 }
 
-                PC[tid] = nextPC[tid];
-                nextPC[tid] = nextNPC[tid];
-                nextNPC[tid] = nextNPC[tid] + sizeof(TheISA::MachInst);
-                microPC[tid] = nextMicroPC[tid];
-                nextMicroPC[tid] = microPC[tid] + 1;
+                // Updates misc. registers.
+                head_inst->updateMiscRegs();
+
+                TheISA::advancePC(pc[tid], head_inst->staticInst);
+
+                // 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->seqNum);
 
-#if FULL_SYSTEM
                 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 {
-                    // Debug statement.  Checks to make sure we're not
-                    // currently updating state while handling PC events.
-                    if (count == 0)
-                        assert(!thread[tid]->inSyscall &&
-                               !thread[tid]->trapPending);
-                    oldpc = PC[tid];
-                    cpu->system->pcEventQueue.service(
-                        thread[tid]->getTC());
+                    oldpc = pc[tid].instAddr();
+                    cpu->system->pcEventQueue.service(thread[tid]->getTC());
                     count++;
-                } while (oldpc != PC[tid]);
+                } while (oldpc != pc[tid].instAddr());
                 if (count > 1) {
-                    DPRINTF(Commit, "PC skip function event, stopping commit\n");
+                    DPRINTF(Commit,
+                            "PC skip function event, stopping commit\n");
                     break;
                 }
-#endif
             } 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;
             }
         }
@@ -952,7 +987,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.
@@ -967,10 +1002,10 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
             head_inst->isWriteBarrier()) {
 
             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());
+                    "instruction [sn:%lli] at the head of the ROB, PC %s.\n",
+                    head_inst->seqNum, head_inst->pcState());
 
-            if (inst_num > 0 || iewStage->hasStoresToWB()) {
+            if (inst_num > 0 || iewStage->hasStoresToWB(tid)) {
                 DPRINTF(Commit, "Waiting for all stores to writeback.\n");
                 return false;
             }
@@ -985,14 +1020,14 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
 
             return false;
         } else if (head_inst->isLoad()) {
-            if (inst_num > 0 || iewStage->hasStoresToWB()) {
+            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());
+            DPRINTF(Commit, "[sn:%lli]: Uncached load, PC %s.\n",
+                    head_inst->seqNum, head_inst->pcState());
 
             // Send back the non-speculative instruction's sequence
             // number.  Tell the lsq to re-execute the load.
@@ -1030,17 +1065,11 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
     }
 #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() || inst_num > 0) {
+        if (iewStage->hasStoresToWB(tid) || inst_num > 0) {
             DPRINTF(Commit, "Stores outstanding, fault must wait.\n");
             return false;
         }
@@ -1065,7 +1094,7 @@ 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;
@@ -1073,16 +1102,17 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
         commitStatus[tid] = TrapPending;
 
         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]->numInst);
+                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());
         return false;
     }
 
@@ -1090,15 +1120,19 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
 
 #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();
+        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 (CPA::available()) {
+        if (head_inst->isControl()) {
+            ThreadContext *tc = thread[tid]->getTC();
+            CPA::cpa()->swAutoBegin(tc, head_inst->nextInstAddr());
+        }
+    }
 #endif
 
     if (head_inst->traceData) {
@@ -1142,15 +1176,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);
 
@@ -1158,9 +1192,9 @@ DefaultCommit<Impl>::getInsts()
 
             youngestSeqNum[tid] = inst->seqNum;
         } 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, tid);
+                    inst->pcState(), inst->seqNum, tid);
         }
     }
 }
@@ -1176,14 +1210,14 @@ DefaultCommit<Impl>::skidInsert()
         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,
+            DPRINTF(Commit, "Inserting PC %s [sn:%i] [tid:%i] into ",
+                    "skidBuffer.\n", inst->pcState(), 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, inst->threadNumber);
         }
     }
 }
@@ -1199,10 +1233,10 @@ DefaultCommit<Impl>::markCompletedInsts()
          ++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.
@@ -1215,11 +1249,11 @@ template <class Impl>
 bool
 DefaultCommit<Impl>::robDoneSquashing()
 {
-    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->isDoneSquashing(tid))
             return false;
@@ -1232,40 +1266,40 @@ 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]++;
+        statComSwp[tid]++;
     } else {
-        statComInst[thread]++;
+        statComInst[tid]++;
     }
 #else
-    statComInst[thread]++;
+    statComInst[tid]++;
 #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]++;
     }
 }
 
@@ -1275,7 +1309,7 @@ DefaultCommit<Impl>::updateComInstStats(DynInstPtr &inst)
 //                                    //
 ////////////////////////////////////////
 template <class Impl>
-int
+ThreadID
 DefaultCommit<Impl>::getCommittingThread()
 {
     if (numThreads > 1) {
@@ -1294,31 +1328,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 ||
@@ -1335,21 +1369,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 ||
@@ -1373,6 +1407,6 @@ DefaultCommit<Impl>::oldestReady()
     if (!first) {
         return oldest;
     } else {
-        return -1;
+        return InvalidThreadID;
     }
 }