summaryrefslogtreecommitdiff
path: root/src/sim/guest_abi.test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim/guest_abi.test.cc')
-rw-r--r--src/sim/guest_abi.test.cc44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/sim/guest_abi.test.cc b/src/sim/guest_abi.test.cc
index 19efb7db2..2f896f9b3 100644
--- a/src/sim/guest_abi.test.cc
+++ b/src/sim/guest_abi.test.cc
@@ -66,6 +66,12 @@ struct TestABI_1D
using Position = int;
};
+// ABI anchor for an ABI which allocates a register for non-void return types.
+struct TestABI_RetReg
+{
+ using Position = int;
+};
+
// ABI anchor for an ABI which has 2D progress. Conceptually, this could be
// because integer and floating point arguments are stored in separate
// registers.
@@ -121,6 +127,22 @@ struct Result<TestABI_1D, Ret,
}
};
+// Hooks for the return value allocating ABI. It uses the same rules as the
+// 1D ABI for arguments, but allocates space for and discards return values.
+template <typename Arg>
+struct Argument<TestABI_RetReg, Arg> : public Argument<TestABI_1D, Arg> {};
+
+template <typename Ret>
+struct Result<TestABI_RetReg, Ret>
+{
+ static void store(ThreadContext *tc, const Ret &ret) {}
+ static void
+ allocate(ThreadContext *tc, TestABI_RetReg::Position &position)
+ {
+ position++;
+ }
+};
+
// Hooks for the 2D ABI arguments and return value. Add 2 or 2.0 to return
// values so we can tell they went through the right set of hooks.
@@ -184,6 +206,21 @@ testIntVoid(ThreadContext *tc, int a, float b, int c, double d,
EXPECT_EQ(varargs.get<double>(), tc->floats[6]);
}
+// Test functions which verify that the return allocating ABI allocates space
+// for its return value successfully.
+void
+testRetRegVoid(ThreadContext *tc, int a)
+{
+ EXPECT_EQ(a, tc->ints[0]);
+}
+
+int
+testRetRegInt(ThreadContext *tc, int a)
+{
+ EXPECT_EQ(a, tc->ints[1]);
+ return 0;
+}
+
// Test function which verifies that its arguments reflect the 2D ABI and
// which doesn't return anything.
void
@@ -219,6 +256,13 @@ TEST(GuestABI, ABI_1D_args)
EXPECT_EQ(tc.floatResult, tc.DefaultFloatResult);
}
+TEST(GuestABI, ABI_RetReg)
+{
+ ThreadContext tc;
+ invokeSimcall<TestABI_RetReg>(&tc, testRetRegVoid);
+ invokeSimcall<TestABI_RetReg>(&tc, testRetRegInt);
+}
+
TEST(GuestABI, ABI_2D_args)
{
ThreadContext tc;