diff options
Diffstat (limited to 'src/sim/guest_abi.test.cc')
-rw-r--r-- | src/sim/guest_abi.test.cc | 44 |
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; |