1 /* Test variable number of 256-bit vector arguments passed to functions.  */
2 
3 #include <stdio.h>
4 #include "avx-check.h"
5 #include "args.h"
6 
7 struct IntegerRegisters iregs;
8 struct FloatRegisters fregs;
9 
10 /* This struct holds values for argument checking.  */
11 struct
12 {
13   YMM_T i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;
14 } values;
15 
16 char *pass;
17 int failed = 0;
18 
19 #undef assert
20 #define assert(c) do { \
21   if (!(c)) {failed++; printf ("failed %s\n", pass); } \
22 } while (0)
23 
24 #define compare(X1,X2,T) do { \
25   assert (memcmp (&X1, &X2, sizeof (T)) == 0); \
26 } while (0)
27 
28 void
fun_check_passing_m256_varargs(__m256 i0,__m256 i1,__m256 i2,__m256 i3,...)29 fun_check_passing_m256_varargs (__m256 i0, __m256 i1, __m256 i2,
30 				__m256 i3, ...)
31 {
32   /* Check argument values.  */
33   void **fp = __builtin_frame_address (0);
34   void *ra = __builtin_return_address (0);
35   __m256 *argp;
36 
37   compare (values.i0, i0, __m256);
38   compare (values.i1, i1, __m256);
39   compare (values.i2, i2, __m256);
40   compare (values.i3, i3, __m256);
41 
42   /* Get the pointer to the return address on stack.  */
43   while (*fp != ra)
44     fp++;
45 
46   /* Skip the return address stack slot.  */
47   argp = (__m256 *) (((char *) fp) + 8);
48 
49   /* Check __m256 arguments passed on stack.  */
50   compare (values.i4, argp[0], __m256);
51   compare (values.i5, argp[1], __m256);
52   compare (values.i6, argp[2], __m256);
53   compare (values.i7, argp[3], __m256);
54   compare (values.i8, argp[4], __m256);
55   compare (values.i9, argp[5], __m256);
56 
57   /* Check register contents.  */
58   compare (fregs.ymm0, ymm_regs[0], __m256);
59   compare (fregs.ymm1, ymm_regs[1], __m256);
60   compare (fregs.ymm2, ymm_regs[2], __m256);
61   compare (fregs.ymm3, ymm_regs[3], __m256);
62 }
63 
64 #define def_check_int_passing_varargs(_i0, _i1, _i2, _i3, _i4, _i5, \
65 				      _i6, _i7, _i8, _i9, \
66 				      _func, TYPE) \
67   values.i0.TYPE[0] = _i0; \
68   values.i1.TYPE[0] = _i1; \
69   values.i2.TYPE[0] = _i2; \
70   values.i3.TYPE[0] = _i3; \
71   values.i4.TYPE[0] = _i4; \
72   values.i5.TYPE[0] = _i5; \
73   values.i6.TYPE[0] = _i6; \
74   values.i7.TYPE[0] = _i7; \
75   values.i8.TYPE[0] = _i8; \
76   values.i9.TYPE[0] = _i9; \
77   clear_struct_registers; \
78   fregs.F0.TYPE[0] = _i0; \
79   fregs.F1.TYPE[0] = _i1; \
80   fregs.F2.TYPE[0] = _i2; \
81   fregs.F3.TYPE[0] = _i3; \
82   WRAP_CALL(_func) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9);
83 
84 void
test_m256_varargs(void)85 test_m256_varargs (void)
86 {
87   __m256 x[10];
88   int i;
89   for (i = 0; i < 10; i++)
90     x[i] = (__m256){32+i, 0, 0, 0, 0, 0, 0, 0};
91   pass = "m256-varargs";
92   def_check_int_passing_varargs (x[0], x[1], x[2], x[3], x[4], x[5],
93 				 x[6], x[7], x[8], x[9],
94 				 fun_check_passing_m256_varargs,
95 				 _m256);
96 }
97 
98 void
avx_test(void)99 avx_test (void)
100 {
101   test_m256_varargs ();
102   if (failed)
103     abort ();
104 }
105