From: Anthony Green Date: Sat, 23 Nov 2019 00:27:34 +0000 (-0500) Subject: More more closure tests to the closure test directory X-Git-Tag: upstream/3.3~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c88c0e92a9fbb4e69513394682c61aa848a035cc;p=platform%2Fupstream%2Flibffi.git More more closure tests to the closure test directory --- diff --git a/testsuite/libffi.bhaible/bhaible.exp b/testsuite/libffi.bhaible/bhaible.exp index 3522bd4..44aebc5 100644 --- a/testsuite/libffi.bhaible/bhaible.exp +++ b/testsuite/libffi.bhaible/bhaible.exp @@ -47,7 +47,13 @@ for {set i 1} {$i < 82} {incr i} { set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/test-callback.c]] for {set i 1} {$i < 81} {incr i} { - run-many-tests $tlist [format "-DDGTEST=%d %s" $i $warning_options] + if { [libffi_feature_test "#if FFI_CLOSURES"] } { + run-many-tests $tlist [format "-DDGTEST=%d %s" $i $warning_options] + } else { + foreach test $tlist { + unsupported [format "%s -DDGTEST=%d %s" $test $i $warning_options] + } + } } dg-finish diff --git a/testsuite/libffi.call/err_bad_abi.c b/testsuite/libffi.call/err_bad_abi.c deleted file mode 100644 index f5a7317..0000000 --- a/testsuite/libffi.call/err_bad_abi.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Area: ffi_prep_cif, ffi_prep_closure - Purpose: Test error return for bad ABIs. - Limitations: none. - PR: none. - Originator: Blake Chaffin 6/6/2007 */ - -/* { dg-do run } */ - -#include "ffitest.h" - -static void -dummy_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, - void** args __UNUSED__, void* userdata __UNUSED__) -{} - -int main (void) -{ - ffi_cif cif; - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - ffi_type* arg_types[1]; - - arg_types[0] = NULL; - - CHECK(ffi_prep_cif(&cif, 255, 0, &ffi_type_void, - arg_types) == FFI_BAD_ABI); - - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &ffi_type_void, - arg_types) == FFI_OK); - - cif.abi= 255; - - CHECK(ffi_prep_closure_loc(pcl, &cif, dummy_fn, NULL, code) == FFI_BAD_ABI); - - exit(0); -} diff --git a/testsuite/libffi.call/huge_struct.c b/testsuite/libffi.call/huge_struct.c deleted file mode 100644 index 1915c3f..0000000 --- a/testsuite/libffi.call/huge_struct.c +++ /dev/null @@ -1,341 +0,0 @@ -/* Area: ffi_call, closure_call - Purpose: Check large structure returns. - Limitations: none. - PR: none. - Originator: Blake Chaffin 6/18/2007 -*/ - -/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ -/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */ -/* { dg-options -Wformat=0 { target moxie*-*-elf or1k-*-* } } */ - -#include "ffitest.h" - -typedef struct BigStruct{ - uint8_t a; - int8_t b; - uint16_t c; - int16_t d; - uint32_t e; - int32_t f; - uint64_t g; - int64_t h; - float i; - double j; - long double k; - char* l; - uint8_t m; - int8_t n; - uint16_t o; - int16_t p; - uint32_t q; - int32_t r; - uint64_t s; - int64_t t; - float u; - double v; - long double w; - char* x; - uint8_t y; - int8_t z; - uint16_t aa; - int16_t bb; - uint32_t cc; - int32_t dd; - uint64_t ee; - int64_t ff; - float gg; - double hh; - long double ii; - char* jj; - uint8_t kk; - int8_t ll; - uint16_t mm; - int16_t nn; - uint32_t oo; - int32_t pp; - uint64_t qq; - int64_t rr; - float ss; - double tt; - long double uu; - char* vv; - uint8_t ww; - int8_t xx; -} BigStruct; - -BigStruct -test_large_fn( - uint8_t ui8_1, - int8_t si8_1, - uint16_t ui16_1, - int16_t si16_1, - uint32_t ui32_1, - int32_t si32_1, - uint64_t ui64_1, - int64_t si64_1, - float f_1, - double d_1, - long double ld_1, - char* p_1, - uint8_t ui8_2, - int8_t si8_2, - uint16_t ui16_2, - int16_t si16_2, - uint32_t ui32_2, - int32_t si32_2, - uint64_t ui64_2, - int64_t si64_2, - float f_2, - double d_2, - long double ld_2, - char* p_2, - uint8_t ui8_3, - int8_t si8_3, - uint16_t ui16_3, - int16_t si16_3, - uint32_t ui32_3, - int32_t si32_3, - uint64_t ui64_3, - int64_t si64_3, - float f_3, - double d_3, - long double ld_3, - char* p_3, - uint8_t ui8_4, - int8_t si8_4, - uint16_t ui16_4, - int16_t si16_4, - uint32_t ui32_4, - int32_t si32_4, - uint64_t ui64_4, - int64_t si64_4, - float f_4, - double d_4, - long double ld_4, - char* p_4, - uint8_t ui8_5, - int8_t si8_5) -{ - BigStruct retVal = { - ui8_1 + 1, si8_1 + 1, ui16_1 + 1, si16_1 + 1, ui32_1 + 1, si32_1 + 1, - ui64_1 + 1, si64_1 + 1, f_1 + 1, d_1 + 1, ld_1 + 1, (char*)((intptr_t)p_1 + 1), - ui8_2 + 2, si8_2 + 2, ui16_2 + 2, si16_2 + 2, ui32_2 + 2, si32_2 + 2, - ui64_2 + 2, si64_2 + 2, f_2 + 2, d_2 + 2, ld_2 + 2, (char*)((intptr_t)p_2 + 2), - ui8_3 + 3, si8_3 + 3, ui16_3 + 3, si16_3 + 3, ui32_3 + 3, si32_3 + 3, - ui64_3 + 3, si64_3 + 3, f_3 + 3, d_3 + 3, ld_3 + 3, (char*)((intptr_t)p_3 + 3), - ui8_4 + 4, si8_4 + 4, ui16_4 + 4, si16_4 + 4, ui32_4 + 4, si32_4 + 4, - ui64_4 + 4, si64_4 + 4, f_4 + 4, d_4 + 4, ld_4 + 4, (char*)((intptr_t)p_4 + 4), - ui8_5 + 5, si8_5 + 5}; - - printf("%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 ": " - "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n", - 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, - 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, - 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, - 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, - retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f, - retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l, - retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r, - retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x, - retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd, - retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj, - retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp, - retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx); - - return retVal; -} - -static void -cls_large_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__) -{ - uint8_t ui8_1 = *(uint8_t*)args[0]; - int8_t si8_1 = *(int8_t*)args[1]; - uint16_t ui16_1 = *(uint16_t*)args[2]; - int16_t si16_1 = *(int16_t*)args[3]; - uint32_t ui32_1 = *(uint32_t*)args[4]; - int32_t si32_1 = *(int32_t*)args[5]; - uint64_t ui64_1 = *(uint64_t*)args[6]; - int64_t si64_1 = *(int64_t*)args[7]; - float f_1 = *(float*)args[8]; - double d_1 = *(double*)args[9]; - long double ld_1 = *(long double*)args[10]; - char* p_1 = *(char**)args[11]; - uint8_t ui8_2 = *(uint8_t*)args[12]; - int8_t si8_2 = *(int8_t*)args[13]; - uint16_t ui16_2 = *(uint16_t*)args[14]; - int16_t si16_2 = *(int16_t*)args[15]; - uint32_t ui32_2 = *(uint32_t*)args[16]; - int32_t si32_2 = *(int32_t*)args[17]; - uint64_t ui64_2 = *(uint64_t*)args[18]; - int64_t si64_2 = *(int64_t*)args[19]; - float f_2 = *(float*)args[20]; - double d_2 = *(double*)args[21]; - long double ld_2 = *(long double*)args[22]; - char* p_2 = *(char**)args[23]; - uint8_t ui8_3 = *(uint8_t*)args[24]; - int8_t si8_3 = *(int8_t*)args[25]; - uint16_t ui16_3 = *(uint16_t*)args[26]; - int16_t si16_3 = *(int16_t*)args[27]; - uint32_t ui32_3 = *(uint32_t*)args[28]; - int32_t si32_3 = *(int32_t*)args[29]; - uint64_t ui64_3 = *(uint64_t*)args[30]; - int64_t si64_3 = *(int64_t*)args[31]; - float f_3 = *(float*)args[32]; - double d_3 = *(double*)args[33]; - long double ld_3 = *(long double*)args[34]; - char* p_3 = *(char**)args[35]; - uint8_t ui8_4 = *(uint8_t*)args[36]; - int8_t si8_4 = *(int8_t*)args[37]; - uint16_t ui16_4 = *(uint16_t*)args[38]; - int16_t si16_4 = *(int16_t*)args[39]; - uint32_t ui32_4 = *(uint32_t*)args[40]; - int32_t si32_4 = *(int32_t*)args[41]; - uint64_t ui64_4 = *(uint64_t*)args[42]; - int64_t si64_4 = *(int64_t*)args[43]; - float f_4 = *(float*)args[44]; - double d_4 = *(double*)args[45]; - long double ld_4 = *(long double*)args[46]; - char* p_4 = *(char**)args[47]; - uint8_t ui8_5 = *(uint8_t*)args[48]; - int8_t si8_5 = *(int8_t*)args[49]; - - *(BigStruct*)resp = test_large_fn( - ui8_1, si8_1, ui16_1, si16_1, ui32_1, si32_1, ui64_1, si64_1, f_1, d_1, ld_1, p_1, - ui8_2, si8_2, ui16_2, si16_2, ui32_2, si32_2, ui64_2, si64_2, f_2, d_2, ld_2, p_2, - ui8_3, si8_3, ui16_3, si16_3, ui32_3, si32_3, ui64_3, si64_3, f_3, d_3, ld_3, p_3, - ui8_4, si8_4, ui16_4, si16_4, ui32_4, si32_4, ui64_4, si64_4, f_4, d_4, ld_4, p_4, - ui8_5, si8_5); -} - -int -main(int argc __UNUSED__, const char** argv __UNUSED__) -{ - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - - ffi_cif cif; - ffi_type* argTypes[51]; - void* argValues[51]; - - ffi_type ret_struct_type; - ffi_type* st_fields[51]; - BigStruct retVal; - - uint8_t ui8 = 1; - int8_t si8 = 2; - uint16_t ui16 = 3; - int16_t si16 = 4; - uint32_t ui32 = 5; - int32_t si32 = 6; - uint64_t ui64 = 7; - int64_t si64 = 8; - float f = 9; - double d = 10; - long double ld = 11; - char* p = (char*)0x12345678; - - memset (&retVal, 0, sizeof(retVal)); - - ret_struct_type.size = 0; - ret_struct_type.alignment = 0; - ret_struct_type.type = FFI_TYPE_STRUCT; - ret_struct_type.elements = st_fields; - - st_fields[0] = st_fields[12] = st_fields[24] = st_fields[36] = st_fields[48] = &ffi_type_uint8; - st_fields[1] = st_fields[13] = st_fields[25] = st_fields[37] = st_fields[49] = &ffi_type_sint8; - st_fields[2] = st_fields[14] = st_fields[26] = st_fields[38] = &ffi_type_uint16; - st_fields[3] = st_fields[15] = st_fields[27] = st_fields[39] = &ffi_type_sint16; - st_fields[4] = st_fields[16] = st_fields[28] = st_fields[40] = &ffi_type_uint32; - st_fields[5] = st_fields[17] = st_fields[29] = st_fields[41] = &ffi_type_sint32; - st_fields[6] = st_fields[18] = st_fields[30] = st_fields[42] = &ffi_type_uint64; - st_fields[7] = st_fields[19] = st_fields[31] = st_fields[43] = &ffi_type_sint64; - st_fields[8] = st_fields[20] = st_fields[32] = st_fields[44] = &ffi_type_float; - st_fields[9] = st_fields[21] = st_fields[33] = st_fields[45] = &ffi_type_double; - st_fields[10] = st_fields[22] = st_fields[34] = st_fields[46] = &ffi_type_longdouble; - st_fields[11] = st_fields[23] = st_fields[35] = st_fields[47] = &ffi_type_pointer; - - st_fields[50] = NULL; - - argTypes[0] = argTypes[12] = argTypes[24] = argTypes[36] = argTypes[48] = &ffi_type_uint8; - argValues[0] = argValues[12] = argValues[24] = argValues[36] = argValues[48] = &ui8; - argTypes[1] = argTypes[13] = argTypes[25] = argTypes[37] = argTypes[49] = &ffi_type_sint8; - argValues[1] = argValues[13] = argValues[25] = argValues[37] = argValues[49] = &si8; - argTypes[2] = argTypes[14] = argTypes[26] = argTypes[38] = &ffi_type_uint16; - argValues[2] = argValues[14] = argValues[26] = argValues[38] = &ui16; - argTypes[3] = argTypes[15] = argTypes[27] = argTypes[39] = &ffi_type_sint16; - argValues[3] = argValues[15] = argValues[27] = argValues[39] = &si16; - argTypes[4] = argTypes[16] = argTypes[28] = argTypes[40] = &ffi_type_uint32; - argValues[4] = argValues[16] = argValues[28] = argValues[40] = &ui32; - argTypes[5] = argTypes[17] = argTypes[29] = argTypes[41] = &ffi_type_sint32; - argValues[5] = argValues[17] = argValues[29] = argValues[41] = &si32; - argTypes[6] = argTypes[18] = argTypes[30] = argTypes[42] = &ffi_type_uint64; - argValues[6] = argValues[18] = argValues[30] = argValues[42] = &ui64; - argTypes[7] = argTypes[19] = argTypes[31] = argTypes[43] = &ffi_type_sint64; - argValues[7] = argValues[19] = argValues[31] = argValues[43] = &si64; - argTypes[8] = argTypes[20] = argTypes[32] = argTypes[44] = &ffi_type_float; - argValues[8] = argValues[20] = argValues[32] = argValues[44] = &f; - argTypes[9] = argTypes[21] = argTypes[33] = argTypes[45] = &ffi_type_double; - argValues[9] = argValues[21] = argValues[33] = argValues[45] = &d; - argTypes[10] = argTypes[22] = argTypes[34] = argTypes[46] = &ffi_type_longdouble; - argValues[10] = argValues[22] = argValues[34] = argValues[46] = &ld; - argTypes[11] = argTypes[23] = argTypes[35] = argTypes[47] = &ffi_type_pointer; - argValues[11] = argValues[23] = argValues[35] = argValues[47] = &p; - - argTypes[50] = NULL; - argValues[50] = NULL; - - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 50, &ret_struct_type, argTypes) == FFI_OK); - - ffi_call(&cif, FFI_FN(test_large_fn), &retVal, argValues); - /* { 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" } */ - printf("res: %" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n", - retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f, - retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l, - retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r, - retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x, - retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd, - retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj, - retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp, - retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx); - /* { 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" } */ - - CHECK(ffi_prep_closure_loc(pcl, &cif, cls_large_fn, NULL, code) == FFI_OK); - - retVal = ((BigStruct(*)( - uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*, - uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*, - uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*, - uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*, - uint8_t, int8_t))(code))( - ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p, - ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p, - ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p, - ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p, - ui8, si8); - /* { 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" } */ - printf("res: %" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n", - retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f, - retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l, - retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r, - retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x, - retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd, - retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj, - retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp, - retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx); - /* { 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" } */ - - return 0; -} diff --git a/testsuite/libffi.call/nested_struct.c b/testsuite/libffi.call/nested_struct.c deleted file mode 100644 index c15e3a0..0000000 --- a/testsuite/libffi.call/nested_struct.c +++ /dev/null @@ -1,152 +0,0 @@ -/* Area: ffi_call, closure_call - Purpose: Check structure passing with different structure size. - Contains structs as parameter of the struct itself. - Limitations: none. - PR: none. - Originator: 20030828 */ - -/* { dg-do run } */ -#include "ffitest.h" - -typedef struct cls_struct_16byte1 { - double a; - float b; - int c; -} cls_struct_16byte1; - -typedef struct cls_struct_16byte2 { - int ii; - double dd; - float ff; -} cls_struct_16byte2; - -typedef struct cls_struct_combined { - cls_struct_16byte1 d; - cls_struct_16byte2 e; -} cls_struct_combined; - -cls_struct_combined cls_struct_combined_fn(struct cls_struct_16byte1 b0, - struct cls_struct_16byte2 b1, - struct cls_struct_combined b2) -{ - struct cls_struct_combined result; - - result.d.a = b0.a + b1.dd + b2.d.a; - result.d.b = b0.b + b1.ff + b2.d.b; - result.d.c = b0.c + b1.ii + b2.d.c; - result.e.ii = b0.c + b1.ii + b2.e.ii; - result.e.dd = b0.a + b1.dd + b2.e.dd; - result.e.ff = b0.b + b1.ff + b2.e.ff; - - printf("%g %g %d %d %g %g %g %g %d %d %g %g: %g %g %d %d %g %g\n", - b0.a, b0.b, b0.c, - b1.ii, b1.dd, b1.ff, - b2.d.a, b2.d.b, b2.d.c, - b2.e.ii, b2.e.dd, b2.e.ff, - result.d.a, result.d.b, result.d.c, - result.e.ii, result.e.dd, result.e.ff); - - return result; -} - -static void -cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, - void* userdata __UNUSED__) -{ - struct cls_struct_16byte1 b0; - struct cls_struct_16byte2 b1; - struct cls_struct_combined b2; - - b0 = *(struct cls_struct_16byte1*)(args[0]); - b1 = *(struct cls_struct_16byte2*)(args[1]); - b2 = *(struct cls_struct_combined*)(args[2]); - - - *(cls_struct_combined*)resp = cls_struct_combined_fn(b0, b1, b2); -} - -int main (void) -{ - ffi_cif cif; - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - void* args_dbl[5]; - ffi_type* cls_struct_fields[5]; - ffi_type* cls_struct_fields1[5]; - ffi_type* cls_struct_fields2[5]; - ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; - ffi_type* dbl_arg_types[5]; - - struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6}; - struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0}; - struct cls_struct_combined g_dbl = {{4.0, 5.0, 6}, - {3, 1.0, 8.0}}; - struct cls_struct_combined res_dbl; - - cls_struct_type.size = 0; - cls_struct_type.alignment = 0; - cls_struct_type.type = FFI_TYPE_STRUCT; - cls_struct_type.elements = cls_struct_fields; - - cls_struct_type1.size = 0; - cls_struct_type1.alignment = 0; - cls_struct_type1.type = FFI_TYPE_STRUCT; - cls_struct_type1.elements = cls_struct_fields1; - - cls_struct_type2.size = 0; - cls_struct_type2.alignment = 0; - cls_struct_type2.type = FFI_TYPE_STRUCT; - cls_struct_type2.elements = cls_struct_fields2; - - cls_struct_fields[0] = &ffi_type_double; - cls_struct_fields[1] = &ffi_type_float; - cls_struct_fields[2] = &ffi_type_sint; - cls_struct_fields[3] = NULL; - - cls_struct_fields1[0] = &ffi_type_sint; - cls_struct_fields1[1] = &ffi_type_double; - cls_struct_fields1[2] = &ffi_type_float; - cls_struct_fields1[3] = NULL; - - cls_struct_fields2[0] = &cls_struct_type; - cls_struct_fields2[1] = &cls_struct_type1; - cls_struct_fields2[2] = NULL; - - - dbl_arg_types[0] = &cls_struct_type; - dbl_arg_types[1] = &cls_struct_type1; - dbl_arg_types[2] = &cls_struct_type2; - dbl_arg_types[3] = NULL; - - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type2, - dbl_arg_types) == FFI_OK); - - args_dbl[0] = &e_dbl; - args_dbl[1] = &f_dbl; - args_dbl[2] = &g_dbl; - args_dbl[3] = NULL; - - ffi_call(&cif, FFI_FN(cls_struct_combined_fn), &res_dbl, args_dbl); - /* { dg-output "9 2 6 1 2 3 4 5 6 3 1 8: 15 10 13 10 12 13" } */ - CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a)); - CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b)); - CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c)); - CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii)); - CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd)); - CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff)); - - CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK); - - res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1, - cls_struct_16byte2, - cls_struct_combined)) - (code))(e_dbl, f_dbl, g_dbl); - /* { dg-output "\n9 2 6 1 2 3 4 5 6 3 1 8: 15 10 13 10 12 13" } */ - CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a)); - CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b)); - CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c)); - CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii)); - CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd)); - CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff)); - exit(0); -} diff --git a/testsuite/libffi.call/nested_struct1.c b/testsuite/libffi.call/nested_struct1.c deleted file mode 100644 index 477a6b9..0000000 --- a/testsuite/libffi.call/nested_struct1.c +++ /dev/null @@ -1,161 +0,0 @@ -/* Area: ffi_call, closure_call - Purpose: Check structure passing with different structure size. - Contains structs as parameter of the struct itself. - Limitations: none. - PR: none. - Originator: 20030828 */ - -/* { dg-do run } */ -#include "ffitest.h" - -typedef struct cls_struct_16byte1 { - double a; - float b; - int c; -} cls_struct_16byte1; - -typedef struct cls_struct_16byte2 { - int ii; - double dd; - float ff; -} cls_struct_16byte2; - -typedef struct cls_struct_combined { - cls_struct_16byte1 d; - cls_struct_16byte2 e; -} cls_struct_combined; - -cls_struct_combined cls_struct_combined_fn(struct cls_struct_16byte1 b0, - struct cls_struct_16byte2 b1, - struct cls_struct_combined b2, - struct cls_struct_16byte1 b3) -{ - struct cls_struct_combined result; - - result.d.a = b0.a + b1.dd + b2.d.a; - result.d.b = b0.b + b1.ff + b2.d.b; - result.d.c = b0.c + b1.ii + b2.d.c; - result.e.ii = b0.c + b1.ii + b2.e.ii; - result.e.dd = b0.a + b1.dd + b2.e.dd; - result.e.ff = b0.b + b1.ff + b2.e.ff; - - printf("%g %g %d %d %g %g %g %g %d %d %g %g %g %g %d: %g %g %d %d %g %g\n", - b0.a, b0.b, b0.c, - b1.ii, b1.dd, b1.ff, - b2.d.a, b2.d.b, b2.d.c, - b2.e.ii, b2.e.dd, b2.e.ff, - b3.a, b3.b, b3.c, - result.d.a, result.d.b, result.d.c, - result.e.ii, result.e.dd, result.e.ff); - - return result; -} - -static void -cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, - void* userdata __UNUSED__) -{ - struct cls_struct_16byte1 b0; - struct cls_struct_16byte2 b1; - struct cls_struct_combined b2; - struct cls_struct_16byte1 b3; - - b0 = *(struct cls_struct_16byte1*)(args[0]); - b1 = *(struct cls_struct_16byte2*)(args[1]); - b2 = *(struct cls_struct_combined*)(args[2]); - b3 = *(struct cls_struct_16byte1*)(args[3]); - - - *(cls_struct_combined*)resp = cls_struct_combined_fn(b0, b1, b2, b3); -} - -int main (void) -{ - ffi_cif cif; - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - void* args_dbl[5]; - ffi_type* cls_struct_fields[5]; - ffi_type* cls_struct_fields1[5]; - ffi_type* cls_struct_fields2[5]; - ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; - ffi_type* dbl_arg_types[5]; - - struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6}; - struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0}; - struct cls_struct_combined g_dbl = {{4.0, 5.0, 6}, - {3, 1.0, 8.0}}; - struct cls_struct_16byte1 h_dbl = { 3.0, 2.0, 4}; - struct cls_struct_combined res_dbl; - - cls_struct_type.size = 0; - cls_struct_type.alignment = 0; - cls_struct_type.type = FFI_TYPE_STRUCT; - cls_struct_type.elements = cls_struct_fields; - - cls_struct_type1.size = 0; - cls_struct_type1.alignment = 0; - cls_struct_type1.type = FFI_TYPE_STRUCT; - cls_struct_type1.elements = cls_struct_fields1; - - cls_struct_type2.size = 0; - cls_struct_type2.alignment = 0; - cls_struct_type2.type = FFI_TYPE_STRUCT; - cls_struct_type2.elements = cls_struct_fields2; - - cls_struct_fields[0] = &ffi_type_double; - cls_struct_fields[1] = &ffi_type_float; - cls_struct_fields[2] = &ffi_type_sint; - cls_struct_fields[3] = NULL; - - cls_struct_fields1[0] = &ffi_type_sint; - cls_struct_fields1[1] = &ffi_type_double; - cls_struct_fields1[2] = &ffi_type_float; - cls_struct_fields1[3] = NULL; - - cls_struct_fields2[0] = &cls_struct_type; - cls_struct_fields2[1] = &cls_struct_type1; - cls_struct_fields2[2] = NULL; - - - dbl_arg_types[0] = &cls_struct_type; - dbl_arg_types[1] = &cls_struct_type1; - dbl_arg_types[2] = &cls_struct_type2; - dbl_arg_types[3] = &cls_struct_type; - dbl_arg_types[4] = NULL; - - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type2, - dbl_arg_types) == FFI_OK); - - args_dbl[0] = &e_dbl; - args_dbl[1] = &f_dbl; - args_dbl[2] = &g_dbl; - args_dbl[3] = &h_dbl; - args_dbl[4] = NULL; - - ffi_call(&cif, FFI_FN(cls_struct_combined_fn), &res_dbl, args_dbl); - /* { dg-output "9 2 6 1 2 3 4 5 6 3 1 8 3 2 4: 15 10 13 10 12 13" } */ - CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a)); - CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b)); - CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c)); - CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii)); - CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd)); - CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff)); - - CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK); - - res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1, - cls_struct_16byte2, - cls_struct_combined, - cls_struct_16byte1)) - (code))(e_dbl, f_dbl, g_dbl, h_dbl); - /* { dg-output "\n9 2 6 1 2 3 4 5 6 3 1 8 3 2 4: 15 10 13 10 12 13" } */ - CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a)); - CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b)); - CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c)); - CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii)); - CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd)); - CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff)); - /* CHECK( 1 == 0); */ - exit(0); -} diff --git a/testsuite/libffi.call/nested_struct10.c b/testsuite/libffi.call/nested_struct10.c deleted file mode 100644 index 3cf2b44..0000000 --- a/testsuite/libffi.call/nested_struct10.c +++ /dev/null @@ -1,134 +0,0 @@ -/* Area: ffi_call, closure_call - Purpose: Check structure passing with different structure size. - Contains structs as parameter of the struct itself. - Sample taken from Alan Modras patch to src/prep_cif.c. - Limitations: none. - PR: none. - Originator: 20051010 */ - -/* { dg-do run } */ -#include "ffitest.h" - -typedef struct A { - unsigned long long a; - unsigned char b; -} A; - -typedef struct B { - unsigned char y; - struct A x; - unsigned int z; -} B; - -typedef struct C { - unsigned long long d; - unsigned char e; -} C; - -static B B_fn(struct A b2, struct B b3, struct C b4) -{ - struct B result; - - result.x.a = b2.a + b3.x.a + b3.z + b4.d; - result.x.b = b2.b + b3.x.b + b3.y + b4.e; - result.y = b2.b + b3.x.b + b4.e; - result.z = 0; - - printf("%d %d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b, - (int)b3.x.a, b3.x.b, b3.y, b3.z, (int)b4.d, b4.e, - (int)result.x.a, result.x.b, result.y); - - return result; -} - -static void -B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, - void* userdata __UNUSED__) -{ - struct A b0; - struct B b1; - struct C b2; - - b0 = *(struct A*)(args[0]); - b1 = *(struct B*)(args[1]); - b2 = *(struct C*)(args[2]); - - *(B*)resp = B_fn(b0, b1, b2); -} - -int main (void) -{ - ffi_cif cif; - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - void* args_dbl[4]; - ffi_type* cls_struct_fields[3]; - ffi_type* cls_struct_fields1[4]; - ffi_type* cls_struct_fields2[3]; - ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; - ffi_type* dbl_arg_types[4]; - - struct A e_dbl = { 1LL, 7}; - struct B f_dbl = { 99, {12LL , 127}, 255}; - struct C g_dbl = { 2LL, 9}; - - struct B res_dbl; - - cls_struct_type.size = 0; - cls_struct_type.alignment = 0; - cls_struct_type.type = FFI_TYPE_STRUCT; - cls_struct_type.elements = cls_struct_fields; - - cls_struct_type1.size = 0; - cls_struct_type1.alignment = 0; - cls_struct_type1.type = FFI_TYPE_STRUCT; - cls_struct_type1.elements = cls_struct_fields1; - - cls_struct_type2.size = 0; - cls_struct_type2.alignment = 0; - cls_struct_type2.type = FFI_TYPE_STRUCT; - cls_struct_type2.elements = cls_struct_fields2; - - cls_struct_fields[0] = &ffi_type_uint64; - cls_struct_fields[1] = &ffi_type_uchar; - cls_struct_fields[2] = NULL; - - cls_struct_fields1[0] = &ffi_type_uchar; - cls_struct_fields1[1] = &cls_struct_type; - cls_struct_fields1[2] = &ffi_type_uint; - cls_struct_fields1[3] = NULL; - - cls_struct_fields2[0] = &ffi_type_uint64; - cls_struct_fields2[1] = &ffi_type_uchar; - cls_struct_fields2[2] = NULL; - - - dbl_arg_types[0] = &cls_struct_type; - dbl_arg_types[1] = &cls_struct_type1; - dbl_arg_types[2] = &cls_struct_type2; - dbl_arg_types[3] = NULL; - - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1, - dbl_arg_types) == FFI_OK); - - args_dbl[0] = &e_dbl; - args_dbl[1] = &f_dbl; - args_dbl[2] = &g_dbl; - args_dbl[3] = NULL; - - ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); - /* { dg-output "1 7 12 127 99 255 2 9: 270 242 143" } */ - CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + f_dbl.z + g_dbl.d)); - CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); - CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); - - CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); - - res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl); - /* { dg-output "\n1 7 12 127 99 255 2 9: 270 242 143" } */ - CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + f_dbl.z + g_dbl.d)); - CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); - CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); - - exit(0); -} diff --git a/testsuite/libffi.call/nested_struct11.c b/testsuite/libffi.call/nested_struct11.c deleted file mode 100644 index 3510493..0000000 --- a/testsuite/libffi.call/nested_struct11.c +++ /dev/null @@ -1,121 +0,0 @@ -/* Area: ffi_call, closure_call - Purpose: Check parameter passing with nested structs - of a single type. This tests the special cases - for homogeneous floating-point aggregates in the - AArch64 PCS. - Limitations: none. - PR: none. - Originator: ARM Ltd. */ - -/* { dg-do run } */ -#include "ffitest.h" - -typedef struct A { - float a_x; - float a_y; -} A; - -typedef struct B { - float b_x; - float b_y; -} B; - -typedef struct C { - A a; - B b; -} C; - -static C C_fn (int x, int y, int z, C source, int i, int j, int k) -{ - C result; - result.a.a_x = source.a.a_x; - result.a.a_y = source.a.a_y; - result.b.b_x = source.b.b_x; - result.b.b_y = source.b.b_y; - - printf ("%d, %d, %d, %d, %d, %d\n", x, y, z, i, j, k); - - printf ("%.1f, %.1f, %.1f, %.1f, " - "%.1f, %.1f, %.1f, %.1f\n", - source.a.a_x, source.a.a_y, - source.b.b_x, source.b.b_y, - result.a.a_x, result.a.a_y, - result.b.b_x, result.b.b_y); - - return result; -} - -int main (void) -{ - ffi_cif cif; - - ffi_type* struct_fields_source_a[3]; - ffi_type* struct_fields_source_b[3]; - ffi_type* struct_fields_source_c[3]; - ffi_type* arg_types[8]; - - ffi_type struct_type_a, struct_type_b, struct_type_c; - - struct A source_fld_a = {1.0, 2.0}; - struct B source_fld_b = {4.0, 8.0}; - int k = 1; - - struct C result; - struct C source = {source_fld_a, source_fld_b}; - - struct_type_a.size = 0; - struct_type_a.alignment = 0; - struct_type_a.type = FFI_TYPE_STRUCT; - struct_type_a.elements = struct_fields_source_a; - - struct_type_b.size = 0; - struct_type_b.alignment = 0; - struct_type_b.type = FFI_TYPE_STRUCT; - struct_type_b.elements = struct_fields_source_b; - - struct_type_c.size = 0; - struct_type_c.alignment = 0; - struct_type_c.type = FFI_TYPE_STRUCT; - struct_type_c.elements = struct_fields_source_c; - - struct_fields_source_a[0] = &ffi_type_float; - struct_fields_source_a[1] = &ffi_type_float; - struct_fields_source_a[2] = NULL; - - struct_fields_source_b[0] = &ffi_type_float; - struct_fields_source_b[1] = &ffi_type_float; - struct_fields_source_b[2] = NULL; - - struct_fields_source_c[0] = &struct_type_a; - struct_fields_source_c[1] = &struct_type_b; - struct_fields_source_c[2] = NULL; - - arg_types[0] = &ffi_type_sint32; - arg_types[1] = &ffi_type_sint32; - arg_types[2] = &ffi_type_sint32; - arg_types[3] = &struct_type_c; - arg_types[4] = &ffi_type_sint32; - arg_types[5] = &ffi_type_sint32; - arg_types[6] = &ffi_type_sint32; - arg_types[7] = NULL; - - void *args[7]; - args[0] = &k; - args[1] = &k; - args[2] = &k; - args[3] = &source; - args[4] = &k; - args[5] = &k; - args[6] = &k; - CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 7, &struct_type_c, - arg_types) == FFI_OK); - - ffi_call (&cif, FFI_FN (C_fn), &result, args); - /* { dg-output "1, 1, 1, 1, 1, 1\n" } */ - /* { dg-output "1.0, 2.0, 4.0, 8.0, 1.0, 2.0, 4.0, 8.0" } */ - CHECK (result.a.a_x == source.a.a_x); - CHECK (result.a.a_y == source.a.a_y); - CHECK (result.b.b_x == source.b.b_x); - CHECK (result.b.b_y == source.b.b_y); - exit (0); -} diff --git a/testsuite/libffi.call/nested_struct2.c b/testsuite/libffi.call/nested_struct2.c deleted file mode 100644 index 69268cd..0000000 --- a/testsuite/libffi.call/nested_struct2.c +++ /dev/null @@ -1,110 +0,0 @@ -/* Area: ffi_call, closure_call - Purpose: Check structure passing with different structure size. - Contains structs as parameter of the struct itself. - Sample taken from Alan Modras patch to src/prep_cif.c. - Limitations: none. - PR: none. - Originator: 20030911 */ - -/* { dg-do run } */ -#include "ffitest.h" - -typedef struct A { - unsigned long a; - unsigned char b; -} A; - -typedef struct B { - struct A x; - unsigned char y; -} B; - -B B_fn(struct A b0, struct B b1) -{ - struct B result; - - result.x.a = b0.a + b1.x.a; - result.x.b = b0.b + b1.x.b + b1.y; - result.y = b0.b + b1.x.b; - - printf("%lu %d %lu %d %d: %lu %d %d\n", b0.a, b0.b, b1.x.a, b1.x.b, b1.y, - result.x.a, result.x.b, result.y); - - return result; -} - -static void -B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, - void* userdata __UNUSED__) -{ - struct A b0; - struct B b1; - - b0 = *(struct A*)(args[0]); - b1 = *(struct B*)(args[1]); - - *(B*)resp = B_fn(b0, b1); -} - -int main (void) -{ - ffi_cif cif; - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - void* args_dbl[3]; - ffi_type* cls_struct_fields[3]; - ffi_type* cls_struct_fields1[3]; - ffi_type cls_struct_type, cls_struct_type1; - ffi_type* dbl_arg_types[3]; - - struct A e_dbl = { 1, 7}; - struct B f_dbl = {{12 , 127}, 99}; - - struct B res_dbl; - - cls_struct_type.size = 0; - cls_struct_type.alignment = 0; - cls_struct_type.type = FFI_TYPE_STRUCT; - cls_struct_type.elements = cls_struct_fields; - - cls_struct_type1.size = 0; - cls_struct_type1.alignment = 0; - cls_struct_type1.type = FFI_TYPE_STRUCT; - cls_struct_type1.elements = cls_struct_fields1; - - cls_struct_fields[0] = &ffi_type_ulong; - cls_struct_fields[1] = &ffi_type_uchar; - cls_struct_fields[2] = NULL; - - cls_struct_fields1[0] = &cls_struct_type; - cls_struct_fields1[1] = &ffi_type_uchar; - cls_struct_fields1[2] = NULL; - - - dbl_arg_types[0] = &cls_struct_type; - dbl_arg_types[1] = &cls_struct_type1; - dbl_arg_types[2] = NULL; - - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1, - dbl_arg_types) == FFI_OK); - - args_dbl[0] = &e_dbl; - args_dbl[1] = &f_dbl; - args_dbl[2] = NULL; - - ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); - /* { dg-output "1 7 12 127 99: 13 233 134" } */ - CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); - CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); - CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); - - CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); - - res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl); - /* { dg-output "\n1 7 12 127 99: 13 233 134" } */ - CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); - CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); - CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); - - exit(0); -} diff --git a/testsuite/libffi.call/nested_struct4.c b/testsuite/libffi.call/nested_struct4.c deleted file mode 100644 index 2ffb4d6..0000000 --- a/testsuite/libffi.call/nested_struct4.c +++ /dev/null @@ -1,111 +0,0 @@ -/* Area: ffi_call, closure_call - Purpose: Check structure passing with different structure size. - Contains structs as parameter of the struct itself. - Sample taken from Alan Modras patch to src/prep_cif.c. - Limitations: none. - PR: PR 25630. - Originator: 20051010 */ - -/* { dg-do run } */ -#include "ffitest.h" - -typedef struct A { - double a; - unsigned char b; -} A; - -typedef struct B { - struct A x; - unsigned char y; -} B; - -static B B_fn(struct A b2, struct B b3) -{ - struct B result; - - result.x.a = b2.a + b3.x.a; - result.x.b = b2.b + b3.x.b + b3.y; - result.y = b2.b + b3.x.b; - - printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b, - (int)b3.x.a, b3.x.b, b3.y, - (int)result.x.a, result.x.b, result.y); - - return result; -} - -static void -B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, - void* userdata __UNUSED__) -{ - struct A b0; - struct B b1; - - b0 = *(struct A*)(args[0]); - b1 = *(struct B*)(args[1]); - - *(B*)resp = B_fn(b0, b1); -} - -int main (void) -{ - ffi_cif cif; - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - void* args_dbl[3]; - ffi_type* cls_struct_fields[3]; - ffi_type* cls_struct_fields1[3]; - ffi_type cls_struct_type, cls_struct_type1; - ffi_type* dbl_arg_types[3]; - - struct A e_dbl = { 1.0, 7}; - struct B f_dbl = {{12.0 , 127}, 99}; - - struct B res_dbl; - - cls_struct_type.size = 0; - cls_struct_type.alignment = 0; - cls_struct_type.type = FFI_TYPE_STRUCT; - cls_struct_type.elements = cls_struct_fields; - - cls_struct_type1.size = 0; - cls_struct_type1.alignment = 0; - cls_struct_type1.type = FFI_TYPE_STRUCT; - cls_struct_type1.elements = cls_struct_fields1; - - cls_struct_fields[0] = &ffi_type_double; - cls_struct_fields[1] = &ffi_type_uchar; - cls_struct_fields[2] = NULL; - - cls_struct_fields1[0] = &cls_struct_type; - cls_struct_fields1[1] = &ffi_type_uchar; - cls_struct_fields1[2] = NULL; - - - dbl_arg_types[0] = &cls_struct_type; - dbl_arg_types[1] = &cls_struct_type1; - dbl_arg_types[2] = NULL; - - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1, - dbl_arg_types) == FFI_OK); - - args_dbl[0] = &e_dbl; - args_dbl[1] = &f_dbl; - args_dbl[2] = NULL; - - ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); - /* { dg-output "1 7 12 127 99: 13 233 134" } */ - CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); - CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); - CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); - - CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); - - res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl); - /* { dg-output "\n1 7 12 127 99: 13 233 134" } */ - CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); - CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); - CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); - - exit(0); -} diff --git a/testsuite/libffi.call/nested_struct5.c b/testsuite/libffi.call/nested_struct5.c deleted file mode 100644 index 6c79845..0000000 --- a/testsuite/libffi.call/nested_struct5.c +++ /dev/null @@ -1,112 +0,0 @@ -/* Area: ffi_call, closure_call - Purpose: Check structure passing with different structure size. - Contains structs as parameter of the struct itself. - Sample taken from Alan Modras patch to src/prep_cif.c. - Limitations: none. - PR: none. - Originator: 20051010 */ - -/* { dg-do run } */ -#include "ffitest.h" - -typedef struct A { - long double a; - unsigned char b; -} A; - -typedef struct B { - struct A x; - unsigned char y; -} B; - -static B B_fn(struct A b2, struct B b3) -{ - struct B result; - - result.x.a = b2.a + b3.x.a; - result.x.b = b2.b + b3.x.b + b3.y; - result.y = b2.b + b3.x.b; - - printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b, - (int)b3.x.a, b3.x.b, b3.y, - (int)result.x.a, result.x.b, result.y); - - return result; -} - -static void -B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, - void* userdata __UNUSED__) -{ - struct A b0; - struct B b1; - - b0 = *(struct A*)(args[0]); - b1 = *(struct B*)(args[1]); - - *(B*)resp = B_fn(b0, b1); -} - -int main (void) -{ - ffi_cif cif; - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - void* args_dbl[3]; - ffi_type* cls_struct_fields[3]; - ffi_type* cls_struct_fields1[3]; - ffi_type cls_struct_type, cls_struct_type1; - ffi_type* dbl_arg_types[3]; - - struct A e_dbl = { 1.0, 7}; - struct B f_dbl = {{12.0 , 127}, 99}; - - struct B res_dbl; - - cls_struct_type.size = 0; - cls_struct_type.alignment = 0; - cls_struct_type.type = FFI_TYPE_STRUCT; - cls_struct_type.elements = cls_struct_fields; - - cls_struct_type1.size = 0; - cls_struct_type1.alignment = 0; - cls_struct_type1.type = FFI_TYPE_STRUCT; - cls_struct_type1.elements = cls_struct_fields1; - - cls_struct_fields[0] = &ffi_type_longdouble; - cls_struct_fields[1] = &ffi_type_uchar; - cls_struct_fields[2] = NULL; - - cls_struct_fields1[0] = &cls_struct_type; - cls_struct_fields1[1] = &ffi_type_uchar; - cls_struct_fields1[2] = NULL; - - - dbl_arg_types[0] = &cls_struct_type; - dbl_arg_types[1] = &cls_struct_type1; - dbl_arg_types[2] = NULL; - - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1, - dbl_arg_types) == FFI_OK); - - args_dbl[0] = &e_dbl; - args_dbl[1] = &f_dbl; - args_dbl[2] = NULL; - - ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); - /* { dg-output "1 7 12 127 99: 13 233 134" } */ - CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); - CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); - CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); - - - CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); - - res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl); - /* { dg-output "\n1 7 12 127 99: 13 233 134" } */ - CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); - CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); - CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); - - exit(0); -} diff --git a/testsuite/libffi.call/nested_struct6.c b/testsuite/libffi.call/nested_struct6.c deleted file mode 100644 index 59d3579..0000000 --- a/testsuite/libffi.call/nested_struct6.c +++ /dev/null @@ -1,131 +0,0 @@ -/* Area: ffi_call, closure_call - Purpose: Check structure passing with different structure size. - Contains structs as parameter of the struct itself. - Sample taken from Alan Modras patch to src/prep_cif.c. - Limitations: none. - PR: PR 25630. - Originator: 20051010 */ - -/* { dg-do run } */ -#include "ffitest.h" - -typedef struct A { - double a; - unsigned char b; -} A; - -typedef struct B { - struct A x; - unsigned char y; -} B; - -typedef struct C { - long d; - unsigned char e; -} C; - -static B B_fn(struct A b2, struct B b3, struct C b4) -{ - struct B result; - - result.x.a = b2.a + b3.x.a + b4.d; - result.x.b = b2.b + b3.x.b + b3.y + b4.e; - result.y = b2.b + b3.x.b + b4.e; - - printf("%d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b, - (int)b3.x.a, b3.x.b, b3.y, (int)b4.d, b4.e, - (int)result.x.a, result.x.b, result.y); - - return result; -} - -static void -B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, - void* userdata __UNUSED__) -{ - struct A b0; - struct B b1; - struct C b2; - - b0 = *(struct A*)(args[0]); - b1 = *(struct B*)(args[1]); - b2 = *(struct C*)(args[2]); - - *(B*)resp = B_fn(b0, b1, b2); -} - -int main (void) -{ - ffi_cif cif; - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - void* args_dbl[4]; - ffi_type* cls_struct_fields[3]; - ffi_type* cls_struct_fields1[3]; - ffi_type* cls_struct_fields2[3]; - ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; - ffi_type* dbl_arg_types[4]; - - struct A e_dbl = { 1.0, 7}; - struct B f_dbl = {{12.0 , 127}, 99}; - struct C g_dbl = { 2, 9}; - - struct B res_dbl; - - cls_struct_type.size = 0; - cls_struct_type.alignment = 0; - cls_struct_type.type = FFI_TYPE_STRUCT; - cls_struct_type.elements = cls_struct_fields; - - cls_struct_type1.size = 0; - cls_struct_type1.alignment = 0; - cls_struct_type1.type = FFI_TYPE_STRUCT; - cls_struct_type1.elements = cls_struct_fields1; - - cls_struct_type2.size = 0; - cls_struct_type2.alignment = 0; - cls_struct_type2.type = FFI_TYPE_STRUCT; - cls_struct_type2.elements = cls_struct_fields2; - - cls_struct_fields[0] = &ffi_type_double; - cls_struct_fields[1] = &ffi_type_uchar; - cls_struct_fields[2] = NULL; - - cls_struct_fields1[0] = &cls_struct_type; - cls_struct_fields1[1] = &ffi_type_uchar; - cls_struct_fields1[2] = NULL; - - cls_struct_fields2[0] = &ffi_type_slong; - cls_struct_fields2[1] = &ffi_type_uchar; - cls_struct_fields2[2] = NULL; - - - dbl_arg_types[0] = &cls_struct_type; - dbl_arg_types[1] = &cls_struct_type1; - dbl_arg_types[2] = &cls_struct_type2; - dbl_arg_types[3] = NULL; - - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1, - dbl_arg_types) == FFI_OK); - - args_dbl[0] = &e_dbl; - args_dbl[1] = &f_dbl; - args_dbl[2] = &g_dbl; - args_dbl[3] = NULL; - - ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); - /* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */ - CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d)); - CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); - CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); - - CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); - - res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl); - /* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */ - CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d)); - CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); - CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); - - exit(0); -} diff --git a/testsuite/libffi.call/nested_struct7.c b/testsuite/libffi.call/nested_struct7.c deleted file mode 100644 index 27595e6..0000000 --- a/testsuite/libffi.call/nested_struct7.c +++ /dev/null @@ -1,111 +0,0 @@ -/* Area: ffi_call, closure_call - Purpose: Check structure passing with different structure size. - Contains structs as parameter of the struct itself. - Sample taken from Alan Modras patch to src/prep_cif.c. - Limitations: none. - PR: none. - Originator: 20051010 */ - -/* { dg-do run } */ -#include "ffitest.h" - -typedef struct A { - unsigned long long a; - unsigned char b; -} A; - -typedef struct B { - struct A x; - unsigned char y; -} B; - -static B B_fn(struct A b2, struct B b3) -{ - struct B result; - - result.x.a = b2.a + b3.x.a; - result.x.b = b2.b + b3.x.b + b3.y; - result.y = b2.b + b3.x.b; - - printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b, - (int)b3.x.a, b3.x.b, b3.y, - (int)result.x.a, result.x.b, result.y); - - return result; -} - -static void -B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, - void* userdata __UNUSED__) -{ - struct A b0; - struct B b1; - - b0 = *(struct A*)(args[0]); - b1 = *(struct B*)(args[1]); - - *(B*)resp = B_fn(b0, b1); -} - -int main (void) -{ - ffi_cif cif; - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - void* args_dbl[3]; - ffi_type* cls_struct_fields[3]; - ffi_type* cls_struct_fields1[3]; - ffi_type cls_struct_type, cls_struct_type1; - ffi_type* dbl_arg_types[3]; - - struct A e_dbl = { 1LL, 7}; - struct B f_dbl = {{12.0 , 127}, 99}; - - struct B res_dbl; - - cls_struct_type.size = 0; - cls_struct_type.alignment = 0; - cls_struct_type.type = FFI_TYPE_STRUCT; - cls_struct_type.elements = cls_struct_fields; - - cls_struct_type1.size = 0; - cls_struct_type1.alignment = 0; - cls_struct_type1.type = FFI_TYPE_STRUCT; - cls_struct_type1.elements = cls_struct_fields1; - - cls_struct_fields[0] = &ffi_type_uint64; - cls_struct_fields[1] = &ffi_type_uchar; - cls_struct_fields[2] = NULL; - - cls_struct_fields1[0] = &cls_struct_type; - cls_struct_fields1[1] = &ffi_type_uchar; - cls_struct_fields1[2] = NULL; - - - dbl_arg_types[0] = &cls_struct_type; - dbl_arg_types[1] = &cls_struct_type1; - dbl_arg_types[2] = NULL; - - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1, - dbl_arg_types) == FFI_OK); - - args_dbl[0] = &e_dbl; - args_dbl[1] = &f_dbl; - args_dbl[2] = NULL; - - ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); - /* { dg-output "1 7 12 127 99: 13 233 134" } */ - CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); - CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); - CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); - - CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); - - res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl); - /* { dg-output "\n1 7 12 127 99: 13 233 134" } */ - CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); - CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); - CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); - - exit(0); -} diff --git a/testsuite/libffi.call/nested_struct8.c b/testsuite/libffi.call/nested_struct8.c deleted file mode 100644 index 0e6c682..0000000 --- a/testsuite/libffi.call/nested_struct8.c +++ /dev/null @@ -1,131 +0,0 @@ -/* Area: ffi_call, closure_call - Purpose: Check structure passing with different structure size. - Contains structs as parameter of the struct itself. - Sample taken from Alan Modras patch to src/prep_cif.c. - Limitations: none. - PR: none. - Originator: 20051010 */ - -/* { dg-do run } */ -#include "ffitest.h" - -typedef struct A { - unsigned long long a; - unsigned char b; -} A; - -typedef struct B { - struct A x; - unsigned char y; -} B; - -typedef struct C { - unsigned long long d; - unsigned char e; -} C; - -static B B_fn(struct A b2, struct B b3, struct C b4) -{ - struct B result; - - result.x.a = b2.a + b3.x.a + b4.d; - result.x.b = b2.b + b3.x.b + b3.y + b4.e; - result.y = b2.b + b3.x.b + b4.e; - - printf("%d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b, - (int)b3.x.a, b3.x.b, b3.y, (int)b4.d, b4.e, - (int)result.x.a, result.x.b, result.y); - - return result; -} - -static void -B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, - void* userdata __UNUSED__) -{ - struct A b0; - struct B b1; - struct C b2; - - b0 = *(struct A*)(args[0]); - b1 = *(struct B*)(args[1]); - b2 = *(struct C*)(args[2]); - - *(B*)resp = B_fn(b0, b1, b2); -} - -int main (void) -{ - ffi_cif cif; - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - void* args_dbl[4]; - ffi_type* cls_struct_fields[3]; - ffi_type* cls_struct_fields1[3]; - ffi_type* cls_struct_fields2[3]; - ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; - ffi_type* dbl_arg_types[4]; - - struct A e_dbl = { 1LL, 7}; - struct B f_dbl = {{12LL , 127}, 99}; - struct C g_dbl = { 2LL, 9}; - - struct B res_dbl; - - cls_struct_type.size = 0; - cls_struct_type.alignment = 0; - cls_struct_type.type = FFI_TYPE_STRUCT; - cls_struct_type.elements = cls_struct_fields; - - cls_struct_type1.size = 0; - cls_struct_type1.alignment = 0; - cls_struct_type1.type = FFI_TYPE_STRUCT; - cls_struct_type1.elements = cls_struct_fields1; - - cls_struct_type2.size = 0; - cls_struct_type2.alignment = 0; - cls_struct_type2.type = FFI_TYPE_STRUCT; - cls_struct_type2.elements = cls_struct_fields2; - - cls_struct_fields[0] = &ffi_type_uint64; - cls_struct_fields[1] = &ffi_type_uchar; - cls_struct_fields[2] = NULL; - - cls_struct_fields1[0] = &cls_struct_type; - cls_struct_fields1[1] = &ffi_type_uchar; - cls_struct_fields1[2] = NULL; - - cls_struct_fields2[0] = &ffi_type_uint64; - cls_struct_fields2[1] = &ffi_type_uchar; - cls_struct_fields2[2] = NULL; - - - dbl_arg_types[0] = &cls_struct_type; - dbl_arg_types[1] = &cls_struct_type1; - dbl_arg_types[2] = &cls_struct_type2; - dbl_arg_types[3] = NULL; - - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1, - dbl_arg_types) == FFI_OK); - - args_dbl[0] = &e_dbl; - args_dbl[1] = &f_dbl; - args_dbl[2] = &g_dbl; - args_dbl[3] = NULL; - - ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); - /* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */ - CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d)); - CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); - CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); - - CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); - - res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl); - /* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */ - CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d)); - CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); - CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); - - exit(0); -} diff --git a/testsuite/libffi.call/nested_struct9.c b/testsuite/libffi.call/nested_struct9.c deleted file mode 100644 index 5f7ac67..0000000 --- a/testsuite/libffi.call/nested_struct9.c +++ /dev/null @@ -1,131 +0,0 @@ -/* Area: ffi_call, closure_call - Purpose: Check structure passing with different structure size. - Contains structs as parameter of the struct itself. - Sample taken from Alan Modras patch to src/prep_cif.c. - Limitations: none. - PR: none. - Originator: 20051010 */ - -/* { dg-do run } */ -#include "ffitest.h" - -typedef struct A { - unsigned char a; - unsigned long long b; -} A; - -typedef struct B { - struct A x; - unsigned char y; -} B; - -typedef struct C { - unsigned long d; - unsigned char e; -} C; - -static B B_fn(struct A b2, struct B b3, struct C b4) -{ - struct B result; - - result.x.a = b2.a + b3.x.a + b4.d; - result.x.b = b2.b + b3.x.b + b3.y + b4.e; - result.y = b2.b + b3.x.b + b4.e; - - printf("%d %d %d %d %d %d %d: %d %d %d\n", b2.a, (int)b2.b, - b3.x.a, (int)b3.x.b, b3.y, (int)b4.d, b4.e, - result.x.a, (int)result.x.b, result.y); - - return result; -} - -static void -B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, - void* userdata __UNUSED__) -{ - struct A b0; - struct B b1; - struct C b2; - - b0 = *(struct A*)(args[0]); - b1 = *(struct B*)(args[1]); - b2 = *(struct C*)(args[2]); - - *(B*)resp = B_fn(b0, b1, b2); -} - -int main (void) -{ - ffi_cif cif; - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - void* args_dbl[4]; - ffi_type* cls_struct_fields[3]; - ffi_type* cls_struct_fields1[3]; - ffi_type* cls_struct_fields2[3]; - ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; - ffi_type* dbl_arg_types[4]; - - struct A e_dbl = { 1, 7LL}; - struct B f_dbl = {{12.0 , 127}, 99}; - struct C g_dbl = { 2, 9}; - - struct B res_dbl; - - cls_struct_type.size = 0; - cls_struct_type.alignment = 0; - cls_struct_type.type = FFI_TYPE_STRUCT; - cls_struct_type.elements = cls_struct_fields; - - cls_struct_type1.size = 0; - cls_struct_type1.alignment = 0; - cls_struct_type1.type = FFI_TYPE_STRUCT; - cls_struct_type1.elements = cls_struct_fields1; - - cls_struct_type2.size = 0; - cls_struct_type2.alignment = 0; - cls_struct_type2.type = FFI_TYPE_STRUCT; - cls_struct_type2.elements = cls_struct_fields2; - - cls_struct_fields[0] = &ffi_type_uchar; - cls_struct_fields[1] = &ffi_type_uint64; - cls_struct_fields[2] = NULL; - - cls_struct_fields1[0] = &cls_struct_type; - cls_struct_fields1[1] = &ffi_type_uchar; - cls_struct_fields1[2] = NULL; - - cls_struct_fields2[0] = &ffi_type_ulong; - cls_struct_fields2[1] = &ffi_type_uchar; - cls_struct_fields2[2] = NULL; - - - dbl_arg_types[0] = &cls_struct_type; - dbl_arg_types[1] = &cls_struct_type1; - dbl_arg_types[2] = &cls_struct_type2; - dbl_arg_types[3] = NULL; - - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1, - dbl_arg_types) == FFI_OK); - - args_dbl[0] = &e_dbl; - args_dbl[1] = &f_dbl; - args_dbl[2] = &g_dbl; - args_dbl[3] = NULL; - - ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); - /* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */ - CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d)); - CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); - CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); - - CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); - - res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl); - /* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */ - CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d)); - CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); - CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); - - exit(0); -} diff --git a/testsuite/libffi.call/problem1.c b/testsuite/libffi.call/problem1.c deleted file mode 100644 index 6a91555..0000000 --- a/testsuite/libffi.call/problem1.c +++ /dev/null @@ -1,90 +0,0 @@ -/* Area: ffi_call, closure_call - Purpose: Check structure passing with different structure size. - Limitations: none. - PR: none. - Originator: 20030828 */ - -/* { dg-do run } */ -#include "ffitest.h" - -typedef struct my_ffi_struct { - double a; - double b; - double c; -} my_ffi_struct; - -my_ffi_struct callee(struct my_ffi_struct a1, struct my_ffi_struct a2) -{ - struct my_ffi_struct result; - result.a = a1.a + a2.a; - result.b = a1.b + a2.b; - result.c = a1.c + a2.c; - - - printf("%g %g %g %g %g %g: %g %g %g\n", a1.a, a1.b, a1.c, - a2.a, a2.b, a2.c, result.a, result.b, result.c); - - return result; -} - -void stub(ffi_cif* cif __UNUSED__, void* resp, void** args, - void* userdata __UNUSED__) -{ - struct my_ffi_struct a1; - struct my_ffi_struct a2; - - a1 = *(struct my_ffi_struct*)(args[0]); - a2 = *(struct my_ffi_struct*)(args[1]); - - *(my_ffi_struct *)resp = callee(a1, a2); -} - - -int main(void) -{ - ffi_type* my_ffi_struct_fields[4]; - ffi_type my_ffi_struct_type; - ffi_cif cif; - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - void* args[4]; - ffi_type* arg_types[3]; - - struct my_ffi_struct g = { 1.0, 2.0, 3.0 }; - struct my_ffi_struct f = { 1.0, 2.0, 3.0 }; - struct my_ffi_struct res; - - my_ffi_struct_type.size = 0; - my_ffi_struct_type.alignment = 0; - my_ffi_struct_type.type = FFI_TYPE_STRUCT; - my_ffi_struct_type.elements = my_ffi_struct_fields; - - my_ffi_struct_fields[0] = &ffi_type_double; - my_ffi_struct_fields[1] = &ffi_type_double; - my_ffi_struct_fields[2] = &ffi_type_double; - my_ffi_struct_fields[3] = NULL; - - arg_types[0] = &my_ffi_struct_type; - arg_types[1] = &my_ffi_struct_type; - arg_types[2] = NULL; - - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &my_ffi_struct_type, - arg_types) == FFI_OK); - - args[0] = &g; - args[1] = &f; - args[2] = NULL; - ffi_call(&cif, FFI_FN(callee), &res, args); - /* { dg-output "1 2 3 1 2 3: 2 4 6" } */ - printf("res: %g %g %g\n", res.a, res.b, res.c); - /* { dg-output "\nres: 2 4 6" } */ - - CHECK(ffi_prep_closure_loc(pcl, &cif, stub, NULL, code) == FFI_OK); - - res = ((my_ffi_struct(*)(struct my_ffi_struct, struct my_ffi_struct))(code))(g, f); - /* { dg-output "\n1 2 3 1 2 3: 2 4 6" } */ - printf("res: %g %g %g\n", res.a, res.b, res.c); - /* { dg-output "\nres: 2 4 6" } */ - - exit(0);; -} diff --git a/testsuite/libffi.call/stret_large.c b/testsuite/libffi.call/stret_large.c deleted file mode 100644 index 71c2469..0000000 --- a/testsuite/libffi.call/stret_large.c +++ /dev/null @@ -1,145 +0,0 @@ -/* Area: ffi_call, closure_call - Purpose: Check structure returning with different structure size. - Depending on the ABI. Check bigger struct which overlaps - the gp and fp register count on Darwin/AIX/ppc64. - Limitations: none. - PR: none. - Originator: Blake Chaffin 6/21/2007 */ - -/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ -#include "ffitest.h" - -/* 13 FPRs: 104 bytes */ -/* 14 FPRs: 112 bytes */ - -typedef struct struct_108byte { - double a; - double b; - double c; - double d; - double e; - double f; - double g; - double h; - double i; - double j; - double k; - double l; - double m; - int n; -} struct_108byte; - -struct_108byte cls_struct_108byte_fn( - struct_108byte b0, - struct_108byte b1, - struct_108byte b2, - struct_108byte b3) -{ - struct_108byte result; - - result.a = b0.a + b1.a + b2.a + b3.a; - result.b = b0.b + b1.b + b2.b + b3.b; - result.c = b0.c + b1.c + b2.c + b3.c; - result.d = b0.d + b1.d + b2.d + b3.d; - result.e = b0.e + b1.e + b2.e + b3.e; - result.f = b0.f + b1.f + b2.f + b3.f; - result.g = b0.g + b1.g + b2.g + b3.g; - result.h = b0.h + b1.h + b2.h + b3.h; - result.i = b0.i + b1.i + b2.i + b3.i; - result.j = b0.j + b1.j + b2.j + b3.j; - result.k = b0.k + b1.k + b2.k + b3.k; - result.l = b0.l + b1.l + b2.l + b3.l; - result.m = b0.m + b1.m + b2.m + b3.m; - result.n = b0.n + b1.n + b2.n + b3.n; - - printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", result.a, result.b, result.c, - result.d, result.e, result.f, result.g, result.h, result.i, - result.j, result.k, result.l, result.m, result.n); - - return result; -} - -static void -cls_struct_108byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__) -{ - struct_108byte b0, b1, b2, b3; - - b0 = *(struct_108byte*)(args[0]); - b1 = *(struct_108byte*)(args[1]); - b2 = *(struct_108byte*)(args[2]); - b3 = *(struct_108byte*)(args[3]); - - *(struct_108byte*)resp = cls_struct_108byte_fn(b0, b1, b2, b3); -} - -int main (void) -{ - ffi_cif cif; - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - void* args_dbl[5]; - ffi_type* cls_struct_fields[15]; - ffi_type cls_struct_type; - ffi_type* dbl_arg_types[5]; - - struct_108byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 1.0, 2.0, 3.0, 7.0, 2.0, 7 }; - struct_108byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0, 5.0, 7.0, 9.0, 1.0, 4 }; - struct_108byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 8.0, 6.0, 1.0, 4.0, 0.0, 3 }; - struct_108byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 9.0, 2.0, 6.0, 5.0, 3.0, 2 }; - struct_108byte res_dbl; - - cls_struct_type.size = 0; - cls_struct_type.alignment = 0; - cls_struct_type.type = FFI_TYPE_STRUCT; - cls_struct_type.elements = cls_struct_fields; - - cls_struct_fields[0] = &ffi_type_double; - cls_struct_fields[1] = &ffi_type_double; - cls_struct_fields[2] = &ffi_type_double; - cls_struct_fields[3] = &ffi_type_double; - cls_struct_fields[4] = &ffi_type_double; - cls_struct_fields[5] = &ffi_type_double; - cls_struct_fields[6] = &ffi_type_double; - cls_struct_fields[7] = &ffi_type_double; - cls_struct_fields[8] = &ffi_type_double; - cls_struct_fields[9] = &ffi_type_double; - cls_struct_fields[10] = &ffi_type_double; - cls_struct_fields[11] = &ffi_type_double; - cls_struct_fields[12] = &ffi_type_double; - cls_struct_fields[13] = &ffi_type_sint32; - cls_struct_fields[14] = NULL; - - dbl_arg_types[0] = &cls_struct_type; - dbl_arg_types[1] = &cls_struct_type; - dbl_arg_types[2] = &cls_struct_type; - dbl_arg_types[3] = &cls_struct_type; - dbl_arg_types[4] = NULL; - - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type, - dbl_arg_types) == FFI_OK); - - args_dbl[0] = &e_dbl; - args_dbl[1] = &f_dbl; - args_dbl[2] = &g_dbl; - args_dbl[3] = &h_dbl; - args_dbl[4] = NULL; - - ffi_call(&cif, FFI_FN(cls_struct_108byte_fn), &res_dbl, args_dbl); - /* { dg-output "22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */ - printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b, - res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i, - res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n); - /* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */ - - CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_108byte_gn, NULL, code) == FFI_OK); - - res_dbl = ((struct_108byte(*)(struct_108byte, struct_108byte, - struct_108byte, struct_108byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl); - /* { dg-output "\n22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */ - printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b, - res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i, - res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n); - /* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */ - - exit(0); -} diff --git a/testsuite/libffi.call/stret_large2.c b/testsuite/libffi.call/stret_large2.c deleted file mode 100644 index d9c750e..0000000 --- a/testsuite/libffi.call/stret_large2.c +++ /dev/null @@ -1,148 +0,0 @@ -/* Area: ffi_call, closure_call - Purpose: Check structure returning with different structure size. - Depending on the ABI. Check bigger struct which overlaps - the gp and fp register count on Darwin/AIX/ppc64. - Limitations: none. - PR: none. - Originator: Blake Chaffin 6/21/2007 */ - -/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ -#include "ffitest.h" - -/* 13 FPRs: 104 bytes */ -/* 14 FPRs: 112 bytes */ - -typedef struct struct_116byte { - double a; - double b; - double c; - double d; - double e; - double f; - double g; - double h; - double i; - double j; - double k; - double l; - double m; - double n; - int o; -} struct_116byte; - -struct_116byte cls_struct_116byte_fn( - struct_116byte b0, - struct_116byte b1, - struct_116byte b2, - struct_116byte b3) -{ - struct_116byte result; - - result.a = b0.a + b1.a + b2.a + b3.a; - result.b = b0.b + b1.b + b2.b + b3.b; - result.c = b0.c + b1.c + b2.c + b3.c; - result.d = b0.d + b1.d + b2.d + b3.d; - result.e = b0.e + b1.e + b2.e + b3.e; - result.f = b0.f + b1.f + b2.f + b3.f; - result.g = b0.g + b1.g + b2.g + b3.g; - result.h = b0.h + b1.h + b2.h + b3.h; - result.i = b0.i + b1.i + b2.i + b3.i; - result.j = b0.j + b1.j + b2.j + b3.j; - result.k = b0.k + b1.k + b2.k + b3.k; - result.l = b0.l + b1.l + b2.l + b3.l; - result.m = b0.m + b1.m + b2.m + b3.m; - result.n = b0.n + b1.n + b2.n + b3.n; - result.o = b0.o + b1.o + b2.o + b3.o; - - printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", result.a, result.b, result.c, - result.d, result.e, result.f, result.g, result.h, result.i, - result.j, result.k, result.l, result.m, result.n, result.o); - - return result; -} - -static void -cls_struct_116byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__) -{ - struct_116byte b0, b1, b2, b3; - - b0 = *(struct_116byte*)(args[0]); - b1 = *(struct_116byte*)(args[1]); - b2 = *(struct_116byte*)(args[2]); - b3 = *(struct_116byte*)(args[3]); - - *(struct_116byte*)resp = cls_struct_116byte_fn(b0, b1, b2, b3); -} - -int main (void) -{ - ffi_cif cif; - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - void* args_dbl[5]; - ffi_type* cls_struct_fields[16]; - ffi_type cls_struct_type; - ffi_type* dbl_arg_types[5]; - - struct_116byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 7 }; - struct_116byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0, 5.0, 7.0, 9.0, 1.0, 6.0, 4 }; - struct_116byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 8.0, 6.0, 1.0, 4.0, 0.0, 7.0, 3 }; - struct_116byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 9.0, 2.0, 6.0, 5.0, 3.0, 8.0, 2 }; - struct_116byte res_dbl; - - cls_struct_type.size = 0; - cls_struct_type.alignment = 0; - cls_struct_type.type = FFI_TYPE_STRUCT; - cls_struct_type.elements = cls_struct_fields; - - cls_struct_fields[0] = &ffi_type_double; - cls_struct_fields[1] = &ffi_type_double; - cls_struct_fields[2] = &ffi_type_double; - cls_struct_fields[3] = &ffi_type_double; - cls_struct_fields[4] = &ffi_type_double; - cls_struct_fields[5] = &ffi_type_double; - cls_struct_fields[6] = &ffi_type_double; - cls_struct_fields[7] = &ffi_type_double; - cls_struct_fields[8] = &ffi_type_double; - cls_struct_fields[9] = &ffi_type_double; - cls_struct_fields[10] = &ffi_type_double; - cls_struct_fields[11] = &ffi_type_double; - cls_struct_fields[12] = &ffi_type_double; - cls_struct_fields[13] = &ffi_type_double; - cls_struct_fields[14] = &ffi_type_sint32; - cls_struct_fields[15] = NULL; - - dbl_arg_types[0] = &cls_struct_type; - dbl_arg_types[1] = &cls_struct_type; - dbl_arg_types[2] = &cls_struct_type; - dbl_arg_types[3] = &cls_struct_type; - dbl_arg_types[4] = NULL; - - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type, - dbl_arg_types) == FFI_OK); - - args_dbl[0] = &e_dbl; - args_dbl[1] = &f_dbl; - args_dbl[2] = &g_dbl; - args_dbl[3] = &h_dbl; - args_dbl[4] = NULL; - - ffi_call(&cif, FFI_FN(cls_struct_116byte_fn), &res_dbl, args_dbl); - /* { dg-output "22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */ - printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b, - res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i, - res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n, res_dbl.o); - /* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */ - - CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_116byte_gn, NULL, code) == FFI_OK); - - res_dbl = ((struct_116byte(*)(struct_116byte, struct_116byte, - struct_116byte, struct_116byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl); - /* { dg-output "\n22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */ - printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b, - res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i, - res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n, res_dbl.o); - /* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */ - - exit(0); -} diff --git a/testsuite/libffi.call/stret_medium.c b/testsuite/libffi.call/stret_medium.c deleted file mode 100644 index 973ee02..0000000 --- a/testsuite/libffi.call/stret_medium.c +++ /dev/null @@ -1,124 +0,0 @@ -/* Area: ffi_call, closure_call - Purpose: Check structure returning with different structure size. - Depending on the ABI. Check bigger struct which overlaps - the gp and fp register count on Darwin/AIX/ppc64. - Limitations: none. - PR: none. - Originator: Blake Chaffin 6/21/2007 */ - -/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ -#include "ffitest.h" - -typedef struct struct_72byte { - double a; - double b; - double c; - double d; - double e; - double f; - double g; - double h; - double i; -} struct_72byte; - -struct_72byte cls_struct_72byte_fn( - struct_72byte b0, - struct_72byte b1, - struct_72byte b2, - struct_72byte b3) -{ - struct_72byte result; - - result.a = b0.a + b1.a + b2.a + b3.a; - result.b = b0.b + b1.b + b2.b + b3.b; - result.c = b0.c + b1.c + b2.c + b3.c; - result.d = b0.d + b1.d + b2.d + b3.d; - result.e = b0.e + b1.e + b2.e + b3.e; - result.f = b0.f + b1.f + b2.f + b3.f; - result.g = b0.g + b1.g + b2.g + b3.g; - result.h = b0.h + b1.h + b2.h + b3.h; - result.i = b0.i + b1.i + b2.i + b3.i; - - printf("%g %g %g %g %g %g %g %g %g\n", result.a, result.b, result.c, - result.d, result.e, result.f, result.g, result.h, result.i); - - return result; -} - -static void -cls_struct_72byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__) -{ - struct_72byte b0, b1, b2, b3; - - b0 = *(struct_72byte*)(args[0]); - b1 = *(struct_72byte*)(args[1]); - b2 = *(struct_72byte*)(args[2]); - b3 = *(struct_72byte*)(args[3]); - - *(struct_72byte*)resp = cls_struct_72byte_fn(b0, b1, b2, b3); -} - -int main (void) -{ - ffi_cif cif; - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - void* args_dbl[5]; - ffi_type* cls_struct_fields[10]; - ffi_type cls_struct_type; - ffi_type* dbl_arg_types[5]; - - struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7.0 }; - struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0 }; - struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3.0 }; - struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2.0 }; - struct_72byte res_dbl; - - cls_struct_type.size = 0; - cls_struct_type.alignment = 0; - cls_struct_type.type = FFI_TYPE_STRUCT; - cls_struct_type.elements = cls_struct_fields; - - cls_struct_fields[0] = &ffi_type_double; - cls_struct_fields[1] = &ffi_type_double; - cls_struct_fields[2] = &ffi_type_double; - cls_struct_fields[3] = &ffi_type_double; - cls_struct_fields[4] = &ffi_type_double; - cls_struct_fields[5] = &ffi_type_double; - cls_struct_fields[6] = &ffi_type_double; - cls_struct_fields[7] = &ffi_type_double; - cls_struct_fields[8] = &ffi_type_double; - cls_struct_fields[9] = NULL; - - dbl_arg_types[0] = &cls_struct_type; - dbl_arg_types[1] = &cls_struct_type; - dbl_arg_types[2] = &cls_struct_type; - dbl_arg_types[3] = &cls_struct_type; - dbl_arg_types[4] = NULL; - - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type, - dbl_arg_types) == FFI_OK); - - args_dbl[0] = &e_dbl; - args_dbl[1] = &f_dbl; - args_dbl[2] = &g_dbl; - args_dbl[3] = &h_dbl; - args_dbl[4] = NULL; - - ffi_call(&cif, FFI_FN(cls_struct_72byte_fn), &res_dbl, args_dbl); - /* { dg-output "22 15 17 25 6 13 19 18 16" } */ - printf("res: %g %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c, - res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i); - /* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */ - - CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_72byte_gn, NULL, code) == FFI_OK); - - res_dbl = ((struct_72byte(*)(struct_72byte, struct_72byte, - struct_72byte, struct_72byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl); - /* { dg-output "\n22 15 17 25 6 13 19 18 16" } */ - printf("res: %g %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c, - res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i); - /* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */ - - exit(0); -} diff --git a/testsuite/libffi.call/stret_medium2.c b/testsuite/libffi.call/stret_medium2.c deleted file mode 100644 index 84323d1..0000000 --- a/testsuite/libffi.call/stret_medium2.c +++ /dev/null @@ -1,125 +0,0 @@ -/* Area: ffi_call, closure_call - Purpose: Check structure returning with different structure size. - Depending on the ABI. Check bigger struct which overlaps - the gp and fp register count on Darwin/AIX/ppc64. - Limitations: none. - PR: none. - Originator: Blake Chaffin 6/21/2007 */ - -/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ -/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */ -#include "ffitest.h" - -typedef struct struct_72byte { - double a; - double b; - double c; - double d; - double e; - double f; - double g; - double h; - long long i; -} struct_72byte; - -struct_72byte cls_struct_72byte_fn( - struct_72byte b0, - struct_72byte b1, - struct_72byte b2, - struct_72byte b3) -{ - struct_72byte result; - - result.a = b0.a + b1.a + b2.a + b3.a; - result.b = b0.b + b1.b + b2.b + b3.b; - result.c = b0.c + b1.c + b2.c + b3.c; - result.d = b0.d + b1.d + b2.d + b3.d; - result.e = b0.e + b1.e + b2.e + b3.e; - result.f = b0.f + b1.f + b2.f + b3.f; - result.g = b0.g + b1.g + b2.g + b3.g; - result.h = b0.h + b1.h + b2.h + b3.h; - result.i = b0.i + b1.i + b2.i + b3.i; - - printf("%g %g %g %g %g %g %g %g %" PRIdLL "\n", result.a, result.b, result.c, - result.d, result.e, result.f, result.g, result.h, result.i); - - return result; -} - -static void -cls_struct_72byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__) -{ - struct_72byte b0, b1, b2, b3; - - b0 = *(struct_72byte*)(args[0]); - b1 = *(struct_72byte*)(args[1]); - b2 = *(struct_72byte*)(args[2]); - b3 = *(struct_72byte*)(args[3]); - - *(struct_72byte*)resp = cls_struct_72byte_fn(b0, b1, b2, b3); -} - -int main (void) -{ - ffi_cif cif; - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - void* args_dbl[5]; - ffi_type* cls_struct_fields[10]; - ffi_type cls_struct_type; - ffi_type* dbl_arg_types[5]; - - struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7 }; - struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4 }; - struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3 }; - struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2 }; - struct_72byte res_dbl; - - cls_struct_type.size = 0; - cls_struct_type.alignment = 0; - cls_struct_type.type = FFI_TYPE_STRUCT; - cls_struct_type.elements = cls_struct_fields; - - cls_struct_fields[0] = &ffi_type_double; - cls_struct_fields[1] = &ffi_type_double; - cls_struct_fields[2] = &ffi_type_double; - cls_struct_fields[3] = &ffi_type_double; - cls_struct_fields[4] = &ffi_type_double; - cls_struct_fields[5] = &ffi_type_double; - cls_struct_fields[6] = &ffi_type_double; - cls_struct_fields[7] = &ffi_type_double; - cls_struct_fields[8] = &ffi_type_sint64; - cls_struct_fields[9] = NULL; - - dbl_arg_types[0] = &cls_struct_type; - dbl_arg_types[1] = &cls_struct_type; - dbl_arg_types[2] = &cls_struct_type; - dbl_arg_types[3] = &cls_struct_type; - dbl_arg_types[4] = NULL; - - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type, - dbl_arg_types) == FFI_OK); - - args_dbl[0] = &e_dbl; - args_dbl[1] = &f_dbl; - args_dbl[2] = &g_dbl; - args_dbl[3] = &h_dbl; - args_dbl[4] = NULL; - - ffi_call(&cif, FFI_FN(cls_struct_72byte_fn), &res_dbl, args_dbl); - /* { dg-output "22 15 17 25 6 13 19 18 16" } */ - printf("res: %g %g %g %g %g %g %g %g %" PRIdLL "\n", res_dbl.a, res_dbl.b, res_dbl.c, - res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i); - /* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */ - - CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_72byte_gn, NULL, code) == FFI_OK); - - res_dbl = ((struct_72byte(*)(struct_72byte, struct_72byte, - struct_72byte, struct_72byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl); - /* { dg-output "\n22 15 17 25 6 13 19 18 16" } */ - printf("res: %g %g %g %g %g %g %g %g %" PRIdLL "\n", res_dbl.a, res_dbl.b, res_dbl.c, - res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i); - /* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */ - - exit(0); -} diff --git a/testsuite/libffi.call/testclosure.c b/testsuite/libffi.call/testclosure.c deleted file mode 100644 index ca31056..0000000 --- a/testsuite/libffi.call/testclosure.c +++ /dev/null @@ -1,70 +0,0 @@ -/* Area: closure_call - Purpose: Check return value float. - Limitations: none. - PR: 41908. - Originator: 20091102 */ - -/* { dg-do run } */ -#include "ffitest.h" - -typedef struct cls_struct_combined { - float a; - float b; - float c; - float d; -} cls_struct_combined; - -void cls_struct_combined_fn(struct cls_struct_combined arg) -{ - printf("%g %g %g %g\n", - arg.a, arg.b, - arg.c, arg.d); - fflush(stdout); -} - -static void -cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, - void** args, void* userdata __UNUSED__) -{ - struct cls_struct_combined a0; - - a0 = *(struct cls_struct_combined*)(args[0]); - - cls_struct_combined_fn(a0); -} - - -int main (void) -{ - ffi_cif cif; - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - ffi_type* cls_struct_fields0[5]; - ffi_type cls_struct_type0; - ffi_type* dbl_arg_types[5]; - - struct cls_struct_combined g_dbl = {4.0, 5.0, 1.0, 8.0}; - - cls_struct_type0.size = 0; - cls_struct_type0.alignment = 0; - cls_struct_type0.type = FFI_TYPE_STRUCT; - cls_struct_type0.elements = cls_struct_fields0; - - cls_struct_fields0[0] = &ffi_type_float; - cls_struct_fields0[1] = &ffi_type_float; - cls_struct_fields0[2] = &ffi_type_float; - cls_struct_fields0[3] = &ffi_type_float; - cls_struct_fields0[4] = NULL; - - dbl_arg_types[0] = &cls_struct_type0; - dbl_arg_types[1] = NULL; - - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, - dbl_arg_types) == FFI_OK); - - CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK); - - ((void(*)(cls_struct_combined)) (code))(g_dbl); - /* { dg-output "4 5 1 8" } */ - exit(0); -} diff --git a/testsuite/libffi.call/unwindtest.cc b/testsuite/libffi.call/unwindtest.cc deleted file mode 100644 index e114565..0000000 --- a/testsuite/libffi.call/unwindtest.cc +++ /dev/null @@ -1,117 +0,0 @@ -/* Area: ffi_closure, unwind info - Purpose: Check if the unwind information is passed correctly. - Limitations: none. - PR: none. - Originator: Jeff Sturm */ - -/* { dg-do run { xfail x86_64-apple-darwin* moxie*-*-* } } */ - -#include "ffitest.h" - -void ABI_ATTR -closure_test_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, - void** args __UNUSED__, void* userdata __UNUSED__) -{ - throw 9; -} - -typedef void (*closure_test_type)(); - -void closure_test_fn1(ffi_cif* cif __UNUSED__, void* resp, - void** args, void* userdata __UNUSED__) - { - *(ffi_arg*)resp = - (int)*(float *)args[0] +(int)(*(float *)args[1]) + - (int)(*(float *)args[2]) + (int)*(float *)args[3] + - (int)(*(signed short *)args[4]) + (int)(*(float *)args[5]) + - (int)*(float *)args[6] + (int)(*(int *)args[7]) + - (int)(*(double*)args[8]) + (int)*(int *)args[9] + - (int)(*(int *)args[10]) + (int)(*(float *)args[11]) + - (int)*(int *)args[12] + (int)(*(int *)args[13]) + - (int)(*(int *)args[14]) + *(int *)args[15] + (int)(intptr_t)userdata; - - printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n", - (int)*(float *)args[0], (int)(*(float *)args[1]), - (int)(*(float *)args[2]), (int)*(float *)args[3], - (int)(*(signed short *)args[4]), (int)(*(float *)args[5]), - (int)*(float *)args[6], (int)(*(int *)args[7]), - (int)(*(double *)args[8]), (int)*(int *)args[9], - (int)(*(int *)args[10]), (int)(*(float *)args[11]), - (int)*(int *)args[12], (int)(*(int *)args[13]), - (int)(*(int *)args[14]), *(int *)args[15], - (int)(intptr_t)userdata, (int)*(ffi_arg*)resp); - - throw (int)*(ffi_arg*)resp; -} - -typedef int (*closure_test_type1)(float, float, float, float, signed short, - float, float, int, double, int, int, float, - int, int, int, int); - -int main (void) -{ - ffi_cif cif; - void *code; - ffi_closure *pcl = (ffi_closure *)ffi_closure_alloc(sizeof(ffi_closure), &code); - ffi_type * cl_arg_types[17]; - - { - cl_arg_types[1] = NULL; - - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, - &ffi_type_void, cl_arg_types) == FFI_OK); - CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn, NULL, code) == FFI_OK); - - try - { - (*((closure_test_type)(code)))(); - } catch (int exception_code) - { - CHECK(exception_code == 9); - } - - printf("part one OK\n"); - /* { dg-output "part one OK" } */ - } - - { - - cl_arg_types[0] = &ffi_type_float; - cl_arg_types[1] = &ffi_type_float; - cl_arg_types[2] = &ffi_type_float; - cl_arg_types[3] = &ffi_type_float; - cl_arg_types[4] = &ffi_type_sshort; - cl_arg_types[5] = &ffi_type_float; - cl_arg_types[6] = &ffi_type_float; - cl_arg_types[7] = &ffi_type_uint; - cl_arg_types[8] = &ffi_type_double; - cl_arg_types[9] = &ffi_type_uint; - cl_arg_types[10] = &ffi_type_uint; - cl_arg_types[11] = &ffi_type_float; - cl_arg_types[12] = &ffi_type_uint; - cl_arg_types[13] = &ffi_type_uint; - cl_arg_types[14] = &ffi_type_uint; - cl_arg_types[15] = &ffi_type_uint; - cl_arg_types[16] = NULL; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16, - &ffi_type_sint, cl_arg_types) == FFI_OK); - - CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn1, - (void *) 3 /* userdata */, code) == FFI_OK); - try - { - (*((closure_test_type1)code)) - (1.1, 2.2, 3.3, 4.4, 127, 5.5, 6.6, 8, 9, 10, 11, 12.0, 13, - 19, 21, 1); - /* { dg-output "\n1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */ - } catch (int exception_code) - { - CHECK(exception_code == 255); - } - printf("part two OK\n"); - /* { dg-output "\npart two OK" } */ - } - exit(0); -} diff --git a/testsuite/libffi.closures/closure.exp b/testsuite/libffi.closures/closure.exp index eafbef0..9bbc807 100644 --- a/testsuite/libffi.closures/closure.exp +++ b/testsuite/libffi.closures/closure.exp @@ -43,6 +43,22 @@ if { [libffi_feature_test "#if FFI_CLOSURES"] } { } } +set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.cc]] + +# No C++ for or1k +if { [istarget "or1k-*-*"] } { + foreach test $tlist { + unsupported "$test" + } +} else { + if { [libffi_feature_test "#if FFI_CLOSURES"] } { + run-many-tests $tlist $additional_options + } else { + foreach test $tlist { + unsupported "$test" + } +} + dg-finish # Local Variables: diff --git a/testsuite/libffi.closures/err_bad_abi.c b/testsuite/libffi.closures/err_bad_abi.c new file mode 100644 index 0000000..f5a7317 --- /dev/null +++ b/testsuite/libffi.closures/err_bad_abi.c @@ -0,0 +1,36 @@ +/* Area: ffi_prep_cif, ffi_prep_closure + Purpose: Test error return for bad ABIs. + Limitations: none. + PR: none. + Originator: Blake Chaffin 6/6/2007 */ + +/* { dg-do run } */ + +#include "ffitest.h" + +static void +dummy_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, + void** args __UNUSED__, void* userdata __UNUSED__) +{} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type* arg_types[1]; + + arg_types[0] = NULL; + + CHECK(ffi_prep_cif(&cif, 255, 0, &ffi_type_void, + arg_types) == FFI_BAD_ABI); + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &ffi_type_void, + arg_types) == FFI_OK); + + cif.abi= 255; + + CHECK(ffi_prep_closure_loc(pcl, &cif, dummy_fn, NULL, code) == FFI_BAD_ABI); + + exit(0); +} diff --git a/testsuite/libffi.closures/huge_struct.c b/testsuite/libffi.closures/huge_struct.c new file mode 100644 index 0000000..1915c3f --- /dev/null +++ b/testsuite/libffi.closures/huge_struct.c @@ -0,0 +1,341 @@ +/* Area: ffi_call, closure_call + Purpose: Check large structure returns. + Limitations: none. + PR: none. + Originator: Blake Chaffin 6/18/2007 +*/ + +/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ +/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */ +/* { dg-options -Wformat=0 { target moxie*-*-elf or1k-*-* } } */ + +#include "ffitest.h" + +typedef struct BigStruct{ + uint8_t a; + int8_t b; + uint16_t c; + int16_t d; + uint32_t e; + int32_t f; + uint64_t g; + int64_t h; + float i; + double j; + long double k; + char* l; + uint8_t m; + int8_t n; + uint16_t o; + int16_t p; + uint32_t q; + int32_t r; + uint64_t s; + int64_t t; + float u; + double v; + long double w; + char* x; + uint8_t y; + int8_t z; + uint16_t aa; + int16_t bb; + uint32_t cc; + int32_t dd; + uint64_t ee; + int64_t ff; + float gg; + double hh; + long double ii; + char* jj; + uint8_t kk; + int8_t ll; + uint16_t mm; + int16_t nn; + uint32_t oo; + int32_t pp; + uint64_t qq; + int64_t rr; + float ss; + double tt; + long double uu; + char* vv; + uint8_t ww; + int8_t xx; +} BigStruct; + +BigStruct +test_large_fn( + uint8_t ui8_1, + int8_t si8_1, + uint16_t ui16_1, + int16_t si16_1, + uint32_t ui32_1, + int32_t si32_1, + uint64_t ui64_1, + int64_t si64_1, + float f_1, + double d_1, + long double ld_1, + char* p_1, + uint8_t ui8_2, + int8_t si8_2, + uint16_t ui16_2, + int16_t si16_2, + uint32_t ui32_2, + int32_t si32_2, + uint64_t ui64_2, + int64_t si64_2, + float f_2, + double d_2, + long double ld_2, + char* p_2, + uint8_t ui8_3, + int8_t si8_3, + uint16_t ui16_3, + int16_t si16_3, + uint32_t ui32_3, + int32_t si32_3, + uint64_t ui64_3, + int64_t si64_3, + float f_3, + double d_3, + long double ld_3, + char* p_3, + uint8_t ui8_4, + int8_t si8_4, + uint16_t ui16_4, + int16_t si16_4, + uint32_t ui32_4, + int32_t si32_4, + uint64_t ui64_4, + int64_t si64_4, + float f_4, + double d_4, + long double ld_4, + char* p_4, + uint8_t ui8_5, + int8_t si8_5) +{ + BigStruct retVal = { + ui8_1 + 1, si8_1 + 1, ui16_1 + 1, si16_1 + 1, ui32_1 + 1, si32_1 + 1, + ui64_1 + 1, si64_1 + 1, f_1 + 1, d_1 + 1, ld_1 + 1, (char*)((intptr_t)p_1 + 1), + ui8_2 + 2, si8_2 + 2, ui16_2 + 2, si16_2 + 2, ui32_2 + 2, si32_2 + 2, + ui64_2 + 2, si64_2 + 2, f_2 + 2, d_2 + 2, ld_2 + 2, (char*)((intptr_t)p_2 + 2), + ui8_3 + 3, si8_3 + 3, ui16_3 + 3, si16_3 + 3, ui32_3 + 3, si32_3 + 3, + ui64_3 + 3, si64_3 + 3, f_3 + 3, d_3 + 3, ld_3 + 3, (char*)((intptr_t)p_3 + 3), + ui8_4 + 4, si8_4 + 4, ui16_4 + 4, si16_4 + 4, ui32_4 + 4, si32_4 + 4, + ui64_4 + 4, si64_4 + 4, f_4 + 4, d_4 + 4, ld_4 + 4, (char*)((intptr_t)p_4 + 4), + ui8_5 + 5, si8_5 + 5}; + + printf("%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 ": " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n", + 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, + 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, + 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, + 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, + retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f, + retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l, + retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r, + retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x, + retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd, + retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj, + retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp, + retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx); + + return retVal; +} + +static void +cls_large_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__) +{ + uint8_t ui8_1 = *(uint8_t*)args[0]; + int8_t si8_1 = *(int8_t*)args[1]; + uint16_t ui16_1 = *(uint16_t*)args[2]; + int16_t si16_1 = *(int16_t*)args[3]; + uint32_t ui32_1 = *(uint32_t*)args[4]; + int32_t si32_1 = *(int32_t*)args[5]; + uint64_t ui64_1 = *(uint64_t*)args[6]; + int64_t si64_1 = *(int64_t*)args[7]; + float f_1 = *(float*)args[8]; + double d_1 = *(double*)args[9]; + long double ld_1 = *(long double*)args[10]; + char* p_1 = *(char**)args[11]; + uint8_t ui8_2 = *(uint8_t*)args[12]; + int8_t si8_2 = *(int8_t*)args[13]; + uint16_t ui16_2 = *(uint16_t*)args[14]; + int16_t si16_2 = *(int16_t*)args[15]; + uint32_t ui32_2 = *(uint32_t*)args[16]; + int32_t si32_2 = *(int32_t*)args[17]; + uint64_t ui64_2 = *(uint64_t*)args[18]; + int64_t si64_2 = *(int64_t*)args[19]; + float f_2 = *(float*)args[20]; + double d_2 = *(double*)args[21]; + long double ld_2 = *(long double*)args[22]; + char* p_2 = *(char**)args[23]; + uint8_t ui8_3 = *(uint8_t*)args[24]; + int8_t si8_3 = *(int8_t*)args[25]; + uint16_t ui16_3 = *(uint16_t*)args[26]; + int16_t si16_3 = *(int16_t*)args[27]; + uint32_t ui32_3 = *(uint32_t*)args[28]; + int32_t si32_3 = *(int32_t*)args[29]; + uint64_t ui64_3 = *(uint64_t*)args[30]; + int64_t si64_3 = *(int64_t*)args[31]; + float f_3 = *(float*)args[32]; + double d_3 = *(double*)args[33]; + long double ld_3 = *(long double*)args[34]; + char* p_3 = *(char**)args[35]; + uint8_t ui8_4 = *(uint8_t*)args[36]; + int8_t si8_4 = *(int8_t*)args[37]; + uint16_t ui16_4 = *(uint16_t*)args[38]; + int16_t si16_4 = *(int16_t*)args[39]; + uint32_t ui32_4 = *(uint32_t*)args[40]; + int32_t si32_4 = *(int32_t*)args[41]; + uint64_t ui64_4 = *(uint64_t*)args[42]; + int64_t si64_4 = *(int64_t*)args[43]; + float f_4 = *(float*)args[44]; + double d_4 = *(double*)args[45]; + long double ld_4 = *(long double*)args[46]; + char* p_4 = *(char**)args[47]; + uint8_t ui8_5 = *(uint8_t*)args[48]; + int8_t si8_5 = *(int8_t*)args[49]; + + *(BigStruct*)resp = test_large_fn( + ui8_1, si8_1, ui16_1, si16_1, ui32_1, si32_1, ui64_1, si64_1, f_1, d_1, ld_1, p_1, + ui8_2, si8_2, ui16_2, si16_2, ui32_2, si32_2, ui64_2, si64_2, f_2, d_2, ld_2, p_2, + ui8_3, si8_3, ui16_3, si16_3, ui32_3, si32_3, ui64_3, si64_3, f_3, d_3, ld_3, p_3, + ui8_4, si8_4, ui16_4, si16_4, ui32_4, si32_4, ui64_4, si64_4, f_4, d_4, ld_4, p_4, + ui8_5, si8_5); +} + +int +main(int argc __UNUSED__, const char** argv __UNUSED__) +{ + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + + ffi_cif cif; + ffi_type* argTypes[51]; + void* argValues[51]; + + ffi_type ret_struct_type; + ffi_type* st_fields[51]; + BigStruct retVal; + + uint8_t ui8 = 1; + int8_t si8 = 2; + uint16_t ui16 = 3; + int16_t si16 = 4; + uint32_t ui32 = 5; + int32_t si32 = 6; + uint64_t ui64 = 7; + int64_t si64 = 8; + float f = 9; + double d = 10; + long double ld = 11; + char* p = (char*)0x12345678; + + memset (&retVal, 0, sizeof(retVal)); + + ret_struct_type.size = 0; + ret_struct_type.alignment = 0; + ret_struct_type.type = FFI_TYPE_STRUCT; + ret_struct_type.elements = st_fields; + + st_fields[0] = st_fields[12] = st_fields[24] = st_fields[36] = st_fields[48] = &ffi_type_uint8; + st_fields[1] = st_fields[13] = st_fields[25] = st_fields[37] = st_fields[49] = &ffi_type_sint8; + st_fields[2] = st_fields[14] = st_fields[26] = st_fields[38] = &ffi_type_uint16; + st_fields[3] = st_fields[15] = st_fields[27] = st_fields[39] = &ffi_type_sint16; + st_fields[4] = st_fields[16] = st_fields[28] = st_fields[40] = &ffi_type_uint32; + st_fields[5] = st_fields[17] = st_fields[29] = st_fields[41] = &ffi_type_sint32; + st_fields[6] = st_fields[18] = st_fields[30] = st_fields[42] = &ffi_type_uint64; + st_fields[7] = st_fields[19] = st_fields[31] = st_fields[43] = &ffi_type_sint64; + st_fields[8] = st_fields[20] = st_fields[32] = st_fields[44] = &ffi_type_float; + st_fields[9] = st_fields[21] = st_fields[33] = st_fields[45] = &ffi_type_double; + st_fields[10] = st_fields[22] = st_fields[34] = st_fields[46] = &ffi_type_longdouble; + st_fields[11] = st_fields[23] = st_fields[35] = st_fields[47] = &ffi_type_pointer; + + st_fields[50] = NULL; + + argTypes[0] = argTypes[12] = argTypes[24] = argTypes[36] = argTypes[48] = &ffi_type_uint8; + argValues[0] = argValues[12] = argValues[24] = argValues[36] = argValues[48] = &ui8; + argTypes[1] = argTypes[13] = argTypes[25] = argTypes[37] = argTypes[49] = &ffi_type_sint8; + argValues[1] = argValues[13] = argValues[25] = argValues[37] = argValues[49] = &si8; + argTypes[2] = argTypes[14] = argTypes[26] = argTypes[38] = &ffi_type_uint16; + argValues[2] = argValues[14] = argValues[26] = argValues[38] = &ui16; + argTypes[3] = argTypes[15] = argTypes[27] = argTypes[39] = &ffi_type_sint16; + argValues[3] = argValues[15] = argValues[27] = argValues[39] = &si16; + argTypes[4] = argTypes[16] = argTypes[28] = argTypes[40] = &ffi_type_uint32; + argValues[4] = argValues[16] = argValues[28] = argValues[40] = &ui32; + argTypes[5] = argTypes[17] = argTypes[29] = argTypes[41] = &ffi_type_sint32; + argValues[5] = argValues[17] = argValues[29] = argValues[41] = &si32; + argTypes[6] = argTypes[18] = argTypes[30] = argTypes[42] = &ffi_type_uint64; + argValues[6] = argValues[18] = argValues[30] = argValues[42] = &ui64; + argTypes[7] = argTypes[19] = argTypes[31] = argTypes[43] = &ffi_type_sint64; + argValues[7] = argValues[19] = argValues[31] = argValues[43] = &si64; + argTypes[8] = argTypes[20] = argTypes[32] = argTypes[44] = &ffi_type_float; + argValues[8] = argValues[20] = argValues[32] = argValues[44] = &f; + argTypes[9] = argTypes[21] = argTypes[33] = argTypes[45] = &ffi_type_double; + argValues[9] = argValues[21] = argValues[33] = argValues[45] = &d; + argTypes[10] = argTypes[22] = argTypes[34] = argTypes[46] = &ffi_type_longdouble; + argValues[10] = argValues[22] = argValues[34] = argValues[46] = &ld; + argTypes[11] = argTypes[23] = argTypes[35] = argTypes[47] = &ffi_type_pointer; + argValues[11] = argValues[23] = argValues[35] = argValues[47] = &p; + + argTypes[50] = NULL; + argValues[50] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 50, &ret_struct_type, argTypes) == FFI_OK); + + ffi_call(&cif, FFI_FN(test_large_fn), &retVal, argValues); + /* { 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" } */ + printf("res: %" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n", + retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f, + retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l, + retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r, + retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x, + retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd, + retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj, + retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp, + retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx); + /* { 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" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_large_fn, NULL, code) == FFI_OK); + + retVal = ((BigStruct(*)( + uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*, + uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*, + uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*, + uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*, + uint8_t, int8_t))(code))( + ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p, + ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p, + ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p, + ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p, + ui8, si8); + /* { 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" } */ + printf("res: %" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n", + retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f, + retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l, + retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r, + retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x, + retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd, + retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj, + retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp, + retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx); + /* { 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" } */ + + return 0; +} diff --git a/testsuite/libffi.closures/nested_struct.c b/testsuite/libffi.closures/nested_struct.c new file mode 100644 index 0000000..c15e3a0 --- /dev/null +++ b/testsuite/libffi.closures/nested_struct.c @@ -0,0 +1,152 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_16byte1 { + double a; + float b; + int c; +} cls_struct_16byte1; + +typedef struct cls_struct_16byte2 { + int ii; + double dd; + float ff; +} cls_struct_16byte2; + +typedef struct cls_struct_combined { + cls_struct_16byte1 d; + cls_struct_16byte2 e; +} cls_struct_combined; + +cls_struct_combined cls_struct_combined_fn(struct cls_struct_16byte1 b0, + struct cls_struct_16byte2 b1, + struct cls_struct_combined b2) +{ + struct cls_struct_combined result; + + result.d.a = b0.a + b1.dd + b2.d.a; + result.d.b = b0.b + b1.ff + b2.d.b; + result.d.c = b0.c + b1.ii + b2.d.c; + result.e.ii = b0.c + b1.ii + b2.e.ii; + result.e.dd = b0.a + b1.dd + b2.e.dd; + result.e.ff = b0.b + b1.ff + b2.e.ff; + + printf("%g %g %d %d %g %g %g %g %d %d %g %g: %g %g %d %d %g %g\n", + b0.a, b0.b, b0.c, + b1.ii, b1.dd, b1.ff, + b2.d.a, b2.d.b, b2.d.c, + b2.e.ii, b2.e.dd, b2.e.ff, + result.d.a, result.d.b, result.d.c, + result.e.ii, result.e.dd, result.e.ff); + + return result; +} + +static void +cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct cls_struct_16byte1 b0; + struct cls_struct_16byte2 b1; + struct cls_struct_combined b2; + + b0 = *(struct cls_struct_16byte1*)(args[0]); + b1 = *(struct cls_struct_16byte2*)(args[1]); + b2 = *(struct cls_struct_combined*)(args[2]); + + + *(cls_struct_combined*)resp = cls_struct_combined_fn(b0, b1, b2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[5]; + ffi_type* cls_struct_fields1[5]; + ffi_type* cls_struct_fields2[5]; + ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6}; + struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0}; + struct cls_struct_combined g_dbl = {{4.0, 5.0, 6}, + {3, 1.0, 8.0}}; + struct cls_struct_combined res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_type2.size = 0; + cls_struct_type2.alignment = 0; + cls_struct_type2.type = FFI_TYPE_STRUCT; + cls_struct_type2.elements = cls_struct_fields2; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_float; + cls_struct_fields[2] = &ffi_type_sint; + cls_struct_fields[3] = NULL; + + cls_struct_fields1[0] = &ffi_type_sint; + cls_struct_fields1[1] = &ffi_type_double; + cls_struct_fields1[2] = &ffi_type_float; + cls_struct_fields1[3] = NULL; + + cls_struct_fields2[0] = &cls_struct_type; + cls_struct_fields2[1] = &cls_struct_type1; + cls_struct_fields2[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = &cls_struct_type2; + dbl_arg_types[3] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type2, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_combined_fn), &res_dbl, args_dbl); + /* { dg-output "9 2 6 1 2 3 4 5 6 3 1 8: 15 10 13 10 12 13" } */ + CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a)); + CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b)); + CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c)); + CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii)); + CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd)); + CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff)); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1, + cls_struct_16byte2, + cls_struct_combined)) + (code))(e_dbl, f_dbl, g_dbl); + /* { dg-output "\n9 2 6 1 2 3 4 5 6 3 1 8: 15 10 13 10 12 13" } */ + CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a)); + CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b)); + CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c)); + CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii)); + CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd)); + CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff)); + exit(0); +} diff --git a/testsuite/libffi.closures/nested_struct1.c b/testsuite/libffi.closures/nested_struct1.c new file mode 100644 index 0000000..477a6b9 --- /dev/null +++ b/testsuite/libffi.closures/nested_struct1.c @@ -0,0 +1,161 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_16byte1 { + double a; + float b; + int c; +} cls_struct_16byte1; + +typedef struct cls_struct_16byte2 { + int ii; + double dd; + float ff; +} cls_struct_16byte2; + +typedef struct cls_struct_combined { + cls_struct_16byte1 d; + cls_struct_16byte2 e; +} cls_struct_combined; + +cls_struct_combined cls_struct_combined_fn(struct cls_struct_16byte1 b0, + struct cls_struct_16byte2 b1, + struct cls_struct_combined b2, + struct cls_struct_16byte1 b3) +{ + struct cls_struct_combined result; + + result.d.a = b0.a + b1.dd + b2.d.a; + result.d.b = b0.b + b1.ff + b2.d.b; + result.d.c = b0.c + b1.ii + b2.d.c; + result.e.ii = b0.c + b1.ii + b2.e.ii; + result.e.dd = b0.a + b1.dd + b2.e.dd; + result.e.ff = b0.b + b1.ff + b2.e.ff; + + printf("%g %g %d %d %g %g %g %g %d %d %g %g %g %g %d: %g %g %d %d %g %g\n", + b0.a, b0.b, b0.c, + b1.ii, b1.dd, b1.ff, + b2.d.a, b2.d.b, b2.d.c, + b2.e.ii, b2.e.dd, b2.e.ff, + b3.a, b3.b, b3.c, + result.d.a, result.d.b, result.d.c, + result.e.ii, result.e.dd, result.e.ff); + + return result; +} + +static void +cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct cls_struct_16byte1 b0; + struct cls_struct_16byte2 b1; + struct cls_struct_combined b2; + struct cls_struct_16byte1 b3; + + b0 = *(struct cls_struct_16byte1*)(args[0]); + b1 = *(struct cls_struct_16byte2*)(args[1]); + b2 = *(struct cls_struct_combined*)(args[2]); + b3 = *(struct cls_struct_16byte1*)(args[3]); + + + *(cls_struct_combined*)resp = cls_struct_combined_fn(b0, b1, b2, b3); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[5]; + ffi_type* cls_struct_fields1[5]; + ffi_type* cls_struct_fields2[5]; + ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6}; + struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0}; + struct cls_struct_combined g_dbl = {{4.0, 5.0, 6}, + {3, 1.0, 8.0}}; + struct cls_struct_16byte1 h_dbl = { 3.0, 2.0, 4}; + struct cls_struct_combined res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_type2.size = 0; + cls_struct_type2.alignment = 0; + cls_struct_type2.type = FFI_TYPE_STRUCT; + cls_struct_type2.elements = cls_struct_fields2; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_float; + cls_struct_fields[2] = &ffi_type_sint; + cls_struct_fields[3] = NULL; + + cls_struct_fields1[0] = &ffi_type_sint; + cls_struct_fields1[1] = &ffi_type_double; + cls_struct_fields1[2] = &ffi_type_float; + cls_struct_fields1[3] = NULL; + + cls_struct_fields2[0] = &cls_struct_type; + cls_struct_fields2[1] = &cls_struct_type1; + cls_struct_fields2[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = &cls_struct_type2; + dbl_arg_types[3] = &cls_struct_type; + dbl_arg_types[4] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type2, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = &h_dbl; + args_dbl[4] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_combined_fn), &res_dbl, args_dbl); + /* { dg-output "9 2 6 1 2 3 4 5 6 3 1 8 3 2 4: 15 10 13 10 12 13" } */ + CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a)); + CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b)); + CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c)); + CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii)); + CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd)); + CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff)); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK); + + res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1, + cls_struct_16byte2, + cls_struct_combined, + cls_struct_16byte1)) + (code))(e_dbl, f_dbl, g_dbl, h_dbl); + /* { dg-output "\n9 2 6 1 2 3 4 5 6 3 1 8 3 2 4: 15 10 13 10 12 13" } */ + CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a)); + CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b)); + CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c)); + CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii)); + CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd)); + CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff)); + /* CHECK( 1 == 0); */ + exit(0); +} diff --git a/testsuite/libffi.closures/nested_struct10.c b/testsuite/libffi.closures/nested_struct10.c new file mode 100644 index 0000000..3cf2b44 --- /dev/null +++ b/testsuite/libffi.closures/nested_struct10.c @@ -0,0 +1,134 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Sample taken from Alan Modras patch to src/prep_cif.c. + Limitations: none. + PR: none. + Originator: 20051010 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct A { + unsigned long long a; + unsigned char b; +} A; + +typedef struct B { + unsigned char y; + struct A x; + unsigned int z; +} B; + +typedef struct C { + unsigned long long d; + unsigned char e; +} C; + +static B B_fn(struct A b2, struct B b3, struct C b4) +{ + struct B result; + + result.x.a = b2.a + b3.x.a + b3.z + b4.d; + result.x.b = b2.b + b3.x.b + b3.y + b4.e; + result.y = b2.b + b3.x.b + b4.e; + result.z = 0; + + printf("%d %d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b, + (int)b3.x.a, b3.x.b, b3.y, b3.z, (int)b4.d, b4.e, + (int)result.x.a, result.x.b, result.y); + + return result; +} + +static void +B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct A b0; + struct B b1; + struct C b2; + + b0 = *(struct A*)(args[0]); + b1 = *(struct B*)(args[1]); + b2 = *(struct C*)(args[2]); + + *(B*)resp = B_fn(b0, b1, b2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[4]; + ffi_type* cls_struct_fields[3]; + ffi_type* cls_struct_fields1[4]; + ffi_type* cls_struct_fields2[3]; + ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; + ffi_type* dbl_arg_types[4]; + + struct A e_dbl = { 1LL, 7}; + struct B f_dbl = { 99, {12LL , 127}, 255}; + struct C g_dbl = { 2LL, 9}; + + struct B res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_type2.size = 0; + cls_struct_type2.alignment = 0; + cls_struct_type2.type = FFI_TYPE_STRUCT; + cls_struct_type2.elements = cls_struct_fields2; + + cls_struct_fields[0] = &ffi_type_uint64; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = NULL; + + cls_struct_fields1[0] = &ffi_type_uchar; + cls_struct_fields1[1] = &cls_struct_type; + cls_struct_fields1[2] = &ffi_type_uint; + cls_struct_fields1[3] = NULL; + + cls_struct_fields2[0] = &ffi_type_uint64; + cls_struct_fields2[1] = &ffi_type_uchar; + cls_struct_fields2[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = &cls_struct_type2; + dbl_arg_types[3] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = NULL; + + ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); + /* { dg-output "1 7 12 127 99 255 2 9: 270 242 143" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + f_dbl.z + g_dbl.d)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); + + CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); + + res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl); + /* { dg-output "\n1 7 12 127 99 255 2 9: 270 242 143" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + f_dbl.z + g_dbl.d)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); + + exit(0); +} diff --git a/testsuite/libffi.closures/nested_struct11.c b/testsuite/libffi.closures/nested_struct11.c new file mode 100644 index 0000000..3510493 --- /dev/null +++ b/testsuite/libffi.closures/nested_struct11.c @@ -0,0 +1,121 @@ +/* Area: ffi_call, closure_call + Purpose: Check parameter passing with nested structs + of a single type. This tests the special cases + for homogeneous floating-point aggregates in the + AArch64 PCS. + Limitations: none. + PR: none. + Originator: ARM Ltd. */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct A { + float a_x; + float a_y; +} A; + +typedef struct B { + float b_x; + float b_y; +} B; + +typedef struct C { + A a; + B b; +} C; + +static C C_fn (int x, int y, int z, C source, int i, int j, int k) +{ + C result; + result.a.a_x = source.a.a_x; + result.a.a_y = source.a.a_y; + result.b.b_x = source.b.b_x; + result.b.b_y = source.b.b_y; + + printf ("%d, %d, %d, %d, %d, %d\n", x, y, z, i, j, k); + + printf ("%.1f, %.1f, %.1f, %.1f, " + "%.1f, %.1f, %.1f, %.1f\n", + source.a.a_x, source.a.a_y, + source.b.b_x, source.b.b_y, + result.a.a_x, result.a.a_y, + result.b.b_x, result.b.b_y); + + return result; +} + +int main (void) +{ + ffi_cif cif; + + ffi_type* struct_fields_source_a[3]; + ffi_type* struct_fields_source_b[3]; + ffi_type* struct_fields_source_c[3]; + ffi_type* arg_types[8]; + + ffi_type struct_type_a, struct_type_b, struct_type_c; + + struct A source_fld_a = {1.0, 2.0}; + struct B source_fld_b = {4.0, 8.0}; + int k = 1; + + struct C result; + struct C source = {source_fld_a, source_fld_b}; + + struct_type_a.size = 0; + struct_type_a.alignment = 0; + struct_type_a.type = FFI_TYPE_STRUCT; + struct_type_a.elements = struct_fields_source_a; + + struct_type_b.size = 0; + struct_type_b.alignment = 0; + struct_type_b.type = FFI_TYPE_STRUCT; + struct_type_b.elements = struct_fields_source_b; + + struct_type_c.size = 0; + struct_type_c.alignment = 0; + struct_type_c.type = FFI_TYPE_STRUCT; + struct_type_c.elements = struct_fields_source_c; + + struct_fields_source_a[0] = &ffi_type_float; + struct_fields_source_a[1] = &ffi_type_float; + struct_fields_source_a[2] = NULL; + + struct_fields_source_b[0] = &ffi_type_float; + struct_fields_source_b[1] = &ffi_type_float; + struct_fields_source_b[2] = NULL; + + struct_fields_source_c[0] = &struct_type_a; + struct_fields_source_c[1] = &struct_type_b; + struct_fields_source_c[2] = NULL; + + arg_types[0] = &ffi_type_sint32; + arg_types[1] = &ffi_type_sint32; + arg_types[2] = &ffi_type_sint32; + arg_types[3] = &struct_type_c; + arg_types[4] = &ffi_type_sint32; + arg_types[5] = &ffi_type_sint32; + arg_types[6] = &ffi_type_sint32; + arg_types[7] = NULL; + + void *args[7]; + args[0] = &k; + args[1] = &k; + args[2] = &k; + args[3] = &source; + args[4] = &k; + args[5] = &k; + args[6] = &k; + CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 7, &struct_type_c, + arg_types) == FFI_OK); + + ffi_call (&cif, FFI_FN (C_fn), &result, args); + /* { dg-output "1, 1, 1, 1, 1, 1\n" } */ + /* { dg-output "1.0, 2.0, 4.0, 8.0, 1.0, 2.0, 4.0, 8.0" } */ + CHECK (result.a.a_x == source.a.a_x); + CHECK (result.a.a_y == source.a.a_y); + CHECK (result.b.b_x == source.b.b_x); + CHECK (result.b.b_y == source.b.b_y); + exit (0); +} diff --git a/testsuite/libffi.closures/nested_struct2.c b/testsuite/libffi.closures/nested_struct2.c new file mode 100644 index 0000000..69268cd --- /dev/null +++ b/testsuite/libffi.closures/nested_struct2.c @@ -0,0 +1,110 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Sample taken from Alan Modras patch to src/prep_cif.c. + Limitations: none. + PR: none. + Originator: 20030911 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct A { + unsigned long a; + unsigned char b; +} A; + +typedef struct B { + struct A x; + unsigned char y; +} B; + +B B_fn(struct A b0, struct B b1) +{ + struct B result; + + result.x.a = b0.a + b1.x.a; + result.x.b = b0.b + b1.x.b + b1.y; + result.y = b0.b + b1.x.b; + + printf("%lu %d %lu %d %d: %lu %d %d\n", b0.a, b0.b, b1.x.a, b1.x.b, b1.y, + result.x.a, result.x.b, result.y); + + return result; +} + +static void +B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct A b0; + struct B b1; + + b0 = *(struct A*)(args[0]); + b1 = *(struct B*)(args[1]); + + *(B*)resp = B_fn(b0, b1); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[3]; + ffi_type* cls_struct_fields[3]; + ffi_type* cls_struct_fields1[3]; + ffi_type cls_struct_type, cls_struct_type1; + ffi_type* dbl_arg_types[3]; + + struct A e_dbl = { 1, 7}; + struct B f_dbl = {{12 , 127}, 99}; + + struct B res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_fields[0] = &ffi_type_ulong; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = NULL; + + cls_struct_fields1[0] = &cls_struct_type; + cls_struct_fields1[1] = &ffi_type_uchar; + cls_struct_fields1[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); + /* { dg-output "1 7 12 127 99: 13 233 134" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); + + CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); + + res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl); + /* { dg-output "\n1 7 12 127 99: 13 233 134" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); + + exit(0); +} diff --git a/testsuite/libffi.closures/nested_struct4.c b/testsuite/libffi.closures/nested_struct4.c new file mode 100644 index 0000000..2ffb4d6 --- /dev/null +++ b/testsuite/libffi.closures/nested_struct4.c @@ -0,0 +1,111 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Sample taken from Alan Modras patch to src/prep_cif.c. + Limitations: none. + PR: PR 25630. + Originator: 20051010 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct A { + double a; + unsigned char b; +} A; + +typedef struct B { + struct A x; + unsigned char y; +} B; + +static B B_fn(struct A b2, struct B b3) +{ + struct B result; + + result.x.a = b2.a + b3.x.a; + result.x.b = b2.b + b3.x.b + b3.y; + result.y = b2.b + b3.x.b; + + printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b, + (int)b3.x.a, b3.x.b, b3.y, + (int)result.x.a, result.x.b, result.y); + + return result; +} + +static void +B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct A b0; + struct B b1; + + b0 = *(struct A*)(args[0]); + b1 = *(struct B*)(args[1]); + + *(B*)resp = B_fn(b0, b1); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[3]; + ffi_type* cls_struct_fields[3]; + ffi_type* cls_struct_fields1[3]; + ffi_type cls_struct_type, cls_struct_type1; + ffi_type* dbl_arg_types[3]; + + struct A e_dbl = { 1.0, 7}; + struct B f_dbl = {{12.0 , 127}, 99}; + + struct B res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = NULL; + + cls_struct_fields1[0] = &cls_struct_type; + cls_struct_fields1[1] = &ffi_type_uchar; + cls_struct_fields1[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); + /* { dg-output "1 7 12 127 99: 13 233 134" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); + + CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); + + res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl); + /* { dg-output "\n1 7 12 127 99: 13 233 134" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); + + exit(0); +} diff --git a/testsuite/libffi.closures/nested_struct5.c b/testsuite/libffi.closures/nested_struct5.c new file mode 100644 index 0000000..6c79845 --- /dev/null +++ b/testsuite/libffi.closures/nested_struct5.c @@ -0,0 +1,112 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Sample taken from Alan Modras patch to src/prep_cif.c. + Limitations: none. + PR: none. + Originator: 20051010 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct A { + long double a; + unsigned char b; +} A; + +typedef struct B { + struct A x; + unsigned char y; +} B; + +static B B_fn(struct A b2, struct B b3) +{ + struct B result; + + result.x.a = b2.a + b3.x.a; + result.x.b = b2.b + b3.x.b + b3.y; + result.y = b2.b + b3.x.b; + + printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b, + (int)b3.x.a, b3.x.b, b3.y, + (int)result.x.a, result.x.b, result.y); + + return result; +} + +static void +B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct A b0; + struct B b1; + + b0 = *(struct A*)(args[0]); + b1 = *(struct B*)(args[1]); + + *(B*)resp = B_fn(b0, b1); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[3]; + ffi_type* cls_struct_fields[3]; + ffi_type* cls_struct_fields1[3]; + ffi_type cls_struct_type, cls_struct_type1; + ffi_type* dbl_arg_types[3]; + + struct A e_dbl = { 1.0, 7}; + struct B f_dbl = {{12.0 , 127}, 99}; + + struct B res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_fields[0] = &ffi_type_longdouble; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = NULL; + + cls_struct_fields1[0] = &cls_struct_type; + cls_struct_fields1[1] = &ffi_type_uchar; + cls_struct_fields1[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); + /* { dg-output "1 7 12 127 99: 13 233 134" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); + + + CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); + + res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl); + /* { dg-output "\n1 7 12 127 99: 13 233 134" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); + + exit(0); +} diff --git a/testsuite/libffi.closures/nested_struct6.c b/testsuite/libffi.closures/nested_struct6.c new file mode 100644 index 0000000..59d3579 --- /dev/null +++ b/testsuite/libffi.closures/nested_struct6.c @@ -0,0 +1,131 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Sample taken from Alan Modras patch to src/prep_cif.c. + Limitations: none. + PR: PR 25630. + Originator: 20051010 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct A { + double a; + unsigned char b; +} A; + +typedef struct B { + struct A x; + unsigned char y; +} B; + +typedef struct C { + long d; + unsigned char e; +} C; + +static B B_fn(struct A b2, struct B b3, struct C b4) +{ + struct B result; + + result.x.a = b2.a + b3.x.a + b4.d; + result.x.b = b2.b + b3.x.b + b3.y + b4.e; + result.y = b2.b + b3.x.b + b4.e; + + printf("%d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b, + (int)b3.x.a, b3.x.b, b3.y, (int)b4.d, b4.e, + (int)result.x.a, result.x.b, result.y); + + return result; +} + +static void +B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct A b0; + struct B b1; + struct C b2; + + b0 = *(struct A*)(args[0]); + b1 = *(struct B*)(args[1]); + b2 = *(struct C*)(args[2]); + + *(B*)resp = B_fn(b0, b1, b2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[4]; + ffi_type* cls_struct_fields[3]; + ffi_type* cls_struct_fields1[3]; + ffi_type* cls_struct_fields2[3]; + ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; + ffi_type* dbl_arg_types[4]; + + struct A e_dbl = { 1.0, 7}; + struct B f_dbl = {{12.0 , 127}, 99}; + struct C g_dbl = { 2, 9}; + + struct B res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_type2.size = 0; + cls_struct_type2.alignment = 0; + cls_struct_type2.type = FFI_TYPE_STRUCT; + cls_struct_type2.elements = cls_struct_fields2; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = NULL; + + cls_struct_fields1[0] = &cls_struct_type; + cls_struct_fields1[1] = &ffi_type_uchar; + cls_struct_fields1[2] = NULL; + + cls_struct_fields2[0] = &ffi_type_slong; + cls_struct_fields2[1] = &ffi_type_uchar; + cls_struct_fields2[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = &cls_struct_type2; + dbl_arg_types[3] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = NULL; + + ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); + /* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); + + CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); + + res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl); + /* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); + + exit(0); +} diff --git a/testsuite/libffi.closures/nested_struct7.c b/testsuite/libffi.closures/nested_struct7.c new file mode 100644 index 0000000..27595e6 --- /dev/null +++ b/testsuite/libffi.closures/nested_struct7.c @@ -0,0 +1,111 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Sample taken from Alan Modras patch to src/prep_cif.c. + Limitations: none. + PR: none. + Originator: 20051010 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct A { + unsigned long long a; + unsigned char b; +} A; + +typedef struct B { + struct A x; + unsigned char y; +} B; + +static B B_fn(struct A b2, struct B b3) +{ + struct B result; + + result.x.a = b2.a + b3.x.a; + result.x.b = b2.b + b3.x.b + b3.y; + result.y = b2.b + b3.x.b; + + printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b, + (int)b3.x.a, b3.x.b, b3.y, + (int)result.x.a, result.x.b, result.y); + + return result; +} + +static void +B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct A b0; + struct B b1; + + b0 = *(struct A*)(args[0]); + b1 = *(struct B*)(args[1]); + + *(B*)resp = B_fn(b0, b1); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[3]; + ffi_type* cls_struct_fields[3]; + ffi_type* cls_struct_fields1[3]; + ffi_type cls_struct_type, cls_struct_type1; + ffi_type* dbl_arg_types[3]; + + struct A e_dbl = { 1LL, 7}; + struct B f_dbl = {{12.0 , 127}, 99}; + + struct B res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_fields[0] = &ffi_type_uint64; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = NULL; + + cls_struct_fields1[0] = &cls_struct_type; + cls_struct_fields1[1] = &ffi_type_uchar; + cls_struct_fields1[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = NULL; + + ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); + /* { dg-output "1 7 12 127 99: 13 233 134" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); + + CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); + + res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl); + /* { dg-output "\n1 7 12 127 99: 13 233 134" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); + + exit(0); +} diff --git a/testsuite/libffi.closures/nested_struct8.c b/testsuite/libffi.closures/nested_struct8.c new file mode 100644 index 0000000..0e6c682 --- /dev/null +++ b/testsuite/libffi.closures/nested_struct8.c @@ -0,0 +1,131 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Sample taken from Alan Modras patch to src/prep_cif.c. + Limitations: none. + PR: none. + Originator: 20051010 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct A { + unsigned long long a; + unsigned char b; +} A; + +typedef struct B { + struct A x; + unsigned char y; +} B; + +typedef struct C { + unsigned long long d; + unsigned char e; +} C; + +static B B_fn(struct A b2, struct B b3, struct C b4) +{ + struct B result; + + result.x.a = b2.a + b3.x.a + b4.d; + result.x.b = b2.b + b3.x.b + b3.y + b4.e; + result.y = b2.b + b3.x.b + b4.e; + + printf("%d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b, + (int)b3.x.a, b3.x.b, b3.y, (int)b4.d, b4.e, + (int)result.x.a, result.x.b, result.y); + + return result; +} + +static void +B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct A b0; + struct B b1; + struct C b2; + + b0 = *(struct A*)(args[0]); + b1 = *(struct B*)(args[1]); + b2 = *(struct C*)(args[2]); + + *(B*)resp = B_fn(b0, b1, b2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[4]; + ffi_type* cls_struct_fields[3]; + ffi_type* cls_struct_fields1[3]; + ffi_type* cls_struct_fields2[3]; + ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; + ffi_type* dbl_arg_types[4]; + + struct A e_dbl = { 1LL, 7}; + struct B f_dbl = {{12LL , 127}, 99}; + struct C g_dbl = { 2LL, 9}; + + struct B res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_type2.size = 0; + cls_struct_type2.alignment = 0; + cls_struct_type2.type = FFI_TYPE_STRUCT; + cls_struct_type2.elements = cls_struct_fields2; + + cls_struct_fields[0] = &ffi_type_uint64; + cls_struct_fields[1] = &ffi_type_uchar; + cls_struct_fields[2] = NULL; + + cls_struct_fields1[0] = &cls_struct_type; + cls_struct_fields1[1] = &ffi_type_uchar; + cls_struct_fields1[2] = NULL; + + cls_struct_fields2[0] = &ffi_type_uint64; + cls_struct_fields2[1] = &ffi_type_uchar; + cls_struct_fields2[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = &cls_struct_type2; + dbl_arg_types[3] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = NULL; + + ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); + /* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); + + CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); + + res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl); + /* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); + + exit(0); +} diff --git a/testsuite/libffi.closures/nested_struct9.c b/testsuite/libffi.closures/nested_struct9.c new file mode 100644 index 0000000..5f7ac67 --- /dev/null +++ b/testsuite/libffi.closures/nested_struct9.c @@ -0,0 +1,131 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Contains structs as parameter of the struct itself. + Sample taken from Alan Modras patch to src/prep_cif.c. + Limitations: none. + PR: none. + Originator: 20051010 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct A { + unsigned char a; + unsigned long long b; +} A; + +typedef struct B { + struct A x; + unsigned char y; +} B; + +typedef struct C { + unsigned long d; + unsigned char e; +} C; + +static B B_fn(struct A b2, struct B b3, struct C b4) +{ + struct B result; + + result.x.a = b2.a + b3.x.a + b4.d; + result.x.b = b2.b + b3.x.b + b3.y + b4.e; + result.y = b2.b + b3.x.b + b4.e; + + printf("%d %d %d %d %d %d %d: %d %d %d\n", b2.a, (int)b2.b, + b3.x.a, (int)b3.x.b, b3.y, (int)b4.d, b4.e, + result.x.a, (int)result.x.b, result.y); + + return result; +} + +static void +B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct A b0; + struct B b1; + struct C b2; + + b0 = *(struct A*)(args[0]); + b1 = *(struct B*)(args[1]); + b2 = *(struct C*)(args[2]); + + *(B*)resp = B_fn(b0, b1, b2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[4]; + ffi_type* cls_struct_fields[3]; + ffi_type* cls_struct_fields1[3]; + ffi_type* cls_struct_fields2[3]; + ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; + ffi_type* dbl_arg_types[4]; + + struct A e_dbl = { 1, 7LL}; + struct B f_dbl = {{12.0 , 127}, 99}; + struct C g_dbl = { 2, 9}; + + struct B res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_type1.size = 0; + cls_struct_type1.alignment = 0; + cls_struct_type1.type = FFI_TYPE_STRUCT; + cls_struct_type1.elements = cls_struct_fields1; + + cls_struct_type2.size = 0; + cls_struct_type2.alignment = 0; + cls_struct_type2.type = FFI_TYPE_STRUCT; + cls_struct_type2.elements = cls_struct_fields2; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &ffi_type_uint64; + cls_struct_fields[2] = NULL; + + cls_struct_fields1[0] = &cls_struct_type; + cls_struct_fields1[1] = &ffi_type_uchar; + cls_struct_fields1[2] = NULL; + + cls_struct_fields2[0] = &ffi_type_ulong; + cls_struct_fields2[1] = &ffi_type_uchar; + cls_struct_fields2[2] = NULL; + + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type1; + dbl_arg_types[2] = &cls_struct_type2; + dbl_arg_types[3] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = NULL; + + ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); + /* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); + + CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK); + + res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl); + /* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */ + CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d)); + CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); + CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); + + exit(0); +} diff --git a/testsuite/libffi.closures/problem1.c b/testsuite/libffi.closures/problem1.c new file mode 100644 index 0000000..6a91555 --- /dev/null +++ b/testsuite/libffi.closures/problem1.c @@ -0,0 +1,90 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct my_ffi_struct { + double a; + double b; + double c; +} my_ffi_struct; + +my_ffi_struct callee(struct my_ffi_struct a1, struct my_ffi_struct a2) +{ + struct my_ffi_struct result; + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + + + printf("%g %g %g %g %g %g: %g %g %g\n", a1.a, a1.b, a1.c, + a2.a, a2.b, a2.c, result.a, result.b, result.c); + + return result; +} + +void stub(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + struct my_ffi_struct a1; + struct my_ffi_struct a2; + + a1 = *(struct my_ffi_struct*)(args[0]); + a2 = *(struct my_ffi_struct*)(args[1]); + + *(my_ffi_struct *)resp = callee(a1, a2); +} + + +int main(void) +{ + ffi_type* my_ffi_struct_fields[4]; + ffi_type my_ffi_struct_type; + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args[4]; + ffi_type* arg_types[3]; + + struct my_ffi_struct g = { 1.0, 2.0, 3.0 }; + struct my_ffi_struct f = { 1.0, 2.0, 3.0 }; + struct my_ffi_struct res; + + my_ffi_struct_type.size = 0; + my_ffi_struct_type.alignment = 0; + my_ffi_struct_type.type = FFI_TYPE_STRUCT; + my_ffi_struct_type.elements = my_ffi_struct_fields; + + my_ffi_struct_fields[0] = &ffi_type_double; + my_ffi_struct_fields[1] = &ffi_type_double; + my_ffi_struct_fields[2] = &ffi_type_double; + my_ffi_struct_fields[3] = NULL; + + arg_types[0] = &my_ffi_struct_type; + arg_types[1] = &my_ffi_struct_type; + arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &my_ffi_struct_type, + arg_types) == FFI_OK); + + args[0] = &g; + args[1] = &f; + args[2] = NULL; + ffi_call(&cif, FFI_FN(callee), &res, args); + /* { dg-output "1 2 3 1 2 3: 2 4 6" } */ + printf("res: %g %g %g\n", res.a, res.b, res.c); + /* { dg-output "\nres: 2 4 6" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, stub, NULL, code) == FFI_OK); + + res = ((my_ffi_struct(*)(struct my_ffi_struct, struct my_ffi_struct))(code))(g, f); + /* { dg-output "\n1 2 3 1 2 3: 2 4 6" } */ + printf("res: %g %g %g\n", res.a, res.b, res.c); + /* { dg-output "\nres: 2 4 6" } */ + + exit(0);; +} diff --git a/testsuite/libffi.closures/stret_large.c b/testsuite/libffi.closures/stret_large.c new file mode 100644 index 0000000..71c2469 --- /dev/null +++ b/testsuite/libffi.closures/stret_large.c @@ -0,0 +1,145 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure returning with different structure size. + Depending on the ABI. Check bigger struct which overlaps + the gp and fp register count on Darwin/AIX/ppc64. + Limitations: none. + PR: none. + Originator: Blake Chaffin 6/21/2007 */ + +/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +/* 13 FPRs: 104 bytes */ +/* 14 FPRs: 112 bytes */ + +typedef struct struct_108byte { + double a; + double b; + double c; + double d; + double e; + double f; + double g; + double h; + double i; + double j; + double k; + double l; + double m; + int n; +} struct_108byte; + +struct_108byte cls_struct_108byte_fn( + struct_108byte b0, + struct_108byte b1, + struct_108byte b2, + struct_108byte b3) +{ + struct_108byte result; + + result.a = b0.a + b1.a + b2.a + b3.a; + result.b = b0.b + b1.b + b2.b + b3.b; + result.c = b0.c + b1.c + b2.c + b3.c; + result.d = b0.d + b1.d + b2.d + b3.d; + result.e = b0.e + b1.e + b2.e + b3.e; + result.f = b0.f + b1.f + b2.f + b3.f; + result.g = b0.g + b1.g + b2.g + b3.g; + result.h = b0.h + b1.h + b2.h + b3.h; + result.i = b0.i + b1.i + b2.i + b3.i; + result.j = b0.j + b1.j + b2.j + b3.j; + result.k = b0.k + b1.k + b2.k + b3.k; + result.l = b0.l + b1.l + b2.l + b3.l; + result.m = b0.m + b1.m + b2.m + b3.m; + result.n = b0.n + b1.n + b2.n + b3.n; + + printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", result.a, result.b, result.c, + result.d, result.e, result.f, result.g, result.h, result.i, + result.j, result.k, result.l, result.m, result.n); + + return result; +} + +static void +cls_struct_108byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__) +{ + struct_108byte b0, b1, b2, b3; + + b0 = *(struct_108byte*)(args[0]); + b1 = *(struct_108byte*)(args[1]); + b2 = *(struct_108byte*)(args[2]); + b3 = *(struct_108byte*)(args[3]); + + *(struct_108byte*)resp = cls_struct_108byte_fn(b0, b1, b2, b3); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[15]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct_108byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 1.0, 2.0, 3.0, 7.0, 2.0, 7 }; + struct_108byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0, 5.0, 7.0, 9.0, 1.0, 4 }; + struct_108byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 8.0, 6.0, 1.0, 4.0, 0.0, 3 }; + struct_108byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 9.0, 2.0, 6.0, 5.0, 3.0, 2 }; + struct_108byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_double; + cls_struct_fields[2] = &ffi_type_double; + cls_struct_fields[3] = &ffi_type_double; + cls_struct_fields[4] = &ffi_type_double; + cls_struct_fields[5] = &ffi_type_double; + cls_struct_fields[6] = &ffi_type_double; + cls_struct_fields[7] = &ffi_type_double; + cls_struct_fields[8] = &ffi_type_double; + cls_struct_fields[9] = &ffi_type_double; + cls_struct_fields[10] = &ffi_type_double; + cls_struct_fields[11] = &ffi_type_double; + cls_struct_fields[12] = &ffi_type_double; + cls_struct_fields[13] = &ffi_type_sint32; + cls_struct_fields[14] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = &cls_struct_type; + dbl_arg_types[3] = &cls_struct_type; + dbl_arg_types[4] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = &h_dbl; + args_dbl[4] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_108byte_fn), &res_dbl, args_dbl); + /* { dg-output "22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */ + printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b, + res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i, + res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n); + /* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_108byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((struct_108byte(*)(struct_108byte, struct_108byte, + struct_108byte, struct_108byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl); + /* { dg-output "\n22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */ + printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b, + res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i, + res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n); + /* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */ + + exit(0); +} diff --git a/testsuite/libffi.closures/stret_large2.c b/testsuite/libffi.closures/stret_large2.c new file mode 100644 index 0000000..d9c750e --- /dev/null +++ b/testsuite/libffi.closures/stret_large2.c @@ -0,0 +1,148 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure returning with different structure size. + Depending on the ABI. Check bigger struct which overlaps + the gp and fp register count on Darwin/AIX/ppc64. + Limitations: none. + PR: none. + Originator: Blake Chaffin 6/21/2007 */ + +/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +/* 13 FPRs: 104 bytes */ +/* 14 FPRs: 112 bytes */ + +typedef struct struct_116byte { + double a; + double b; + double c; + double d; + double e; + double f; + double g; + double h; + double i; + double j; + double k; + double l; + double m; + double n; + int o; +} struct_116byte; + +struct_116byte cls_struct_116byte_fn( + struct_116byte b0, + struct_116byte b1, + struct_116byte b2, + struct_116byte b3) +{ + struct_116byte result; + + result.a = b0.a + b1.a + b2.a + b3.a; + result.b = b0.b + b1.b + b2.b + b3.b; + result.c = b0.c + b1.c + b2.c + b3.c; + result.d = b0.d + b1.d + b2.d + b3.d; + result.e = b0.e + b1.e + b2.e + b3.e; + result.f = b0.f + b1.f + b2.f + b3.f; + result.g = b0.g + b1.g + b2.g + b3.g; + result.h = b0.h + b1.h + b2.h + b3.h; + result.i = b0.i + b1.i + b2.i + b3.i; + result.j = b0.j + b1.j + b2.j + b3.j; + result.k = b0.k + b1.k + b2.k + b3.k; + result.l = b0.l + b1.l + b2.l + b3.l; + result.m = b0.m + b1.m + b2.m + b3.m; + result.n = b0.n + b1.n + b2.n + b3.n; + result.o = b0.o + b1.o + b2.o + b3.o; + + printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", result.a, result.b, result.c, + result.d, result.e, result.f, result.g, result.h, result.i, + result.j, result.k, result.l, result.m, result.n, result.o); + + return result; +} + +static void +cls_struct_116byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__) +{ + struct_116byte b0, b1, b2, b3; + + b0 = *(struct_116byte*)(args[0]); + b1 = *(struct_116byte*)(args[1]); + b2 = *(struct_116byte*)(args[2]); + b3 = *(struct_116byte*)(args[3]); + + *(struct_116byte*)resp = cls_struct_116byte_fn(b0, b1, b2, b3); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[16]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct_116byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 7 }; + struct_116byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0, 5.0, 7.0, 9.0, 1.0, 6.0, 4 }; + struct_116byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 8.0, 6.0, 1.0, 4.0, 0.0, 7.0, 3 }; + struct_116byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 9.0, 2.0, 6.0, 5.0, 3.0, 8.0, 2 }; + struct_116byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_double; + cls_struct_fields[2] = &ffi_type_double; + cls_struct_fields[3] = &ffi_type_double; + cls_struct_fields[4] = &ffi_type_double; + cls_struct_fields[5] = &ffi_type_double; + cls_struct_fields[6] = &ffi_type_double; + cls_struct_fields[7] = &ffi_type_double; + cls_struct_fields[8] = &ffi_type_double; + cls_struct_fields[9] = &ffi_type_double; + cls_struct_fields[10] = &ffi_type_double; + cls_struct_fields[11] = &ffi_type_double; + cls_struct_fields[12] = &ffi_type_double; + cls_struct_fields[13] = &ffi_type_double; + cls_struct_fields[14] = &ffi_type_sint32; + cls_struct_fields[15] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = &cls_struct_type; + dbl_arg_types[3] = &cls_struct_type; + dbl_arg_types[4] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = &h_dbl; + args_dbl[4] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_116byte_fn), &res_dbl, args_dbl); + /* { dg-output "22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */ + printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b, + res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i, + res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n, res_dbl.o); + /* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_116byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((struct_116byte(*)(struct_116byte, struct_116byte, + struct_116byte, struct_116byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl); + /* { dg-output "\n22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */ + printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b, + res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i, + res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n, res_dbl.o); + /* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */ + + exit(0); +} diff --git a/testsuite/libffi.closures/stret_medium.c b/testsuite/libffi.closures/stret_medium.c new file mode 100644 index 0000000..973ee02 --- /dev/null +++ b/testsuite/libffi.closures/stret_medium.c @@ -0,0 +1,124 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure returning with different structure size. + Depending on the ABI. Check bigger struct which overlaps + the gp and fp register count on Darwin/AIX/ppc64. + Limitations: none. + PR: none. + Originator: Blake Chaffin 6/21/2007 */ + +/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +typedef struct struct_72byte { + double a; + double b; + double c; + double d; + double e; + double f; + double g; + double h; + double i; +} struct_72byte; + +struct_72byte cls_struct_72byte_fn( + struct_72byte b0, + struct_72byte b1, + struct_72byte b2, + struct_72byte b3) +{ + struct_72byte result; + + result.a = b0.a + b1.a + b2.a + b3.a; + result.b = b0.b + b1.b + b2.b + b3.b; + result.c = b0.c + b1.c + b2.c + b3.c; + result.d = b0.d + b1.d + b2.d + b3.d; + result.e = b0.e + b1.e + b2.e + b3.e; + result.f = b0.f + b1.f + b2.f + b3.f; + result.g = b0.g + b1.g + b2.g + b3.g; + result.h = b0.h + b1.h + b2.h + b3.h; + result.i = b0.i + b1.i + b2.i + b3.i; + + printf("%g %g %g %g %g %g %g %g %g\n", result.a, result.b, result.c, + result.d, result.e, result.f, result.g, result.h, result.i); + + return result; +} + +static void +cls_struct_72byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__) +{ + struct_72byte b0, b1, b2, b3; + + b0 = *(struct_72byte*)(args[0]); + b1 = *(struct_72byte*)(args[1]); + b2 = *(struct_72byte*)(args[2]); + b3 = *(struct_72byte*)(args[3]); + + *(struct_72byte*)resp = cls_struct_72byte_fn(b0, b1, b2, b3); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[10]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7.0 }; + struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0 }; + struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3.0 }; + struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2.0 }; + struct_72byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_double; + cls_struct_fields[2] = &ffi_type_double; + cls_struct_fields[3] = &ffi_type_double; + cls_struct_fields[4] = &ffi_type_double; + cls_struct_fields[5] = &ffi_type_double; + cls_struct_fields[6] = &ffi_type_double; + cls_struct_fields[7] = &ffi_type_double; + cls_struct_fields[8] = &ffi_type_double; + cls_struct_fields[9] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = &cls_struct_type; + dbl_arg_types[3] = &cls_struct_type; + dbl_arg_types[4] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = &h_dbl; + args_dbl[4] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_72byte_fn), &res_dbl, args_dbl); + /* { dg-output "22 15 17 25 6 13 19 18 16" } */ + printf("res: %g %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c, + res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i); + /* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_72byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((struct_72byte(*)(struct_72byte, struct_72byte, + struct_72byte, struct_72byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl); + /* { dg-output "\n22 15 17 25 6 13 19 18 16" } */ + printf("res: %g %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c, + res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i); + /* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */ + + exit(0); +} diff --git a/testsuite/libffi.closures/stret_medium2.c b/testsuite/libffi.closures/stret_medium2.c new file mode 100644 index 0000000..84323d1 --- /dev/null +++ b/testsuite/libffi.closures/stret_medium2.c @@ -0,0 +1,125 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure returning with different structure size. + Depending on the ABI. Check bigger struct which overlaps + the gp and fp register count on Darwin/AIX/ppc64. + Limitations: none. + PR: none. + Originator: Blake Chaffin 6/21/2007 */ + +/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ +/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */ +#include "ffitest.h" + +typedef struct struct_72byte { + double a; + double b; + double c; + double d; + double e; + double f; + double g; + double h; + long long i; +} struct_72byte; + +struct_72byte cls_struct_72byte_fn( + struct_72byte b0, + struct_72byte b1, + struct_72byte b2, + struct_72byte b3) +{ + struct_72byte result; + + result.a = b0.a + b1.a + b2.a + b3.a; + result.b = b0.b + b1.b + b2.b + b3.b; + result.c = b0.c + b1.c + b2.c + b3.c; + result.d = b0.d + b1.d + b2.d + b3.d; + result.e = b0.e + b1.e + b2.e + b3.e; + result.f = b0.f + b1.f + b2.f + b3.f; + result.g = b0.g + b1.g + b2.g + b3.g; + result.h = b0.h + b1.h + b2.h + b3.h; + result.i = b0.i + b1.i + b2.i + b3.i; + + printf("%g %g %g %g %g %g %g %g %" PRIdLL "\n", result.a, result.b, result.c, + result.d, result.e, result.f, result.g, result.h, result.i); + + return result; +} + +static void +cls_struct_72byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__) +{ + struct_72byte b0, b1, b2, b3; + + b0 = *(struct_72byte*)(args[0]); + b1 = *(struct_72byte*)(args[1]); + b2 = *(struct_72byte*)(args[2]); + b3 = *(struct_72byte*)(args[3]); + + *(struct_72byte*)resp = cls_struct_72byte_fn(b0, b1, b2, b3); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_dbl[5]; + ffi_type* cls_struct_fields[10]; + ffi_type cls_struct_type; + ffi_type* dbl_arg_types[5]; + + struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7 }; + struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4 }; + struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3 }; + struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2 }; + struct_72byte res_dbl; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_double; + cls_struct_fields[1] = &ffi_type_double; + cls_struct_fields[2] = &ffi_type_double; + cls_struct_fields[3] = &ffi_type_double; + cls_struct_fields[4] = &ffi_type_double; + cls_struct_fields[5] = &ffi_type_double; + cls_struct_fields[6] = &ffi_type_double; + cls_struct_fields[7] = &ffi_type_double; + cls_struct_fields[8] = &ffi_type_sint64; + cls_struct_fields[9] = NULL; + + dbl_arg_types[0] = &cls_struct_type; + dbl_arg_types[1] = &cls_struct_type; + dbl_arg_types[2] = &cls_struct_type; + dbl_arg_types[3] = &cls_struct_type; + dbl_arg_types[4] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type, + dbl_arg_types) == FFI_OK); + + args_dbl[0] = &e_dbl; + args_dbl[1] = &f_dbl; + args_dbl[2] = &g_dbl; + args_dbl[3] = &h_dbl; + args_dbl[4] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_72byte_fn), &res_dbl, args_dbl); + /* { dg-output "22 15 17 25 6 13 19 18 16" } */ + printf("res: %g %g %g %g %g %g %g %g %" PRIdLL "\n", res_dbl.a, res_dbl.b, res_dbl.c, + res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i); + /* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_72byte_gn, NULL, code) == FFI_OK); + + res_dbl = ((struct_72byte(*)(struct_72byte, struct_72byte, + struct_72byte, struct_72byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl); + /* { dg-output "\n22 15 17 25 6 13 19 18 16" } */ + printf("res: %g %g %g %g %g %g %g %g %" PRIdLL "\n", res_dbl.a, res_dbl.b, res_dbl.c, + res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i); + /* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */ + + exit(0); +} diff --git a/testsuite/libffi.closures/testclosure.c b/testsuite/libffi.closures/testclosure.c new file mode 100644 index 0000000..ca31056 --- /dev/null +++ b/testsuite/libffi.closures/testclosure.c @@ -0,0 +1,70 @@ +/* Area: closure_call + Purpose: Check return value float. + Limitations: none. + PR: 41908. + Originator: 20091102 */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct cls_struct_combined { + float a; + float b; + float c; + float d; +} cls_struct_combined; + +void cls_struct_combined_fn(struct cls_struct_combined arg) +{ + printf("%g %g %g %g\n", + arg.a, arg.b, + arg.c, arg.d); + fflush(stdout); +} + +static void +cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, + void** args, void* userdata __UNUSED__) +{ + struct cls_struct_combined a0; + + a0 = *(struct cls_struct_combined*)(args[0]); + + cls_struct_combined_fn(a0); +} + + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type* cls_struct_fields0[5]; + ffi_type cls_struct_type0; + ffi_type* dbl_arg_types[5]; + + struct cls_struct_combined g_dbl = {4.0, 5.0, 1.0, 8.0}; + + cls_struct_type0.size = 0; + cls_struct_type0.alignment = 0; + cls_struct_type0.type = FFI_TYPE_STRUCT; + cls_struct_type0.elements = cls_struct_fields0; + + cls_struct_fields0[0] = &ffi_type_float; + cls_struct_fields0[1] = &ffi_type_float; + cls_struct_fields0[2] = &ffi_type_float; + cls_struct_fields0[3] = &ffi_type_float; + cls_struct_fields0[4] = NULL; + + dbl_arg_types[0] = &cls_struct_type0; + dbl_arg_types[1] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, + dbl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK); + + ((void(*)(cls_struct_combined)) (code))(g_dbl); + /* { dg-output "4 5 1 8" } */ + exit(0); +} diff --git a/testsuite/libffi.closures/unwindtest.cc b/testsuite/libffi.closures/unwindtest.cc new file mode 100644 index 0000000..e114565 --- /dev/null +++ b/testsuite/libffi.closures/unwindtest.cc @@ -0,0 +1,117 @@ +/* Area: ffi_closure, unwind info + Purpose: Check if the unwind information is passed correctly. + Limitations: none. + PR: none. + Originator: Jeff Sturm */ + +/* { dg-do run { xfail x86_64-apple-darwin* moxie*-*-* } } */ + +#include "ffitest.h" + +void ABI_ATTR +closure_test_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, + void** args __UNUSED__, void* userdata __UNUSED__) +{ + throw 9; +} + +typedef void (*closure_test_type)(); + +void closure_test_fn1(ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) + { + *(ffi_arg*)resp = + (int)*(float *)args[0] +(int)(*(float *)args[1]) + + (int)(*(float *)args[2]) + (int)*(float *)args[3] + + (int)(*(signed short *)args[4]) + (int)(*(float *)args[5]) + + (int)*(float *)args[6] + (int)(*(int *)args[7]) + + (int)(*(double*)args[8]) + (int)*(int *)args[9] + + (int)(*(int *)args[10]) + (int)(*(float *)args[11]) + + (int)*(int *)args[12] + (int)(*(int *)args[13]) + + (int)(*(int *)args[14]) + *(int *)args[15] + (int)(intptr_t)userdata; + + printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n", + (int)*(float *)args[0], (int)(*(float *)args[1]), + (int)(*(float *)args[2]), (int)*(float *)args[3], + (int)(*(signed short *)args[4]), (int)(*(float *)args[5]), + (int)*(float *)args[6], (int)(*(int *)args[7]), + (int)(*(double *)args[8]), (int)*(int *)args[9], + (int)(*(int *)args[10]), (int)(*(float *)args[11]), + (int)*(int *)args[12], (int)(*(int *)args[13]), + (int)(*(int *)args[14]), *(int *)args[15], + (int)(intptr_t)userdata, (int)*(ffi_arg*)resp); + + throw (int)*(ffi_arg*)resp; +} + +typedef int (*closure_test_type1)(float, float, float, float, signed short, + float, float, int, double, int, int, float, + int, int, int, int); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = (ffi_closure *)ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[17]; + + { + cl_arg_types[1] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, + &ffi_type_void, cl_arg_types) == FFI_OK); + CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn, NULL, code) == FFI_OK); + + try + { + (*((closure_test_type)(code)))(); + } catch (int exception_code) + { + CHECK(exception_code == 9); + } + + printf("part one OK\n"); + /* { dg-output "part one OK" } */ + } + + { + + cl_arg_types[0] = &ffi_type_float; + cl_arg_types[1] = &ffi_type_float; + cl_arg_types[2] = &ffi_type_float; + cl_arg_types[3] = &ffi_type_float; + cl_arg_types[4] = &ffi_type_sshort; + cl_arg_types[5] = &ffi_type_float; + cl_arg_types[6] = &ffi_type_float; + cl_arg_types[7] = &ffi_type_uint; + cl_arg_types[8] = &ffi_type_double; + cl_arg_types[9] = &ffi_type_uint; + cl_arg_types[10] = &ffi_type_uint; + cl_arg_types[11] = &ffi_type_float; + cl_arg_types[12] = &ffi_type_uint; + cl_arg_types[13] = &ffi_type_uint; + cl_arg_types[14] = &ffi_type_uint; + cl_arg_types[15] = &ffi_type_uint; + cl_arg_types[16] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16, + &ffi_type_sint, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn1, + (void *) 3 /* userdata */, code) == FFI_OK); + try + { + (*((closure_test_type1)code)) + (1.1, 2.2, 3.3, 4.4, 127, 5.5, 6.6, 8, 9, 10, 11, 12.0, 13, + 19, 21, 1); + /* { dg-output "\n1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */ + } catch (int exception_code) + { + CHECK(exception_code == 255); + } + printf("part two OK\n"); + /* { dg-output "\npart two OK" } */ + } + exit(0); +}