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