From: Andreas Krebbel Date: Mon, 7 Oct 2013 07:52:25 +0000 (+0000) Subject: s390.c (s390_register_info): Make the call-saved FPR loop to work also for 31bit... X-Git-Tag: misc/gupc_5_2_0_release~136^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=36c0bd4feeb6ac1fa0fa17e6ce877a5ae2ebdeeb;p=thirdparty%2Fgcc.git s390.c (s390_register_info): Make the call-saved FPR loop to work also for 31bit ABI. 2013-10-07 Andreas Krebbel * config/s390/s390.c (s390_register_info): Make the call-saved FPR loop to work also for 31bit ABI. Save the stack pointer for frame_size > 0. 2013-10-07 Andreas Krebbel * gcc.target/s390/htm-nofloat-2.c: New testcase. From-SVN: r203240 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d91beec906ba..d54cf03792bb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-10-07 Andreas Krebbel + + * config/s390/s390.c (s390_register_info): Make the call-saved FPR + loop to work also for 31bit ABI. + Save the stack pointer for frame_size > 0. + 2013-10-07 Andreas Krebbel * config/s390/s390.md ("tbegin", "tbegin_nofloat", "tbegin_retry") diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 898e683641c7..338a09ecb90f 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -7509,8 +7509,11 @@ s390_register_info (int clobbered_regs[]) { cfun_frame_layout.fpr_bitmap = 0; cfun_frame_layout.high_fprs = 0; - if (TARGET_64BIT) - for (i = FPR8_REGNUM; i <= FPR15_REGNUM; i++) + + for (i = FPR0_REGNUM; i <= FPR15_REGNUM; i++) + { + if (call_really_used_regs[i]) + continue; /* During reload we have to use the df_regs_ever_live infos since reload is marking FPRs used as spill slots there as live before actually making the code changes. Without @@ -7523,8 +7526,11 @@ s390_register_info (int clobbered_regs[]) && !global_regs[i]) { cfun_set_fpr_save (i); - cfun_frame_layout.high_fprs++; + + if (i >= FPR8_REGNUM) + cfun_frame_layout.high_fprs++; } + } } for (i = 0; i < 16; i++) @@ -7554,6 +7560,7 @@ s390_register_info (int clobbered_regs[]) || TARGET_TPF_PROFILING || cfun_save_high_fprs_p || get_frame_size () > 0 + || (reload_completed && cfun_frame_layout.frame_size > 0) || cfun->calls_alloca || cfun->stdarg); @@ -7652,14 +7659,6 @@ s390_register_info (int clobbered_regs[]) cfun_set_fpr_save (i + FPR0_REGNUM); } } - - if (!TARGET_64BIT) - { - if (df_regs_ever_live_p (FPR4_REGNUM) && !global_regs[FPR4_REGNUM]) - cfun_set_fpr_save (FPR4_REGNUM); - if (df_regs_ever_live_p (FPR6_REGNUM) && !global_regs[FPR6_REGNUM]) - cfun_set_fpr_save (FPR6_REGNUM); - } } /* Fill cfun->machine with info about frame of current function. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5dccbe770574..2d3561d718ff 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2013-10-07 Andreas Krebbel + + * gcc.target/s390/htm-nofloat-2.c: New testcase. + 2013-10-07 Andreas Krebbel * gcc.target/s390/htm-1.c: Add more tests to cover different diff --git a/gcc/testsuite/gcc.target/s390/htm-nofloat-2.c b/gcc/testsuite/gcc.target/s390/htm-nofloat-2.c new file mode 100644 index 000000000000..db9064284f91 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/htm-nofloat-2.c @@ -0,0 +1,55 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -mhtm -Wa,-march=zEC12 --save-temps" } */ + +/* __builtin_tbegin has to emit clobbers for all FPRs since the tbegin + instruction does not automatically preserves them. If the + transaction body is fully contained in a function the backend tries + after reload to get rid of the FPR save/restore operations + triggered by the clobbers. This testcase failed since the backend + was able to get rid of all FPR saves/restores and since these were + the only stack operations also of the entire stack space. So even + the save/restore of the stack pointer was omitted in the end. + However, since the frame layout has been fixed before, the prologue + still generated the stack pointer decrement making foo return with + a modified stack pointer. */ + +void abort(void); + +void __attribute__((noinline)) +foo (int a) +{ + /* This is just to prevent the tbegin code from actually being + executed. That way the test may even run on machines prior to + zEC12. */ + if (a == 42) + return; + + if (__builtin_tbegin (0) == 0) + __builtin_tend (); +} + +#ifdef __s390x__ +#define GET_STACK_POINTER(SP) \ + asm volatile ("stg %%r15, %0" : "=QRST" (SP)); +#else +#define GET_STACK_POINTER(SP) \ + asm volatile ("st %%r15, %0" : "=QR" (SP)); +#endif + +int main(void) +{ + unsigned long new_sp, old_sp; + + GET_STACK_POINTER (old_sp); + foo(42); + GET_STACK_POINTER (new_sp); + + if (old_sp != new_sp) + abort (); + + return 0; +} + +/* Make sure no FPR saves/restores are emitted. */ +/* { dg-final { scan-assembler-not "\tstd\t" } } */ +/* { dg-final { scan-assembler-not "\tld\t" } } */