func-vararg-alternate-d128-2.c: New.
authorH.J. Lu <hongjiu.lu@intel.com>
Wed, 30 Jul 2008 19:24:02 +0000 (19:24 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Wed, 30 Jul 2008 19:24:02 +0000 (12:24 -0700)
2008-07-30  H.J. Lu  <hongjiu.lu@intel.com>
    Joey Ye  <joey.ye@intel.com>

* gcc.dg/dfp/func-vararg-alternate-d128-2.c: New.
* gcc.dg/dfp/func-vararg-mixed-2.c: Likewise.
* gcc.dg/torture/stackalign/alloca-1.c: Likewise.
* gcc.dg/torture/stackalign/builtin-apply-1.c: Likewise.
* gcc.dg/torture/stackalign/builtin-apply-2.c: Likewise.
* gcc.dg/torture/stackalign/builtin-apply-3.c: Likewise.
* gcc.dg/torture/stackalign/builtin-apply-4.c: Likewise.
* gcc.dg/torture/stackalign/builtin-return-1.c: Likewise.
* gcc.dg/torture/stackalign/check.h: Likewise.
* gcc.dg/torture/stackalign/comp-goto-1.c: Likewise.
* gcc.dg/torture/stackalign/fastcall-1.c: Likewise.
* gcc.dg/torture/stackalign/global-1.c: Likewise.
* gcc.dg/torture/stackalign/inline-1.c: Likewise.
* gcc.dg/torture/stackalign/inline-2.c: Likewise.
* gcc.dg/torture/stackalign/nested-1.c: Likewise.
* gcc.dg/torture/stackalign/nested-2.c: Likewise.
* gcc.dg/torture/stackalign/nested-3.c: Likewise.
* gcc.dg/torture/stackalign/nested-4.c: Likewise.
* gcc.dg/torture/stackalign/nested-5.c: Likewise.
* gcc.dg/torture/stackalign/nested-6.c: Likewise.
* gcc.dg/torture/stackalign/non-local-goto-1.c: Likewise.
* gcc.dg/torture/stackalign/non-local-goto-2.c: Likewise.
* gcc.dg/torture/stackalign/non-local-goto-3.c: Likewise.
* gcc.dg/torture/stackalign/non-local-goto-4.c: Likewise.
* gcc.dg/torture/stackalign/non-local-goto-5.c: Likewise.
* gcc.dg/torture/stackalign/pr16660-1.c: Likewise.
* gcc.dg/torture/stackalign/pr16660-2.c: Likewise.
* gcc.dg/torture/stackalign/pr16660-3.c: Likewise.
* gcc.dg/torture/stackalign/regparm-1.c: Likewise.
* gcc.dg/torture/stackalign/ret-struct-1.c: Likewise.
* gcc.dg/torture/stackalign/setjmp-1.c: Likewise.
* gcc.dg/torture/stackalign/setjmp-2.c: Likewise.
* gcc.dg/torture/stackalign/setjmp-3.c: Likewise.
* gcc.dg/torture/stackalign/setjmp-4.c: Likewise.
* gcc.dg/torture/stackalign/sibcall-1.c: Likewise.
* gcc.dg/torture/stackalign/stackalign.exp: Likewise.
* gcc.dg/torture/stackalign/struct-1.c: Likewise.
* gcc.dg/torture/stackalign/vararg-1.c: Likewise.
* gcc.dg/torture/stackalign/vararg-2.c: Likewise.
* gcc.target/i386/align-main-1.c: Likewise.
* gcc.target/i386/align-main-2.c: Likewise.
* gcc.target/i386/pr32000-2.c: Likewise.
* gcc.target/i386/stackalign/asm-1.c: Likewise.
* gcc.target/i386/stackalign/return-1.c: Likewise.
* gcc.target/i386/stackalign/return-2.c: Likewise.
* gcc.target/i386/stackalign/return-3.c: Likewise.
* gcc.target/i386/stackalign/return-4.c: Likewise.
* gcc.target/i386/stackalign/return-5.c: Likewise.
* gcc.target/i386/stackalign/return-6.c: Likewise.
* gcc.target/i386/stackalign/stackalign.exp: Likewise.
* g++.dg/torture/stackalign/check.h: Likewise.
* g++.dg/torture/stackalign/eh-alloca-1.C: Likewise.
* g++.dg/torture/stackalign/eh-fastcall-1.C: Likewise.
* g++.dg/torture/stackalign/eh-global-1.C: Likewise.
* g++.dg/torture/stackalign/eh-inline-1.C: Likewise.
* g++.dg/torture/stackalign/eh-inline-2.C: Likewise.
* g++.dg/torture/stackalign/eh-vararg-1.C: Likewise.
* g++.dg/torture/stackalign/eh-vararg-2.C: Likewise.
* g++.dg/torture/stackalign/stackalign.exp: Likewise.
* g++.dg/torture/stackalign/stdcall-1.C: Likewise.
* g++.dg/torture/stackalign/test-unwind.h: Likewise.
* g++.dg/torture/stackalign/throw-1.C: Likewise.
* g++.dg/torture/stackalign/throw-2.C: Likewise.
* g++.dg/torture/stackalign/throw-3.C: Likewise.
* g++.dg/torture/stackalign/throw-4.C: Likewise.
* g++.dg/torture/stackalign/unwind-0.C: Likewise.
* g++.dg/torture/stackalign/unwind-1.C: Likewise.
* g++.dg/torture/stackalign/unwind-2.C: Likewise.
* g++.dg/torture/stackalign/unwind-3.C: Likewise.
* g++.dg/torture/stackalign/unwind-4.C: Likewise.
* g++.dg/torture/stackalign/unwind-5.C: Likewise.
* g++.dg/torture/stackalign/unwind-6.C: Likewise.

* gcc.target/i386/20060512-1.c: Add -mpreferred-stack-boundary=4.
(main): Move "popl" after check.
* gcc.target/i386/20060512-3.c: Likewise.

* gcc.target/i386/20060512-2.c: Add -mpreferred-stack-boundary=4.
Remove dg-error.

* gcc.target/i386/20060512-4.c: Add -mpreferred-stack-boundary=4.
Remove dg-warning.

* lib/target-supports.exp (check_effective_target_unaligned_stack):
Always return 0.
(check_effective_target_automatic_stack_alignment): New.

Co-Authored-By: Joey Ye <joey.ye@intel.com>
From-SVN: r138336

78 files changed:
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/stackalign/check.h [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/eh-alloca-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/eh-fastcall-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/eh-global-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/eh-inline-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/eh-inline-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/stackalign.exp [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/stdcall-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/test-unwind.h [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/throw-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/throw-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/throw-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/throw-4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/unwind-0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/unwind-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/unwind-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/unwind-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/unwind-4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/unwind-5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/stackalign/unwind-6.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d128-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/func-vararg-mixed-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/alloca-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/builtin-return-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/check.h [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/comp-goto-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/fastcall-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/global-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/inline-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/inline-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/nested-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/nested-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/nested-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/nested-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/nested-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/nested-6.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/pr16660-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/pr16660-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/pr16660-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/regparm-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/ret-struct-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/setjmp-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/setjmp-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/setjmp-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/setjmp-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/sibcall-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/stackalign.exp [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/struct-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/vararg-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/vararg-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/20060512-1.c
gcc/testsuite/gcc.target/i386/20060512-2.c
gcc/testsuite/gcc.target/i386/20060512-3.c
gcc/testsuite/gcc.target/i386/20060512-4.c
gcc/testsuite/gcc.target/i386/align-main-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/align-main-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr32000-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/stackalign/asm-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/stackalign/return-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/stackalign/return-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/stackalign/return-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/stackalign/return-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/stackalign/return-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/stackalign/return-6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/stackalign/stackalign.exp [new file with mode: 0644]
gcc/testsuite/lib/target-supports.exp

index cdfa294..ab4b945 100644 (file)
@@ -1,3 +1,93 @@
+2008-07-30  H.J. Lu  <hongjiu.lu@intel.com>
+           Joey Ye  <joey.ye@intel.com>
+
+       * gcc.dg/dfp/func-vararg-alternate-d128-2.c: New.
+       * gcc.dg/dfp/func-vararg-mixed-2.c: Likewise.
+       * gcc.dg/torture/stackalign/alloca-1.c: Likewise.
+       * gcc.dg/torture/stackalign/builtin-apply-1.c: Likewise.
+       * gcc.dg/torture/stackalign/builtin-apply-2.c: Likewise.
+       * gcc.dg/torture/stackalign/builtin-apply-3.c: Likewise.
+       * gcc.dg/torture/stackalign/builtin-apply-4.c: Likewise.
+       * gcc.dg/torture/stackalign/builtin-return-1.c: Likewise.
+       * gcc.dg/torture/stackalign/check.h: Likewise.
+       * gcc.dg/torture/stackalign/comp-goto-1.c: Likewise.
+       * gcc.dg/torture/stackalign/fastcall-1.c: Likewise.
+       * gcc.dg/torture/stackalign/global-1.c: Likewise.
+       * gcc.dg/torture/stackalign/inline-1.c: Likewise.
+       * gcc.dg/torture/stackalign/inline-2.c: Likewise.
+       * gcc.dg/torture/stackalign/nested-1.c: Likewise.
+       * gcc.dg/torture/stackalign/nested-2.c: Likewise.
+       * gcc.dg/torture/stackalign/nested-3.c: Likewise.
+       * gcc.dg/torture/stackalign/nested-4.c: Likewise.
+       * gcc.dg/torture/stackalign/nested-5.c: Likewise.
+       * gcc.dg/torture/stackalign/nested-6.c: Likewise.
+       * gcc.dg/torture/stackalign/non-local-goto-1.c: Likewise.
+       * gcc.dg/torture/stackalign/non-local-goto-2.c: Likewise.
+       * gcc.dg/torture/stackalign/non-local-goto-3.c: Likewise.
+       * gcc.dg/torture/stackalign/non-local-goto-4.c: Likewise.
+       * gcc.dg/torture/stackalign/non-local-goto-5.c: Likewise.
+       * gcc.dg/torture/stackalign/pr16660-1.c: Likewise.
+       * gcc.dg/torture/stackalign/pr16660-2.c: Likewise.
+       * gcc.dg/torture/stackalign/pr16660-3.c: Likewise.
+       * gcc.dg/torture/stackalign/regparm-1.c: Likewise.
+       * gcc.dg/torture/stackalign/ret-struct-1.c: Likewise.
+       * gcc.dg/torture/stackalign/setjmp-1.c: Likewise.
+       * gcc.dg/torture/stackalign/setjmp-2.c: Likewise.
+       * gcc.dg/torture/stackalign/setjmp-3.c: Likewise.
+       * gcc.dg/torture/stackalign/setjmp-4.c: Likewise.
+       * gcc.dg/torture/stackalign/sibcall-1.c: Likewise.
+       * gcc.dg/torture/stackalign/stackalign.exp: Likewise.
+       * gcc.dg/torture/stackalign/struct-1.c: Likewise.
+       * gcc.dg/torture/stackalign/vararg-1.c: Likewise.
+       * gcc.dg/torture/stackalign/vararg-2.c: Likewise.
+       * gcc.target/i386/align-main-1.c: Likewise.
+       * gcc.target/i386/align-main-2.c: Likewise.
+       * gcc.target/i386/pr32000-2.c: Likewise.
+       * gcc.target/i386/stackalign/asm-1.c: Likewise.
+       * gcc.target/i386/stackalign/return-1.c: Likewise.
+       * gcc.target/i386/stackalign/return-2.c: Likewise.
+       * gcc.target/i386/stackalign/return-3.c: Likewise.
+       * gcc.target/i386/stackalign/return-4.c: Likewise.
+       * gcc.target/i386/stackalign/return-5.c: Likewise.
+       * gcc.target/i386/stackalign/return-6.c: Likewise.
+       * gcc.target/i386/stackalign/stackalign.exp: Likewise.
+       * g++.dg/torture/stackalign/check.h: Likewise.
+       * g++.dg/torture/stackalign/eh-alloca-1.C: Likewise.
+       * g++.dg/torture/stackalign/eh-fastcall-1.C: Likewise.
+       * g++.dg/torture/stackalign/eh-global-1.C: Likewise.
+       * g++.dg/torture/stackalign/eh-inline-1.C: Likewise.
+       * g++.dg/torture/stackalign/eh-inline-2.C: Likewise.
+       * g++.dg/torture/stackalign/eh-vararg-1.C: Likewise.
+       * g++.dg/torture/stackalign/eh-vararg-2.C: Likewise.
+       * g++.dg/torture/stackalign/stackalign.exp: Likewise.
+       * g++.dg/torture/stackalign/stdcall-1.C: Likewise.
+       * g++.dg/torture/stackalign/test-unwind.h: Likewise.
+       * g++.dg/torture/stackalign/throw-1.C: Likewise.
+       * g++.dg/torture/stackalign/throw-2.C: Likewise.
+       * g++.dg/torture/stackalign/throw-3.C: Likewise.
+       * g++.dg/torture/stackalign/throw-4.C: Likewise.
+       * g++.dg/torture/stackalign/unwind-0.C: Likewise.
+       * g++.dg/torture/stackalign/unwind-1.C: Likewise.
+       * g++.dg/torture/stackalign/unwind-2.C: Likewise.
+       * g++.dg/torture/stackalign/unwind-3.C: Likewise.
+       * g++.dg/torture/stackalign/unwind-4.C: Likewise.
+       * g++.dg/torture/stackalign/unwind-5.C: Likewise.
+       * g++.dg/torture/stackalign/unwind-6.C: Likewise.
+
+       * gcc.target/i386/20060512-1.c: Add -mpreferred-stack-boundary=4.
+       (main): Move "popl" after check.
+       * gcc.target/i386/20060512-3.c: Likewise.
+
+       * gcc.target/i386/20060512-2.c: Add -mpreferred-stack-boundary=4.
+       Remove dg-error.
+
+       * gcc.target/i386/20060512-4.c: Add -mpreferred-stack-boundary=4.
+       Remove dg-warning.
+
+       * lib/target-supports.exp (check_effective_target_unaligned_stack):
+       Always return 0.
+       (check_effective_target_automatic_stack_alignment): New.
+
 2008-07-30  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/36967
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/check.h b/gcc/testsuite/g++.dg/torture/stackalign/check.h
new file mode 100644 (file)
index 0000000..af19885
--- /dev/null
@@ -0,0 +1,36 @@
+#include <stddef.h>
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#ifdef  __cplusplus
+extern "C" void abort (void);
+#else
+extern void abort (void);
+#endif
+
+int
+check_int (int *i, int align)
+{
+  *i = 20;
+  if ((((ptrdiff_t) i) & (align - 1)) != 0)
+    {
+#ifdef DEBUG
+      printf ("\nUnalign address (%d): %p!\n", align, i);
+#endif
+      abort ();
+    }
+  return *i;
+}
+
+void
+check (void *p, int align)
+{
+  if ((((ptrdiff_t) p) & (align - 1)) != 0)
+    {
+#ifdef DEBUG
+      printf ("\nUnalign address (%d): %p!\n", align, p);
+#endif
+      abort ();
+    }
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-alloca-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-alloca-1.C
new file mode 100644 (file)
index 0000000..a20f074
--- /dev/null
@@ -0,0 +1,56 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+bar (char *p, int size)
+{
+  __builtin_strncpy (p, "good", size);
+}
+
+class Base {};
+
+struct A : virtual public Base
+{
+  A() {}
+};
+
+struct B {};
+
+void
+foo (int size) throw (B,A)
+{
+  char *p = (char*) __builtin_alloca (size + 1);
+  aligned i;
+
+  bar (p, size);
+  if (__builtin_strncmp (p, "good", size) != 0)
+    {
+#ifdef DEBUG
+      p[size] = '\0';
+      printf ("Failed: %s != good\n", p);
+#endif
+      abort ();
+    }
+
+  if (check_int (&i,  __alignof__(i)) != i)
+    abort ();
+
+  throw A();
+}
+
+int
+main()
+{
+  try {        foo (5); }
+  catch (A& a) { }
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-fastcall-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-fastcall-1.C
new file mode 100644 (file)
index 0000000..4b849a2
--- /dev/null
@@ -0,0 +1,43 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+class Base {};
+
+struct A : virtual public Base
+{
+  A() {}
+};
+
+struct B {};
+
+__attribute__ ((fastcall))
+void
+foo (int j, int k, int m, int n, int o) throw (B,A)
+{
+  aligned i;
+
+  if (check_int (&i,  __alignof__(i)) != i)
+    abort ();
+
+  if (i != 20 || j != 1 || k != 2 || m != 3 || n != 4 || o != 5)
+    abort ();
+
+  throw A();
+}
+
+int
+main()
+{
+  try { foo (1, 2, 3, 4, 5); }
+  catch (A& a) { }
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-global-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-global-1.C
new file mode 100644 (file)
index 0000000..2692f94
--- /dev/null
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+class Base {};
+
+struct A : virtual public Base
+{
+  A() {}
+};
+
+struct B {};
+
+void
+foo (void) throw (B,A)
+{
+  aligned i;
+
+  if (check_int (&i,  __alignof__(i)) != i)
+    abort ();
+
+  throw A();
+}
+
+int
+main()
+{
+  try {        foo (); }
+  catch (A& a) { }
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-1.C
new file mode 100644 (file)
index 0000000..72ac7fd
--- /dev/null
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+class Base {};
+
+struct A : virtual public Base
+{
+  A() {}
+};
+
+struct B {};
+
+static void
+inline __attribute__((always_inline))
+foo (void) throw (B,A)
+{
+  aligned i;
+
+  if (check_int (&i,  __alignof__(i)) != i)
+    abort ();
+  throw A();
+}
+
+int
+main()
+{
+  try {        foo (); }
+  catch (A& a) { }
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-2.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-inline-2.C
new file mode 100644 (file)
index 0000000..4feb3f0
--- /dev/null
@@ -0,0 +1,57 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+bar (char *p, int size)
+{
+  __builtin_strncpy (p, "good", size);
+}
+
+class Base {};
+
+struct A : virtual public Base
+{
+  A() {}
+};
+
+struct B {};
+
+static void
+inline __attribute__((always_inline))
+foo (int size) throw (B,A)
+{
+  char *p = (char *) __builtin_alloca (size + 1);
+  aligned i;
+
+  bar (p, size);
+  if (__builtin_strncmp (p, "good", size) != 0)
+    {
+#ifdef DEBUG
+      p[size] = '\0';
+      printf ("Failed: %s != good\n", p);
+#endif
+      abort ();
+    }
+
+  if (check_int (&i,  __alignof__(i)) != i)
+    abort ();
+
+  throw A();
+}
+
+int
+main()
+{
+  try {        foo (5); }
+  catch (A& a) { }
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-1.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-1.C
new file mode 100644 (file)
index 0000000..74b48fa
--- /dev/null
@@ -0,0 +1,72 @@
+/* { dg-do run } */
+
+#include <stdarg.h>
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+bar (char *p, int size)
+{
+  __builtin_strncpy (p, "good", size);
+}
+
+class Base {};
+
+struct A : virtual public Base
+{
+  A() {}
+};
+
+struct B {};
+
+void
+foo (const char *fmt, ...) throw (B,A)
+{
+  va_list arg;
+  char *p;
+  aligned i;
+  int size;
+  double x;
+
+  va_start (arg, fmt);
+  size = va_arg (arg, int);
+  if (size != 5)
+    abort ();
+  p = (char *) __builtin_alloca (size + 1);
+
+  x = va_arg (arg, double);
+  if (x != 5.0)
+    abort ();
+
+  bar (p, size);
+  if (__builtin_strncmp (p, "good", size) != 0)
+    {
+#ifdef DEBUG
+      p[size] = '\0';
+      printf ("Failed: %s != good\n", p);
+#endif
+      abort ();
+    }
+
+  if (check_int (&i,  __alignof__(i)) != i)
+    abort ();
+
+  throw A();
+
+  va_end (arg);
+}
+
+int
+main()
+{
+  try {        foo ("foo", 5, 5.0); }
+  catch (A& a) { }
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-2.C b/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-2.C
new file mode 100644 (file)
index 0000000..719c839
--- /dev/null
@@ -0,0 +1,77 @@
+/* { dg-do run } */
+
+#include <stdarg.h>
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+bar (char *p, int size)
+{
+  __builtin_strncpy (p, "good", size);
+}
+
+class Base {};
+
+struct A : virtual public Base
+{
+  A() {}
+};
+
+struct B {};
+
+void
+test (va_list arg) throw (B,A)
+{
+  char *p;
+  aligned i;
+  int size;
+  double x;
+
+  size = va_arg (arg, int);
+  if (size != 5)
+    abort ();
+
+  p = (char *) __builtin_alloca (size + 1);
+
+  x = va_arg (arg, double);
+  if (x != 5.0)
+    abort ();
+
+  bar (p, size);
+  if (__builtin_strncmp (p, "good", size) != 0)
+    {
+#ifdef DEBUG
+      p[size] = '\0';
+      printf ("Failed: %s != good\n", p);
+#endif
+      abort ();
+    }
+
+  if (check_int (&i,  __alignof__(i)) != i)
+    abort ();
+
+  throw A();
+}
+
+void
+foo (const char *fmt, ...)
+{
+  va_list arg;
+  va_start (arg, fmt);
+  test (arg);
+  va_end (arg);
+}
+int
+main()
+{
+  try {        foo ("foo", 5, 5.0); }
+  catch (A& a) { }
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/stackalign.exp b/gcc/testsuite/g++.dg/torture/stackalign/stackalign.exp
new file mode 100644 (file)
index 0000000..bfa413e
--- /dev/null
@@ -0,0 +1,39 @@
+# Copyright (C) 2008
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# This harness is for tests that should be run at all optimisation levels.
+
+load_lib g++-dg.exp
+
+# Only run on targets which support automatic stack alignment.
+if { ![check_effective_target_automatic_stack_alignment] } then {
+    return
+}
+
+set additional_flags ""
+if { [istarget i?86*-*-*] || [istarget x86_64-*-*] } then {
+    lappend additional_flags "-mstackrealign"
+    lappend additional_flags "-mpreferred-stack-boundary=5"
+}
+
+dg-init
+gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.C]] $additional_flags
+if { [check_effective_target_fpic] } then {
+    lappend additional_flags "-fpic"
+    gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.C]] $additional_flags
+}
+dg-finish
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/stdcall-1.C b/gcc/testsuite/g++.dg/torture/stackalign/stdcall-1.C
new file mode 100644 (file)
index 0000000..393b37e
--- /dev/null
@@ -0,0 +1,17 @@
+// { dg-do compile { target { { i?86-*-* x86_64-*-* } && ilp32 } } }
+
+// This case is to detect an assertion failure in stack branch development.
+
+bool f();
+struct S {
+    __attribute__ ((stdcall)) ~S();
+};
+void g() {
+    for (;;) {
+        S s1, s2, s3;
+        if (f())
+            continue;
+        if (f())
+            return;
+    }
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/test-unwind.h b/gcc/testsuite/g++.dg/torture/stackalign/test-unwind.h
new file mode 100644 (file)
index 0000000..e6493ff
--- /dev/null
@@ -0,0 +1,132 @@
+#include "check.h"
+
+#ifdef  __cplusplus
+extern "C" void abort (void);
+#else
+extern void abort (void);
+#endif
+
+extern void foo(void);
+
+#define INIT_EDI 1
+#define INIT_ESI 2
+#define INIT_EBX 3
+
+/* Set DI/SI/BX to wrong value
+   Use following template so that RA will save/restore callee
+   save registers in prologue/epilogue */
+#define ALTER_REGS() \
+  { \
+        int dummy;      \
+        __asm__  __volatile__ (\
+        "movl %1, %0" : "=D" (dummy) : "i" (-INIT_EDI)\
+        );\
+        __asm__  __volatile__ (\
+        "movl %1, %0" : "=S" (dummy) : "i" (-INIT_ESI)\
+        );\
+        __asm__  __volatile__ (\
+        "movl %1, %0" : "=b" (dummy) : "i" (-INIT_EBX)\
+        );\
+  }
+
+#ifdef __PIC__
+int
+main ()
+{
+  return 0;
+}
+#else
+void __attribute__ ((noinline))
+copy (char *p, int size)
+{
+  __builtin_strncpy (p, "good", size);
+}
+
+int g_edi=INIT_EDI, g_esi=INIT_ESI, g_ebx=INIT_EBX; 
+int g_ebp, g_ebp_save, g_esp, g_esp_save;
+int n_error;
+
+int
+main()
+{
+        int dummy;
+       // Init registers to correct value.
+        // Use following template so that RA will save/restore callee
+       // save registers in prologue/epilogue
+       __asm__  __volatile__ (
+       "movl %1, %0"
+       : "=D" (dummy)
+       : "i" (INIT_EDI)
+       );
+       __asm__  __volatile__ (
+       "movl %1, %0"
+       : "=S" (dummy)
+       : "i" (INIT_ESI)
+       );
+       __asm__  __volatile__ (
+       "movl %1, %0"
+       : "=b" (dummy)
+       : "i" (INIT_EBX)
+       );
+       __asm__ __volatile__ (
+       "movl %ebp, g_ebp_save\n\t"
+       "movl %esp, g_esp_save\n\t"
+       );
+       try {
+               foo();
+       }
+       catch (...)
+       {
+       }
+
+       // Get DI/SI/BX register value after exception caught
+       __asm__ __volatile__ (
+       "movl %edi, g_edi\n\t"
+       "movl %esi, g_esi\n\t"
+       "movl %ebx, g_ebx\n\t"
+       "movl %ebp, g_ebp\n\t"
+       "movl %esp, g_esp\n\t"
+       );
+
+       // Check if DI/SI/BX register value are the same as before calling
+        // foo.
+       if (g_edi != INIT_EDI)
+       {
+               n_error++;
+#ifdef DEBUG
+               printf("edi=%d, correct value:%d\n", g_edi, INIT_EDI);
+#endif
+       }
+       if (g_esi != INIT_ESI)
+       {
+               n_error++;
+#ifdef DEBUG
+               printf("esi=%d, correct value:%d\n", g_esi, INIT_ESI);
+#endif
+       }
+       if (g_ebx != INIT_EBX)
+       {
+               n_error++;
+#ifdef DEBUG
+               printf("ebx=%d, correct value:%d\n", g_ebx, INIT_EBX);
+#endif
+       }
+       if (g_ebp != g_ebp_save)
+       {
+               n_error++;
+#ifdef DEBUG
+               printf("ebp=0x%x, correct value:0x%x\n", g_ebp, g_ebp_save);
+#endif
+       }
+       if (g_esp != g_esp_save)
+       {
+               n_error++;
+#ifdef DEBUG
+               printf("esp=0x%x, correct value:0x%x\n", g_esp, g_esp_save);
+#endif
+       }
+       if (n_error !=0)
+               abort();
+       return 0;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/throw-1.C b/gcc/testsuite/g++.dg/torture/stackalign/throw-1.C
new file mode 100644 (file)
index 0000000..b1d2e27
--- /dev/null
@@ -0,0 +1,61 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT       64
+#endif
+
+typedef int t_align __attribute__((aligned(ALIGNMENT)));
+
+
+int global, global2;
+void bar()
+{
+       volatile t_align a = 1;
+        int i,j,k,l,m,n;
+        i=j=k=0;
+       for (i=0; i < global; i++)
+         for (j=0; j < i; j++)
+         for (k=0; k < j; k++)
+         for (l=0; l < k; l++)
+         for (m=0; m < l; m++)
+         for (n=0; n < m; n++)
+               global2 = k;
+       if (check_int ((int *) &a,  __alignof__(a)) != a)
+         abort ();
+       throw 0;
+}
+
+void foo()
+{
+       bar();
+}
+
+int main()
+{
+       int ll = 1;
+        int i = 0,j = 1,k = 2,l = 3,m = 4,n = 5;
+       try {
+         for (; i < global; i++)
+         for (; j < i; j++)
+         for (; k < j; k++)
+         for (; l < k; l++)
+         for (; m < l; m++)
+         for (; n < m; n++)
+               global2 = k;
+         foo();
+       }
+       catch (...)
+       {
+       }
+       ll = i+j+k+l+m+n;
+       if (ll != 15)
+       {
+#ifdef DEBUG
+               printf("FAIL: sum %d != 15\n", ll);
+#endif
+               abort();
+       }
+       return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/throw-2.C b/gcc/testsuite/g++.dg/torture/stackalign/throw-2.C
new file mode 100644 (file)
index 0000000..5f3f1dc
--- /dev/null
@@ -0,0 +1,52 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT       64
+#endif
+
+typedef int t_align __attribute__((aligned(ALIGNMENT)));
+
+
+int global, global2;
+void bar()
+{
+       volatile t_align a = 1;
+        int i,j,k;
+        i=j=k=0;
+       for (i=0; i < global; i++)
+         for (j=0; j < i; j++)
+               global2 = k;
+       if (check_int ((int *) &a,  __alignof__(a)) != a)
+         abort ();
+       throw 0;
+}
+
+int main()
+{
+       int ll = 1;
+        int i = 0,j = 1,k = 2,l = 3,m = 4,n = 5;
+       try {
+         for (; i < global; i++)
+         for (; j < i; j++)
+         for (; k < j; k++)
+         for (; l < k; l++)
+         for (; m < l; m++)
+         for (; n < m; n++)
+               global2 = k;
+         bar ();
+       }
+       catch (...)
+       {
+       }
+       ll = i+j+k+l+m+n;
+       if (ll != 15)
+       {
+#ifdef DEBUG
+               printf("FAIL: sum %d != 15\n", ll);
+#endif
+               abort();
+       }
+       return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/throw-3.C b/gcc/testsuite/g++.dg/torture/stackalign/throw-3.C
new file mode 100644 (file)
index 0000000..d3e53b8
--- /dev/null
@@ -0,0 +1,52 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT       64
+#endif
+
+typedef int t_align __attribute__((aligned(ALIGNMENT)));
+
+
+int global, global2;
+void bar()
+{
+       volatile t_align a = 1;
+        int i,j,k;
+        i=j=k=0;
+       for (i=0; i < global; i++)
+         for (j=0; j < i; j++)
+               global2 = k;
+       throw 0;
+       if (check_int ((int *) &a,  __alignof__(a)) != a)
+         abort ();
+}
+
+int main()
+{
+       int ll = 1;
+        int i = 0,j = 1,k = 2,l = 3,m = 4,n = 5;
+       try {
+         for (; i < global; i++)
+         for (; j < i; j++)
+         for (; k < j; k++)
+         for (; l < k; l++)
+         for (; m < l; m++)
+         for (; n < m; n++)
+               global2 = k;
+         bar ();
+       }
+       catch (...)
+       {
+       }
+       ll = i+j+k+l+m+n;
+       if (ll != 15)
+       {
+#ifdef DEBUG
+               printf("FAIL: sum %d != 15\n", ll);
+#endif
+               abort();
+       }
+       return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/throw-4.C b/gcc/testsuite/g++.dg/torture/stackalign/throw-4.C
new file mode 100644 (file)
index 0000000..a9c15bd
--- /dev/null
@@ -0,0 +1,54 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT       64
+#endif
+
+typedef int t_align __attribute__((aligned(ALIGNMENT)));
+
+
+int global, global2;
+void bar()
+{
+       volatile t_align a = 1;
+        int i,j,k;
+        i=j=k=0;
+       for (i=0; i < global; i++)
+         for (j=0; j < i; j++)
+           {
+             global2 = k;
+             throw 0;
+           }
+       if (check_int ((int *) &a,  __alignof__(a)) != a)
+         abort ();
+}
+
+int main()
+{
+       int ll = 1;
+        int i = 0,j = 1,k = 2,l = 3,m = 4,n = 5;
+       try {
+         for (; i < global; i++)
+         for (; j < i; j++)
+         for (; k < j; k++)
+         for (; l < k; l++)
+         for (; m < l; m++)
+         for (; n < m; n++)
+               global2 = k;
+         bar ();
+       }
+       catch (...)
+       {
+       }
+       ll = i+j+k+l+m+n;
+       if (ll != 15)
+       {
+#ifdef DEBUG
+               printf("FAIL: sum %d != 15\n", ll);
+#endif
+               abort();
+       }
+       return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-0.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-0.C
new file mode 100644 (file)
index 0000000..546123b
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#ifndef __PIC__
+void __attribute__ ((noinline)) foo()
+{
+        ALTER_REGS();
+        // Throw the except and expect returning to main
+        throw 1;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-1.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-1.C
new file mode 100644 (file)
index 0000000..3b80964
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#ifndef __PIC__
+/* Test situation 1: Stack really realign without DRAP */
+void __attribute__ ((noinline))
+foo ()
+{
+  int __attribute__ ((aligned(64))) a=1;
+  if (check_int (&a,  __alignof__(a)) != a)
+    abort ();
+  ALTER_REGS();
+  throw a;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-2.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-2.C
new file mode 100644 (file)
index 0000000..1569ed8
--- /dev/null
@@ -0,0 +1,29 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#ifndef __PIC__
+/* Test situation 2: stack really realign with DRAP reg CX */
+void __attribute__ ((noinline))
+foo ()
+{
+  int __attribute__ ((aligned(64))) a=4;
+  char * s = (char *) __builtin_alloca (a + 1);
+
+  copy (s, a);
+  if (__builtin_strncmp (s, "good", a) != 0)
+    {
+#ifdef DEBUG
+      s[a] = '\0';
+      printf ("Failed: %s != good\n", s);
+#endif
+      abort ();
+    }
+
+  if (check_int (&a,  __alignof__(a)) != a)
+    abort ();
+
+  ALTER_REGS();
+  throw a;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-3.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-3.C
new file mode 100644 (file)
index 0000000..48eddaf
--- /dev/null
@@ -0,0 +1,35 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#ifndef __PIC__
+/* Test situation 3: Stack realign really happen with DRAP reg DI */
+void __attribute__ ((noinline)) __attribute__ ((regparm(3))) 
+bar (int arg1, int arg2, int arg3)
+{
+  int __attribute__ ((aligned(64))) a=1;
+  char * s = (char *) __builtin_alloca (arg3 + 1);
+
+  copy (s, arg3);
+  if (__builtin_strncmp (s, "good", arg3) != 0)
+    {
+#ifdef DEBUG
+      s[arg3] = '\0';
+      printf ("Failed: %s != good\n", s);
+#endif
+      abort ();
+    }
+
+  if (check_int (&a,  __alignof__(a)) != a)
+    abort ();
+
+  ALTER_REGS();
+  throw arg1+arg2+arg3+a;
+}
+
+void
+foo()
+{
+  bar (1,2,3);
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-4.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-4.C
new file mode 100644 (file)
index 0000000..dacbd3d
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#ifndef __PIC__
+volatile int __attribute__ ((aligned(32))) g_a=1;
+/* Test situation 4: no Drap and stack realign doesn't really happen */
+void __attribute__ ((noinline))
+foo()
+{
+       int i;
+       ALTER_REGS();
+       for (i=0; i < 10; i++)
+               g_a++;
+       throw g_a;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-5.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-5.C
new file mode 100644 (file)
index 0000000..fde430b
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#ifndef __PIC__
+double g_f=1.0;
+/* Test situation 5: Stack realign dosn't really happen with DRAP reg CX */
+void __attribute__ ((noinline)) __attribute__ ((regparm(2))) 
+bar(int arg1, int arg2, int arg3, int arg4)
+{
+  char * s = (char *) __builtin_alloca (arg4 + 1);
+
+  copy (s, arg4);
+  if (__builtin_strncmp (s, "good", arg4) != 0)
+    {
+#ifdef DEBUG
+      s[arg4] = '\0';
+      printf ("Failed: %s != good\n", s);
+#endif
+      abort ();
+    }
+  ALTER_REGS();
+  if (g_f) throw arg1+arg2+arg3+ g_f;
+}
+
+void __attribute__((noinline))
+foo()
+{
+  bar(1,2,3,4);
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/stackalign/unwind-6.C b/gcc/testsuite/g++.dg/torture/stackalign/unwind-6.C
new file mode 100644 (file)
index 0000000..7c9dee1
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "test-unwind.h"
+
+#ifndef __PIC__
+double g_f=1.0;
+/* Test situation 6: Stack realign dosn't really happen with DRAP reg DI */
+void __attribute__ ((noinline)) __attribute__ ((regparm(3))) 
+bar(int arg1, int arg2, int arg3, int arg4)
+{
+  char * s = (char *) __builtin_alloca (arg4 + 1);
+
+  copy (s, arg4);
+  if (__builtin_strncmp (s, "good", arg4) != 0)
+    {
+#ifdef DEBUG
+      s[arg4] = '\0';
+      printf ("Failed: %s != good\n", s);
+#endif
+      abort ();
+    }
+  ALTER_REGS();
+  if (g_f) throw arg1+arg2+arg3+ g_f;
+}
+
+void __attribute__((noinline))
+foo()
+{
+  bar(1,2,3,4);
+}
+#endif
diff --git a/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d128-2.c b/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d128-2.c
new file mode 100644 (file)
index 0000000..167da24
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-options "-std=gnu99 -mpreferred-stack-boundary=2" } */
+
+/* Simple test of vararg passing for problematic types with and without
+   double values passed between them.  */
+
+#define DTYPE _Decimal128
+#define ONE 1.0dl
+#define THREE 3.0dl
+#define SEVEN 7.0dl
+#define ELEVEN 11.0dl
+#define INTS 4
+
+#include "func-vararg-alternate.h"
+
+int
+main ()
+{
+  doit ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/func-vararg-mixed-2.c b/gcc/testsuite/gcc.dg/dfp/func-vararg-mixed-2.c
new file mode 100644 (file)
index 0000000..c1b349c
--- /dev/null
@@ -0,0 +1,118 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-options "-std=gnu99 -mpreferred-stack-boundary=2" } */
+
+/* C99 6.5.2.2 Function calls.
+   Test passing varargs of the combination of decimal float types and
+   other types.  */
+
+#include <stdarg.h>
+
+extern void abort (void);
+static int failcnt = 0;
+                                                                                
+/* Support compiling the test to report individual failures; default is
+   to abort as soon as a check fails.  */
+#ifdef DBG
+#include <stdio.h>
+#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
+#else
+#define FAILURE abort ();
+#endif
+
+/* Supposing the list of varying number of arguments is:
+   unsigned int, _Decimal128, double, _Decimal32, _Decimal64.  */
+
+static _Decimal32
+vararg_d32 (unsigned arg, ...)
+{
+  va_list ap;
+  _Decimal32 result;
+
+  va_start (ap, arg);
+
+  va_arg (ap, unsigned int);
+  va_arg (ap, _Decimal128);
+  va_arg (ap, double);
+  result = va_arg (ap, _Decimal32);
+
+  va_end (ap);
+  return result;
+}
+
+static _Decimal32
+vararg_d64 (unsigned arg, ...)
+{
+  va_list ap;
+  _Decimal64 result;
+
+  va_start (ap, arg);
+
+  va_arg (ap, unsigned int);
+  va_arg (ap, _Decimal128);
+  va_arg (ap, double);
+  va_arg (ap, _Decimal32);
+  result = va_arg (ap, _Decimal64);
+
+  va_end (ap);
+  return result;
+}
+
+static _Decimal128
+vararg_d128 (unsigned arg, ...)
+{
+  va_list ap;
+  _Decimal128 result;
+
+  va_start (ap, arg);
+
+  va_arg (ap, unsigned int);
+  result = va_arg (ap, _Decimal128);
+
+  va_end (ap);
+  return result;
+}
+
+static unsigned int
+vararg_int (unsigned arg, ...)
+{
+  va_list ap;
+  unsigned int result;
+
+  va_start (ap, arg);
+
+  result = va_arg (ap, unsigned int);
+
+  va_end (ap);
+  return result;
+}
+
+static double
+vararg_double (unsigned arg, ...)
+{
+  va_list ap;
+  float result;
+
+  va_start (ap, arg);
+
+  va_arg (ap, unsigned int);
+  va_arg (ap, _Decimal128);
+  result = va_arg (ap, double);
+
+  va_end (ap);
+  return result;
+}
+
+
+int
+main ()
+{
+  if (vararg_d32 (3, 0, 1.0dl, 2.0, 3.0df, 4.0dd) != 3.0df) FAILURE
+  if (vararg_d64 (4, 0, 1.0dl, 2.0, 3.0df, 4.0dd) != 4.0dd) FAILURE
+  if (vararg_d128 (1, 0, 1.0dl, 2.0, 3.0df, 4.0dd) != 1.0dl) FAILURE
+  if (vararg_int (0, 0, 1.0dl, 2.0, 3.0df, 4.0dd) != 0) FAILURE
+  if (vararg_double (2, 0, 1.0dl, 2.0, 3.0df, 4.0dd) != 2.0) FAILURE
+
+  if (failcnt != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/alloca-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/alloca-1.c
new file mode 100644 (file)
index 0000000..1370f63
--- /dev/null
@@ -0,0 +1,44 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+bar (char *p, int size)
+{
+  __builtin_strncpy (p, "good", size);
+}
+
+void
+foo (int size)
+{
+  char *p = __builtin_alloca (size + 1);
+  aligned i;
+
+  bar (p, size);
+  if (__builtin_strncmp (p, "good", size) != 0)
+    {
+#ifdef DEBUG
+      p[size] = '\0';
+      printf ("Failed: %s != good\n", p);
+#endif
+      abort ();
+    }
+
+  if (check_int (&i,  __alignof__(i)) != i)
+    abort ();
+}
+
+int
+main()
+{
+  foo (5);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-1.c
new file mode 100644 (file)
index 0000000..38b384e
--- /dev/null
@@ -0,0 +1,9 @@
+/* PR 11184 */
+/* Origin:  Dara Hazeghi <dhazeghi@yahoo.com> */
+
+void *
+objc_msg_sendv (char * arg_frame, void (*foo)())
+{
+  return __builtin_apply ( foo, arg_frame, 4);
+}
+
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c
new file mode 100644 (file)
index 0000000..a1ba20f
--- /dev/null
@@ -0,0 +1,30 @@
+/* PR target/12503 */
+/* Origin: <pierre.nguyen-tuong@asim.lip6.fr> */
+
+/* Verify that __builtin_apply behaves correctly on targets
+   with pre-pushed arguments (e.g. SPARC).  */
+
+/* { dg-do run } */
+   
+
+#define INTEGER_ARG  5
+
+extern void abort(void);
+
+void foo(char *name, double d, double e, double f, int g)
+{
+  if (g != INTEGER_ARG)
+    abort();
+}
+
+void bar(char *name, ...)
+{
+  __builtin_apply(foo, __builtin_apply_args(), 64);
+}
+
+int main(void)
+{
+  bar("eeee", 5.444567, 8.90765, 4.567789, INTEGER_ARG);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-3.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-3.c
new file mode 100644 (file)
index 0000000..1335d09
--- /dev/null
@@ -0,0 +1,31 @@
+/* PR middle-end/12210 */
+/* Origin: Ossadchy Yury A. <waspcoder@mail.ru> */
+
+/* This used to fail on i686 because the argument was not copied
+   to the right location by __builtin_apply after the direct call.  */
+
+/* { dg-do run } */
+
+
+#define INTEGER_ARG  5
+
+extern void abort(void);
+
+void foo(int arg)
+{
+  if (arg != INTEGER_ARG)
+    abort();
+}
+
+void bar(int arg)
+{
+  foo(arg);
+  __builtin_apply(foo, __builtin_apply_args(), 16);
+}
+
+int main(void)
+{
+  bar(INTEGER_ARG);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-4.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-4.c
new file mode 100644 (file)
index 0000000..28dc610
--- /dev/null
@@ -0,0 +1,29 @@
+/* PR tree-optimization/20076 */
+/* { dg-do run } */
+
+extern void abort (void);
+
+double
+foo (int arg)
+{
+  if (arg != 116)
+    abort();
+  return arg + 1;
+}
+
+inline double
+bar (int arg)
+{
+  foo (arg);
+  __builtin_return (__builtin_apply ((void (*) ()) foo,
+                                    __builtin_apply_args (), 16));
+}
+
+int
+main (int argc, char **argv)
+{
+  if (bar (116) != 117.0)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-return-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-return-1.c
new file mode 100644 (file)
index 0000000..75c9acd
--- /dev/null
@@ -0,0 +1,34 @@
+/* PR middle-end/11151 */
+/* Originator: Andrew Church <gcczilla@achurch.org> */
+/* { dg-do run } */
+
+/* This used to fail on SPARC because the (undefined) return
+   value of 'bar' was overwriting that of 'foo'.  */
+
+extern void abort(void);
+
+int foo(int n)
+{
+  return n+1;
+}
+
+int bar(int n)
+{
+  __builtin_return(__builtin_apply((void (*)(void))foo, __builtin_apply_args(), 64));
+}
+
+char *g;
+
+int main(void)
+{
+  /* Allocate 64 bytes on the stack to make sure that __builtin_apply
+     can read at least 64 bytes above the return address.  */
+  char dummy[64];
+
+  g = dummy;
+
+  if (bar(1) != 2)
+    abort();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/check.h b/gcc/testsuite/gcc.dg/torture/stackalign/check.h
new file mode 100644 (file)
index 0000000..af19885
--- /dev/null
@@ -0,0 +1,36 @@
+#include <stddef.h>
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#ifdef  __cplusplus
+extern "C" void abort (void);
+#else
+extern void abort (void);
+#endif
+
+int
+check_int (int *i, int align)
+{
+  *i = 20;
+  if ((((ptrdiff_t) i) & (align - 1)) != 0)
+    {
+#ifdef DEBUG
+      printf ("\nUnalign address (%d): %p!\n", align, i);
+#endif
+      abort ();
+    }
+  return *i;
+}
+
+void
+check (void *p, int align)
+{
+  if ((((ptrdiff_t) p) & (align - 1)) != 0)
+    {
+#ifdef DEBUG
+      printf ("\nUnalign address (%d): %p!\n", align, p);
+#endif
+      abort ();
+    }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/comp-goto-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/comp-goto-1.c
new file mode 100644 (file)
index 0000000..7558f01
--- /dev/null
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+
+#ifdef STACK_SIZE
+#define DEPTH ((STACK_SIZE) / 512 + 1)
+#else
+#define DEPTH 1000
+#endif
+
+extern void abort (void);
+extern void exit (int);
+
+#if ! defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES)
+int
+x(a)
+{
+  __label__ xlab;
+  void y(a)
+    {
+      void *x = &&llab;
+      if (a==-1)
+       goto *x;
+      if (a==0)
+       goto xlab;
+    llab:
+      y (a-1);
+    }
+  y (a);
+ xlab:;
+  return a;
+}
+#endif
+
+int
+main ()
+{
+#if ! defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES)
+  if (x (DEPTH) != DEPTH)
+    abort ();
+#endif
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/fastcall-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/fastcall-1.c
new file mode 100644 (file)
index 0000000..d1cda10
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+__attribute__ ((fastcall))
+void
+foo (int j, int k, int m, int n, int o)
+{
+  aligned i;
+
+  if (check_int (&i,  __alignof__(i)) != i)
+    abort ();
+
+  if (i != 20 || j != 1 || k != 2 || m != 3 || n != 4 || o != 5)
+    abort ();
+}
+
+int
+main()
+{
+  foo (1, 2, 3, 4, 5);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/global-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/global-1.c
new file mode 100644 (file)
index 0000000..284daad
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+foo (void)
+{
+  aligned i;
+
+  if (check_int (&i,  __alignof__(i)) != i)
+    abort ();
+}
+
+int
+main()
+{
+  foo ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/inline-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/inline-1.c
new file mode 100644 (file)
index 0000000..11e71c6
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+static void
+inline __attribute__((always_inline))
+foo (void)
+{
+  aligned i;
+
+  if (check_int (&i,  __alignof__(i)) != i)
+    abort ();
+}
+
+int
+main()
+{
+  foo ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/inline-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/inline-2.c
new file mode 100644 (file)
index 0000000..fd51b5f
--- /dev/null
@@ -0,0 +1,45 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+bar (char *p, int size)
+{
+  __builtin_strncpy (p, "good", size);
+}
+
+static void
+inline __attribute__((always_inline))
+foo (int size)
+{
+  char *p = __builtin_alloca (size + 1);
+  aligned i;
+
+  bar (p, size);
+  if (__builtin_strncmp (p, "good", size) != 0)
+    {
+#ifdef DEBUG
+      p[size] = '\0';
+      printf ("Failed: %s != good\n", p);
+#endif
+      abort ();
+    }
+
+  if (check_int (&i,  __alignof__(i)) != i)
+    abort ();
+}
+
+int
+main()
+{
+  foo (5);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/nested-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/nested-1.c
new file mode 100644 (file)
index 0000000..4e2c872
--- /dev/null
@@ -0,0 +1,44 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+foo (void)
+{
+  aligned j;
+
+  void bar ()
+    {
+      aligned i;
+
+      if (check_int (&i,  __alignof__(i)) != i)
+       abort ();
+
+      if (check_int (&j,  __alignof__(j)) != j)
+       abort ();
+
+      j = -20;
+    }
+  bar ();
+
+  if (j != -20)
+    abort ();
+
+  if (check_int (&j,  __alignof__(j)) != j)
+    abort ();
+}
+
+int
+main()
+{
+  foo ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/nested-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/nested-2.c
new file mode 100644 (file)
index 0000000..d54e3b9
--- /dev/null
@@ -0,0 +1,45 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+foo (void)
+{
+  aligned j;
+
+   __attribute__ ((__noinline__))
+  void bar ()
+    {
+      aligned i;
+
+      if (check_int (&i,  __alignof__(i)) != i)
+       abort ();
+
+      if (check_int (&j,  __alignof__(j)) != j)
+       abort ();
+
+      j = -20;
+    }
+  bar ();
+
+  if (j != -20)
+    abort ();
+
+  if (check_int (&j,  __alignof__(j)) != j)
+    abort ();
+}
+
+int
+main()
+{
+  foo ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/nested-3.c b/gcc/testsuite/gcc.dg/torture/stackalign/nested-3.c
new file mode 100644 (file)
index 0000000..3732991
--- /dev/null
@@ -0,0 +1,62 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+copy (char *p, int size)
+{
+  __builtin_strncpy (p, "good", size);
+}
+
+void
+foo (int size)
+{
+  aligned j;
+
+   __attribute__ ((__noinline__))
+  void bar (int size)
+    {
+      char *p = __builtin_alloca (size + 1);
+      aligned i;
+
+      copy (p, size);
+      if (strncmp (p, "good", size) != 0)
+       {
+#ifdef DEBUG
+         p[size] = '\0';
+         printf ("Failed: %s != good\n", p);
+#endif
+         abort ();
+       }
+
+      if (check_int (&i,  __alignof__(i)) != i)
+       abort ();
+
+      if (check_int (&j,  __alignof__(j)) != j)
+       abort ();
+
+      j = -20;
+    }
+  bar (size);
+
+  if (j != -20)
+    abort ();
+
+  if (check_int (&j,  __alignof__(j)) != j)
+    abort ();
+}
+
+int
+main()
+{
+  foo (5);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/nested-4.c b/gcc/testsuite/gcc.dg/torture/stackalign/nested-4.c
new file mode 100644 (file)
index 0000000..60322fc
--- /dev/null
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int n;
+
+void
+g (void)
+{
+  __label__ lab;
+  void h (void)
+    {
+      aligned t;
+      if (check_int (&t,  __alignof__(t)) != t)
+       abort ();
+      if (n+t == 0) goto lab;
+    }
+  h();
+lab:
+  return;
+}
+
+int main()
+{
+  g();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/nested-5.c b/gcc/testsuite/gcc.dg/torture/stackalign/nested-5.c
new file mode 100644 (file)
index 0000000..95eba04
--- /dev/null
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+
+extern void abort (void);
+extern void exit (int);
+
+#ifndef NO_TRAMPOLINES
+static void recursive (int n, void (*proc) (void))
+{
+  __label__ l1;
+
+  void do_goto (void)
+  {
+    goto l1;
+  }
+
+  if (n == 3)
+      recursive (n - 1, do_goto);
+  else if (n > 0)
+    recursive (n - 1, proc);
+  else
+    (*proc) ();
+  return;
+
+l1:
+  if (n == 3)
+    exit (0);
+  else
+    abort ();
+}
+
+int main ()
+{
+  recursive (10, abort);
+  abort ();
+}
+#else
+int main () { return 0; }
+#endif
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/nested-6.c b/gcc/testsuite/gcc.dg/torture/stackalign/nested-6.c
new file mode 100644 (file)
index 0000000..d853825
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+
+#ifndef NO_TRAMPOLINES
+
+typedef __SIZE_TYPE__ size_t;
+extern void abort (void);
+extern void exit (int);
+extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *));
+
+int main ()
+{
+  __label__ nonlocal;
+  int compare (const void *a, const void *b)
+  {
+    goto nonlocal;
+  }
+
+  char array[3];
+  qsort (array, 3, 1, compare);
+  abort ();
+
+ nonlocal:
+  exit (0);
+}
+
+#else
+int main() { return 0; }
+#endif
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-1.c
new file mode 100644 (file)
index 0000000..263d448
--- /dev/null
@@ -0,0 +1,55 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+int global;
+
+static void foo(void) __attribute__((noinline));
+
+static void foo(void)
+{
+  global = 1;
+}
+
+static void bar(void)
+{
+  foo ();
+}
+
+int execute(int cmd)
+{
+  __label__ start;
+
+  void raise(void)
+  {
+    goto start;
+  }
+
+  int last = -1;
+
+  bar ();
+
+  last = 0;
+
+start:
+
+  if (last == 0)
+    while (1)
+      {
+        last = 1;
+        raise ();
+      }
+
+  if (last == 0)
+    return 0;
+  else
+    return cmd;
+}
+
+int main(void)
+{
+  if (execute (1) == 0)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-2.c
new file mode 100644 (file)
index 0000000..5a64d54
--- /dev/null
@@ -0,0 +1,56 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+int global;
+
+static void foo(void) __attribute__((noinline));
+
+static void foo(void)
+{
+  global = 1;
+}
+
+static void bar(void)
+{
+  foo ();
+  global = 0;
+}
+
+int execute(int cmd)
+{
+  __label__ start;
+
+  void raise(void)
+  {
+    goto start;
+  }
+
+  int last = -1;
+
+  bar ();
+
+  last = 0;
+
+start:
+
+  if (last == 0)
+    while (1)
+      {
+        last = 1;
+        raise ();
+      }
+
+  if (last == 0)
+    return 0;
+  else
+    return cmd;
+}
+
+int main(void)
+{
+  if (execute (1) == 0)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-3.c b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-3.c
new file mode 100644 (file)
index 0000000..3afc8cc
--- /dev/null
@@ -0,0 +1,42 @@
+/* { dg-do run } */
+
+#ifndef NO_TRAMPOLINES
+extern void abort (void);
+
+int x(int a, int b)
+{
+  __label__ xlab;
+
+  void y(int b)
+    {
+       switch (b)
+        {
+          case 1: goto xlab;
+          case 2: goto xlab;
+        }
+    }
+
+  a = a + 2;
+  y (b);
+
+ xlab:
+  return a;
+}
+
+int main ()
+{
+  int i, j;
+
+  for (j = 1; j <= 2; ++j)
+    for (i = 1; i <= 2; ++i)
+      {
+       int a = x (j, i);
+       if (a != 2 + j)
+         abort ();
+      }
+
+  return 0;
+}
+#else
+int main() { return 0; }
+#endif
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-4.c b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-4.c
new file mode 100644 (file)
index 0000000..3673f1a
--- /dev/null
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+
+extern void abort (void);
+extern void exit (int);
+
+#ifdef STACK_SIZE
+#define DEPTH ((STACK_SIZE) / 512 + 1)
+#else
+#define DEPTH 1000
+#endif
+
+#if ! defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES)
+int
+
+x(a)
+{
+  __label__ xlab;
+  void y(a)
+    {
+      if (a==0)
+       goto xlab;
+      y (a-1);
+    }
+  y (a);
+ xlab:;
+  return a;
+}
+#endif
+
+int
+main ()
+{
+#if ! defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES)
+  if (x (DEPTH) != DEPTH)
+    abort ();
+#endif
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-5.c b/gcc/testsuite/gcc.dg/torture/stackalign/non-local-goto-5.c
new file mode 100644 (file)
index 0000000..08ca95d
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+
+#if !defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES)
+extern void abort (void);
+extern void exit (int);
+int s(i){if(i>0){__label__ l1;int f(int i){if(i==2)goto l1;return 0;}return f(i);l1:;}return 1;}
+int x(){return s(0)==1&&s(1)==0&&s(2)==1;}
+int main(){if(x()!=1)abort();exit(0);}
+#else
+int main(){ exit (0); }
+#endif
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-1.c
new file mode 100644 (file)
index 0000000..b68c3d0
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+
+void
+f ()
+{
+  unsigned long tmp[4] __attribute__((aligned(16)));
+  asm("movaps %%xmm0, (%0)" : : "r" (tmp) : "memory");
+}
+
+int
+main()
+{
+  f();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-2.c
new file mode 100644 (file)
index 0000000..9a039eb
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+typedef __SIZE_TYPE__ size_t;
+#define ALIGNMENT 256
+int main(void)
+{
+  int a[ALIGNMENT/sizeof(int)] __attribute__((aligned(ALIGNMENT)));
+  check (&a, ALIGNMENT);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-3.c b/gcc/testsuite/gcc.dg/torture/stackalign/pr16660-3.c
new file mode 100644 (file)
index 0000000..1c1ddd1
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+typedef __SIZE_TYPE__ size_t;
+#define ALIGNMENT 256
+int main(void)
+{
+  int a[ALIGNMENT/sizeof(int)] __attribute__((aligned(ALIGNMENT)));
+  check (&a, ALIGNMENT);
+  int b[ALIGNMENT/sizeof(int)] __attribute__((aligned(ALIGNMENT)));
+  check (&b, ALIGNMENT);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/regparm-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/regparm-1.c
new file mode 100644 (file)
index 0000000..9dac024
--- /dev/null
@@ -0,0 +1,60 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int test_nested (int i)
+{
+  aligned y;
+
+  int __attribute__ ((__noinline__, __regparm__(2))) foo (int j, int k, int l)
+  {
+    aligned x;
+
+    if (check_int (&x,  __alignof__(x)) != x)
+      abort ();
+
+    if (x != 20)
+      abort ();
+
+    return i + j + k + l;
+  }
+
+  if (check_int (&y,  __alignof__(y)) != y)
+    abort ();
+
+  if (y != 20)
+    abort ();
+
+  return foo(i, i+1, i+2) * i;
+}
+
+int __attribute__ ((__noinline__, __regparm__(3), __force_align_arg_pointer__))
+test_realigned (int j, int k, int l)
+{
+  aligned y;
+
+  if (check_int (&y,  __alignof__(y)) != y)
+    abort ();
+
+  if (y != 20)
+    abort ();
+
+  return j + k + l;
+}
+
+int main ()
+{
+  if (test_nested(10) != 430)
+    abort ();
+
+  if (test_realigned(10, 11, 12) != 33)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/ret-struct-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/ret-struct-1.c
new file mode 100644 (file)
index 0000000..163e54c
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT       64
+#endif
+
+extern void abort();
+typedef struct my_struct
+{
+       char str[31];
+} stype ;
+
+stype g_s;
+
+stype __attribute__((noinline))
+foo (char arg1, char arg2, char arg3)
+{
+       stype __attribute__((aligned(ALIGNMENT))) s;
+       s.str[0] = arg1;
+       s.str[1] = arg2;
+       s.str[30] = arg3;
+       check(&s, ALIGNMENT);
+       return s;
+}
+
+int main()
+{
+       g_s = foo(1,2,3);
+
+       if (g_s.str[0] != 1 || g_s.str[1] != 2 || g_s.str[30] !=3)
+         abort();
+       return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-1.c
new file mode 100644 (file)
index 0000000..6ab67e3
--- /dev/null
@@ -0,0 +1,43 @@
+/* { dg-do run } */
+
+extern int strcmp(const char *, const char *);
+extern char *strcpy(char *, const char *);
+extern void abort(void);
+extern void exit(int);
+
+void *buf[20];
+
+void __attribute__((noinline))
+sub2 (void)
+{
+  __builtin_longjmp (buf, 1);
+}
+
+int
+main ()
+{
+  char *p = 0;
+  
+  p = (char *) __builtin_alloca (20);
+
+  strcpy (p, "test");
+
+  if (__builtin_setjmp (buf))
+    {
+      if (strcmp (p, "test") != 0)
+       abort ();
+
+      exit (0);
+    }
+
+  {
+    int *q = (int *) __builtin_alloca (p[2] * sizeof (int));
+    int i;
+    
+    for (i = 0; i < p[2]; i++)
+      q[i] = 0;
+
+    while (1)
+      sub2 ();
+  }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-2.c
new file mode 100644 (file)
index 0000000..c93ffa8
--- /dev/null
@@ -0,0 +1,46 @@
+/* { dg-do run { target i?86-*-linux* x86_64-*-linux* } } */
+
+#include <setjmp.h>
+#include <signal.h>
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+static jmp_buf segv_jmpbuf;
+
+static void segv_handler(int seg)
+{
+   __builtin_longjmp(segv_jmpbuf, 1);
+}
+
+static int is_addressable(void *p, size_t size)
+{
+   volatile char * volatile cp = (volatile char *)p;
+   volatile int ret;
+   struct sigaction sa, origsa;
+   sigset_t mask;
+   
+   sa.sa_handler = segv_handler;
+   sa.sa_flags = 0;
+   sigfillset(&sa.sa_mask);
+   sigaction(SIGSEGV, &sa, &origsa);
+   sigprocmask(SIG_SETMASK, NULL, &mask);
+
+   if (__builtin_setjmp(segv_jmpbuf) == 0) {
+      while(size--)
+        *cp++;
+      ret = 1;
+    } else
+      ret = 0;
+
+   sigaction(SIGSEGV, &origsa, NULL);
+   sigprocmask(SIG_SETMASK, &mask, NULL);
+
+   return ret;
+}
+
+int main(int argc, char **argv)
+{
+   is_addressable(0x0, 1);
+   return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-3.c b/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-3.c
new file mode 100644 (file)
index 0000000..fee0d28
--- /dev/null
@@ -0,0 +1,37 @@
+/* { dg-do run } */
+
+#include <setjmp.h>
+
+extern void abort (void);
+
+jmp_buf buf;
+
+void raise0(void)
+{
+  __builtin_longjmp (buf, 1);
+}
+
+int execute(int cmd)
+{
+  int last = 0;
+
+  if (__builtin_setjmp (buf) == 0)
+    while (1)
+      {
+       last = 1;
+       raise0 ();
+      }
+
+  if (last == 0)
+    return 0;
+  else
+    return cmd;
+}
+
+int main(void)
+{
+  if (execute (1) == 0)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-4.c b/gcc/testsuite/gcc.dg/torture/stackalign/setjmp-4.c
new file mode 100644 (file)
index 0000000..d167122
--- /dev/null
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+
+#include <setjmp.h>
+
+extern void abort (void);
+
+jmp_buf buf;
+
+void raise0(void)
+{
+  __builtin_longjmp (buf, 1);
+}
+
+int execute(int cmd)
+{
+  int last = 0;
+
+  __builtin_setjmp (buf);
+
+  if (last == 0)
+    while (1)
+      {
+       last = 1;
+       raise0 ();
+      }
+
+  if (last == 0)
+    return 0;
+  else
+    return cmd;
+}
+
+int main(void)
+{
+  if (execute (1) == 0)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/sibcall-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/sibcall-1.c
new file mode 100644 (file)
index 0000000..8c17475
--- /dev/null
@@ -0,0 +1,35 @@
+/* { dg-do run } */
+
+extern int ok (int);
+extern void exit ();
+static int gen_x86_64_shrd (int);
+static int
+gen_x86_64_shrd(int a __attribute__ ((__unused__)))
+{
+  return 0;
+}
+
+extern int gen_x86_shrd_1 (int);
+extern void ix86_split_ashr (int);
+
+void
+ix86_split_ashr (int mode)
+{
+          (mode != 0
+                      ? ok
+                      : gen_x86_64_shrd) (0);
+}
+
+volatile int one = 1;
+int
+main (void)
+{
+  ix86_split_ashr (one);
+  return 1;
+}
+
+int
+ok (int i)
+{
+  exit (i);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/stackalign.exp b/gcc/testsuite/gcc.dg/torture/stackalign/stackalign.exp
new file mode 100644 (file)
index 0000000..3574e4d
--- /dev/null
@@ -0,0 +1,52 @@
+# Copyright (C) 2008
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# This harness is for tests that should be run at all optimisation levels.
+
+load_lib gcc-dg.exp
+
+# Only run on targets which support automatic stack alignment.
+if { ![check_effective_target_automatic_stack_alignment] } then {
+    return
+}
+
+set additional_flags ""
+if { [istarget i?86*-*-*] || [istarget x86_64-*-*] } then {
+    lappend additional_flags "-mstackrealign"
+    lappend additional_flags "-mpreferred-stack-boundary=5"
+}
+
+dg-init
+
+gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] $additional_flags
+if { [check_effective_target_fpic] } then {
+    set pic_additional_flags $additional_flags
+    lappend pic_additional_flags "-fpic"
+    gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] $pic_additional_flags
+}
+
+if { [istarget i?86*-*-*] || [istarget x86_64-*-*] } then {
+    lappend additional_flags "-mforce-drap"
+    gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] $additional_flags
+    if { [check_effective_target_fpic] } then {
+       set pic_additional_flags $additional_flags
+       lappend pic_additional_flags "-fpic"
+       gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] $pic_additional_flags
+    }
+}
+
+dg-finish
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/struct-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/struct-1.c
new file mode 100644 (file)
index 0000000..79e3733
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+void
+foo (void)
+{
+  struct i
+    {
+      aligned i;
+    } i;
+
+  if (check_int (&i.i,  __alignof__(i.i)) != i.i)
+    abort ();
+}
+
+int
+main()
+{
+  foo ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/vararg-1.c b/gcc/testsuite/gcc.dg/torture/stackalign/vararg-1.c
new file mode 100644 (file)
index 0000000..62b2365
--- /dev/null
@@ -0,0 +1,59 @@
+/* { dg-do run } */
+
+#include <stdarg.h>
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+bar (char *p, int size)
+{
+  __builtin_strncpy (p, "good", size);
+}
+
+void
+foo (const char *fmt, ...)
+{
+  va_list arg;
+  char *p;
+  aligned i;
+  int size;
+  double x;
+
+  va_start (arg, fmt);
+  size = va_arg (arg, int);
+  if (size != 5)
+    abort ();
+  p = __builtin_alloca (size + 1);
+
+  x = va_arg (arg, double);
+  if (x != 5.0)
+    abort ();
+
+  bar (p, size);
+  if (__builtin_strncmp (p, "good", size) != 0)
+    {
+#ifdef DEBUG
+      p[size] = '\0';
+      printf ("Failed: %s != good\n", p);
+#endif
+      abort ();
+    }
+
+  if (check_int (&i,  __alignof__(i)) != i)
+    abort ();
+  va_end (arg);
+}
+
+int
+main()
+{
+  foo ("foo", 5, 5.0);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/vararg-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/vararg-2.c
new file mode 100644 (file)
index 0000000..00b723b
--- /dev/null
@@ -0,0 +1,65 @@
+/* { dg-do run } */
+
+#include <stdarg.h>
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      64
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+int global;
+
+void
+bar (char *p, int size)
+{
+  __builtin_strncpy (p, "good", size);
+}
+
+void
+test (va_list arg)
+{
+  char *p;
+  aligned i;
+  int size;
+  double x;
+
+  size = va_arg (arg, int);
+  if (size != 5)
+    abort ();
+
+  p = __builtin_alloca (size + 1);
+
+  x = va_arg (arg, double);
+  if (x != 5.0)
+    abort ();
+
+  bar (p, size);
+  if (__builtin_strncmp (p, "good", size) != 0)
+    {
+#ifdef DEBUG
+      p[size] = '\0';
+      printf ("Failed: %s != good\n", p);
+#endif
+      abort ();
+    }
+
+  if (check_int (&i,  __alignof__(i)) != i)
+    abort ();
+}
+
+void
+foo (const char *fmt, ...)
+{
+  va_list arg;
+  va_start (arg, fmt);
+  test (arg);
+  va_end (arg);
+}
+int
+main()
+{
+  foo ("foo", 5, 5.0);
+  return 0;
+}
index 3defe64..8109f94 100644 (file)
@@ -1,6 +1,6 @@
 /* { dg-do run } */
 /* { dg-require-effective-target ilp32 } */
-/* { dg-options "-std=gnu99 -msse2" } */
+/* { dg-options "-std=gnu99 -msse2 -mpreferred-stack-boundary=4" } */
 
 #include "sse2-check.h"
 
@@ -28,7 +28,7 @@ sse2_test (void)
   int result;
   asm ("pushl %esi");          /* Disalign runtime stack.  */
   result = self_aligning_function (g_1, g_2);
-  asm ("popl %esi");
   if (result != 42)
     abort ();
+  asm ("popl %esi");
 }
index 0e446cf..fe1af56 100644 (file)
@@ -1,12 +1,12 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target ilp32 } */
-/* { dg-options "-std=gnu99" } */
+/* { dg-options "-std=gnu99 -mpreferred-stack-boundary=4" } */
 int
 outer_function (int x, int y)
 {
   int __attribute__ ((__noinline__, __force_align_arg_pointer__))
   nested_function (int x, int y)
-    { /* { dg-error "force_align_arg_pointer not supported for nested functions" } */
+    {
       return (x + y);
     }
   return (3 + nested_function (x, y));
index 5ffa812..847f0eb 100644 (file)
@@ -1,6 +1,6 @@
 /* { dg-do run } */
 /* { dg-require-effective-target ilp32 } */
-/* { dg-options "-std=gnu99 -msse2 -mstackrealign" } */
+/* { dg-options "-std=gnu99 -msse2 -mstackrealign -mpreferred-stack-boundary=4" } */
 
 #include "sse2-check.h"
 
@@ -28,7 +28,7 @@ sse2_test (void)
   int result;
   asm ("pushl %esi");          /* Disalign runtime stack.  */
   result = self_aligning_function (g_1, g_2);
-  asm ("popl %esi");
   if (result != 42)
     abort ();
+  asm ("popl %esi");
 }
index f2dd264..ee7b8a4 100644 (file)
@@ -1,12 +1,12 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target ilp32 } */
-/* { dg-options "-mstackrealign" } */
+/* { dg-options "-mstackrealign -mpreferred-stack-boundary=4" } */
 int
 outer_function (int x, int y)
 {
   int __attribute__ ((__noinline__))
   nested_function (int x, int y)
-    { /* { dg-warning "-mstackrealign ignored for nested functions" } */
+    {
       return (x + y);
     }
   return (3 + nested_function (x, y));
diff --git a/gcc/testsuite/gcc.target/i386/align-main-1.c b/gcc/testsuite/gcc.target/i386/align-main-1.c
new file mode 100644 (file)
index 0000000..5bbc101
--- /dev/null
@@ -0,0 +1,25 @@
+/* Test for stack alignment when PREFERRED_STACK_BOUNDARY < alignment
+   of local variable.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mpreferred-stack-boundary=6 -mincoming-stack-boundary=6" } */
+/* { dg-final { scan-assembler "and\[lq\]?\[\\t \]*\\$-128,\[\\t \]*%\[re\]?sp" } } */
+/* { dg-final { scan-assembler-not "and\[lq\]?\[\\t \]*\\$-64,\[\\t \]*%\[re\]?sp" } } */
+
+#include <stddef.h>
+
+#define ALIGNMENT 128
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+extern void abort(void);
+
+void check(void * a)
+{
+  if (((ptrdiff_t)a & (ALIGNMENT-1)) != 0)
+    abort();
+}
+
+int main()
+{
+  aligned a = 1;
+  check(&a);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/align-main-2.c b/gcc/testsuite/gcc.target/i386/align-main-2.c
new file mode 100644 (file)
index 0000000..df45f0e
--- /dev/null
@@ -0,0 +1,25 @@
+/* Test for stack alignment when PREFERRED_STACK_BOUNDARY > alignment
+   of local variable.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mpreferred-stack-boundary=6 -mincoming-stack-boundary=6" } */
+/* { dg-final { scan-assembler "and\[lq\]?\[\\t \]*\\$-64,\[\\t \]*%\[re\]?sp" } } */
+/* { dg-final { scan-assembler-not "and\[lq\]?\[\\t \]*\\$-128,\[\\t \]*%\[re\]?sp" } } */
+
+#include <stddef.h>
+
+#define ALIGNMENT 32
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+extern void abort(void);
+
+void check(void * a)
+{
+  if (((ptrdiff_t)a & (ALIGNMENT-1)) != 0)
+    abort();
+}
+
+int main()
+{
+  aligned a = 1;
+  check(&a);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr32000-2.c b/gcc/testsuite/gcc.target/i386/pr32000-2.c
new file mode 100644 (file)
index 0000000..7230258
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-require-effective-target ilp32 && dfp } */
+/* { dg-options "-O -msse2 -std=gnu99 -mpreferred-stack-boundary=2" } */
+
+#include "sse2-check.h"
+
+typedef struct { _Decimal128 f __attribute__((packed)); } packed;
+
+_Decimal128 __attribute__((noinline))
+foo (_Decimal128 a1, _Decimal128 a2, _Decimal128 a3, _Decimal128 a4,
+     _Decimal128 a5, _Decimal128 a6, _Decimal128 a7, _Decimal128 a8,
+     int b1, int b2, int b3, int b4, int b5, int b6, int b7, packed y)
+{
+  return y.f;
+}
+
+void
+sse2_test (void)
+{
+  packed x;
+  _Decimal128 y = -1;
+  x.f = y;
+  y = foo (0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, -1, x);
+  if (__builtin_memcmp (&y, &x.f, sizeof (y)))
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/stackalign/asm-1.c b/gcc/testsuite/gcc.target/i386/stackalign/asm-1.c
new file mode 100644 (file)
index 0000000..e4d4f20
--- /dev/null
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-mpreferred-stack-boundary=2" } */
+
+/* This case is to detect a compile time regression introduced in stack
+   branch development. */
+f(){asm("%0"::"r"(1.5F));}g(){asm("%0"::"r"(1.5));}
diff --git a/gcc/testsuite/gcc.target/i386/stackalign/return-1.c b/gcc/testsuite/gcc.target/i386/stackalign/return-1.c
new file mode 100644 (file)
index 0000000..c5b32e5
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-mpreferred-stack-boundary=2" } */
+
+/* This compile only test is to detect an assertion failure in stack branch
+   development.  */
+
+double
+foo (void)
+{
+}
diff --git a/gcc/testsuite/gcc.target/i386/stackalign/return-2.c b/gcc/testsuite/gcc.target/i386/stackalign/return-2.c
new file mode 100644 (file)
index 0000000..113e71b
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-mpreferred-stack-boundary=2" } */
+
+/* This compile only test is to detect an assertion failure in stack branch
+   development.  */
+void baz (void);
+                       
+double foo (void)
+{
+  baz ();
+  return;
+}
+
+double bar (void)
+{
+  baz ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/stackalign/return-3.c b/gcc/testsuite/gcc.target/i386/stackalign/return-3.c
new file mode 100644 (file)
index 0000000..d8ab69b
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 && dfp } */
+/* { dg-options "-msse -std=gnu99 -mpreferred-stack-boundary=2" } */
+
+/* This compile only test is to detect an assertion failure in stack branch
+   development.  */
+_Decimal128 test (void)
+{
+  return 1234123412341234.123412341234dl;
+}
diff --git a/gcc/testsuite/gcc.target/i386/stackalign/return-4.c b/gcc/testsuite/gcc.target/i386/stackalign/return-4.c
new file mode 100644 (file)
index 0000000..c66c369
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mpreferred-stack-boundary=4" } */
+/* { dg-final { scan-assembler-not "andl\[^\\n\]*-64,\[^\\n\]*sp" } } */
+
+/* This compile only test is to detect an assertion failure in stack branch
+   development.  */
+typedef int aligned __attribute__((aligned(64)));
+
+aligned
+foo (void) { }
diff --git a/gcc/testsuite/gcc.target/i386/stackalign/return-5.c b/gcc/testsuite/gcc.target/i386/stackalign/return-5.c
new file mode 100644 (file)
index 0000000..84531dd
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-mpreferred-stack-boundary=4" } */
+/* { dg-final { scan-assembler-not "andl\[^\\n\]*-64,\[^\\n\]*sp" } } */
+
+/* This compile only test is to detect an assertion failure in stack branch
+   development.  */
+struct bar
+{
+  int x;
+} __attribute__((aligned(64)));
+
+
+struct bar
+foo (void) { }
diff --git a/gcc/testsuite/gcc.target/i386/stackalign/return-6.c b/gcc/testsuite/gcc.target/i386/stackalign/return-6.c
new file mode 100644 (file)
index 0000000..ceadbad
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-mpreferred-stack-boundary=4" } */
+/* { dg-final { scan-assembler-not "andl\[^\\n\]*-64,\[^\\n\]*sp" } } */
+
+/* This compile only test is to detect an assertion failure in stack branch
+   development.  */
+struct bar
+{
+  int x __attribute__((aligned(64)));
+};
+
+
+struct bar
+foo (void) { }
diff --git a/gcc/testsuite/gcc.target/i386/stackalign/stackalign.exp b/gcc/testsuite/gcc.target/i386/stackalign/stackalign.exp
new file mode 100644 (file)
index 0000000..463ba61
--- /dev/null
@@ -0,0 +1,47 @@
+# Copyright (C) 2008
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Exit immediately if this isn't a x86 target.
+if { ![istarget i?86*-*-*] && ![istarget x86_64-*-*] } then {
+  return
+}
+
+load_lib gcc-dg.exp
+
+# Only run on targets which support automatic stack alignment.
+if { ![check_effective_target_automatic_stack_alignment] } then {
+    return
+}
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+    set DEFAULT_CFLAGS "-w"
+}
+
+# Initialize `dg'.
+dg-init
+
+set additional_flags "-mstackrealign"
+
+dg-runtest [lsort [glob $srcdir/$subdir/*.c]] $additional_flags $DEFAULT_CFLAGS
+
+set additional_flags "-mno-stackrealign"
+
+dg-runtest [lsort [glob $srcdir/$subdir/*.c]] $additional_flags $DEFAULT_CFLAGS
+
+dg-finish
index 5f42666..f56b3f4 100644 (file)
@@ -1841,10 +1841,6 @@ proc check_effective_target_unaligned_stack { } {
         verbose "check_effective_target_unaligned_stack: using cached result" 2
     } else {
         set et_unaligned_stack_saved 0
-        if { ( [istarget i?86-*-*] || [istarget x86_64-*-*] )
-          && (! [istarget *-*-darwin*] ) } {
-            set et_unaligned_stack_saved 1
-        }
     }
     verbose "check_effective_target_unaligned_stack: returning $et_unaligned_stack_saved" 2
     return $et_unaligned_stack_saved
@@ -2466,3 +2462,14 @@ proc check_effective_target_4byte_wchar_t { } {
        int dummy[sizeof (__WCHAR_TYPE__) >= 4 ? 1 : -1];
     }]
 }
+
+# Return 1 if the target supports automatic stack alignment.
+
+proc check_effective_target_automatic_stack_alignment  { } {
+    if { [istarget i?86*-*-*]
+        || [istarget x86_64-*-*] } then {
+       return 1
+    } else {
+       return 0
+    }
+}