This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Committed] S/390 Fix builtin_frame_address with -mpacked-stack
- From: "Andreas Krebbel" <krebbel at linux dot vnet dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 12 Nov 2008 19:08:30 +0100
- Subject: [Committed] S/390 Fix builtin_frame_address with -mpacked-stack
Hello,
the S/390 definition of INITIAL_FRAME_ADDRESS_RTX I've added with:
http://gcc.gnu.org/ml/gcc-patches/2005-01/msg01130.html
is not correct for -mpacked-stack. INITIAL_FRAME_ADDRESS_RTX as well
as DYNAMIC_CHAIN_ADDRESS have special handling for -mpacked-stack
adding 160-8 bytes to the frame address so currently with that option
the adjustment will be done twice.
Bootstrapped on s390 and s390x.
The attached testcases are fixed with the patch.
Committed to mainline and gcc 4.3 branch.
Bye,
-Andreas-
2008-11-12 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* gcc/config/s390/s390.h (INITIAL_FRAME_ADDRESS_RTX): Remove
packed-stack special handling.
(FRAME_ADDR_RTX): Add definition.
2008-11-12 Andreas Krebbel <krebbel1@de.ibm.com>
* gcc.target/s390/frame-addr1.c: New testcase.
* gcc.target/s390/frame-addr2.c: New testcase.
* gcc.target/s390/return-addr1.c: New testcase.
* gcc.target/s390/return-addr2.c: New testcase.
Index: gcc/config/s390/s390.h
===================================================================
*** gcc/config/s390/s390.h.orig 2008-10-17 09:33:53.000000000 +0200
--- gcc/config/s390/s390.h 2008-11-11 15:42:58.000000000 +0100
*************** extern const enum reg_class regclass_map
*** 574,582 ****
/* Defining this macro makes __builtin_frame_address(0) and
__builtin_return_address(0) work with -fomit-frame-pointer. */
#define INITIAL_FRAME_ADDRESS_RTX \
! (TARGET_PACKED_STACK ? \
! plus_constant (arg_pointer_rtx, -UNITS_PER_WORD) : \
! plus_constant (arg_pointer_rtx, -STACK_POINTER_OFFSET))
/* The return address of the current frame is retrieved
from the initial value of register RETURN_REGNUM.
--- 574,580 ----
/* Defining this macro makes __builtin_frame_address(0) and
__builtin_return_address(0) work with -fomit-frame-pointer. */
#define INITIAL_FRAME_ADDRESS_RTX \
! (plus_constant (arg_pointer_rtx, -STACK_POINTER_OFFSET))
/* The return address of the current frame is retrieved
from the initial value of register RETURN_REGNUM.
*************** extern const enum reg_class regclass_map
*** 586,591 ****
--- 584,599 ----
(TARGET_PACKED_STACK ? \
plus_constant ((FRAME), STACK_POINTER_OFFSET - UNITS_PER_WORD) : (FRAME))
+ /* For -mpacked-stack this adds 160 - 8 (96 - 4) to the output of
+ builtin_frame_address. Otherwise arg pointer -
+ STACK_POINTER_OFFSET would be returned for
+ __builtin_frame_address(0) what might result in an address pointing
+ somewhere into the middle of the local variables since the packed
+ stack layout generally does not need all the bytes in the register
+ save area. */
+ #define FRAME_ADDR_RTX(FRAME) \
+ DYNAMIC_CHAIN_ADDRESS ((FRAME))
+
#define RETURN_ADDR_RTX(COUNT, FRAME) \
s390_return_addr_rtx ((COUNT), DYNAMIC_CHAIN_ADDRESS ((FRAME)))
Index: gcc/testsuite/gcc.target/s390/frame-addr1.c
===================================================================
*** /dev/null 1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.target/s390/frame-addr1.c 2008-11-12 17:56:49.000000000 +0100
***************
*** 0 ****
--- 1,53 ----
+ /* builtin_frame_address(n) with n>0 has always been troublesome ...
+ especially when the S/390 packed stack layout comes into play. */
+
+ /* { dg-do run } */
+ /* { dg-options "-O3 -fno-optimize-sibling-calls -mbackchain -mpacked-stack -msoft-float" } */
+
+ #ifdef __s390x__
+ /* 64bit: 3 words to be saved: backchain, r14 and r15 */
+ #define SAVE_AREA_SIZE 3*8
+ #else
+ /* 32bit: 4 words to be saved: backchain, r13, r14 and r15 */
+ #define SAVE_AREA_SIZE 4*4
+ #endif
+ extern void abort(void);
+
+ #define EXPAND_CHECK(n) \
+ void __attribute__((noinline)) \
+ foo1_##n (void *p) \
+ { \
+ if (p - __builtin_frame_address (n) != SAVE_AREA_SIZE) \
+ abort (); \
+ } \
+ void __attribute__((noinline)) \
+ foo2_##n (void *p) \
+ { \
+ if (p - __builtin_frame_address (n) != SAVE_AREA_SIZE) \
+ abort (); \
+ foo1_##n (__builtin_frame_address (n)); \
+ } \
+ void __attribute__((noinline)) \
+ foo3_##n () \
+ { \
+ foo2_##n (__builtin_frame_address (n)); \
+ } \
+ void __attribute__((noinline)) \
+ foo4_##n () \
+ { \
+ foo3_##n (); \
+ }
+
+ EXPAND_CHECK (0)
+ EXPAND_CHECK (1)
+ EXPAND_CHECK (2)
+
+ int
+ main ()
+ {
+ foo4_0 ();
+ foo4_1 ();
+ foo4_2 ();
+
+ return 0;
+ }
Index: gcc/testsuite/gcc.target/s390/frame-addr2.c
===================================================================
*** /dev/null 1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.target/s390/frame-addr2.c 2008-11-12 17:56:49.000000000 +0100
***************
*** 0 ****
--- 1,50 ----
+ /* builtin_frame_address(n) with n>0 has always been troublesome. */
+
+ /* { dg-do run } */
+ /* { dg-options "-O3 -fno-optimize-sibling-calls -mbackchain" } */
+
+ #ifdef __s390x__
+ #define SAVE_AREA_SIZE 160
+ #else
+ #define SAVE_AREA_SIZE 96
+ #endif
+ extern void abort(void);
+
+ #define EXPAND_CHECK(n) \
+ void __attribute__((noinline)) \
+ foo1_##n (void *p) \
+ { \
+ if (p - __builtin_frame_address (n) != SAVE_AREA_SIZE) \
+ abort (); \
+ } \
+ void __attribute__((noinline)) \
+ foo2_##n (void *p) \
+ { \
+ if (p - __builtin_frame_address (n) != SAVE_AREA_SIZE) \
+ abort (); \
+ foo1_##n (__builtin_frame_address (n)); \
+ } \
+ void __attribute__((noinline)) \
+ foo3_##n () \
+ { \
+ foo2_##n (__builtin_frame_address (n)); \
+ } \
+ void __attribute__((noinline)) \
+ foo4_##n () \
+ { \
+ foo3_##n (); \
+ }
+
+ EXPAND_CHECK (0)
+ EXPAND_CHECK (1)
+ EXPAND_CHECK (2)
+
+ int
+ main ()
+ {
+ foo4_0 ();
+ foo4_1 ();
+ foo4_2 ();
+
+ return 0;
+ }
Index: gcc/testsuite/gcc.target/s390/return-addr1.c
===================================================================
*** /dev/null 1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.target/s390/return-addr1.c 2008-11-12 18:21:21.000000000 +0100
***************
*** 0 ****
--- 1,46 ----
+ /* builtin_return_address(n) with n>0 has always been troublesome ...
+ especially when the S/390 packed stack layout comes into play. */
+
+ /* { dg-do run } */
+ /* { dg-options "-O3 -fno-optimize-sibling-calls -mbackchain -mpacked-stack -msoft-float" } */
+
+ void *addr1;
+
+ extern void abort (void);
+
+ void * __attribute__((noinline))
+ foo1 ()
+ {
+ addr1 = __builtin_return_address (2);
+ }
+
+ void * __attribute__((noinline))
+ foo2 ()
+ {
+ foo1 ();
+ }
+
+ void * __attribute__((noinline))
+ foo3 ()
+ {
+ foo2 ();
+ }
+
+ void __attribute__((noinline))
+ bar ()
+ {
+ void *addr2;
+
+ foo3 ();
+ asm volatile ("basr %0,0\n\t" : "=d" (addr2));
+ /* basr is two bytes in length. */
+ if (addr2 - addr1 != 2)
+ abort ();
+ }
+
+ int
+ main ()
+ {
+ bar();
+ return 0;
+ }
Index: gcc/testsuite/gcc.target/s390/return-addr2.c
===================================================================
*** /dev/null 1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.target/s390/return-addr2.c 2008-11-12 18:21:21.000000000 +0100
***************
*** 0 ****
--- 1,45 ----
+ /* builtin_return_address(n) with n>0 has always been troublesome. */
+
+ /* { dg-do run } */
+ /* { dg-options "-O3 -fno-optimize-sibling-calls -mbackchain" } */
+
+ void *addr1;
+
+ extern void abort (void);
+
+ void * __attribute__((noinline))
+ foo1 ()
+ {
+ addr1 = __builtin_return_address (2);
+ }
+
+ void * __attribute__((noinline))
+ foo2 ()
+ {
+ foo1 ();
+ }
+
+ void * __attribute__((noinline))
+ foo3 ()
+ {
+ foo2 ();
+ }
+
+ void __attribute__((noinline))
+ bar ()
+ {
+ void *addr2;
+
+ foo3 ();
+ asm volatile ("basr %0,0\n\t" : "=d" (addr2));
+ /* basr is two bytes in length. */
+ if (addr2 - addr1 != 2)
+ abort ();
+ }
+
+ int
+ main ()
+ {
+ bar();
+ return 0;
+ }