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:
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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__
|
||||
|
||||
Reference in New Issue
Block a user