base: Rename Flags::update as Flags::replace
[gem5.git] / src / sim / pseudo_inst.hh
index 44227aff178122e6dd5060ec0417019432bb3c96..d244adbe1f68004565f059da0561fca62fd9eb2b 100644 (file)
@@ -36,8 +36,6 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Authors: Nathan Binkert
  */
 
 #ifndef __SIM_PSEUDO_INST_HH__
 
 class ThreadContext;
 
-#include "arch/pseudo_inst.hh"
 #include "arch/utility.hh"
+#include "base/bitfield.hh"
 #include "base/types.hh" // For Tick and Addr data types.
 #include "debug/PseudoInst.hh"
 #include "sim/guest_abi.hh"
 
 struct PseudoInstABI
 {
-    using Position = int;
+    using State = int;
 };
 
 namespace GuestABI
 {
 
-template <typename T>
-struct Result<PseudoInstABI, T>
-{
-    static void
-    store(ThreadContext *tc, const T &ret)
-    {
-        // Don't do anything with the pseudo inst results by default.
-    }
-};
-
 template <>
 struct Argument<PseudoInstABI, uint64_t>
 {
     static uint64_t
-    get(ThreadContext *tc, PseudoInstABI::Position &position)
+    get(ThreadContext *tc, PseudoInstABI::State &state)
     {
-        return TheISA::getArgument(tc, position, sizeof(uint64_t), false);
+        uint64_t result =
+            TheISA::getArgument(tc, state, sizeof(uint64_t), false);
+        state++;
+        return result;
     }
 };
 
@@ -109,6 +100,8 @@ uint64_t rpns(ThreadContext *tc);
 void wakeCPU(ThreadContext *tc, uint64_t cpuid);
 void m5exit(ThreadContext *tc, Tick delay);
 void m5fail(ThreadContext *tc, Tick delay, uint64_t code);
+uint64_t m5sum(ThreadContext *tc, uint64_t a, uint64_t b, uint64_t c,
+                                  uint64_t d, uint64_t e, uint64_t f);
 void resetstats(ThreadContext *tc, Tick delay, Tick period);
 void dumpstats(ThreadContext *tc, Tick delay, Tick period);
 void dumpresetstats(ThreadContext *tc, Tick delay, Tick period);
@@ -119,6 +112,7 @@ void workbegin(ThreadContext *tc, uint64_t workid, uint64_t threadid);
 void workend(ThreadContext *tc, uint64_t workid, uint64_t threadid);
 void m5Syscall(ThreadContext *tc);
 void togglesync(ThreadContext *tc);
+void triggerWorkloadEvent(ThreadContext *tc);
 
 /**
  * Execute a decoded M5 pseudo instruction
@@ -129,129 +123,151 @@ void togglesync(ThreadContext *tc);
  * manner using the ISA-specific getArguments functions.
  *
  * @param func M5 pseudo op major function number (see utility/m5/m5ops.h)
+ * @param result A reference to a uint64_t to store a result in.
+ * @return Whether the pseudo instruction was recognized/handled.
  */
 
-template <typename ABI>
-uint64_t
-pseudoInst(ThreadContext *tc, uint8_t func)
+template <typename ABI, bool store_ret>
+bool
+pseudoInstWork(ThreadContext *tc, uint8_t func, uint64_t &result)
 {
     DPRINTF(PseudoInst, "PseudoInst::pseudoInst(%i)\n", func);
 
+    result = 0;
+
     switch (func) {
       case M5OP_ARM:
         invokeSimcall<ABI>(tc, arm);
-        break;
+        return true;
 
       case M5OP_QUIESCE:
         invokeSimcall<ABI>(tc, quiesce);
-        break;
+        return true;
 
       case M5OP_QUIESCE_NS:
         invokeSimcall<ABI>(tc, quiesceNs);
-        break;
+        return true;
 
       case M5OP_QUIESCE_CYCLE:
         invokeSimcall<ABI>(tc, quiesceCycles);
-        break;
+        return true;
 
       case M5OP_QUIESCE_TIME:
-        return invokeSimcall<ABI>(tc, quiesceTime);
+        result = invokeSimcall<ABI, store_ret>(tc, quiesceTime);
+        return true;
 
       case M5OP_RPNS:
-        return invokeSimcall<ABI>(tc, rpns);
+        result = invokeSimcall<ABI, store_ret>(tc, rpns);
+        return true;
 
       case M5OP_WAKE_CPU:
         invokeSimcall<ABI>(tc, wakeCPU);
-        break;
+        return true;
 
       case M5OP_EXIT:
         invokeSimcall<ABI>(tc, m5exit);
-        break;
+        return true;
 
       case M5OP_FAIL:
         invokeSimcall<ABI>(tc, m5fail);
-        break;
+        return true;
+
+      // M5OP_SUM is for sanity checking the gem5 op interface.
+      case M5OP_SUM:
+        result = invokeSimcall<ABI, store_ret>(tc, m5sum);
+        return true;
 
       case M5OP_INIT_PARAM:
-        return invokeSimcall<ABI>(tc, initParam);
+        result = invokeSimcall<ABI, store_ret>(tc, initParam);
+        return true;
 
       case M5OP_LOAD_SYMBOL:
         invokeSimcall<ABI>(tc, loadsymbol);
-        break;
+        return true;
 
       case M5OP_RESET_STATS:
         invokeSimcall<ABI>(tc, resetstats);
-        break;
+        return true;
 
       case M5OP_DUMP_STATS:
         invokeSimcall<ABI>(tc, dumpstats);
-        break;
+        return true;
 
       case M5OP_DUMP_RESET_STATS:
         invokeSimcall<ABI>(tc, dumpresetstats);
-        break;
+        return true;
 
       case M5OP_CHECKPOINT:
         invokeSimcall<ABI>(tc, m5checkpoint);
-        break;
+        return true;
 
       case M5OP_WRITE_FILE:
-        return invokeSimcall<ABI>(tc, writefile);
+        result = invokeSimcall<ABI, store_ret>(tc, writefile);
+        return true;
 
       case M5OP_READ_FILE:
-        return invokeSimcall<ABI>(tc, readfile);
+        result = invokeSimcall<ABI, store_ret>(tc, readfile);
+        return true;
 
       case M5OP_DEBUG_BREAK:
         invokeSimcall<ABI>(tc, debugbreak);
-        break;
+        return true;
 
       case M5OP_SWITCH_CPU:
         invokeSimcall<ABI>(tc, switchcpu);
-        break;
+        return true;
 
       case M5OP_ADD_SYMBOL:
         invokeSimcall<ABI>(tc, addsymbol);
-        break;
+        return true;
 
       case M5OP_PANIC:
         panic("M5 panic instruction called at %s\n", tc->pcState());
 
       case M5OP_WORK_BEGIN:
         invokeSimcall<ABI>(tc, workbegin);
-        break;
+        return true;
 
       case M5OP_WORK_END:
         invokeSimcall<ABI>(tc, workend);
-        break;
+        return true;
 
-      case M5OP_ANNOTATE:
+      case M5OP_RESERVED1:
       case M5OP_RESERVED2:
       case M5OP_RESERVED3:
       case M5OP_RESERVED4:
       case M5OP_RESERVED5:
         warn("Unimplemented m5 op (%#x)\n", func);
-        break;
-
-      /* SE mode functions */
-      case M5OP_SE_SYSCALL:
-        invokeSimcall<ABI>(tc, m5Syscall);
-        break;
-
-      case M5OP_SE_PAGE_FAULT:
-        invokeSimcall<ABI>(tc, TheISA::m5PageFault);
-        break;
+        return false;
 
       /* dist-gem5 functions */
       case M5OP_DIST_TOGGLE_SYNC:
         invokeSimcall<ABI>(tc, togglesync);
-        break;
+        return true;
+
+      case M5OP_WORKLOAD:
+        invokeSimcall<ABI>(tc, triggerWorkloadEvent);
+        return true;
 
       default:
         warn("Unhandled m5 op: %#x\n", func);
-        break;
+        return false;
     }
+}
 
-    return 0;
+template <typename ABI, bool store_ret=false>
+bool
+pseudoInst(ThreadContext *tc, uint8_t func, uint64_t &result)
+{
+    return pseudoInstWork<ABI, store_ret>(tc, func, result);
+}
+
+template <typename ABI, bool store_ret=true>
+bool
+pseudoInst(ThreadContext *tc, uint8_t func)
+{
+    uint64_t result;
+    return pseudoInstWork<ABI, store_ret>(tc, func, result);
 }
 
 } // namespace PseudoInst