sim: Optionally pass "position" to GuestABI::Result::store.

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>
This commit is contained in:
Gabe Black
2019-12-22 03:59:46 -05:00
parent 5e0f5dbde7
commit 10c46f0996
3 changed files with 62 additions and 5 deletions

View 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.

View 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;

View 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__