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