ARM/O3: store the result of the predicate evaluation in DynInst or Threadstate.
authorMin Kyu Jeong <minkyu.jeong@arm.com>
Mon, 23 Aug 2010 16:18:40 +0000 (11:18 -0500)
committerMin Kyu Jeong <minkyu.jeong@arm.com>
Mon, 23 Aug 2010 16:18:40 +0000 (11:18 -0500)
THis allows the CPU to handle predicated-false instructions accordingly.
This particular patch makes loads that are predicated-false to be sent
straight to the commit stage directly, not waiting for return of the data
that was never requested since it was predicated-false.

src/arch/arm/isa/templates/mem.isa
src/arch/arm/isa/templates/pred.isa
src/cpu/base_dyn_inst.hh
src/cpu/base_dyn_inst_impl.hh
src/cpu/o3/lsq_unit_impl.hh
src/cpu/simple/base.hh
src/cpu/simple_thread.hh
src/cpu/thread_context.hh

index ea66ce2a6e653249b5957f86c39b21803d0fff26..5431777b27818e17595c07e6a2340898ba4c14dc 100644 (file)
@@ -69,6 +69,8 @@ def template SwapExecute {{
             if (fault == NoFault) {
                 %(op_wb)s;
             }
+        } else {
+            xc->setPredicate(false);
         }
 
         if (fault == NoFault && machInst.itstateMask != 0) {
@@ -103,6 +105,8 @@ def template SwapInitiateAcc {{
             if (fault == NoFault) {
                 %(op_wb)s;
             }
+        } else {
+            xc->setPredicate(false);
         }
 
         if (fault == NoFault && machInst.itstateMask != 0) {
@@ -164,6 +168,8 @@ def template LoadExecute {{
             if (fault == NoFault) {
                 %(op_wb)s;
             }
+        } else {
+            xc->setPredicate(false);
         }
 
         if (fault == NoFault && machInst.itstateMask != 0) {
@@ -200,6 +206,8 @@ def template StoreExecute {{
             if (fault == NoFault) {
                 %(op_wb)s;
             }
+        } else {
+            xc->setPredicate(false);
         }
 
         if (fault == NoFault && machInst.itstateMask != 0) {
@@ -242,6 +250,8 @@ def template StoreExExecute {{
             if (fault == NoFault) {
                 %(op_wb)s;
             }
+        } else {
+            xc->setPredicate(false);
         }
 
         if (fault == NoFault && machInst.itstateMask != 0) {
@@ -279,6 +289,8 @@ def template StoreExInitiateAcc {{
             if (fault == NoFault) {
                 %(op_wb)s;
             }
+        } else {
+            xc->setPredicate(false);
         }
 
         if (fault == NoFault && machInst.itstateMask != 0) {
@@ -316,6 +328,8 @@ def template StoreInitiateAcc {{
             if (fault == NoFault) {
                 %(op_wb)s;
             }
+        } else {
+            xc->setPredicate(false);
         }
 
         if (fault == NoFault && machInst.itstateMask != 0) {
@@ -342,8 +356,11 @@ def template LoadInitiateAcc {{
             if (fault == NoFault) {
                 fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
             }
-        } else if (fault == NoFault && machInst.itstateMask != 0) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
+        } else {
+            xc->setPredicate(false);
+            if (fault == NoFault && machInst.itstateMask != 0) {
+                xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
+            }
         }
 
         return fault;
index 7a5b92760c54ab37da8f1293d49d6a8c0a45f78c..1029cfaeecbe116a76bd173b5d692735f51528a6 100644 (file)
@@ -142,6 +142,8 @@ def template PredOpExecute {{
             {
                 %(op_wb)s;
             }
+        } else {
+            xc->setPredicate(false);
         }
 
         if (fault == NoFault && machInst.itstateMask != 0) {
index 6ea00dd3d664c0b94260e53bf30cee959b2d6c57..a992664d091a7eb8342219369bf20b2ea6c35766 100644 (file)
@@ -246,6 +246,9 @@ class BaseDynInst : public FastAlloc, public RefCounted
     /** Micro PC of this instruction. */
     Addr microPC;
 
+    /** Did this instruction execute, or is it predicated false */
+    bool predicate;
+
   protected:
     /** Next non-speculative PC.  It is not filled in at fetch, but rather
      *  once the target of the branch is truly known (either decode or
@@ -794,6 +797,16 @@ class BaseDynInst : public FastAlloc, public RefCounted
         nextMicroPC = val;
     }
 
+    bool readPredicate()
+    {
+        return predicate;
+    }
+
+    void setPredicate(bool val)
+    {
+        predicate = val;
+    }
+
     /** Sets the ASID. */
     void setASID(short addr_space_id) { asid = addr_space_id; }
 
index 70c91cedaa1e0b6f18a98b5e883752c48ec342db..7425431db28a4d04938e6ad04fe2a60f6c0b8fc2 100644 (file)
@@ -154,6 +154,7 @@ BaseDynInst<Impl>::initVars()
 
     eaCalcDone = false;
     memOpDone = false;
+    predicate = true;
 
     lqIdx = -1;
     sqIdx = -1;
index fcc57ab09e52b52b1fe14ea1f41c3692feeb07af..dddfb7e1bd650c281e34aba799dbf73230260539 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-2005 The Regents of The University of Michigan
  * All rights reserved.
  *
@@ -439,9 +451,9 @@ LSQUnit<Impl>::executeLoad(DynInstPtr &inst)
 
     load_fault = inst->initiateAcc();
 
-    // If the instruction faulted, then we need to send it along to commit
-    // without the instruction completing.
-    if (load_fault != NoFault) {
+    // If the instruction faulted or predicated false, then we need to send it
+    // along to commit without the instruction completing.
+    if (load_fault != NoFault || inst->readPredicate() == false) {
         // Send this instruction to commit, also make sure iew stage
         // realizes there is activity.
         // Mark it as executed unless it is an uncached load that
index 1265a1f2f22a052766422ac52689fab03afa8a3c..90cb81c0cc68c9a3d036d2804a18c2fc29643c22 100644 (file)
@@ -287,12 +287,15 @@ class BaseSimpleCPU : public BaseCPU
     uint64_t readNextPC() { return thread->readNextPC(); }
     uint64_t readNextMicroPC() { return thread->readNextMicroPC(); }
     uint64_t readNextNPC() { return thread->readNextNPC(); }
+    bool readPredicate() { return thread->readPredicate(); }
 
     void setPC(uint64_t val) { thread->setPC(val); }
     void setMicroPC(uint64_t val) { thread->setMicroPC(val); }
     void setNextPC(uint64_t val) { thread->setNextPC(val); }
     void setNextMicroPC(uint64_t val) { thread->setNextMicroPC(val); }
     void setNextNPC(uint64_t val) { thread->setNextNPC(val); }
+    void setPredicate(bool val)
+    { return thread->setPredicate(val); }
 
     MiscReg readMiscRegNoEffect(int misc_reg)
     {
index bc8588041688171fa860011e99a21910c2d47c12..dcd933ffcb4942e819d76adff782f3bef8e653d3 100644 (file)
@@ -128,6 +128,9 @@ class SimpleThread : public ThreadState
      */
     Addr nextNPC;
 
+    /** Did this instruction execute or is it predicated false */
+    bool predicate;
+
   public:
     // pointer to CPU associated with this SimpleThread
     BaseCPU *cpu;
@@ -371,6 +374,16 @@ class SimpleThread : public ThreadState
 #endif
     }
 
+    bool readPredicate()
+    {
+        return predicate;
+    }
+
+    void setPredicate(bool val)
+    {
+        predicate = val;
+    }
+
     MiscReg
     readMiscRegNoEffect(int misc_reg, ThreadID tid = 0)
     {
index 78ecdacf2d34ebffc888de44746911473211cd14..7f6d258abcb45a2625471a29df0d674e52ddeb2c 100644 (file)
@@ -404,6 +404,11 @@ class ProxyThreadContext : public ThreadContext
 
     void setNextMicroPC(uint64_t val) { actualTC->setNextMicroPC(val); }
 
+    bool readPredicate() { return actualTC->readPredicate(); }
+
+    void setPredicate(bool val)
+    { actualTC->setPredicate(val); }
+
     MiscReg readMiscRegNoEffect(int misc_reg)
     { return actualTC->readMiscRegNoEffect(misc_reg); }