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