This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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;
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]