aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f')
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/abi-avx512f.exp61
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/args.h184
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/asm-support.S98
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/avx512f-check.h41
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/test_m512_returning.c32
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/test_passing_m512.c168
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/test_passing_structs.c65
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/test_passing_unions.c180
8 files changed, 829 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/abi-avx512f.exp b/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/abi-avx512f.exp
new file mode 100644
index 000000000..cef6fa141
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/abi-avx512f.exp
@@ -0,0 +1,61 @@
+# Copyright (C) 2009-2014 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/>.
+
+# The x86-64 AVX512F ABI testsuite needs one additional assembler file for most
+# testcases. For simplicity we will just link it into each test.
+
+load_lib c-torture.exp
+load_lib target-supports.exp
+load_lib torture-options.exp
+
+if { (![istarget x86_64-*-*] && ![istarget i?86-*-*])
+ || ![is-effective-target lp64]
+ || ![is-effective-target avx512f] } then {
+ return
+}
+
+
+# If the linker used understands -M <mapfile>, pass it to clear hardware
+# capabilities set by the Sun assembler.
+set flags ""
+set clearcap_ldflags "-Wl,-M,$srcdir/gcc.target/i386/clearcap.map"
+
+if [check_no_compiler_messages mapfile executable {
+ int main (void) { return 0; }
+ } $clearcap_ldflags ] {
+ set flags $clearcap_ldflags
+}
+
+torture-init
+set-torture-options $C_TORTURE_OPTIONS
+set additional_flags "-W -Wall -mavx512f $flags"
+
+foreach src [lsort [glob -nocomplain $srcdir/$subdir/test_*.c]] {
+ if {[runtest_file_p $runtests $src]} {
+ if { ([istarget *-*-darwin*]) } then {
+ # FIXME: Darwin isn't tested.
+ c-torture-execute [list $src \
+ $srcdir/$subdir/asm-support-darwin.s] \
+ $additional_flags
+ } else {
+ c-torture-execute [list $src \
+ $srcdir/$subdir/asm-support.S] \
+ $additional_flags
+ }
+ }
+}
+
+torture-finish
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/args.h b/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/args.h
new file mode 100644
index 000000000..5e3b265ec
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/args.h
@@ -0,0 +1,184 @@
+#ifndef INCLUDED_ARGS_H
+#define INCLUDED_ARGS_H
+
+#include <immintrin.h>
+#include <string.h>
+
+/* Assertion macro. */
+#define assert(test) if (!(test)) abort()
+
+#ifdef __GNUC__
+#define ATTRIBUTE_UNUSED __attribute__((__unused__))
+#else
+#define ATTRIBUTE_UNUSED
+#endif
+
+/* This defines the calling sequences for integers and floats. */
+#define I0 rdi
+#define I1 rsi
+#define I2 rdx
+#define I3 rcx
+#define I4 r8
+#define I5 r9
+#define F0 zmm0
+#define F1 zmm1
+#define F2 zmm2
+#define F3 zmm3
+#define F4 zmm4
+#define F5 zmm5
+#define F6 zmm6
+#define F7 zmm7
+
+typedef union {
+ float _float[16];
+ double _double[8];
+ long _long[8];
+ int _int[16];
+ unsigned long _ulong[8];
+ __m64 _m64[8];
+ __m128 _m128[4];
+ __m256 _m256[2];
+ __m512 _m512[1];
+} ZMM_T;
+
+typedef union {
+ float _float;
+ double _double;
+ long double _ldouble;
+ unsigned long _ulong[2];
+} X87_T;
+extern void (*callthis)(void);
+extern unsigned long rax,rbx,rcx,rdx,rsi,rdi,rsp,rbp,r8,r9,r10,r11,r12,r13,r14,r15;
+ZMM_T zmm_regs[32];
+X87_T x87_regs[8];
+extern volatile unsigned long volatile_var;
+extern void snapshot (void);
+extern void snapshot_ret (void);
+#define WRAP_CALL(N) \
+ (callthis = (void (*)()) (N), (typeof (&N)) snapshot)
+#define WRAP_RET(N) \
+ (callthis = (void (*)()) (N), (typeof (&N)) snapshot_ret)
+
+/* Clear all integer registers. */
+#define clear_int_hardware_registers \
+ asm __volatile__ ("xor %%rax, %%rax\n\t" \
+ "xor %%rbx, %%rbx\n\t" \
+ "xor %%rcx, %%rcx\n\t" \
+ "xor %%rdx, %%rdx\n\t" \
+ "xor %%rsi, %%rsi\n\t" \
+ "xor %%rdi, %%rdi\n\t" \
+ "xor %%r8, %%r8\n\t" \
+ "xor %%r9, %%r9\n\t" \
+ "xor %%r10, %%r10\n\t" \
+ "xor %%r11, %%r11\n\t" \
+ "xor %%r12, %%r12\n\t" \
+ "xor %%r13, %%r13\n\t" \
+ "xor %%r14, %%r14\n\t" \
+ "xor %%r15, %%r15\n\t" \
+ ::: "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", \
+ "r9", "r10", "r11", "r12", "r13", "r14", "r15");
+
+/* This is the list of registers available for passing arguments. Not all of
+ these are used or even really available. */
+struct IntegerRegisters
+{
+ unsigned long rax, rbx, rcx, rdx, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15;
+};
+struct FloatRegisters
+{
+ double mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7;
+ long double st0, st1, st2, st3, st4, st5, st6, st7;
+ ZMM_T zmm0, zmm1, zmm2, zmm3, zmm4, zmm5, zmm6, zmm7, zmm8, zmm9,
+ zmm10, zmm11, zmm12, zmm13, zmm14, zmm15, zmm16, zmm17, zmm18,
+ zmm19, zmm20, zmm21, zmm22, zmm23, zmm24, zmm25, zmm26, zmm27,
+ zmm28, zmm29, zmm30, zmm31;
+};
+
+/* Implemented in scalarargs.c */
+extern struct IntegerRegisters iregs;
+extern struct FloatRegisters fregs;
+extern unsigned int num_iregs, num_fregs;
+
+#define check_int_arguments do { \
+ assert (num_iregs <= 0 || iregs.I0 == I0); \
+ assert (num_iregs <= 1 || iregs.I1 == I1); \
+ assert (num_iregs <= 2 || iregs.I2 == I2); \
+ assert (num_iregs <= 3 || iregs.I3 == I3); \
+ assert (num_iregs <= 4 || iregs.I4 == I4); \
+ assert (num_iregs <= 5 || iregs.I5 == I5); \
+ } while (0)
+
+#define check_char_arguments check_int_arguments
+#define check_short_arguments check_int_arguments
+#define check_long_arguments check_int_arguments
+
+/* Clear register struct. */
+#define clear_struct_registers \
+ rax = rbx = rcx = rdx = rdi = rsi = rbp = rsp \
+ = r8 = r9 = r10 = r11 = r12 = r13 = r14 = r15 = 0; \
+ memset (&iregs, 0, sizeof (iregs)); \
+ memset (&fregs, 0, sizeof (fregs)); \
+ memset (zmm_regs, 0, sizeof (zmm_regs)); \
+ memset (x87_regs, 0, sizeof (x87_regs));
+
+/* Clear both hardware and register structs for integers. */
+#define clear_int_registers \
+ clear_struct_registers \
+ clear_int_hardware_registers
+
+/* TODO: Do the checking. */
+#define check_f_arguments(T) do { \
+ assert (num_fregs <= 0 || fregs.zmm0._ ## T [0] == zmm_regs[0]._ ## T [0]); \
+ assert (num_fregs <= 1 || fregs.zmm1._ ## T [0] == zmm_regs[1]._ ## T [0]); \
+ assert (num_fregs <= 2 || fregs.zmm2._ ## T [0] == zmm_regs[2]._ ## T [0]); \
+ assert (num_fregs <= 3 || fregs.zmm3._ ## T [0] == zmm_regs[3]._ ## T [0]); \
+ assert (num_fregs <= 4 || fregs.zmm4._ ## T [0] == zmm_regs[4]._ ## T [0]); \
+ assert (num_fregs <= 5 || fregs.zmm5._ ## T [0] == zmm_regs[5]._ ## T [0]); \
+ assert (num_fregs <= 6 || fregs.zmm6._ ## T [0] == zmm_regs[6]._ ## T [0]); \
+ assert (num_fregs <= 7 || fregs.zmm7._ ## T [0] == zmm_regs[7]._ ## T [0]); \
+ } while (0)
+
+#define check_float_arguments check_f_arguments(float)
+#define check_double_arguments check_f_arguments(double)
+
+#define check_vector_arguments(T,O) do { \
+ assert (num_fregs <= 0 \
+ || memcmp (((char *) &fregs.zmm0) + (O), \
+ &zmm_regs[0], \
+ sizeof (__ ## T) - (O)) == 0); \
+ assert (num_fregs <= 1 \
+ || memcmp (((char *) &fregs.zmm1) + (O), \
+ &zmm_regs[1], \
+ sizeof (__ ## T) - (O)) == 0); \
+ assert (num_fregs <= 2 \
+ || memcmp (((char *) &fregs.zmm2) + (O), \
+ &zmm_regs[2], \
+ sizeof (__ ## T) - (O)) == 0); \
+ assert (num_fregs <= 3 \
+ || memcmp (((char *) &fregs.zmm3) + (O), \
+ &zmm_regs[3], \
+ sizeof (__ ## T) - (O)) == 0); \
+ assert (num_fregs <= 4 \
+ || memcmp (((char *) &fregs.zmm4) + (O), \
+ &zmm_regs[4], \
+ sizeof (__ ## T) - (O)) == 0); \
+ assert (num_fregs <= 5 \
+ || memcmp (((char *) &fregs.zmm5) + (O), \
+ &zmm_regs[5], \
+ sizeof (__ ## T) - (O)) == 0); \
+ assert (num_fregs <= 6 \
+ || memcmp (((char *) &fregs.zmm6) + (O), \
+ &zmm_regs[6], \
+ sizeof (__ ## T) - (O)) == 0); \
+ assert (num_fregs <= 7 \
+ || memcmp (((char *) &fregs.zmm7) + (O), \
+ &zmm_regs[7], \
+ sizeof (__ ## T) - (O)) == 0); \
+ } while (0)
+
+#define check_m64_arguments check_vector_arguments(m64, 0)
+#define check_m128_arguments check_vector_arguments(m128, 0)
+#define check_m256_arguments check_vector_arguments(m256, 0)
+#define check_m512_arguments check_vector_arguments(m512, 0)
+
+#endif /* INCLUDED_ARGS_H */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/asm-support.S b/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/asm-support.S
new file mode 100644
index 000000000..e0309aeac
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/asm-support.S
@@ -0,0 +1,98 @@
+ .file "snapshot.S"
+ .text
+ .p2align 4,,15
+.globl snapshot
+ .type snapshot, @function
+snapshot:
+.LFB3:
+ movq %rax, rax(%rip)
+ movq %rbx, rbx(%rip)
+ movq %rcx, rcx(%rip)
+ movq %rdx, rdx(%rip)
+ movq %rdi, rdi(%rip)
+ movq %rsi, rsi(%rip)
+ movq %rbp, rbp(%rip)
+ movq %rsp, rsp(%rip)
+ movq %r8, r8(%rip)
+ movq %r9, r9(%rip)
+ movq %r10, r10(%rip)
+ movq %r11, r11(%rip)
+ movq %r12, r12(%rip)
+ movq %r13, r13(%rip)
+ movq %r14, r14(%rip)
+ movq %r15, r15(%rip)
+ vmovdqu32 %zmm0, zmm_regs+0(%rip)
+ vmovdqu32 %zmm1, zmm_regs+64(%rip)
+ vmovdqu32 %zmm2, zmm_regs+128(%rip)
+ vmovdqu32 %zmm3, zmm_regs+192(%rip)
+ vmovdqu32 %zmm4, zmm_regs+256(%rip)
+ vmovdqu32 %zmm5, zmm_regs+320(%rip)
+ vmovdqu32 %zmm6, zmm_regs+384(%rip)
+ vmovdqu32 %zmm7, zmm_regs+448(%rip)
+ vmovdqu32 %zmm8, zmm_regs+512(%rip)
+ vmovdqu32 %zmm9, zmm_regs+576(%rip)
+ vmovdqu32 %zmm10, zmm_regs+640(%rip)
+ vmovdqu32 %zmm11, zmm_regs+704(%rip)
+ vmovdqu32 %zmm12, zmm_regs+768(%rip)
+ vmovdqu32 %zmm13, zmm_regs+832(%rip)
+ vmovdqu32 %zmm14, zmm_regs+896(%rip)
+ vmovdqu32 %zmm15, zmm_regs+960(%rip)
+ vmovdqu32 %zmm16, zmm_regs+1024(%rip)
+ vmovdqu32 %zmm17, zmm_regs+1088(%rip)
+ vmovdqu32 %zmm18, zmm_regs+1152(%rip)
+ vmovdqu32 %zmm19, zmm_regs+1216(%rip)
+ vmovdqu32 %zmm20, zmm_regs+1280(%rip)
+ vmovdqu32 %zmm21, zmm_regs+1344(%rip)
+ vmovdqu32 %zmm22, zmm_regs+1408(%rip)
+ vmovdqu32 %zmm23, zmm_regs+1472(%rip)
+ vmovdqu32 %zmm24, zmm_regs+1536(%rip)
+ vmovdqu32 %zmm25, zmm_regs+1600(%rip)
+ vmovdqu32 %zmm26, zmm_regs+1664(%rip)
+ vmovdqu32 %zmm27, zmm_regs+1728(%rip)
+ vmovdqu32 %zmm28, zmm_regs+1792(%rip)
+ vmovdqu32 %zmm29, zmm_regs+1856(%rip)
+ vmovdqu32 %zmm30, zmm_regs+1920(%rip)
+ vmovdqu32 %zmm31, zmm_regs+1984(%rip)
+ jmp *callthis(%rip)
+.LFE3:
+ .size snapshot, .-snapshot
+
+ .p2align 4,,15
+.globl snapshot_ret
+ .type snapshot_ret, @function
+snapshot_ret:
+ movq %rdi, rdi(%rip)
+ subq $8, %rsp
+ call *callthis(%rip)
+ addq $8, %rsp
+ movq %rax, rax(%rip)
+ movq %rdx, rdx(%rip)
+ vmovdqu32 %zmm0, zmm_regs+0(%rip)
+ vmovdqu32 %zmm1, zmm_regs+64(%rip)
+ fstpt x87_regs(%rip)
+ fstpt x87_regs+16(%rip)
+ fldt x87_regs+16(%rip)
+ fldt x87_regs(%rip)
+ ret
+ .size snapshot_ret, .-snapshot_ret
+
+ .comm callthis,8,8
+ .comm rax,8,8
+ .comm rbx,8,8
+ .comm rcx,8,8
+ .comm rdx,8,8
+ .comm rsi,8,8
+ .comm rdi,8,8
+ .comm rsp,8,8
+ .comm rbp,8,8
+ .comm r8,8,8
+ .comm r9,8,8
+ .comm r10,8,8
+ .comm r11,8,8
+ .comm r12,8,8
+ .comm r13,8,8
+ .comm r14,8,8
+ .comm r15,8,8
+ .comm zmm_regs,2048,64
+ .comm x87_regs,128,32
+ .comm volatile_var,8,8
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/avx512f-check.h b/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/avx512f-check.h
new file mode 100644
index 000000000..25ce544c4
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/avx512f-check.h
@@ -0,0 +1,41 @@
+#include <stdlib.h>
+#include "cpuid.h"
+
+static void avx512f_test (void);
+
+int
+main ()
+{
+ unsigned int eax, ebx, ecx, edx;
+
+ if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+ return 0;
+
+#define DEBUG
+ /* Run AVX test only if host has AVX support. */
+ if ((ecx & bit_OSXSAVE) == bit_OSXSAVE)
+ {
+ if (__get_cpuid_max (0, NULL) < 7)
+ return 0;
+
+ __cpuid_count (7, 0, eax, ebx, ecx, edx);
+
+ if ((ebx & bit_AVX512F) == bit_AVX512F)
+ {
+ avx512f_test ();
+#ifdef DEBUG
+ printf ("PASSED\n");
+#endif
+ }
+#ifdef DEBUG
+ else
+ printf ("SKIPPED\n");
+#endif
+ }
+#ifdef DEBUG
+ else
+ printf ("SKIPPED\n");
+#endif
+
+ return 0;
+}
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/test_m512_returning.c b/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/test_m512_returning.c
new file mode 100644
index 000000000..ee126b551
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/test_m512_returning.c
@@ -0,0 +1,32 @@
+#include <stdio.h>
+#include "avx512f-check.h"
+#include "args.h"
+
+struct IntegerRegisters iregs;
+struct FloatRegisters fregs;
+unsigned int num_iregs, num_fregs;
+
+__m512
+fun_test_returning___m512 (void)
+{
+ volatile_var++;
+ return (__m512){73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+}
+
+__m512 test_512;
+
+static void
+avx512f_test (void)
+{
+ unsigned failed = 0;
+ ZMM_T zmmt1, zmmt2;
+
+ clear_struct_registers;
+ test_512 = (__m512){73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ zmmt1._m512[0] = test_512;
+ zmmt2._m512[0] = WRAP_RET (fun_test_returning___m512)();
+ if (memcmp (&zmmt1, &zmmt2, sizeof (zmmt2)) != 0)
+ printf ("fail m512\n"), failed++;
+ if (failed)
+ abort ();
+}
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/test_passing_m512.c b/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/test_passing_m512.c
new file mode 100644
index 000000000..ead9c6797
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/test_passing_m512.c
@@ -0,0 +1,168 @@
+#include <stdio.h>
+#include "avx512f-check.h"
+#include "args.h"
+
+struct IntegerRegisters iregs;
+struct FloatRegisters fregs;
+unsigned int num_iregs, num_fregs;
+
+/* This struct holds values for argument checking. */
+struct
+{
+ ZMM_T i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23;
+} values;
+
+char *pass;
+int failed = 0;
+
+#undef assert
+#define assert(c) do { \
+ if (!(c)) {failed++; printf ("failed %s\n", pass); } \
+} while (0)
+
+#define compare(X1,X2,T) do { \
+ assert (memcmp (&X1, &X2, sizeof (T)) == 0); \
+} while (0)
+
+fun_check_passing_m512_8_values (__m512 i0 ATTRIBUTE_UNUSED, __m512 i1 ATTRIBUTE_UNUSED, __m512 i2 ATTRIBUTE_UNUSED, __m512 i3 ATTRIBUTE_UNUSED, __m512 i4 ATTRIBUTE_UNUSED, __m512 i5 ATTRIBUTE_UNUSED, __m512 i6 ATTRIBUTE_UNUSED, __m512 i7 ATTRIBUTE_UNUSED)
+{
+ /* Check argument values. */
+ compare (values.i0, i0, __m512);
+ compare (values.i1, i1, __m512);
+ compare (values.i2, i2, __m512);
+ compare (values.i3, i3, __m512);
+ compare (values.i4, i4, __m512);
+ compare (values.i5, i5, __m512);
+ compare (values.i6, i6, __m512);
+ compare (values.i7, i7, __m512);
+}
+
+void
+fun_check_passing_m512_8_regs (__m512 i0 ATTRIBUTE_UNUSED, __m512 i1 ATTRIBUTE_UNUSED, __m512 i2 ATTRIBUTE_UNUSED, __m512 i3 ATTRIBUTE_UNUSED, __m512 i4 ATTRIBUTE_UNUSED, __m512 i5 ATTRIBUTE_UNUSED, __m512 i6 ATTRIBUTE_UNUSED, __m512 i7 ATTRIBUTE_UNUSED)
+{
+ /* Check register contents. */
+ check_m512_arguments;
+}
+
+void
+fun_check_passing_m512_20_values (__m512 i0 ATTRIBUTE_UNUSED, __m512 i1 ATTRIBUTE_UNUSED, __m512 i2 ATTRIBUTE_UNUSED, __m512 i3 ATTRIBUTE_UNUSED, __m512 i4 ATTRIBUTE_UNUSED, __m512 i5 ATTRIBUTE_UNUSED, __m512 i6 ATTRIBUTE_UNUSED, __m512 i7 ATTRIBUTE_UNUSED, __m512 i8 ATTRIBUTE_UNUSED, __m512 i9 ATTRIBUTE_UNUSED, __m512 i10 ATTRIBUTE_UNUSED, __m512 i11 ATTRIBUTE_UNUSED, __m512 i12 ATTRIBUTE_UNUSED, __m512 i13 ATTRIBUTE_UNUSED, __m512 i14 ATTRIBUTE_UNUSED, __m512 i15 ATTRIBUTE_UNUSED, __m512 i16 ATTRIBUTE_UNUSED, __m512 i17 ATTRIBUTE_UNUSED, __m512 i18 ATTRIBUTE_UNUSED, __m512 i19 ATTRIBUTE_UNUSED)
+{
+ /* Check argument values. */
+ compare (values.i0, i0, __m512);
+ compare (values.i1, i1, __m512);
+ compare (values.i2, i2, __m512);
+ compare (values.i3, i3, __m512);
+ compare (values.i4, i4, __m512);
+ compare (values.i5, i5, __m512);
+ compare (values.i6, i6, __m512);
+ compare (values.i7, i7, __m512);
+ compare (values.i8, i8, __m512);
+ compare (values.i9, i9, __m512);
+ compare (values.i10, i10, __m512);
+ compare (values.i11, i11, __m512);
+ compare (values.i12, i12, __m512);
+ compare (values.i13, i13, __m512);
+ compare (values.i14, i14, __m512);
+ compare (values.i15, i15, __m512);
+ compare (values.i16, i16, __m512);
+ compare (values.i17, i17, __m512);
+ compare (values.i18, i18, __m512);
+ compare (values.i19, i19, __m512);
+}
+
+void
+fun_check_passing_m512_20_regs (__m512 i0 ATTRIBUTE_UNUSED, __m512 i1 ATTRIBUTE_UNUSED, __m512 i2 ATTRIBUTE_UNUSED, __m512 i3 ATTRIBUTE_UNUSED, __m512 i4 ATTRIBUTE_UNUSED, __m512 i5 ATTRIBUTE_UNUSED, __m512 i6 ATTRIBUTE_UNUSED, __m512 i7 ATTRIBUTE_UNUSED, __m512 i8 ATTRIBUTE_UNUSED, __m512 i9 ATTRIBUTE_UNUSED, __m512 i10 ATTRIBUTE_UNUSED, __m512 i11 ATTRIBUTE_UNUSED, __m512 i12 ATTRIBUTE_UNUSED, __m512 i13 ATTRIBUTE_UNUSED, __m512 i14 ATTRIBUTE_UNUSED, __m512 i15 ATTRIBUTE_UNUSED, __m512 i16 ATTRIBUTE_UNUSED, __m512 i17 ATTRIBUTE_UNUSED, __m512 i18 ATTRIBUTE_UNUSED, __m512 i19 ATTRIBUTE_UNUSED)
+{
+ /* Check register contents. */
+ check_m512_arguments;
+}
+
+
+#define def_check_passing8(_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _func1, _func2, TYPE) \
+ values.i0.TYPE[0] = _i0; \
+ values.i1.TYPE[0] = _i1; \
+ values.i2.TYPE[0] = _i2; \
+ values.i3.TYPE[0] = _i3; \
+ values.i4.TYPE[0] = _i4; \
+ values.i5.TYPE[0] = _i5; \
+ values.i6.TYPE[0] = _i6; \
+ values.i7.TYPE[0] = _i7; \
+ WRAP_CALL(_func1) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7); \
+ \
+ clear_struct_registers; \
+ fregs.F0.TYPE[0] = _i0; \
+ fregs.F1.TYPE[0] = _i1; \
+ fregs.F2.TYPE[0] = _i2; \
+ fregs.F3.TYPE[0] = _i3; \
+ fregs.F4.TYPE[0] = _i4; \
+ fregs.F5.TYPE[0] = _i5; \
+ fregs.F6.TYPE[0] = _i6; \
+ fregs.F7.TYPE[0] = _i7; \
+ num_fregs = 8; \
+ WRAP_CALL(_func2) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7);
+
+#define def_check_passing20(_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9, _i10, _i11, _i12, _i13, _i14, _i15, _i16, _i17, _i18, _i19, _func1, _func2, TYPE) \
+ values.i0.TYPE[0] = _i0; \
+ values.i1.TYPE[0] = _i1; \
+ values.i2.TYPE[0] = _i2; \
+ values.i3.TYPE[0] = _i3; \
+ values.i4.TYPE[0] = _i4; \
+ values.i5.TYPE[0] = _i5; \
+ values.i6.TYPE[0] = _i6; \
+ values.i7.TYPE[0] = _i7; \
+ values.i8.TYPE[0] = _i8; \
+ values.i9.TYPE[0] = _i9; \
+ values.i10.TYPE[0] = _i10; \
+ values.i11.TYPE[0] = _i11; \
+ values.i12.TYPE[0] = _i12; \
+ values.i13.TYPE[0] = _i13; \
+ values.i14.TYPE[0] = _i14; \
+ values.i15.TYPE[0] = _i15; \
+ values.i16.TYPE[0] = _i16; \
+ values.i17.TYPE[0] = _i17; \
+ values.i18.TYPE[0] = _i18; \
+ values.i19.TYPE[0] = _i19; \
+ WRAP_CALL(_func1) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9, _i10, _i11, _i12, _i13, _i14, _i15, _i16, _i17, _i18, _i19); \
+ \
+ clear_struct_registers; \
+ fregs.F0.TYPE[0] = _i0; \
+ fregs.F1.TYPE[0] = _i1; \
+ fregs.F2.TYPE[0] = _i2; \
+ fregs.F3.TYPE[0] = _i3; \
+ fregs.F4.TYPE[0] = _i4; \
+ fregs.F5.TYPE[0] = _i5; \
+ fregs.F6.TYPE[0] = _i6; \
+ fregs.F7.TYPE[0] = _i7; \
+ num_fregs = 8; \
+ WRAP_CALL(_func2) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9, _i10, _i11, _i12, _i13, _i14, _i15, _i16, _i17, _i18, _i19);
+
+void
+test_m512_on_stack ()
+{
+ __m512 x[8];
+ int i;
+ for (i = 0; i < 8; i++)
+ x[i] = (__m512){32+i, 0, 0, 0, 0, 0, 0, 0};
+ pass = "m512-8";
+ def_check_passing8(x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], fun_check_passing_m512_8_values, fun_check_passing_m512_8_regs, _m512);
+}
+
+void
+test_too_many_m512 ()
+{
+ __m512 x[20];
+ int i;
+ for (i = 0; i < 20; i++)
+ x[i] = (__m512){32+i, 0, 0, 0, 0, 0, 0, 0};
+ pass = "m512-20";
+ def_check_passing20(x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15], x[16], x[17], x[18], x[19], fun_check_passing_m512_20_values, fun_check_passing_m512_20_regs, _m512);
+}
+
+static void
+avx512f_test (void)
+{
+ test_m512_on_stack ();
+ test_too_many_m512 ();
+ if (failed)
+ abort ();
+}
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/test_passing_structs.c b/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/test_passing_structs.c
new file mode 100644
index 000000000..8daa676e7
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/test_passing_structs.c
@@ -0,0 +1,65 @@
+#include "avx512f-check.h"
+#include "args.h"
+
+struct IntegerRegisters iregs;
+struct FloatRegisters fregs;
+unsigned int num_iregs, num_fregs;
+
+struct m512_struct
+{
+ __m512 x;
+};
+
+struct m512_2_struct
+{
+ __m512 x1, x2;
+};
+
+/* Check that the struct is passed as the individual members in fregs. */
+void
+check_struct_passing1 (struct m512_struct ms1 ATTRIBUTE_UNUSED,
+ struct m512_struct ms2 ATTRIBUTE_UNUSED,
+ struct m512_struct ms3 ATTRIBUTE_UNUSED,
+ struct m512_struct ms4 ATTRIBUTE_UNUSED,
+ struct m512_struct ms5 ATTRIBUTE_UNUSED,
+ struct m512_struct ms6 ATTRIBUTE_UNUSED,
+ struct m512_struct ms7 ATTRIBUTE_UNUSED,
+ struct m512_struct ms8 ATTRIBUTE_UNUSED)
+{
+ /* Check register contents. */
+ check_m512_arguments;
+}
+
+void
+check_struct_passing2 (struct m512_2_struct ms ATTRIBUTE_UNUSED)
+{
+ /* Check the passing on the stack by comparing the address of the
+ stack elements to the expected place on the stack. */
+ assert ((unsigned long)&ms.x1 == rsp+8);
+ assert ((unsigned long)&ms.x2 == rsp+72);
+}
+
+static void
+avx512f_test (void)
+{
+ struct m512_struct m512s [8];
+ struct m512_2_struct m512_2s = {
+ { 48.394, 39.3, -397.9, 3484.9, -8.394, -93.3, 7.9, 84.94,
+ 48.3941, 39.31, -397.91, 3484.91, -8.3941, -93.31, 7.91, 84.941 },
+ { -8.394, -3.3, -39.9, 34.9, 7.9, 84.94, -48.394, 39.3,
+ -8.3942, -3.32, -39.92, 34.92, 7.92, 84.942, -48.3942, 39.32 }
+ };
+ int i;
+
+ for (i = 0; i < 8; i++)
+ m512s[i].x = (__m512){32+i, 0, i, 0, -i, 0, i - 12, i + 8,
+ 32+i, 0, i, 0, -i, 0, i - 12, i + 8};
+
+ clear_struct_registers;
+ for (i = 0; i < 8; i++)
+ (&fregs.zmm0)[i]._m512[0] = m512s[i].x;
+ num_fregs = 8;
+ WRAP_CALL (check_struct_passing1)(m512s[0], m512s[1], m512s[2], m512s[3],
+ m512s[4], m512s[5], m512s[6], m512s[7]);
+ WRAP_CALL (check_struct_passing2)(m512_2s);
+}
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/test_passing_unions.c b/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/test_passing_unions.c
new file mode 100644
index 000000000..370d15b62
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/x86_64/abi/avx512f/test_passing_unions.c
@@ -0,0 +1,180 @@
+#include "avx512f-check.h"
+#include "args.h"
+
+struct IntegerRegisters iregs;
+struct FloatRegisters fregs;
+unsigned int num_iregs, num_fregs;
+
+union un1
+{
+ __m512 x;
+ float f;
+};
+
+union un2
+{
+ __m512 x;
+ double d;
+};
+
+union un3
+{
+ __m512 x;
+ __m128 v;
+};
+
+union un4
+{
+ __m512 x;
+ long double ld;
+};
+
+union un5
+{
+ __m512 x;
+ int i;
+};
+
+union un6
+{
+ __m512 x;
+ __m256 v;
+};
+
+
+void
+check_union_passing1(union un1 u1 ATTRIBUTE_UNUSED,
+ union un1 u2 ATTRIBUTE_UNUSED,
+ union un1 u3 ATTRIBUTE_UNUSED,
+ union un1 u4 ATTRIBUTE_UNUSED,
+ union un1 u5 ATTRIBUTE_UNUSED,
+ union un1 u6 ATTRIBUTE_UNUSED,
+ union un1 u7 ATTRIBUTE_UNUSED,
+ union un1 u8 ATTRIBUTE_UNUSED)
+{
+ /* Check register contents. */
+ check_m512_arguments;
+}
+
+void
+check_union_passing2(union un2 u1 ATTRIBUTE_UNUSED,
+ union un2 u2 ATTRIBUTE_UNUSED,
+ union un2 u3 ATTRIBUTE_UNUSED,
+ union un2 u4 ATTRIBUTE_UNUSED,
+ union un2 u5 ATTRIBUTE_UNUSED,
+ union un2 u6 ATTRIBUTE_UNUSED,
+ union un2 u7 ATTRIBUTE_UNUSED,
+ union un2 u8 ATTRIBUTE_UNUSED)
+{
+ /* Check register contents. */
+ check_m512_arguments;
+}
+
+void
+check_union_passing3(union un3 u1 ATTRIBUTE_UNUSED,
+ union un3 u2 ATTRIBUTE_UNUSED,
+ union un3 u3 ATTRIBUTE_UNUSED,
+ union un3 u4 ATTRIBUTE_UNUSED,
+ union un3 u5 ATTRIBUTE_UNUSED,
+ union un3 u6 ATTRIBUTE_UNUSED,
+ union un3 u7 ATTRIBUTE_UNUSED,
+ union un3 u8 ATTRIBUTE_UNUSED)
+{
+ /* Check register contents. */
+ check_m512_arguments;
+}
+
+void
+check_union_passing4(union un4 u ATTRIBUTE_UNUSED)
+{
+ /* Check the passing on the stack by comparing the address of the
+ stack elements to the expected place on the stack. */
+ assert ((unsigned long)&u.x == rsp+8);
+ assert ((unsigned long)&u.ld == rsp+8);
+}
+
+void
+check_union_passing5(union un5 u ATTRIBUTE_UNUSED)
+{
+ /* Check the passing on the stack by comparing the address of the
+ stack elements to the expected place on the stack. */
+ assert ((unsigned long)&u.x == rsp+8);
+ assert ((unsigned long)&u.i == rsp+8);
+}
+
+void
+check_union_passing6(union un6 u1 ATTRIBUTE_UNUSED,
+ union un6 u2 ATTRIBUTE_UNUSED,
+ union un6 u3 ATTRIBUTE_UNUSED,
+ union un6 u4 ATTRIBUTE_UNUSED,
+ union un6 u5 ATTRIBUTE_UNUSED,
+ union un6 u6 ATTRIBUTE_UNUSED,
+ union un6 u7 ATTRIBUTE_UNUSED,
+ union un6 u8 ATTRIBUTE_UNUSED)
+{
+ /* Check register contents. */
+ check_m512_arguments;
+}
+
+#define check_union_passing1 WRAP_CALL(check_union_passing1)
+#define check_union_passing2 WRAP_CALL(check_union_passing2)
+#define check_union_passing3 WRAP_CALL(check_union_passing3)
+#define check_union_passing4 WRAP_CALL(check_union_passing4)
+#define check_union_passing5 WRAP_CALL(check_union_passing5)
+#define check_union_passing6 WRAP_CALL(check_union_passing6)
+
+static void
+avx512f_test (void)
+{
+ union un1 u1[8];
+ union un2 u2[8];
+ union un3 u3[8];
+ union un4 u4;
+ union un5 u5;
+ union un6 u6[8];
+ int i;
+
+ for (i = 0; i < 8; i++)
+ u1[i].x = (__m512){32+i, 0, i, 0, -i, 0, i - 12, i + 8,
+ 32+i, 0, i, 0, -i, 0, i - 12, i + 8};
+
+ clear_struct_registers;
+ for (i = 0; i < 8; i++)
+ (&fregs.zmm0)[i]._m512[0] = u1[i].x;
+ num_fregs = 8;
+ check_union_passing1(u1[0], u1[1], u1[2], u1[3],
+ u1[4], u1[5], u1[6], u1[7]);
+
+ clear_struct_registers;
+ for (i = 0; i < 8; i++)
+ {
+ u2[i].x = u1[i].x;
+ (&fregs.zmm0)[i]._m512[0] = u2[i].x;
+ }
+ num_fregs = 8;
+ check_union_passing2(u2[0], u2[1], u2[2], u2[3],
+ u2[4], u2[5], u2[6], u2[7]);
+
+ clear_struct_registers;
+ for (i = 0; i < 8; i++)
+ {
+ u3[i].x = u1[i].x;
+ (&fregs.zmm0)[i]._m512[0] = u3[i].x;
+ }
+ num_fregs = 8;
+ check_union_passing3(u3[0], u3[1], u3[2], u3[3],
+ u3[4], u3[5], u3[6], u3[7]);
+
+ check_union_passing4(u4);
+ check_union_passing5(u5);
+
+ clear_struct_registers;
+ for (i = 0; i < 8; i++)
+ {
+ u6[i].x = u1[i].x;
+ (&fregs.zmm0)[i]._m512[0] = u6[i].x;
+ }
+ num_fregs = 8;
+ check_union_passing6(u6[0], u6[1], u6[2], u6[3],
+ u6[4], u6[5], u6[6], u6[7]);
+}