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