Rebase
[platform/upstream/libffi.git] / testsuite / libffi.call / huge_struct.c
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 */
7
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* } } */
12
13 #include "ffitest.h"
14
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;
67
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)
120 {
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};
131
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);
152
153         return  retVal;
154 }
155
156 static void
157 cls_large_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
158 {
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];
209
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);
216 }
217
218 int
219 main(int argc __UNUSED__, const char** argv __UNUSED__)
220 {
221         void *code;
222         ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
223
224         ffi_cif         cif;
225         ffi_type*       argTypes[51];
226         void*           argValues[51];
227
228         ffi_type        ret_struct_type;
229         ffi_type*       st_fields[51];
230         BigStruct       retVal;
231
232         memset (&retVal, 0, sizeof(retVal));
233
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;
238
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;
251
252         st_fields[50] = NULL;
253
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;
266
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;
291
292         argTypes[50]    = NULL;
293         argValues[50]   = NULL;
294
295         CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 50, &ret_struct_type, argTypes) == FFI_OK);
296
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" }
312
313         CHECK(ffi_prep_closure_loc(pcl, &cif, cls_large_fn, NULL, code) == FFI_OK);
314
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" }
340
341     return 0;
342 }