sim: Optionally pass "position" to GuestABI::Result::store.
authorGabe Black <gabeblack@google.com>
Sun, 22 Dec 2019 08:59:46 +0000 (03:59 -0500)
committerGabe Black <gabeblack@google.com>
Thu, 12 Mar 2020 07:21:13 +0000 (07:21 +0000)
This will let it get at information about the signature as a whole.

Also, put result storing and argument getting behind functions to hide
some of the templating involved in those mechanisms.

Change-Id: Ib9f26ff69495f8891435f68d3d2f9dfa761a0274
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24105
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu>
Maintainer: Gabe Black <gabeblack@google.com>

src/sim/guest_abi/definition.hh
src/sim/guest_abi/dispatch.hh
src/sim/guest_abi/layout.hh

index ccebcc51054a1b248c8337701d4301c9a3a611ad..c61d1aef966f60afc93cd7dd967d88c9fb5759a7 100644 (file)
@@ -59,7 +59,8 @@ struct Result
 {
   private:
     /*
-     * Store result "ret" into the state accessible through tc.
+     * Store result "ret" into the state accessible through tc. Optionally
+     * accept "position" in case it holds some signature wide information.
      *
      * Note that the declaration below is only to document the expected
      * signature and is private so it won't be used by accident.
@@ -67,6 +68,8 @@ struct Result
      * of this method which actually does something and is public.
      */
     static void store(ThreadContext *tc, const Ret &ret);
+    static void store(ThreadContext *tc, const Ret &ret,
+                      typename ABI::Position &position);
 
     /*
      * Adjust the position of arguments based on the return type, if necessary.
index c817f632c65dcd63ac753bbfd08cb0e786de09e9..eb703a5fd4f27560cb48d16c84f37e38a917c623 100644 (file)
@@ -33,6 +33,7 @@
 #include <type_traits>
 
 #include "sim/guest_abi/definition.hh"
+#include "sim/guest_abi/layout.hh"
 
 class ThreadContext;
 
@@ -57,7 +58,7 @@ callFrom(ThreadContext *tc, typename ABI::Position &position,
         std::function<Ret(ThreadContext *)> target)
 {
     Ret ret = target(tc);
-    Result<ABI, Ret>::store(tc, ret);
+    storeResult<ABI, Ret>(tc, ret, position);
     return ret;
 }
 
@@ -78,7 +79,7 @@ callFrom(ThreadContext *tc, typename ABI::Position &position,
         std::function<Ret(ThreadContext *, NextArg, Args...)> target)
 {
     // Extract the next argument from the thread context.
-    NextArg next = Argument<ABI, NextArg>::get(tc, position);
+    NextArg next = getArgument<ABI, NextArg>(tc, position);
 
     // Build a partial function which adds the next argument to the call.
     std::function<Ret(ThreadContext *, Args...)> partial =
@@ -98,7 +99,7 @@ callFrom(ThreadContext *tc, typename ABI::Position &position,
         std::function<void(ThreadContext *, NextArg, Args...)> target)
 {
     // Extract the next argument from the thread context.
-    NextArg next = Argument<ABI, NextArg>::get(tc, position);
+    NextArg next = getArgument<ABI, NextArg>(tc, position);
 
     // Build a partial function which adds the next argument to the call.
     std::function<void(ThreadContext *, Args...)> partial =
@@ -139,7 +140,7 @@ dumpArgsFrom(int count, std::ostream &os, ThreadContext *tc,
     os << (count ? ", " : "(");
 
     // Extract the next argument from the thread context.
-    NextArg next = Argument<ABI, NextArg>::get(tc, position);
+    NextArg next = getArgument<ABI, NextArg>(tc, position);
 
     // Add this argument to the list.
     os << next;
index e7941f807e7bde5b65d8b83be0999972d5e6146c..562f3ee33378100dfa70915125fd674238231404 100644 (file)
@@ -130,6 +130,59 @@ allocateSignature(ThreadContext *tc, typename ABI::Position &position)
     allocateArguments<ABI, Args...>(tc, position);
 }
 
+/*
+ * This struct template provides a way to call the Result store method and
+ * optionally pass it the position.
+ */
+
+template <typename ABI, typename Ret, typename Enabled=void>
+struct ResultStorer
+{
+    static void
+    store(ThreadContext *tc, const Ret &ret, typename ABI::Position &position)
+    {
+        Result<ABI, Ret>::store(tc, ret);
+    }
+};
+
+template <typename Ret, typename State>
+std::true_type foo(void (*)(ThreadContext *, const Ret &ret, State &state));
+
+template <typename Ret>
+std::false_type foo(void (*)(ThreadContext *, const Ret &ret));
+
+template <typename ABI, typename Ret>
+struct ResultStorer<ABI, Ret, typename std::enable_if<
+    std::is_same<void (*)(ThreadContext *, const Ret &,
+                          typename ABI::Position &),
+                 decltype(&Result<ABI, Ret>::store)>::value>::type>
+{
+    static void
+    store(ThreadContext *tc, const Ret &ret, typename ABI::Position &position)
+    {
+        Result<ABI, Ret>::store(tc, ret, position);
+    }
+};
+
+/*
+ * Function templates to wrap the Result::store and Argument::get methods.
+ */
+
+template <typename ABI, typename Ret>
+static void
+storeResult(ThreadContext *tc, const Ret &ret,
+            typename ABI::Position &position)
+{
+    ResultStorer<ABI, Ret>::store(tc, ret, position);
+}
+
+template <typename ABI, typename Arg>
+static Arg
+getArgument(ThreadContext *tc, typename ABI::Position &position)
+{
+    return Argument<ABI, Arg>::get(tc, position);
+}
+
 } // namespace GuestABI
 
 #endif // __SIM_GUEST_ABI_LAYOUT_HH__