O3: Remove some asserts that no longer seem to be valid.
[gem5.git] / src / cpu / o3 / decode_impl.hh
index d92e97f61c82ff26c84580a1b2cc789e169c6ab3..a523a8b45129801f2c3455e03c463e7b47d247db 100644 (file)
  * Authors: Kevin Lim
  */
 
+#include "arch/types.hh"
+#include "base/trace.hh"
+#include "config/full_system.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 "params/DerivO3CPU.hh"
 
+using namespace std;
+
 template<class Impl>
 DefaultDecode<Impl>::DefaultDecode(O3CPU *_cpu, DerivO3CPUParams *params)
     : cpu(_cpu),
@@ -45,12 +53,12 @@ DefaultDecode<Impl>::DefaultDecode(O3CPU *_cpu, DerivO3CPUParams *params)
     _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;
+        stalls[tid].iew = false;
+        stalls[tid].commit = false;
     }
 
     // @todo: Make into a parameter
@@ -69,44 +77,44 @@ void
 DefaultDecode<Impl>::regStats()
 {
     decodeIdleCycles
-        .name(name() + ".DECODE:IdleCycles")
+        .name(name() + ".IdleCycles")
         .desc("Number of cycles decode is idle")
         .prereq(decodeIdleCycles);
     decodeBlockedCycles
-        .name(name() + ".DECODE:BlockedCycles")
+        .name(name() + ".BlockedCycles")
         .desc("Number of cycles decode is blocked")
         .prereq(decodeBlockedCycles);
     decodeRunCycles
-        .name(name() + ".DECODE:RunCycles")
+        .name(name() + ".RunCycles")
         .desc("Number of cycles decode is running")
         .prereq(decodeRunCycles);
     decodeUnblockCycles
-        .name(name() + ".DECODE:UnblockCycles")
+        .name(name() + ".UnblockCycles")
         .desc("Number of cycles decode is unblocking")
         .prereq(decodeUnblockCycles);
     decodeSquashCycles
-        .name(name() + ".DECODE:SquashCycles")
+        .name(name() + ".SquashCycles")
         .desc("Number of cycles decode is squashing")
         .prereq(decodeSquashCycles);
     decodeBranchResolved
-        .name(name() + ".DECODE:BranchResolved")
+        .name(name() + ".BranchResolved")
         .desc("Number of times decode resolved a branch")
         .prereq(decodeBranchResolved);
     decodeBranchMispred
-        .name(name() + ".DECODE:BranchMispred")
+        .name(name() + ".BranchMispred")
         .desc("Number of times decode detected a branch misprediction")
         .prereq(decodeBranchMispred);
     decodeControlMispred
-        .name(name() + ".DECODE:ControlMispred")
+        .name(name() + ".ControlMispred")
         .desc("Number of times decode detected an instruction incorrectly"
               " predicted as a control")
         .prereq(decodeControlMispred);
     decodeDecodedInsts
-        .name(name() + ".DECODE:DecodedInsts")
+        .name(name() + ".DecodedInsts")
         .desc("Number of instructions handled by decode")
         .prereq(decodeDecodedInsts);
     decodeSquashedInsts
-        .name(name() + ".DECODE:SquashedInsts")
+        .name(name() + ".SquashedInsts")
         .desc("Number of squashed instructions handled by decode")
         .prereq(decodeSquashedInsts);
 }
@@ -148,7 +156,7 @@ DefaultDecode<Impl>::setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr)
 
 template<class Impl>
 void
-DefaultDecode<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
+DefaultDecode<Impl>::setActiveThreads(std::list<ThreadID> *at_ptr)
 {
     activeThreads = at_ptr;
 }
@@ -169,24 +177,24 @@ DefaultDecode<Impl>::takeOverFrom()
     _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) {
+        decodeStatus[tid] = Idle;
+
+        stalls[tid].rename = false;
+        stalls[tid].iew = false;
+        stalls[tid].commit = false;
+        while (!insts[tid].empty())
+            insts[tid].pop();
+        while (!skidBuffer[tid].empty())
+            skidBuffer[tid].pop();
+        branchCount[tid] = 0;
     }
     wroteToTimeBuffer = false;
 }
 
 template<class Impl>
 bool
-DefaultDecode<Impl>::checkStall(unsigned tid) const
+DefaultDecode<Impl>::checkStall(ThreadID tid) const
 {
     bool ret_val = false;
 
@@ -213,7 +221,7 @@ DefaultDecode<Impl>::fetchInstsValid()
 
 template<class Impl>
 bool
-DefaultDecode<Impl>::block(unsigned tid)
+DefaultDecode<Impl>::block(ThreadID tid)
 {
     DPRINTF(Decode, "[tid:%u]: Blocking.\n", tid);
 
@@ -241,7 +249,7 @@ 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()) {
@@ -260,31 +268,19 @@ DefaultDecode<Impl>::unblock(unsigned tid)
 
 template<class Impl>
 void
-DefaultDecode<Impl>::squash(DynInstPtr &inst, unsigned tid)
+DefaultDecode<Impl>::squash(DynInstPtr &inst, ThreadID tid)
 {
-    DPRINTF(Decode, "[tid:%i]: [sn:%i] Squashing due to incorrect branch prediction "
-            "detected at decode.\n", tid, inst->seqNum);
+    DPRINTF(Decode, "[tid:%i]: [sn:%i] 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].predIncorrect = true;
     toFetch->decodeInfo[tid].squash = true;
     toFetch->decodeInfo[tid].doneSeqNum = inst->seqNum;
-    toFetch->decodeInfo[tid].nextMicroPC = inst->readMicroPC();
-
-#if ISA_HAS_DELAY_SLOT
-    toFetch->decodeInfo[tid].nextPC = inst->readPC() + sizeof(TheISA::MachInst);
-    toFetch->decodeInfo[tid].nextNPC = inst->branchTarget();
-    toFetch->decodeInfo[tid].branchTaken = inst->readNextNPC() !=
-        (inst->readNextPC() + sizeof(TheISA::MachInst));
-#else
     toFetch->decodeInfo[tid].nextPC = inst->branchTarget();
-    toFetch->decodeInfo[tid].nextNPC =
-        inst->branchTarget() + sizeof(TheISA::MachInst);
-    toFetch->decodeInfo[tid].branchTaken =
-        inst->readNextPC() != (inst->readPC() + sizeof(TheISA::MachInst));
-#endif
-
+    toFetch->decodeInfo[tid].branchTaken = inst->pcState().branching();
+    toFetch->decodeInfo[tid].squashInst = inst;
 
     InstSeqNum squash_seq_num = inst->seqNum;
 
@@ -320,7 +316,7 @@ DefaultDecode<Impl>::squash(DynInstPtr &inst, unsigned tid)
 
 template<class Impl>
 unsigned
-DefaultDecode<Impl>::squash(unsigned tid)
+DefaultDecode<Impl>::squash(ThreadID tid)
 {
     DPRINTF(Decode, "[tid:%i]: Squashing.\n",tid);
 
@@ -369,7 +365,7 @@ DefaultDecode<Impl>::squash(unsigned tid)
 
 template<class Impl>
 void
-DefaultDecode<Impl>::skidInsert(unsigned tid)
+DefaultDecode<Impl>::skidInsert(ThreadID tid)
 {
     DynInstPtr inst = NULL;
 
@@ -380,8 +376,8 @@ 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);
+        DPRINTF(Decode,"Inserting [sn:%lli] PC: %s into decode skidBuffer %i\n",
+                inst->seqNum, inst->pcState(), inst->threadNumber);
 
         skidBuffer[tid].push(inst);
     }
@@ -395,11 +391,11 @@ template<class Impl>
 bool
 DefaultDecode<Impl>::skidsEmpty()
 {
-    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 (!skidBuffer[tid].empty())
             return false;
     }
@@ -413,11 +409,11 @@ DefaultDecode<Impl>::updateStatus()
 {
     bool any_unblocking = false;
 
-    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 (decodeStatus[tid] == Unblocking) {
             any_unblocking = true;
@@ -451,10 +447,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]);
     }
@@ -462,7 +454,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;
@@ -494,7 +486,7 @@ DefaultDecode<Impl>::readStallSignals(unsigned tid)
 
 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.
@@ -569,14 +561,14 @@ DefaultDecode<Impl>::tick()
 
     toRenameIndex = 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();
 
     sortInsts();
 
     //Check stall and squash signals.
     while (threads != end) {
-        unsigned tid = *threads++;
+        ThreadID tid = *threads++;
 
         DPRINTF(Decode,"Processing [tid:%i]\n",tid);
         status_change =  checkSignalsAndUpdate(tid) || status_change;
@@ -597,7 +589,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()
@@ -642,7 +634,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.
@@ -679,13 +671,12 @@ DefaultDecode<Impl>::decodeInsts(unsigned tid)
         insts_to_decode.pop();
 
         DPRINTF(Decode, "[tid:%u]: Processing instruction [sn:%lli] with "
-                "PC %#x\n",
-                tid, inst->seqNum, inst->readPC());
+                "PC %s\n", tid, inst->seqNum, inst->pcState());
 
         if (inst->isSquashed()) {
-            DPRINTF(Decode, "[tid:%u]: Instruction %i with PC %#x is "
+            DPRINTF(Decode, "[tid:%u]: Instruction %i with PC %s is "
                     "squashed, skipping.\n",
-                    tid, inst->seqNum, inst->readPC());
+                    tid, inst->seqNum, inst->pcState());
 
             ++decodeSquashedInsts;
 
@@ -712,12 +703,13 @@ DefaultDecode<Impl>::decodeInsts(unsigned tid)
         ++decodeDecodedInsts;
         --insts_available;
 
+#if TRACING_ON
+        inst->decodeTick = curTick();
+#endif
+
         // Ensure that if it was predicted as a branch, it really is a
         // branch.
         if (inst->readPredTaken() && !inst->isControl()) {
-            DPRINTF(Decode, "PredPC : %#x != NextPC: %#x\n",
-                    inst->readPredPC(), inst->readNextPC() + 4);
-
             panic("Instruction predicted as a branch!");
 
             ++decodeControlMispred;
@@ -733,26 +725,18 @@ DefaultDecode<Impl>::decodeInsts(unsigned tid)
         if (inst->isDirectCtrl() && inst->isUncondCtrl()) {
             ++decodeBranchResolved;
 
-            if (inst->branchTarget() != inst->readPredPC()) {
+            if (!(inst->branchTarget() == inst->readPredTarg())) {
                 ++decodeBranchMispred;
 
                 // Might want to set some sort of boolean and just do
                 // a check at the end
                 squash(inst, inst->threadNumber);
-                Addr target = inst->branchTarget();
-
-#if ISA_HAS_DELAY_SLOT
-                DPRINTF(Decode, "[sn:%i]: Updating predictions: PredPC: %#x  PredNextPC: %#x\n",
-                        inst->seqNum, inst->readPC() + sizeof(TheISA::MachInst), target);
+                TheISA::PCState target = inst->branchTarget();
 
+                DPRINTF(Decode, "[sn:%i]: Updating predictions: PredPC: %s\n",
+                        inst->seqNum, target);
                 //The micro pc after an instruction level branch should be 0
-                inst->setPredTarg(inst->readPC() + sizeof(TheISA::MachInst), target, 0);
-#else
-                DPRINTF(Decode, "[sn:%i]: Updating predictions: PredPC: %#x  PredNextPC: %#x\n",
-                        inst->seqNum, target, target + sizeof(TheISA::MachInst));
-                //The micro pc after an instruction level branch should be 0
-                inst->setPredTarg(target, target + sizeof(TheISA::MachInst), 0);
-#endif
+                inst->setPredTarg(target);
                 break;
             }
         }