[multiple changes]
authorAndreas Krebbel <krebbel@gcc.gnu.org>
Wed, 12 Nov 2008 18:04:39 +0000 (18:04 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Wed, 12 Nov 2008 18:04:39 +0000 (18:04 +0000)
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.

From-SVN: r141796

gcc/ChangeLog
gcc/config/s390/s390.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/s390/frame-addr1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/frame-addr2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/return-addr1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/return-addr2.c [new file with mode: 0644]

index fb4e453..e94f822 100644 (file)
@@ -1,3 +1,9 @@
+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  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/35366
index a58bc34..449c1b6 100644 (file)
@@ -574,9 +574,7 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
 /* 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))
+  (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.
@@ -586,6 +584,16 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
   (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 fe9c909..7d93db1 100644 (file)
@@ -1,3 +1,10 @@
+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.
+
 2008-11-12  Jack Howarth  <howarth@bromo.med.uc.edu>
 
        PR testsuite/38008
diff --git a/gcc/testsuite/gcc.target/s390/frame-addr1.c b/gcc/testsuite/gcc.target/s390/frame-addr1.c
new file mode 100644 (file)
index 0000000..fda419f
--- /dev/null
@@ -0,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;
+}
diff --git a/gcc/testsuite/gcc.target/s390/frame-addr2.c b/gcc/testsuite/gcc.target/s390/frame-addr2.c
new file mode 100644 (file)
index 0000000..f6f9687
--- /dev/null
@@ -0,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;
+}
diff --git a/gcc/testsuite/gcc.target/s390/return-addr1.c b/gcc/testsuite/gcc.target/s390/return-addr1.c
new file mode 100644 (file)
index 0000000..8872b89
--- /dev/null
@@ -0,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;
+}
diff --git a/gcc/testsuite/gcc.target/s390/return-addr2.c b/gcc/testsuite/gcc.target/s390/return-addr2.c
new file mode 100644 (file)
index 0000000..c94d052
--- /dev/null
@@ -0,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;
+}