Add support for "serializing" instructions that flush
authorSteve Reinhardt <stever@eecs.umich.edu>
Thu, 5 Feb 2004 05:42:00 +0000 (21:42 -0800)
committerSteve Reinhardt <stever@eecs.umich.edu>
Thu, 5 Feb 2004 05:42:00 +0000 (21:42 -0800)
execution pipeline (Alpha trapb & excb).

Add support for write memory barriers (mostly impacts
store buffer).

Add StaticInst flag to indicate memory barriers, though
this is not modeled in the pipeline yet.

arch/alpha/isa_desc:
    Implement trapb, excb, mb, and wmb as insts with
    no execution effect (empty execute() function) but
    with flags that indicate their side effects.

    Also make sure every instruction that needs to go to
    the execute stage has a real opClass value, since we
    are now using No_OpClass to signal insts that can get
    dropped at dispatch.

    StaticInst::branchTarget() is now a const method.
cpu/static_inst.hh:
    Add flags to indicate serializing insts (trapb, excb) and
    memory and write barriers.

    Also declare some StaticInst methods as const methods.
dev/etherlink.hh:
sim/eventq.hh:
sim/serialize.cc:
sim/serialize.hh:
sim/sim_object.hh:
    Make name() return value const.

--HG--
extra : convert_revision : 39520e71469fa20e0a7446b2e06b494eec17a02c

arch/alpha/isa_desc
cpu/static_inst.hh
dev/etherlink.hh
sim/eventq.hh
sim/serialize.cc
sim/serialize.hh
sim/sim_object.hh

index 51bce65c22bf680005fb29f5bfd32bc425d30d14..d4636f60902800715d653c4fc5c3c8c56fe7ec2c 100644 (file)
@@ -1225,7 +1225,7 @@ declare {{
        {
        }
 
-       Addr branchTarget(Addr branchPC)
+       Addr branchTarget(Addr branchPC) const
        {
            return branchPC + 4 + disp;
        }
@@ -1287,7 +1287,7 @@ declare {{
        {
        }
 
-       Addr branchTarget(ExecContext *xc)
+       Addr branchTarget(ExecContext *xc) const
        {
            Addr NPC = xc->readPC() + 4;
            uint64_t Rb = xc->readIntReg(_srcRegIdx[0]);
@@ -2330,10 +2330,6 @@ decode OPCODE default Unknown::unknown() {
     // miscellaneous mem-format ops
     0x18: decode MEMFUNC {
        format WarnUnimpl {
-           0x0000: trapb();
-           0x0400: excb();
-           0x4000: mb();
-           0x4400: wmb();
            0x8000: fetch();
            0xa000: fetch_m();
            0xe800: ecb();
@@ -2347,6 +2343,27 @@ decode OPCODE default Unknown::unknown() {
 
        format BasicOperate {
            0xc000: rpcc({{ Ra = curTick; }});
+
+           // All of the barrier instructions below do nothing in
+           // their execute() methods (hence the empty code blocks).
+           // All of their functionality is hard-coded in the
+           // pipeline based on the flags IsSerializing,
+           // IsMemBarrier, and IsWriteBarrier.  In the current
+           // detailed CPU model, the execute() function only gets
+           // called at fetch, so there's no way to generate pipeline
+           // behavior at any other stage.  Once we go to an
+           // exec-in-exec CPU model we should be able to get rid of
+           // these flags and implement this behavior via the
+           // execute() methods.
+
+           // trapb is just a barrier on integer traps, where excb is
+           // a barrier on integer and FP traps.  "EXCB is thus a
+           // superset of TRAPB." (Alpha ARM, Sec 4.11.4) We treat
+           // them the same though.
+           0x0000: trapb({{ }}, IsSerializing, No_OpClass);
+           0x0400: excb({{ }}, IsSerializing, No_OpClass);
+           0x4000: mb({{ }}, IsMemBarrier);
+           0x4400: wmb({{ }}, IsWriteBarrier);
        }
 
 #ifdef FULL_SYSTEM
@@ -2356,13 +2373,13 @@ decode OPCODE default Unknown::unknown() {
                if (!xc->misspeculating()) {
                    xc->regs.intrflag = 0;
                }
-           }}, No_OpClass);
+           }});
            0xf000: rs({{
                Ra = xc->regs.intrflag;
                if (!xc->misspeculating()) {
                    xc->regs.intrflag = 1;
                }
-           }}, No_OpClass);
+           }});
        }
 #else
        format FailUnimpl {
@@ -2476,7 +2493,7 @@ decode OPCODE default Unknown::unknown() {
                if (!xc->misspeculating())
                    AlphaPseudo::m5exit(xc);
            }}, No_OpClass);
-            0x30: initparam({{ Ra = xc->cpu->system->init_param; }});
+            0x30: initparam({{ Ra = cpu->system->init_param; }});
             0x40: resetstats({{
                if (!xc->misspeculating())
                    AlphaPseudo::resetstats(xc);
index f3fd6fa246330a21ab14592f1466819341ec9d33..5f4bcae3d3618ca155c2f2a14477d0fb488d63b0 100644 (file)
@@ -78,6 +78,12 @@ class StaticInstBase : public RefCounted
     /// - If IsControl is set, then exactly one of IsDirectControl or
     /// IsIndirect Control will be set, and exactly one of
     /// IsCondControl or IsUncondControl will be set.
+    /// - IsSerializing, IsMemBarrier, and IsWriteBarrier are
+    /// implemented as flags since in the current model there's no
+    /// other way for instructions to inject behavior into the
+    /// pipeline outside of fetch.  Once we go to an exec-in-exec CPU
+    /// model we should be able to get rid of these flags and
+    /// implement this behavior via the execute() methods.
     ///
     enum Flags {
         IsNop,         ///< Is a no-op (no effect at all).
@@ -99,7 +105,12 @@ class StaticInstBase : public RefCounted
         IsCall,                        ///< Subroutine call.
         IsReturn,              ///< Subroutine return.
 
-        IsThreadSync,          ///< Thread synchronization operation.
+        IsThreadSync,  ///< Thread synchronization operation.
+
+        IsSerializing, ///< Serializes pipeline: won't until all
+                        /// older instructions have committed.
+        IsMemBarrier,  ///< Is a memory barrier
+        IsWriteBarrier,        ///< Is a write barrier
 
         NumFlags
     };
@@ -178,6 +189,9 @@ class StaticInstBase : public RefCounted
     bool isUncondCtrl()          const { return flags[IsUncondControl]; }
 
     bool isThreadSync()   const { return flags[IsThreadSync]; }
+    bool isSerializing()  const { return flags[IsSerializing]; }
+    bool isMemBarrier()   const { return flags[IsMemBarrier]; }
+    bool isWriteBarrier() const { return flags[IsWriteBarrier]; }
     //@}
 
     /// Operation class.  Used to select appropriate function unit in issue.
@@ -216,11 +230,11 @@ class StaticInst : public StaticInstBase
 
     /// Return logical index (architectural reg num) of i'th destination reg.
     /// Only the entries from 0 through numDestRegs()-1 are valid.
-    RegIndex destRegIdx(int i) { return _destRegIdx[i]; }
+    RegIndex destRegIdx(int i) const { return _destRegIdx[i]; }
 
     /// Return logical index (architectural reg num) of i'th source reg.
     /// Only the entries from 0 through numSrcRegs()-1 are valid.
-    RegIndex srcRegIdx(int i)  { return _srcRegIdx[i]; }
+    RegIndex srcRegIdx(int i)  const { return _srcRegIdx[i]; }
 
     /// Pointer to a statically allocated "null" instruction object.
     /// Used to give eaCompInst() and memAccInst() something to return
@@ -305,7 +319,7 @@ class StaticInst : public StaticInstBase
      * Invalid if not a PC-relative branch (i.e. isDirectCtrl()
      * should be true).
      */
-    virtual Addr branchTarget(Addr branchPC)
+    virtual Addr branchTarget(Addr branchPC) const
     {
         panic("StaticInst::branchTarget() called on instruction "
               "that is not a PC-relative branch.");
@@ -318,7 +332,7 @@ class StaticInst : public StaticInstBase
      * execute the branch in question.  Invalid if not an indirect
      * branch (i.e. isIndirectCtrl() should be true).
      */
-    virtual Addr branchTarget(ExecContext *xc)
+    virtual Addr branchTarget(ExecContext *xc) const
     {
         panic("StaticInst::branchTarget() called on instruction "
               "that is not an indirect branch.");
index 895bac2e1e730ca9fcce846d02303c4e6a82047d..e1a7957ee330583c08f1aade905d488a8d3b414a 100644 (file)
@@ -89,7 +89,7 @@ class EtherLink : public SimObject
         Link(const std::string &name, double rate, EtherDump *dump);
         ~Link() {}
 
-        virtual std::string name() const { return objName; }
+        virtual const std::string name() const { return objName; }
 
         bool busy() const { return (bool)packet; }
         bool transmit(PacketPtr &packet);
index 36cb402a859f7e2961a8f448e72042a534f39044..31bf9d6527417e4df9f4648543d53289e40c00e4 100644 (file)
@@ -153,7 +153,7 @@ class Event : public Serializable, public FastAlloc
 
     ~Event() {}
 
-    virtual std::string name() const {
+    virtual const std::string name() const {
         return csprintf("Event_%x", (uintptr_t)this);
     }
 
@@ -257,7 +257,7 @@ class EventQueue : public Serializable
         : objName(n), head(NULL)
     {}
 
-    virtual std::string name() const { return objName; }
+    virtual const std::string name() const { return objName; }
 
     // schedule the given event on this queue
     void schedule(Event *ev);
index 180cc38a0063812f29eef3062486018dcff78f0c..d836e7c203fa234ff1b275f4175efa03b5f0468a 100644 (file)
@@ -186,7 +186,7 @@ INSTANTIATE_PARAM_TEMPLATES(string)
 class Globals : public Serializable
 {
   public:
-    string name() const;
+    const string name() const;
     void serialize(ostream& os);
     void unserialize(Checkpoint *cp);
 };
@@ -194,7 +194,7 @@ class Globals : public Serializable
 /// The one and only instance of the Globals class.
 Globals globals;
 
-string
+const string
 Globals::name() const
 {
     return "Globals";
index 9ab2fa8332691f9834d4491ab4d8dff5bdab5f1e..43dbd2c8586a658c4f866b074ad88108792e6ce0 100644 (file)
@@ -111,7 +111,7 @@ class Serializable
     virtual ~Serializable() {}
 
     // manditory virtual function, so objects must provide names
-    virtual std::string name() const = 0;
+    virtual const std::string name() const = 0;
 
     virtual void serialize(std::ostream& os) {}
     virtual void unserialize(Checkpoint *cp, const std::string &section) {}
index 165931b2b5fafa51c72256dd2d3ade4cb919e040..aaaafc04bf9946b9df938996327aa716e6e8fb8a 100644 (file)
@@ -63,7 +63,7 @@ class SimObject : public Serializable
 
     virtual ~SimObject() {}
 
-    virtual std::string name() const { return objName; }
+    virtual const std::string name() const { return objName; }
 
     // initialization pass of all objects.  Gets invoked by SimInit()
     virtual void init();