2010-08-09 Andreas Tobler <andreast@fgznet.ch>
[official-gcc.git] / libffi / testsuite / libffi.call / huge_struct.c
blob602437ade59fb328a4af4328e398613f12513c98
1 /* Area: ffi_call, closure_call
2 Purpose: Check large structure returns.
3 Limitations: none.
4 PR: none.
5 Originator: Blake Chaffin 6/18/2007
6 */
8 /* { dg-excess-errors "" { target x86_64-*-mingw* x86_64-*-cygwin* } } */
9 /* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
10 /* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
11 /* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
13 #include "ffitest.h"
15 typedef struct BigStruct{
16 uint8_t a;
17 int8_t b;
18 uint16_t c;
19 int16_t d;
20 uint32_t e;
21 int32_t f;
22 uint64_t g;
23 int64_t h;
24 float i;
25 double j;
26 long double k;
27 char* l;
28 uint8_t m;
29 int8_t n;
30 uint16_t o;
31 int16_t p;
32 uint32_t q;
33 int32_t r;
34 uint64_t s;
35 int64_t t;
36 float u;
37 double v;
38 long double w;
39 char* x;
40 uint8_t y;
41 int8_t z;
42 uint16_t aa;
43 int16_t bb;
44 uint32_t cc;
45 int32_t dd;
46 uint64_t ee;
47 int64_t ff;
48 float gg;
49 double hh;
50 long double ii;
51 char* jj;
52 uint8_t kk;
53 int8_t ll;
54 uint16_t mm;
55 int16_t nn;
56 uint32_t oo;
57 int32_t pp;
58 uint64_t qq;
59 int64_t rr;
60 float ss;
61 double tt;
62 long double uu;
63 char* vv;
64 uint8_t ww;
65 int8_t xx;
66 } BigStruct;
68 BigStruct
69 test_large_fn(
70 uint8_t ui8_1,
71 int8_t si8_1,
72 uint16_t ui16_1,
73 int16_t si16_1,
74 uint32_t ui32_1,
75 int32_t si32_1,
76 uint64_t ui64_1,
77 int64_t si64_1,
78 float f_1,
79 double d_1,
80 long double ld_1,
81 char* p_1,
82 uint8_t ui8_2,
83 int8_t si8_2,
84 uint16_t ui16_2,
85 int16_t si16_2,
86 uint32_t ui32_2,
87 int32_t si32_2,
88 uint64_t ui64_2,
89 int64_t si64_2,
90 float f_2,
91 double d_2,
92 long double ld_2,
93 char* p_2,
94 uint8_t ui8_3,
95 int8_t si8_3,
96 uint16_t ui16_3,
97 int16_t si16_3,
98 uint32_t ui32_3,
99 int32_t si32_3,
100 uint64_t ui64_3,
101 int64_t si64_3,
102 float f_3,
103 double d_3,
104 long double ld_3,
105 char* p_3,
106 uint8_t ui8_4,
107 int8_t si8_4,
108 uint16_t ui16_4,
109 int16_t si16_4,
110 uint32_t ui32_4,
111 int32_t si32_4,
112 uint64_t ui64_4,
113 int64_t si64_4,
114 float f_4,
115 double d_4,
116 long double ld_4,
117 char* p_4,
118 uint8_t ui8_5,
119 int8_t si8_5)
121 BigStruct retVal = {
122 ui8_1 + 1, si8_1 + 1, ui16_1 + 1, si16_1 + 1, ui32_1 + 1, si32_1 + 1,
123 ui64_1 + 1, si64_1 + 1, f_1 + 1, d_1 + 1, ld_1 + 1, (char*)((intptr_t)p_1 + 1),
124 ui8_2 + 2, si8_2 + 2, ui16_2 + 2, si16_2 + 2, ui32_2 + 2, si32_2 + 2,
125 ui64_2 + 2, si64_2 + 2, f_2 + 2, d_2 + 2, ld_2 + 2, (char*)((intptr_t)p_2 + 2),
126 ui8_3 + 3, si8_3 + 3, ui16_3 + 3, si16_3 + 3, ui32_3 + 3, si32_3 + 3,
127 ui64_3 + 3, si64_3 + 3, f_3 + 3, d_3 + 3, ld_3 + 3, (char*)((intptr_t)p_3 + 3),
128 ui8_4 + 4, si8_4 + 4, ui16_4 + 4, si16_4 + 4, ui32_4 + 4, si32_4 + 4,
129 ui64_4 + 4, si64_4 + 4, f_4 + 4, d_4 + 4, ld_4 + 4, (char*)((intptr_t)p_4 + 4),
130 ui8_5 + 5, si8_5 + 5};
132 printf("%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
133 "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
134 "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
135 "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %hhu %hhd: "
136 "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
137 "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
138 "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
139 "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %hhu %hhd\n",
140 ui8_1, si8_1, ui16_1, si16_1, ui32_1, si32_1, ui64_1, si64_1, f_1, d_1, ld_1, (unsigned long)p_1,
141 ui8_2, si8_2, ui16_2, si16_2, ui32_2, si32_2, ui64_2, si64_2, f_2, d_2, ld_2, (unsigned long)p_2,
142 ui8_3, si8_3, ui16_3, si16_3, ui32_3, si32_3, ui64_3, si64_3, f_3, d_3, ld_3, (unsigned long)p_3,
143 ui8_4, si8_4, ui16_4, si16_4, ui32_4, si32_4, ui64_4, si64_4, f_4, d_4, ld_4, (unsigned long)p_4, ui8_5, si8_5,
144 retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f,
145 retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l,
146 retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r,
147 retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x,
148 retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd,
149 retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj,
150 retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp,
151 retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx);
153 return retVal;
156 static void
157 cls_large_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
159 uint8_t ui8_1 = *(uint8_t*)args[0];
160 int8_t si8_1 = *(int8_t*)args[1];
161 uint16_t ui16_1 = *(uint16_t*)args[2];
162 int16_t si16_1 = *(int16_t*)args[3];
163 uint32_t ui32_1 = *(uint32_t*)args[4];
164 int32_t si32_1 = *(int32_t*)args[5];
165 uint64_t ui64_1 = *(uint64_t*)args[6];
166 int64_t si64_1 = *(int64_t*)args[7];
167 float f_1 = *(float*)args[8];
168 double d_1 = *(double*)args[9];
169 long double ld_1 = *(long double*)args[10];
170 char* p_1 = *(char**)args[11];
171 uint8_t ui8_2 = *(uint8_t*)args[12];
172 int8_t si8_2 = *(int8_t*)args[13];
173 uint16_t ui16_2 = *(uint16_t*)args[14];
174 int16_t si16_2 = *(int16_t*)args[15];
175 uint32_t ui32_2 = *(uint32_t*)args[16];
176 int32_t si32_2 = *(int32_t*)args[17];
177 uint64_t ui64_2 = *(uint64_t*)args[18];
178 int64_t si64_2 = *(int64_t*)args[19];
179 float f_2 = *(float*)args[20];
180 double d_2 = *(double*)args[21];
181 long double ld_2 = *(long double*)args[22];
182 char* p_2 = *(char**)args[23];
183 uint8_t ui8_3 = *(uint8_t*)args[24];
184 int8_t si8_3 = *(int8_t*)args[25];
185 uint16_t ui16_3 = *(uint16_t*)args[26];
186 int16_t si16_3 = *(int16_t*)args[27];
187 uint32_t ui32_3 = *(uint32_t*)args[28];
188 int32_t si32_3 = *(int32_t*)args[29];
189 uint64_t ui64_3 = *(uint64_t*)args[30];
190 int64_t si64_3 = *(int64_t*)args[31];
191 float f_3 = *(float*)args[32];
192 double d_3 = *(double*)args[33];
193 long double ld_3 = *(long double*)args[34];
194 char* p_3 = *(char**)args[35];
195 uint8_t ui8_4 = *(uint8_t*)args[36];
196 int8_t si8_4 = *(int8_t*)args[37];
197 uint16_t ui16_4 = *(uint16_t*)args[38];
198 int16_t si16_4 = *(int16_t*)args[39];
199 uint32_t ui32_4 = *(uint32_t*)args[40];
200 int32_t si32_4 = *(int32_t*)args[41];
201 uint64_t ui64_4 = *(uint64_t*)args[42];
202 int64_t si64_4 = *(int64_t*)args[43];
203 float f_4 = *(float*)args[44];
204 double d_4 = *(double*)args[45];
205 long double ld_4 = *(long double*)args[46];
206 char* p_4 = *(char**)args[47];
207 uint8_t ui8_5 = *(uint8_t*)args[48];
208 int8_t si8_5 = *(int8_t*)args[49];
210 *(BigStruct*)resp = test_large_fn(
211 ui8_1, si8_1, ui16_1, si16_1, ui32_1, si32_1, ui64_1, si64_1, f_1, d_1, ld_1, p_1,
212 ui8_2, si8_2, ui16_2, si16_2, ui32_2, si32_2, ui64_2, si64_2, f_2, d_2, ld_2, p_2,
213 ui8_3, si8_3, ui16_3, si16_3, ui32_3, si32_3, ui64_3, si64_3, f_3, d_3, ld_3, p_3,
214 ui8_4, si8_4, ui16_4, si16_4, ui32_4, si32_4, ui64_4, si64_4, f_4, d_4, ld_4, p_4,
215 ui8_5, si8_5);
219 main(int argc __UNUSED__, const char** argv __UNUSED__)
221 void *code;
222 ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
224 ffi_cif cif;
225 ffi_type* argTypes[51];
226 void* argValues[51];
228 ffi_type ret_struct_type;
229 ffi_type* st_fields[51];
230 BigStruct retVal;
232 memset (&retVal, 0, sizeof(retVal));
234 ret_struct_type.size = 0;
235 ret_struct_type.alignment = 0;
236 ret_struct_type.type = FFI_TYPE_STRUCT;
237 ret_struct_type.elements = st_fields;
239 st_fields[0] = st_fields[12] = st_fields[24] = st_fields[36] = st_fields[48] = &ffi_type_uint8;
240 st_fields[1] = st_fields[13] = st_fields[25] = st_fields[37] = st_fields[49] = &ffi_type_sint8;
241 st_fields[2] = st_fields[14] = st_fields[26] = st_fields[38] = &ffi_type_uint16;
242 st_fields[3] = st_fields[15] = st_fields[27] = st_fields[39] = &ffi_type_sint16;
243 st_fields[4] = st_fields[16] = st_fields[28] = st_fields[40] = &ffi_type_uint32;
244 st_fields[5] = st_fields[17] = st_fields[29] = st_fields[41] = &ffi_type_sint32;
245 st_fields[6] = st_fields[18] = st_fields[30] = st_fields[42] = &ffi_type_uint64;
246 st_fields[7] = st_fields[19] = st_fields[31] = st_fields[43] = &ffi_type_sint64;
247 st_fields[8] = st_fields[20] = st_fields[32] = st_fields[44] = &ffi_type_float;
248 st_fields[9] = st_fields[21] = st_fields[33] = st_fields[45] = &ffi_type_double;
249 st_fields[10] = st_fields[22] = st_fields[34] = st_fields[46] = &ffi_type_longdouble;
250 st_fields[11] = st_fields[23] = st_fields[35] = st_fields[47] = &ffi_type_pointer;
252 st_fields[50] = NULL;
254 uint8_t ui8 = 1;
255 int8_t si8 = 2;
256 uint16_t ui16 = 3;
257 int16_t si16 = 4;
258 uint32_t ui32 = 5;
259 int32_t si32 = 6;
260 uint64_t ui64 = 7;
261 int64_t si64 = 8;
262 float f = 9;
263 double d = 10;
264 long double ld = 11;
265 char* p = (char*)0x12345678;
267 argTypes[0] = argTypes[12] = argTypes[24] = argTypes[36] = argTypes[48] = &ffi_type_uint8;
268 argValues[0] = argValues[12] = argValues[24] = argValues[36] = argValues[48] = &ui8;
269 argTypes[1] = argTypes[13] = argTypes[25] = argTypes[37] = argTypes[49] = &ffi_type_sint8;
270 argValues[1] = argValues[13] = argValues[25] = argValues[37] = argValues[49] = &si8;
271 argTypes[2] = argTypes[14] = argTypes[26] = argTypes[38] = &ffi_type_uint16;
272 argValues[2] = argValues[14] = argValues[26] = argValues[38] = &ui16;
273 argTypes[3] = argTypes[15] = argTypes[27] = argTypes[39] = &ffi_type_sint16;
274 argValues[3] = argValues[15] = argValues[27] = argValues[39] = &si16;
275 argTypes[4] = argTypes[16] = argTypes[28] = argTypes[40] = &ffi_type_uint32;
276 argValues[4] = argValues[16] = argValues[28] = argValues[40] = &ui32;
277 argTypes[5] = argTypes[17] = argTypes[29] = argTypes[41] = &ffi_type_sint32;
278 argValues[5] = argValues[17] = argValues[29] = argValues[41] = &si32;
279 argTypes[6] = argTypes[18] = argTypes[30] = argTypes[42] = &ffi_type_uint64;
280 argValues[6] = argValues[18] = argValues[30] = argValues[42] = &ui64;
281 argTypes[7] = argTypes[19] = argTypes[31] = argTypes[43] = &ffi_type_sint64;
282 argValues[7] = argValues[19] = argValues[31] = argValues[43] = &si64;
283 argTypes[8] = argTypes[20] = argTypes[32] = argTypes[44] = &ffi_type_float;
284 argValues[8] = argValues[20] = argValues[32] = argValues[44] = &f;
285 argTypes[9] = argTypes[21] = argTypes[33] = argTypes[45] = &ffi_type_double;
286 argValues[9] = argValues[21] = argValues[33] = argValues[45] = &d;
287 argTypes[10] = argTypes[22] = argTypes[34] = argTypes[46] = &ffi_type_longdouble;
288 argValues[10] = argValues[22] = argValues[34] = argValues[46] = &ld;
289 argTypes[11] = argTypes[23] = argTypes[35] = argTypes[47] = &ffi_type_pointer;
290 argValues[11] = argValues[23] = argValues[35] = argValues[47] = &p;
292 argTypes[50] = NULL;
293 argValues[50] = NULL;
295 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 50, &ret_struct_type, argTypes) == FFI_OK);
297 ffi_call(&cif, FFI_FN(test_large_fn), &retVal, argValues);
298 // { dg-output "1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" }
299 printf("res: %hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
300 "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
301 "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
302 "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %hhu %hhd\n",
303 retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f,
304 retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l,
305 retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r,
306 retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x,
307 retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd,
308 retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj,
309 retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp,
310 retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx);
311 // { dg-output "\nres: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" }
313 CHECK(ffi_prep_closure_loc(pcl, &cif, cls_large_fn, NULL, code) == FFI_OK);
315 retVal = ((BigStruct(*)(
316 uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
317 uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
318 uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
319 uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
320 uint8_t, int8_t))(code))(
321 ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
322 ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
323 ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
324 ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
325 ui8, si8);
326 // { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" }
327 printf("res: %hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
328 "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
329 "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
330 "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %hhu %hhd\n",
331 retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f,
332 retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l,
333 retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r,
334 retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x,
335 retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd,
336 retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj,
337 retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp,
338 retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx);
339 // { dg-output "\nres: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" }
341 return 0;