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
+++ /dev/null
-/* 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);
-}
+++ /dev/null
-/* 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;
-}
+++ /dev/null
-/* 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: <andreast@gcc.gnu.org> 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);
-}
+++ /dev/null
-/* 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: <andreast@gcc.gnu.org> 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);
-}
+++ /dev/null
-/* 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: <andreast@gcc.gnu.org> 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);
-}
+++ /dev/null
-/* 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);
-}
+++ /dev/null
-/* 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: <andreast@gcc.gnu.org> 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);
-}
+++ /dev/null
-/* 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: <andreast@gcc.gnu.org> 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);
-}
+++ /dev/null
-/* 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: <andreast@gcc.gnu.org> 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);
-}
+++ /dev/null
-/* 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: <andreast@gcc.gnu.org> 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);
-}
+++ /dev/null
-/* 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: <andreast@gcc.gnu.org> 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);
-}
+++ /dev/null
-/* 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: <andreast@gcc.gnu.org> 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);
-}
+++ /dev/null
-/* 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: <andreast@gcc.gnu.org> 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);
-}
+++ /dev/null
-/* Area: ffi_call, closure_call
- Purpose: Check structure passing with different structure size.
- Limitations: none.
- PR: none.
- Originator: <andreast@gcc.gnu.org> 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);;
-}
+++ /dev/null
-/* 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);
-}
+++ /dev/null
-/* 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);
-}
+++ /dev/null
-/* 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);
-}
+++ /dev/null
-/* 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);
-}
+++ /dev/null
-/* Area: closure_call
- Purpose: Check return value float.
- Limitations: none.
- PR: 41908.
- Originator: <rfm@gnu.org> 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);
-}
+++ /dev/null
-/* Area: ffi_closure, unwind info
- Purpose: Check if the unwind information is passed correctly.
- Limitations: none.
- PR: none.
- Originator: Jeff Sturm <jsturm@one-point.com> */
-
-/* { 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);
-}
}
}
+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:
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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: <andreast@gcc.gnu.org> 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);
+}
--- /dev/null
+/* 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: <andreast@gcc.gnu.org> 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);
+}
--- /dev/null
+/* 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: <andreast@gcc.gnu.org> 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);
+}
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* 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: <andreast@gcc.gnu.org> 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);
+}
--- /dev/null
+/* 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: <andreast@gcc.gnu.org> 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);
+}
--- /dev/null
+/* 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: <andreast@gcc.gnu.org> 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);
+}
--- /dev/null
+/* 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: <andreast@gcc.gnu.org> 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);
+}
--- /dev/null
+/* 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: <andreast@gcc.gnu.org> 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);
+}
--- /dev/null
+/* 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: <andreast@gcc.gnu.org> 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);
+}
--- /dev/null
+/* 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: <andreast@gcc.gnu.org> 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);
+}
--- /dev/null
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 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);;
+}
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* Area: closure_call
+ Purpose: Check return value float.
+ Limitations: none.
+ PR: 41908.
+ Originator: <rfm@gnu.org> 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);
+}
--- /dev/null
+/* Area: ffi_closure, unwind info
+ Purpose: Check if the unwind information is passed correctly.
+ Limitations: none.
+ PR: none.
+ Originator: Jeff Sturm <jsturm@one-point.com> */
+
+/* { 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);
+}