Add extra flags to help new CPU handle various instructions.
authorKevin Lim <ktlim@umich.edu>
Tue, 23 May 2006 18:38:16 +0000 (14:38 -0400)
committerKevin Lim <ktlim@umich.edu>
Tue, 23 May 2006 18:38:16 +0000 (14:38 -0400)
IsIprAccess flag may go away in the future (op class can be used to tell this), and the CPU still needs a specific way to identify/deal with syscalls.

arch/alpha/isa/decoder.isa:
    Added a few extra flags to help the new CPU identify various classes of instructions without having to force certain behaviors for all CPUs.
cpu/base_dyn_inst.hh:
cpu/static_inst.hh:
    Added extra flags.
cpu/o3/iew_impl.hh:
cpu/o3/inst_queue_impl.hh:
    Handle store conditionals specially.
cpu/o3/lsq_unit_impl.hh:
    Extra flags tells if the instruction is a store conditional.
cpu/o3/rename_impl.hh:
    Handle IPR accesses and store conditionals specially.

--HG--
extra : convert_revision : 39debec4fa5341ae8a8ab5650bd12730aeb6c04f

arch/alpha/isa/decoder.isa
cpu/base_dyn_inst.hh
cpu/o3/iew_impl.hh
cpu/o3/inst_queue_impl.hh
cpu/o3/lsq_unit_impl.hh
cpu/o3/rename_impl.hh
cpu/static_inst.hh

index 48ced0eff548c996669ccb1ccd8f18ed318e8799..b3744a43d06472f5077958f995b4d4caef08795a 100644 (file)
@@ -73,7 +73,7 @@ decode OPCODE default Unknown::unknown() {
                         uint64_t tmp = write_result;
                         // see stq_c
                         Ra = (tmp == 0 || tmp == 1) ? tmp : Ra;
-                    }}, mem_flags = LOCKED);
+                    }}, mem_flags = LOCKED, inst_flags = IsStoreConditional);
         0x2f: stq_c({{ Mem.uq = Ra; }},
                     {{
                         uint64_t tmp = write_result;
@@ -85,7 +85,7 @@ decode OPCODE default Unknown::unknown() {
                         // mailbox access, and we don't update the
                         // result register at all.
                         Ra = (tmp == 0 || tmp == 1) ? tmp : Ra;
-                    }}, mem_flags = LOCKED);
+                    }}, mem_flags = LOCKED, inst_flags = IsStoreConditional);
     }
 
     format IntegerOperate {
@@ -591,8 +591,8 @@ decode OPCODE default Unknown::unknown() {
             0x02e: fcmovle({{ Fc = (Fa <= 0) ? Fb : Fc; }});
             0x02f: fcmovgt({{ Fc = (Fa >  0) ? Fb : Fc; }});
 
-            0x024: mt_fpcr({{ FPCR = Fa.uq; }});
-            0x025: mf_fpcr({{ Fa.uq = FPCR; }});
+            0x024: mt_fpcr({{ FPCR = Fa.uq; }}, IsIprAccess);
+            0x025: mf_fpcr({{ Fa.uq = FPCR; }}, IsIprAccess);
         }
     }
 
@@ -696,9 +696,9 @@ decode OPCODE default Unknown::unknown() {
                 xc->syscall();
             }}, IsNonSpeculative);
             // Read uniq reg into ABI return value register (r0)
-            0x9e: rduniq({{ R0 = Runiq; }});
+            0x9e: rduniq({{ R0 = Runiq; }}, IsIprAccess);
             // Write uniq reg with value from ABI arg register (r16)
-            0x9f: wruniq({{ Runiq = R16; }});
+            0x9f: wruniq({{ Runiq = R16; }}, IsIprAccess);
         }
     }
 #endif
@@ -735,7 +735,7 @@ decode OPCODE default Unknown::unknown() {
         format HwMoveIPR {
             1: hw_mfpr({{
                 Ra = xc->readMiscRegWithEffect(ipr_index, fault);
-            }});
+            }}, IsIprAccess);
         }
     }
 
@@ -745,7 +745,7 @@ decode OPCODE default Unknown::unknown() {
             1: hw_mtpr({{
                 xc->setMiscRegWithEffect(ipr_index, Ra);
                 if (traceData) { traceData->setData(Ra); }
-            }});
+            }}, IsIprAccess);
         }
     }
 
index cd754dc3c4ee243d2d24107246c53ea88f367bcb..9403faec392d35de5059454d1cd6142584ce2188 100644 (file)
@@ -334,6 +334,8 @@ class BaseDynInst : public FastAlloc, public RefCounted
     bool isMemRef()              const { return staticInst->isMemRef(); }
     bool isLoad()        const { return staticInst->isLoad(); }
     bool isStore()       const { return staticInst->isStore(); }
+    bool isStoreConditional() const
+    { return staticInst->isStoreConditional(); }
     bool isInstPrefetch() const { return staticInst->isInstPrefetch(); }
     bool isDataPrefetch() const { return staticInst->isDataPrefetch(); }
     bool isCopy()         const { return staticInst->isCopy(); }
@@ -356,6 +358,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
     bool isWriteBarrier() const { return staticInst->isWriteBarrier(); }
     bool isNonSpeculative() const { return staticInst->isNonSpeculative(); }
     bool isQuiesce() const { return staticInst->isQuiesce(); }
+    bool isIprAccess() const { return staticInst->isIprAccess(); }
     bool isUnverifiable() const { return staticInst->isUnverifiable(); }
 
     /** Temporarily sets this instruction as a serialize before instruction. */
index 59f4055a6c06f9dad646ddc6885f0162f1c6ad51..cf28f2efc39b0d15f49146017a5081b0bded58e3 100644 (file)
@@ -1100,10 +1100,10 @@ DefaultIEW<Impl>::dispatchInsts(unsigned tid)
 
             ++iewDispStoreInsts;
 
-            if (inst->isNonSpeculative()) {
-                // Non-speculative stores (namely store conditionals)
-                // need to be set as "canCommit()" so that commit can
-                // process them when they reach the head of commit.
+            if (inst->isStoreConditional()) {
+                // Store conditionals need to be set as "canCommit()"
+                // so that commit can process them when they reach the
+                // head of commit.
                 inst->setCanCommit();
                 instQueue.insertNonSpec(inst);
                 add_to_iq = false;
index ed57ac257fc722fa98a34e012da7faa2bf5e4e78..71541b4f8994343fa3841bc83a4bb8413c54eb35 100644 (file)
@@ -1041,6 +1041,7 @@ InstructionQueue<Impl>::doSquash(unsigned tid)
 
             // Remove the instruction from the dependency list.
             if (!squashed_inst->isNonSpeculative() &&
+                !squashed_inst->isStoreConditional() &&
                 !squashed_inst->isMemBarrier() &&
                 !squashed_inst->isWriteBarrier()) {
 
index f0b4405ede71bf46f1c54bd21cc911169aee1222..7974ddaadcb9e68b65c73d5c8d6d083151df9e90 100644 (file)
@@ -424,10 +424,9 @@ LSQUnit<Impl>::executeStore(DynInstPtr &store_inst)
 
     assert(store_fault == NoFault);
 
-    if (store_inst->isNonSpeculative()) {
-        // Nonspeculative accesses (namely store conditionals)
-        // need to set themselves as able to writeback if we
-        // haven't had a fault by here.
+    if (store_inst->isStoreConditional()) {
+        // Store conditionals need to set themselves as able to
+        // writeback if we haven't had a fault by here.
         storeQueue[store_idx].canWB = true;
 
         ++storesToWB;
index 081581c9221ccfa51727b9b99d1cd2c304c5ae61..b4f1077d1befcb2b9b4a9871392a8f00a713197e 100644 (file)
@@ -594,7 +594,14 @@ DefaultRename<Impl>::renameInsts(unsigned tid)
         // serializeAfter marks the next instruction as serializeBefore.
         // serializeBefore makes the instruction wait in rename until the ROB
         // is empty.
-        if (inst->isSerializeBefore() && !inst->isSerializeHandled()) {
+
+        // In this model, IPR accesses are serialize before
+        // instructions, and store conditionals are serialize after
+        // instructions.  This is mainly due to lack of support for
+        // out-of-order operations of either of those classes of
+        // instructions.
+        if ((inst->isIprAccess() || inst->isSerializeBefore()) &&
+            !inst->isSerializeHandled()) {
             DPRINTF(Rename, "Serialize before instruction encountered.\n");
 
             if (!inst->isTempSerializeBefore()) {
@@ -613,7 +620,8 @@ DefaultRename<Impl>::renameInsts(unsigned tid)
             blockThisCycle = true;
 
             break;
-        } else if (inst->isSerializeAfter() && !inst->isSerializeHandled()) {
+        } else if ((inst->isStoreConditional() || inst->isSerializeAfter()) &&
+                   !inst->isSerializeHandled()) {
             DPRINTF(Rename, "Serialize after instruction encountered.\n");
 
             renamedSerializing++;
index 0b8fe2f18333bab37229359dced3b12ddc85f7c3..b9d782b7b05d82410e25145c35bb05e0c3c6db5e 100644 (file)
@@ -103,6 +103,7 @@ class StaticInstBase : public RefCounted
         IsMemRef,      ///< References memory (load, store, or prefetch).
         IsLoad,                ///< Reads from memory (load or prefetch).
         IsStore,       ///< Writes to memory.
+        IsStoreConditional,    ///< Store conditional instruction.
         IsInstPrefetch,        ///< Instruction-cache prefetch.
         IsDataPrefetch,        ///< Data-cache prefetch.
         IsCopy,         ///< Fast Cache block copy
@@ -127,9 +128,10 @@ class StaticInstBase : public RefCounted
         IsWriteBarrier,        ///< Is a write barrier
 
         IsNonSpeculative, ///< Should not be executed speculatively
-        IsQuiesce,
+        IsQuiesce,      ///< Is a quiesce instruction
 
-        IsUnverifiable,
+        IsIprAccess,    ///< Accesses IPRs
+        IsUnverifiable, ///< Can't be verified by a checker
 
         NumFlags
     };
@@ -193,6 +195,7 @@ class StaticInstBase : public RefCounted
     bool isMemRef()              const { return flags[IsMemRef]; }
     bool isLoad()        const { return flags[IsLoad]; }
     bool isStore()       const { return flags[IsStore]; }
+    bool isStoreConditional()    const { return flags[IsStoreConditional]; }
     bool isInstPrefetch() const { return flags[IsInstPrefetch]; }
     bool isDataPrefetch() const { return flags[IsDataPrefetch]; }
     bool isCopy()         const { return flags[IsCopy];}
@@ -218,6 +221,7 @@ class StaticInstBase : public RefCounted
     bool isWriteBarrier() const { return flags[IsWriteBarrier]; }
     bool isNonSpeculative() const { return flags[IsNonSpeculative]; }
     bool isQuiesce() const { return flags[IsQuiesce]; }
+    bool isIprAccess() const { return flags[IsIprAccess]; }
     bool isUnverifiable() const { return flags[IsUnverifiable]; }
     //@}