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>
{
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.
* 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.
#include <type_traits>
#include "sim/guest_abi/definition.hh"
+#include "sim/guest_abi/layout.hh"
class ThreadContext;
std::function<Ret(ThreadContext *)> target)
{
Ret ret = target(tc);
- Result<ABI, Ret>::store(tc, ret);
+ storeResult<ABI, Ret>(tc, ret, position);
return ret;
}
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 =
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 =
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;
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__