1 /* This tests passing of structs. */
2 
3 #include "avx512fp16-xmm-check.h"
4 #include "defines.h"
5 #include "args.h"
6 #include <complex.h>
7 
8 struct IntegerRegisters iregs;
9 struct FloatRegisters fregs;
10 unsigned int num_iregs, num_fregs;
11 
12 struct int_struct
13 {
14   int i;
15 };
16 
17 struct long_struct
18 {
19   long long l;
20 };
21 
22 struct long2_struct
23 {
24   long long l1, l2;
25 };
26 
27 struct long3_struct
28 {
29   long long l1, l2, l3;
30 };
31 
32 
33 /* Check that the struct is passed as the individual members in iregs.  */
34 void
check_struct_passing1(struct int_struct is ATTRIBUTE_UNUSED)35 check_struct_passing1 (struct int_struct is ATTRIBUTE_UNUSED)
36 {
37   check_int_arguments;
38 }
39 
40 void
check_struct_passing2(struct long_struct ls ATTRIBUTE_UNUSED)41 check_struct_passing2 (struct long_struct ls ATTRIBUTE_UNUSED)
42 {
43   check_int_arguments;
44 }
45 
46 void
check_struct_passing3(struct long2_struct ls ATTRIBUTE_UNUSED)47 check_struct_passing3 (struct long2_struct ls ATTRIBUTE_UNUSED)
48 {
49   check_int_arguments;
50 }
51 
52 void
check_struct_passing4(struct long3_struct ls ATTRIBUTE_UNUSED)53 check_struct_passing4 (struct long3_struct ls ATTRIBUTE_UNUSED)
54 {
55   /* Check the passing on the stack by comparing the address of the
56      stack elements to the expected place on the stack.  */
57   assert ((unsigned long)&ls.l1 == rsp+8);
58   assert ((unsigned long)&ls.l2 == rsp+16);
59   assert ((unsigned long)&ls.l3 == rsp+24);
60 }
61 
62 #ifdef CHECK_M64_M128
63 struct m128_struct
64 {
65   __m128 x;
66 };
67 
68 struct m128_2_struct
69 {
70   __m128 x1, x2;
71 };
72 
73 /* Check that the struct is passed as the individual members in fregs.  */
74 void
check_struct_passing5(struct m128_struct ms1 ATTRIBUTE_UNUSED,struct m128_struct ms2 ATTRIBUTE_UNUSED,struct m128_struct ms3 ATTRIBUTE_UNUSED,struct m128_struct ms4 ATTRIBUTE_UNUSED,struct m128_struct ms5 ATTRIBUTE_UNUSED,struct m128_struct ms6 ATTRIBUTE_UNUSED,struct m128_struct ms7 ATTRIBUTE_UNUSED,struct m128_struct ms8 ATTRIBUTE_UNUSED)75 check_struct_passing5 (struct m128_struct ms1 ATTRIBUTE_UNUSED,
76 		       struct m128_struct ms2 ATTRIBUTE_UNUSED,
77 		       struct m128_struct ms3 ATTRIBUTE_UNUSED,
78 		       struct m128_struct ms4 ATTRIBUTE_UNUSED,
79 		       struct m128_struct ms5 ATTRIBUTE_UNUSED,
80 		       struct m128_struct ms6 ATTRIBUTE_UNUSED,
81 		       struct m128_struct ms7 ATTRIBUTE_UNUSED,
82 		       struct m128_struct ms8 ATTRIBUTE_UNUSED)
83 {
84   check_m128_arguments;
85 }
86 
87 void
check_struct_passing6(struct m128_2_struct ms ATTRIBUTE_UNUSED)88 check_struct_passing6 (struct m128_2_struct ms ATTRIBUTE_UNUSED)
89 {
90   /* Check the passing on the stack by comparing the address of the
91      stack elements to the expected place on the stack.  */
92   assert ((unsigned long)&ms.x1 == rsp+8);
93   assert ((unsigned long)&ms.x2 == rsp+24);
94 }
95 #endif
96 
97 struct flex1_struct
98 {
99   long long i;
100   long long flex[];
101 };
102 
103 struct flex2_struct
104 {
105   long long i;
106   long long flex[0];
107 };
108 
109 void
check_struct_passing7(struct flex1_struct is ATTRIBUTE_UNUSED)110 check_struct_passing7 (struct flex1_struct is ATTRIBUTE_UNUSED)
111 {
112   check_int_arguments;
113 }
114 
115 void
check_struct_passing8(struct flex2_struct is ATTRIBUTE_UNUSED)116 check_struct_passing8 (struct flex2_struct is ATTRIBUTE_UNUSED)
117 {
118   check_int_arguments;
119 }
120 
121 struct complex1_struct
122 {
123   int c;
124   __complex__ float x;
125 };
126 
127 struct complex1a_struct
128 {
129   long long l;
130   float f;
131 };
132 
133 struct complex2_struct
134 {
135   int c;
136   __complex__ float x;
137   float y;
138 };
139 
140 struct complex2a_struct
141 {
142   long long l;
143   double d;
144 };
145 
146 struct complex3_struct
147 {
148   int c;
149   __complex__ _Float16 x;
150 };
151 
152 struct complex3a_struct
153 {
154   long long l;
155   _Float16 f;
156 };
157 
158 struct complex4_struct
159 {
160   int c;
161   __complex__ _Float16 x;
162   _Float16 y;
163 };
164 
165 struct complex4a_struct
166 {
167   long long l;
168   _Float16 f;
169 };
170 
171 void
check_struct_passing9(struct complex1_struct is ATTRIBUTE_UNUSED)172 check_struct_passing9 (struct complex1_struct is ATTRIBUTE_UNUSED)
173 {
174   check_int_arguments;
175   check_float_arguments;
176 }
177 
178 void
check_struct_passing10(struct complex2_struct is ATTRIBUTE_UNUSED)179 check_struct_passing10 (struct complex2_struct is ATTRIBUTE_UNUSED)
180 {
181   check_int_arguments;
182   check_double_arguments;
183 }
184 
185 void
check_struct_passing11(struct complex3_struct is ATTRIBUTE_UNUSED)186 check_struct_passing11 (struct complex3_struct is ATTRIBUTE_UNUSED)
187 {
188   check_int_arguments;
189   check_float16_arguments;
190 }
191 
192 void
check_struct_passing12(struct complex4_struct is ATTRIBUTE_UNUSED)193 check_struct_passing12 (struct complex4_struct is ATTRIBUTE_UNUSED)
194 {
195   check_int_arguments;
196   check_float16_arguments;
197 }
198 
199 static struct flex1_struct f1s = { 60, { } };
200 static struct flex2_struct f2s = { 61, { } };
201 
202 static void
do_test(void)203 do_test (void)
204 {
205   struct int_struct is = { 48 };
206   struct long_struct ls = { 49 };
207 #ifdef CHECK_LARGER_STRUCTS
208   struct long2_struct l2s = { 50, 51 };
209   struct long3_struct l3s = { 52, 53, 54 };
210 #endif
211 #ifdef CHECK_M64_M128
212   struct m128_struct m128s[8];
213   struct m128_2_struct m128_2s = {
214       { 48.394, 39.3, -397.9, 3484.9 },
215       { -8.394, -93.3, 7.9, 84.94 }
216   };
217   int i;
218 #endif
219   struct complex1_struct c1s = { 4, ( -13.4 + 3.5*I ) };
220   union
221     {
222       struct complex1_struct c;
223       struct complex1a_struct u;
224     } c1u;
225   struct complex2_struct c2s = { 4, ( -13.4 + 3.5*I ), -34.5 };
226   union
227     {
228       struct complex2_struct c;
229       struct complex2a_struct u;
230     } c2u;
231 
232   struct complex3_struct c3s = { 4, ( -13.4 + 3.5*I ) };
233   union
234     {
235       struct complex3_struct c;
236       struct complex3a_struct u;
237     } c3u;
238 
239   struct complex4_struct c4s = { 4, ( -13.4 + 3.5*I ), -34.5 };
240   union
241     {
242       struct complex4_struct c;
243       struct complex4a_struct u;
244     } c4u;
245 
246   clear_struct_registers;
247   iregs.I0 = is.i;
248   num_iregs = 1;
249   clear_int_hardware_registers;
250   WRAP_CALL (check_struct_passing1)(is);
251 
252   clear_struct_registers;
253   iregs.I0 = ls.l;
254   num_iregs = 1;
255   clear_int_hardware_registers;
256   WRAP_CALL (check_struct_passing2)(ls);
257 
258 #ifdef CHECK_LARGER_STRUCTS
259   clear_struct_registers;
260   iregs.I0 = l2s.l1;
261   iregs.I1 = l2s.l2;
262   num_iregs = 2;
263   clear_int_hardware_registers;
264   WRAP_CALL (check_struct_passing3)(l2s);
265   WRAP_CALL (check_struct_passing4)(l3s);
266 #endif
267 
268 #ifdef CHECK_M64_M128
269   clear_struct_registers;
270   for (i = 0; i < 8; i++)
271     {
272       m128s[i].x = (__m128){32+i, 0, i, 0};
273       (&fregs.xmm0)[i]._m128[0] = m128s[i].x;
274     }
275   num_fregs = 8;
276   clear_float_hardware_registers;
277   WRAP_CALL (check_struct_passing5)(m128s[0], m128s[1], m128s[2], m128s[3],
278 				    m128s[4], m128s[5], m128s[6], m128s[7]);
279   WRAP_CALL (check_struct_passing6)(m128_2s);
280 #endif
281 
282   clear_struct_registers;
283   iregs.I0 = f1s.i;
284   num_iregs = 1;
285   clear_int_hardware_registers;
286   WRAP_CALL (check_struct_passing7)(f1s);
287 
288   clear_struct_registers;
289   iregs.I0 = f2s.i;
290   num_iregs = 1;
291   clear_int_hardware_registers;
292   WRAP_CALL (check_struct_passing8)(f2s);
293 
294   clear_struct_registers;
295   c1u.c = c1s;
296   iregs.I0 = c1u.u.l;
297   num_iregs = 1;
298   fregs.xmm0._float [0] = c1u.u.f;
299   num_fregs = 1;
300   clear_int_hardware_registers;
301   clear_float_hardware_registers;
302   WRAP_CALL (check_struct_passing9)(c1s);
303 
304   clear_struct_registers;
305   c2u.c = c2s;
306   iregs.I0 = c2u.u.l;
307   num_iregs = 1;
308   fregs.xmm0._double[0] = c2u.u.d;
309   num_fregs = 1;
310   clear_int_hardware_registers;
311   clear_float_hardware_registers;
312   WRAP_CALL (check_struct_passing10)(c2s);
313 
314   clear_struct_registers;
315   c3u.c = c3s;
316   iregs.I0 = c3u.u.l;
317   num_iregs = 1;
318   num_fregs = 0;
319   clear_int_hardware_registers;
320   clear_float_hardware_registers;
321   WRAP_CALL (check_struct_passing11)(c3s);
322 
323   clear_struct_registers;
324   c4u.c = c4s;
325   iregs.I0 = c4u.u.l;
326   num_iregs = 1;
327   fregs.xmm0.__Float16 [0] = c4u.u.f;
328   num_fregs = 1;
329   clear_int_hardware_registers;
330   clear_float_hardware_registers;
331   WRAP_CALL (check_struct_passing12)(c4s);
332 }
333