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