1 /* Area: ffi_call, closure_call
2 Purpose: Check large structure returns.
5 Originator: Blake Chaffin 6/18/2007
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* } } */
15 typedef struct BigStruct
{
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("%" PRIu8
" %" PRId8
" %hu %hd %u %d %" PRIu64
" %" PRId64
" %.0f %.0f %.0Lf %#lx "
133 "%" 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 %" PRIu8
" %" PRId8
": "
136 "%" PRIu8
" %" PRId8
" %hu %hd %u %d %" PRIu64
" %" PRId64
" %.0f %.0f %.0Lf %#lx "
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 %" PRIu8
" %" PRId8
"\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
);
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
,
219 main(int argc __UNUSED__
, const char** argv __UNUSED__
)
222 ffi_closure
*pcl
= ffi_closure_alloc(sizeof(ffi_closure
), &code
);
225 ffi_type
* argTypes
[51];
228 ffi_type ret_struct_type
;
229 ffi_type
* st_fields
[51];
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
;
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
;
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: %" PRIu8
" %" PRId8
" %hu %hd %u %d %" PRIu64
" %" PRId64
" %.0f %.0f %.0Lf %#lx "
300 "%" 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 %" PRIu8
" %" PRId8
"\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
,
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: %" PRIu8
" %" PRId8
" %hu %hd %u %d %" PRIu64
" %" PRId64
" %.0f %.0f %.0Lf %#lx "
328 "%" 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 %" PRIu8
" %" PRId8
"\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" }