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