+2016-06-08 Alan Lawrence <alan.lawrence@arm.com>
+
+ * gcc.target/aarch64/aapcs64/aapcs64.exp: Also execute rec_*.c
+ * gcc.target/aarch64/aapcs64/rec_align-5.c: New.
+ * gcc.target/aarch64/aapcs64/rec_align-6.c: New.
+ * gcc.target/aarch64/aapcs64/rec_align-7.c: New.
+ * gcc.target/aarch64/aapcs64/rec_align-8.c: New.
+ * gcc.target/aarch64/aapcs64/rec_align-9.c: New.
+ * gcc.target/aarch64/aapcs64/test_align-5.c: New.
+ * gcc.target/aarch64/aapcs64/test_align-6.c: New.
+ * gcc.target/aarch64/aapcs64/test_align-7.c: New.
+ * gcc.target/aarch64/aapcs64/test_align-8.c: New.
+ * gcc.target/aarch64/aapcs64/test_align-9.c: New.
+ * gcc.target/aarch64/aapcs64/rec_vaarg-1.c: New.
+ * gcc.target/aarch64/aapcs64/rec_vaarg-2.c: New.
+
2016-06-08 Richard Biener <rguenther@suse.de>
PR tree-optimization/68558
}
}
+# Test parameter receiving.
+set additional_flags_for_rec $additional_flags
+append additional_flags_for_rec " -fno-inline"
+foreach src [lsort [glob -nocomplain $srcdir/$subdir/rec_*.c]] {
+ if {[runtest_file_p $runtests $src]} {
+ c-torture-execute [list $src] \
+ $additional_flags_for_rec
+ }
+}
+
# Test unnamed argument retrieval via the va_arg macro.
foreach src [lsort [glob -nocomplain $srcdir/$subdir/va_arg-*.c]] {
if {[runtest_file_p $runtests $src]} {
--- /dev/null
+/* Test AAPCS layout (alignment) for callee. */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+extern void abort (void);
+
+typedef __attribute__ ((__aligned__ (8))) int alignedint;
+
+alignedint a = 11;
+alignedint b = 13;
+alignedint c = 17;
+alignedint d = 19;
+alignedint e = 23;
+alignedint f = 29;
+alignedint g = 31;
+alignedint h = 37;
+alignedint i = 41;
+alignedint j = 43;
+
+void
+test_passing_many_alignedint (alignedint x0, alignedint x1, alignedint x2,
+ alignedint x3, alignedint x4, alignedint x5,
+ alignedint x6, alignedint x7, alignedint stack,
+ alignedint stack8)
+{
+ if (x0 != a
+ || x1 != b
+ || x2 != c
+ || x3 != d
+ || x4 != e
+ || x5 != f
+ || x6 != g
+ || x7 != h
+ || stack != i
+ || stack8 !=j)
+ abort ();
+}
+
+int
+main (int argc, char **argv)
+{
+ test_passing_many_alignedint (a, b, c, d, e, f, g, h, i, j);
+ return 0;
+}
--- /dev/null
+/* Test AAPCS layout (alignment) for callee. */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+extern int memcmp (const void *s1, const void *s2, __SIZE_TYPE__ n);
+extern void abort (void);
+
+/* The underlying struct here has alignment 8. */
+typedef struct __attribute__ ((__aligned__ (16)))
+ {
+ long x;
+ long y;
+ } overaligned;
+
+overaligned a = { 2, 3 };
+overaligned b = { 5, 8 };
+overaligned c = { 13, 21 };
+
+void
+test_passing_overaligned_struct (int x0, overaligned x1, int x3, int x4,
+ overaligned x5, int x7, int stack,
+ overaligned stack8)
+{
+ if (x0 != 7 || x3 != 9 || x4 != 11 || x7 != 15 || stack != 10)
+ abort ();
+ if (memcmp ((void *) &x1, (void *)&a, sizeof (overaligned)))
+ abort ();
+ if (memcmp ((void *) &x5, (void *)&b, sizeof (overaligned)))
+ abort ();
+ if (memcmp ((void *)&stack8, (void *)&c, sizeof (overaligned)))
+ abort ();
+ long addr = ((long) &stack8) & 15;
+ if (addr != 0)
+ {
+ __builtin_printf ("Alignment was %d\n", addr);
+ abort ();
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ test_passing_overaligned_struct (7, a, 9, 11, b, 15, 10, c);
+ return 0;
+}
--- /dev/null
+/* Test AAPCS layout (alignment) for callee. */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+extern int memcmp (const void *s1, const void *s2, __SIZE_TYPE__ n);
+extern void abort (void);
+
+struct s
+ {
+ long x;
+ long y;
+ };
+
+/* This still has size 16, so is still passed by value. */
+typedef __attribute__ ((__aligned__ (32))) struct s overaligned;
+
+/* A few structs, at 32-byte-aligned memory locations. */
+overaligned a = { 2, 3 };
+overaligned b = { 5, 8 };
+overaligned c = { 13, 21 };
+
+void
+test_pass_by_value (int x0, overaligned x1, int x3, int x4, overaligned x5,
+ int x7, int stack, overaligned stack8)
+{
+ if (x0 != 7 || x3 != 9 || x4 != 11 || x7 != 15 || stack != 10)
+ abort ();
+ if (memcmp ((void *) &x1, (void *)&a, sizeof (overaligned)))
+ abort ();
+ if (memcmp ((void *) &x5, (void *)&b, sizeof (overaligned)))
+ abort ();
+ if (memcmp ((void *)&stack8, (void *)&c, sizeof (overaligned)))
+ abort ();
+ long addr = ((long) &stack8) & 15;
+ if (addr != 0)
+ {
+ __builtin_printf ("Alignment was %d\n", addr);
+ abort ();
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ test_pass_by_value (7, a, 9, 11, b, 15, 10, c);
+ return 0;
+}
--- /dev/null
+/* Test AAPCS layout (alignment) for callee. */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+extern int memcmp (const void *s1, const void *s2, __SIZE_TYPE__ n);
+extern void abort (void);
+
+/* The alignment also gives this size 32, so will be passed by reference. */
+typedef struct __attribute__ ((__aligned__ (32)))
+ {
+ long x;
+ long y;
+ } overaligned;
+
+overaligned a = { 2, 3 };
+
+void
+test_pass_by_ref (int x0, overaligned x1, int x2)
+{
+ if (x0 != 7 || x2 != 9)
+ abort ();
+ if (memcmp ((void *) &x1, (void *)&a, sizeof (overaligned)))
+ abort ();
+ long addr = ((long) &x1) & 31;
+ if (addr != 0)
+ {
+ __builtin_printf ("Alignment was %d\n", addr);
+ abort ();
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ test_pass_by_ref (7, a, 9);
+ return 0;
+}
--- /dev/null
+/* Test AAPCS layout (alignment) for callee. */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+extern int memcmp (const void *s1, const void *s2, __SIZE_TYPE__ n);
+extern void abort (void);
+
+struct s
+ {
+ /* This forces the alignment and size of the struct to 16. */
+ __attribute__ ((__aligned__ (16))) long x;
+ int y;
+ /* 4 bytes padding. */
+ };
+
+typedef struct s __attribute__ ((__aligned__ (8))) underaligned;
+
+underaligned a = { 1, 4 };
+underaligned b = { 9, 16 };
+underaligned c = { 25, 36 };
+
+void
+test_underaligned_struct (int x0, underaligned x2, int x4, underaligned x6,
+ int stack, underaligned stack16)
+{
+ if (x0 != 3 || x4 != 5 || stack != 7)
+ abort ();
+ if (memcmp ((void *) &x2, (void *)&a, sizeof (underaligned)))
+ abort ();
+ if (memcmp ((void *)&x6, (void *)&b, sizeof (underaligned)))
+ abort ();
+ if (memcmp ((void *)&stack16, (void *)&c, sizeof (underaligned)))
+ abort ();
+}
+
+int
+main (int argc, char **argv)
+{
+ test_underaligned_struct (3, a, 5, b, 7, c);
+ return 0;
+}
--- /dev/null
+/* Test AAPCS layout (alignment of varargs) for callee. */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#include <stdarg.h>
+
+extern void abort (void);
+
+typedef __attribute__ ((__aligned__ (16))) long alignedlong;
+
+void
+test_pass_overaligned_long_vaargs (long l, ...)
+{
+ va_list va;
+ va_start (va, l);
+ /* Arguments should be passed in the same registers as if they were ints. */
+ while (l-- > 0)
+ if (va_arg (va, long) != l)
+ abort ();
+ va_end (va);
+}
+
+int
+main (int argc, char **argv)
+{
+ alignedlong a = 9;
+ alignedlong b = 8;
+ alignedlong c = 7;
+ alignedlong d = 6;
+ alignedlong e = 5;
+ alignedlong f = 4;
+ alignedlong g = 3;
+ alignedlong h = 2;
+ alignedlong i = 1;
+ alignedlong j = 0;
+ test_pass_overaligned_long_vaargs (a, b, c, d, e, f, g, h, i, j);
+ return 0;
+}
--- /dev/null
+/* Test AAPCS layout (alignment of varargs) for callee. */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#include <stdarg.h>
+
+extern void abort (void);
+
+typedef __attribute__ ((__aligned__ (16))) int alignedint;
+
+void
+test_pass_overaligned_int_vaargs (int i, ...)
+{
+ va_list va;
+ va_start (va, i);
+ /* alignedint should be pulled out of regs/stack just like an int. */
+ while (i-- > 0)
+ if (va_arg (va, alignedint) != i)
+ abort ();
+ va_end (va);
+}
+
+int
+main (int argc, char **argv)
+{
+ test_pass_overaligned_int_vaargs (9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+ return 0;
+}
--- /dev/null
+/* Test AAPCS layout (alignment). */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "test_align-5.c"
+
+typedef __attribute__ ((__aligned__ (16))) long alignedint;
+
+alignedint a = 11;
+alignedint b = 13;
+alignedint c = 17;
+alignedint d = 19;
+alignedint e = 23;
+alignedint f = 29;
+alignedint g = 31;
+alignedint h = 37;
+alignedint i = 41;
+alignedint j = 43;
+
+#include "abitest.h"
+#else
+ ARG (alignedint, a, X0)
+ /* Attribute suggests R2, but we should use only natural alignment: */
+ ARG (alignedint, b, X1)
+ ARG (alignedint, c, X2)
+ ARG (alignedint, d, X3)
+ ARG (alignedint, e, X4)
+ ARG (alignedint, f, X5)
+ ARG (alignedint, g, X6)
+ ARG (alignedint, h, X7)
+ ARG (alignedint, i, STACK)
+ /* Attribute would suggest STACK + 16 but should be ignored: */
+ LAST_ARG (alignedint, j, STACK + 8)
+#endif
--- /dev/null
+/* Test AAPCS layout (alignment). */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "test_align-6.c"
+
+/* The underlying struct here has alignment 8. */
+typedef struct __attribute__ ((__aligned__ (16)))
+ {
+ long x;
+ long y;
+ } overaligned;
+
+/* A couple of instances, at 16-byte-aligned memory locations. */
+overaligned a = { 2, 3 };
+overaligned b = { 5, 8 };
+overaligned c = { 13, 21 };
+
+#include "abitest.h"
+#else
+ ARG (int, 7, W0)
+ /* Natural alignment should be 8. */
+ ARG (overaligned, a, X1)
+ ARG (int, 9, W3)
+ ARG (int, 11, W4)
+ ARG (overaligned, b, X5)
+ ARG (int, 15, W7)
+#ifndef __AAPCS64_BIG_ENDIAN__
+ ARG (int, 10, STACK)
+#else
+ ARG (int, 10, STACK + 4)
+#endif
+ /* Natural alignment should be 8. */
+ LAST_ARG (overaligned, c, STACK + 8)
+#endif
--- /dev/null
+/* Test AAPCS layout (alignment). */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "test_align-7.c"
+
+struct s
+ {
+ long x;
+ long y;
+ };
+
+/* This still has size 16, so is still passed by value. */
+typedef __attribute__ ((__aligned__ (32))) struct s overaligned;
+
+/* A few structs, at 32-byte-aligned memory locations. */
+overaligned a = { 2, 3 };
+overaligned b = { 5, 8 };
+overaligned c = { 13, 21 };
+
+#include "abitest.h"
+#else
+ ARG (int, 7, W0)
+ /* Alignment should be 8. */
+ ARG (overaligned, a, X1)
+ ARG (int, 9, W3)
+ ARG (int, 11, W4)
+ ARG (overaligned, b, X5)
+ ARG (int, 15, W7)
+#ifndef __AAPCS64_BIG_ENDIAN__
+ ARG (int, 10, STACK)
+#else
+ ARG (int, 10, STACK + 4)
+#endif
+ /* Natural alignment should be 8. */
+ LAST_ARG (overaligned, c, STACK + 8)
+#endif
--- /dev/null
+/* Test AAPCS layout (alignment). */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "test_align-8.c"
+
+/* The alignment also gives this size 32, so will be passed by reference. */
+typedef struct __attribute__ ((__aligned__ (32)))
+ {
+ long x;
+ long y;
+ } overaligned;
+
+#define EXPECTED_STRUCT_SIZE 32
+extern void link_failure (void);
+int
+foo ()
+{
+ /* Optimization gets rid of this before linking. */
+ if (sizeof (overaligned) != EXPECTED_STRUCT_SIZE)
+ link_failure ();
+}
+
+overaligned a = { 2, 3 };
+
+#include "abitest.h"
+#else
+ ARG (int, 7, W0)
+ /* Alignment should be 8. */
+ PTR (overaligned, a, X1)
+ LAST_ARG (int, 9, W2)
+#endif
--- /dev/null
+/* Test AAPCS layout (alignment). */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "test_align-9.c"
+
+struct s
+ {
+ /* This forces the alignment and size of the struct to 16. */
+ __attribute__ ((__aligned__ (16))) long x;
+ int y;
+ /* 4 bytes padding. */
+ };
+
+typedef struct s __attribute__ ((__aligned__ (8))) underaligned;
+
+#define EXPECTED_STRUCT_SIZE 16
+extern void link_failure (void);
+int
+foo ()
+{
+ /* Optimization gets rid of this before linking. */
+ if (sizeof (struct s) != EXPECTED_STRUCT_SIZE)
+ link_failure ();
+}
+
+underaligned a = { 1, 4 };
+underaligned b = { 9, 16 };
+underaligned c = { 25, 36 };
+
+#include "abitest.h"
+#else
+ ARG (int, 3, W0)
+ /* Object alignment is 16, so skip X1. */
+ ARG (underaligned, a, X2)
+ ARG (int, 5, W4)
+ /* Object alignment is 16, so skip X5. */
+ ARG (underaligned, b, X6)
+#ifndef __AAPCS64_BIG_ENDIAN__
+ ARG (int, 7, STACK)
+#else
+ ARG (int, 7, STACK + 4)
+#endif
+ /* Natural alignment should be 16. */
+ LAST_ARG (underaligned, c, STACK + 16)
+#endif