O3: Support squashing all state after special instruction
authorAli Saidi <Ali.Saidi@ARM.com>
Wed, 8 Dec 2010 00:19:57 +0000 (16:19 -0800)
committerAli Saidi <Ali.Saidi@ARM.com>
Wed, 8 Dec 2010 00:19:57 +0000 (16:19 -0800)
For SPARC ASIs are added to the ExtMachInst. If the ASI is changed simply
marking the instruction as Serializing isn't enough beacuse that only
stops rename. This provides a mechanism to squash all the instructions
and refetch them

src/arch/sparc/isa/decoder.isa
src/cpu/base_dyn_inst.hh
src/cpu/o3/commit.hh
src/cpu/o3/commit_impl.hh
src/cpu/static_inst.hh

index e0a34a1b119df7d15a82b652c488bc834729d237..b62b8400d230342ace302ab2ce4a74f04f2a1b20 100644 (file)
@@ -490,7 +490,8 @@ decode OP default Unknown::unknown()
                 0x00: NoPriv::wry({{Y = (Rs1 ^ Rs2_or_imm13)<31:0>;}});
                 // 0x01 should cause an illegal instruction exception
                 0x02: NoPriv::wrccr({{Ccr = Rs1 ^ Rs2_or_imm13;}});
-                0x03: NoPriv::wrasi({{Asi = Rs1 ^ Rs2_or_imm13;}});
+                0x03: NoPriv::wrasi({{Asi = Rs1 ^ Rs2_or_imm13;}}, false,
+                                    IsSquashAfter);
                 // 0x04-0x05 should cause an illegal instruction exception
                 0x06: NoPriv::wrfprs({{Fprs = Rs1 ^ Rs2_or_imm13;}});
                 // 0x07-0x0E should cause an illegal instruction exception
index bd2d9fa95baf09bb88f86262f25662e08c2c549e..0c566ec6565da02d9a7c239cfc3a069efd39e732 100644 (file)
@@ -478,6 +478,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
     { return staticInst->isSerializeBefore() || status[SerializeBefore]; }
     bool isSerializeAfter() const
     { return staticInst->isSerializeAfter() || status[SerializeAfter]; }
+    bool isSquashAfter() const { return staticInst->isSquashAfter(); }
     bool isMemBarrier()   const { return staticInst->isMemBarrier(); }
     bool isWriteBarrier() const { return staticInst->isWriteBarrier(); }
     bool isNonSpeculative() const { return staticInst->isNonSpeculative(); }
index 326f3a1d3c2f672a8d58f1d0ad9c3678dcbdb3cb..468153dc77880852b24fd7fd4ffa5e2b2166b886 100644 (file)
@@ -245,6 +245,13 @@ class DefaultCommit
     /** Handles squashing due to an TC write. */
     void squashFromTC(ThreadID tid);
 
+    /** Handles squashing from instruction with SquashAfter set.
+     * This differs from the other squashes as it squashes following
+     * instructions instead of the current instruction and doesn't
+     * clean up various status bits about traps/tc writes pending.
+     */
+    void squashAfter(ThreadID tid, uint64_t squash_after_seq_num);
+
 #if FULL_SYSTEM
     /** Handles processing an interrupt. */
     void handleInterrupt();
index 1a44c64eed165c55af8726dd31f24ac0106c47bd..2895de2938c06f2d647d40445a3b2237a85cebf2 100644 (file)
@@ -559,6 +559,33 @@ DefaultCommit<Impl>::squashFromTC(ThreadID 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()
@@ -917,6 +944,11 @@ DefaultCommit<Impl>::commitInsts()
 
                 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);
+
                 int count = 0;
                 Addr oldpc;
                 // Debug statement.  Checks to make sure we're not
index e08cbcdb6539390bf9b1019234f85c2eda937efe..15ac444aee23ebeb531bc6eb01eb11842d65f6e7 100644 (file)
@@ -158,7 +158,7 @@ class StaticInstBase : public RefCounted
         //This flag doesn't do anything yet
         IsMicroBranch,  ///< This microop branches within the microcode for a macroop
         IsDspOp,
-
+        IsSquashAfter, ///< Squash all uncommitted state after executed
         NumFlags
     };
 
@@ -248,6 +248,7 @@ class StaticInstBase : public RefCounted
                                       flags[IsSerializeAfter]; }
     bool isSerializeBefore() const { return flags[IsSerializeBefore]; }
     bool isSerializeAfter() const { return flags[IsSerializeAfter]; }
+    bool isSquashAfter() const { return flags[IsSquashAfter]; }
     bool isMemBarrier()   const { return flags[IsMemBarrier]; }
     bool isWriteBarrier() const { return flags[IsWriteBarrier]; }
     bool isNonSpeculative() const { return flags[IsNonSpeculative]; }