1 /* This tests passing of structs. */
2
3 #include "defines.h"
4 #include "args.h"
5
6 struct IntegerRegisters iregbits = { ~0, ~0, ~0, ~0, ~0, ~0 };
7 struct IntegerRegisters iregs;
8 unsigned int num_iregs;
9
10 struct int_struct
11 {
12 int i;
13 };
14
15 struct long_struct
16 {
17 long l;
18 };
19
20 union un1
21 {
22 char c;
23 int i;
24 };
25
26 union un2
27 {
28 char c1;
29 long l;
30 char c2;
31 };
32
33 union un3
34 {
35 struct int_struct is;
36 struct long_struct ls;
37 union un1 un;
38 };
39
40
41 void
check_union_passing1(union un1 u ATTRIBUTE_UNUSED)42 check_union_passing1(union un1 u ATTRIBUTE_UNUSED)
43 {
44 check_int_arguments;
45 }
46
47 void
check_union_passing2(union un2 u1 ATTRIBUTE_UNUSED)48 check_union_passing2(union un2 u1 ATTRIBUTE_UNUSED)
49 {
50 check_int_arguments;
51 }
52
53 void
check_union_passing3(union un3 u ATTRIBUTE_UNUSED)54 check_union_passing3(union un3 u ATTRIBUTE_UNUSED)
55 {
56 check_int_arguments;
57 }
58
59 #define check_union_passing1 WRAP_CALL(check_union_passing1)
60 #define check_union_passing2 WRAP_CALL(check_union_passing2)
61 #define check_union_passing3 WRAP_CALL(check_union_passing3)
62
63 union un4
64 {
65 int i;
66 float f;
67 };
68
69 union un5
70 {
71 long long ll;
72 double d;
73 };
74
75 void
check_union_passing4(union un4 u1 ATTRIBUTE_UNUSED,union un4 u2 ATTRIBUTE_UNUSED,union un4 u3 ATTRIBUTE_UNUSED,union un4 u4 ATTRIBUTE_UNUSED,union un4 u5 ATTRIBUTE_UNUSED,union un4 u6 ATTRIBUTE_UNUSED,union un4 u7 ATTRIBUTE_UNUSED,union un4 u8 ATTRIBUTE_UNUSED)76 check_union_passing4(union un4 u1 ATTRIBUTE_UNUSED,
77 union un4 u2 ATTRIBUTE_UNUSED,
78 union un4 u3 ATTRIBUTE_UNUSED,
79 union un4 u4 ATTRIBUTE_UNUSED,
80 union un4 u5 ATTRIBUTE_UNUSED,
81 union un4 u6 ATTRIBUTE_UNUSED,
82 union un4 u7 ATTRIBUTE_UNUSED,
83 union un4 u8 ATTRIBUTE_UNUSED)
84 {
85 check_int_arguments;
86 }
87
88 void
check_union_passing5(union un5 u ATTRIBUTE_UNUSED)89 check_union_passing5(union un5 u ATTRIBUTE_UNUSED)
90 {
91 check_int_arguments;
92 }
93
94 #define check_union_passing4 WRAP_CALL(check_union_passing4)
95 #define check_union_passing5 WRAP_CALL(check_union_passing5)
96
97 #ifdef CHECK_FLOAT128
98 union un6
99 {
100 __float128 f128;
101 int i;
102 };
103
104
105 void
check_union_passing6(union un6 u ATTRIBUTE_UNUSED)106 check_union_passing6(union un6 u ATTRIBUTE_UNUSED)
107 {
108 /* Check the passing on the stack by comparing the address of the
109 stack elements to the expected place on the stack. */
110 assert ((unsigned long)&u.f128 == esp+4);
111 assert ((unsigned long)&u.i == esp+4);
112 }
113
114 #define check_union_passing6 WRAP_CALL(check_union_passing6)
115 #endif
116
117 int
main(void)118 main (void)
119 {
120 union un1 u1;
121 #ifdef CHECK_LARGER_UNION_PASSING
122 union un2 u2;
123 union un3 u3;
124 struct int_struct is;
125 struct long_struct ls;
126 #endif /* CHECK_LARGER_UNION_PASSING */
127 union un4 u4[8];
128 union un5 u5;
129 int i;
130 #ifdef CHECK_FLOAT128
131 union un6 u6;
132 #endif
133
134 /* Check a union with char, int. */
135 clear_struct_registers;
136 u1.i = 0; /* clear the struct to not have high bits left */
137 u1.c = 32;
138 iregs.I0 = 32;
139 num_iregs = 1;
140 clear_int_hardware_registers;
141 check_union_passing1(u1);
142 u1.i = 0; /* clear the struct to not have high bits left */
143 u1.i = 33;
144 iregs.I0 = 33;
145 num_iregs = 1;
146 clear_int_hardware_registers;
147 check_union_passing1(u1);
148
149 /* Check a union with char, long, char. */
150 #ifdef CHECK_LARGER_UNION_PASSING
151 clear_struct_registers;
152 u2.l = 0; /* clear the struct to not have high bits left */
153 u2.c1 = 34;
154 iregs.I0 = 34;
155 num_iregs = 1;
156 clear_int_hardware_registers;
157 check_union_passing2(u2);
158 u2.l = 0; /* clear the struct to not have high bits left */
159 u2.l = 35;
160 iregs.I0 = 35;
161 num_iregs = 1;
162 clear_int_hardware_registers;
163 check_union_passing2(u2);
164 u2.l = 0; /* clear the struct to not have high bits left */
165 u2.c2 = 36;
166 iregs.I0 = 36;
167 num_iregs = 1;
168 clear_int_hardware_registers;
169 check_union_passing2(u2);
170
171 /* check a union containing two structs and a union. */
172 clear_struct_registers;
173 is.i = 37;
174 u3.ls.l = 0; /* clear the struct to not have high bits left */
175 u3.is = is;
176 iregs.I0 = 37;
177 num_iregs = 1;
178 clear_int_hardware_registers;
179 check_union_passing3(u3);
180 ls.l = 38;
181 u3.ls.l = 0; /* clear the struct to not have high bits left */
182 u3.ls = ls;
183 iregs.I0 = 38;
184 num_iregs = 1;
185 clear_int_hardware_registers;
186 check_union_passing3(u3);
187 u1.c = 39;
188 u3.ls.l = 0; /* clear the struct to not have high bits left */
189 u3.un = u1;
190 iregs.I0 = 39;
191 num_iregs = 1;
192 clear_int_hardware_registers;
193 check_union_passing3(u3);
194 u1.i = 40;
195 u3.ls.l = 0; /* clear the struct to not have high bits left */
196 u3.un = u1;
197 iregs.I0 = 40;
198 num_iregs = 1;
199 clear_int_hardware_registers;
200 check_union_passing3(u3);
201 #endif /* CHECK_LARGER_UNION_PASSING */
202
203 clear_struct_registers;
204 for (i = 0; i < 8; i++)
205 u4[i].f = 32 + i;
206 iregs.I0 = u4[0].i;
207 iregs.I1 = u4[1].i;
208 iregs.I2 = u4[2].i;
209 num_iregs = 3;
210 clear_int_hardware_registers;
211 check_union_passing4(u4[0], u4[1], u4[2], u4[3],
212 u4[4], u4[5], u4[6], u4[7]);
213
214 clear_struct_registers;
215 u5.d = 48.394;
216 iregs.I0 = u5.ll & 0xffffffff;
217 iregs.I1 = (u5.ll >> 32) & 0xffffffff;
218 num_iregs = 2;
219 clear_int_hardware_registers;
220 check_union_passing5(u5);
221
222 #ifdef CHECK_FLOAT128
223 u6.i = 2;
224 check_union_passing6(u6);
225 #endif
226
227 return 0;
228 }
229