Hi,
This improves the robustness of the aapcs64 test framework for testing
function return ABI rules. It ensures the test facility functions now
able to see the exact content of return registers right at the moment
when a function returns.
OK for trunk?
Thanks,
Yufeng
gcc/testsuite
Make the AAPCS64 function return tests more robust.
* gcc.target/aarch64/aapcs64/abitest-2.h (saved_return_address): New
global variable.
(FUNC_VAL_CHECK): Update to call myfunc via the 'ret' instruction,
instead of calling sequentially in the C code.
* gcc.target/aarch64/aapcs64/abitest.S (LABEL_TEST_FUNC_RETURN): Store
saved_return_address to the stack frame where LR register was stored.
(saved_return_address): Declare weak.diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/abitest-2.h
b/gcc/testsuite/gcc.target/aarch64/aapcs64/abitest-2.h
index c56e7cc..c87fe9b 100644
--- a/gcc/testsuite/gcc.target/aarch64/aapcs64/abitest-2.h
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/abitest-2.h
@@ -5,6 +5,7 @@
#include "validate_memory.h"
void (*testfunc_ptr)(char* stack);
+unsigned long long saved_return_address;
/* Helper macros to generate function name. Example of the function name:
func_return_val_1. */
@@ -71,6 +72,17 @@ __attribute__ ((noinline)) type FUNC_NAME (id) (int i,
double d, type t) \
optimized away. Using i and d prevents \
warnings about unused parameters. \
*/ \
+ /* We save and set up the LR register in a way that essentially \
+ inserts myfunc () between the returning of this function and the
\
+ continueous execution of its caller. By doing this, myfunc () \
+ can save and check the exact content of the registers that are \
+ used for the function return value.
\
+ The previous approach of sequentially calling myfunc right after
\
+ this function does not guarantee myfunc see the exact register \
+ content, as compiler may emit code in between the two calls,
\
+ especially during the -O0 codegen. */ \
+ asm volatile ("mov %0, x30" : "=r" (saved_return_address));
\
+ asm volatile ("mov x30, %0" : : "r" ((unsigned long long) myfunc)); \
return t; \
}
#include TESTFILE
@@ -84,7 +96,8 @@ __attribute__ ((noinline)) type FUNC_NAME (id) (int i, double
d, type t) \
{ \
testfunc_ptr = TEST_FUNC_NAME(id); \
FUNC_NAME(id) (0, 0.0, var); \
- myfunc (); \
+ /* The above function implicitly calls myfunc () on its return, \
+ and the execution resumes from here after myfunc () finishes. */\
}
int main()
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/abitest.S
b/gcc/testsuite/gcc.target/aarch64/aapcs64/abitest.S
index 86ce7be..68845fb 100644
--- a/gcc/testsuite/gcc.target/aarch64/aapcs64/abitest.S
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/abitest.S
@@ -50,6 +50,10 @@ LABEL_TEST_FUNC_RETURN:
add x9, x9, :lo12:testfunc_ptr
ldr x9, [x9, #0]
blr x9 // function return value test
+ adrp x9, saved_return_address
+ add x9, x9, :lo12:saved_return_address
+ ldr x9, [x9, #0]
+ str x9, [sp, #8] // Update the copy of LR reg
saved on stack
LABEL_RET:
ldp x0, x30, [sp]
mov sp, x0
@@ -57,3 +61,4 @@ LABEL_RET:
.weak testfunc
.weak testfunc_ptr
+.weak saved_return_address