1 /* Area: closure_call 2 Purpose: Check register allocation for closure calls with many float and double arguments 3 Limitations: none. 4 PR: none. 5 Originator: <david.schneider (at) picle.org> */ 6 7 /* { dg-do run } */ 8 #include "ffitest.h" 9 #include <float.h> 10 #include <math.h> 11 12 #define NARGS 16 13 14 static void cls_mixed_float_double_fn(ffi_cif* cif , void* ret, void** args, 15 void* userdata __UNUSED__) 16 { 17 double r = 0; 18 unsigned int i; 19 double t; 20 for(i=0; i < cif->nargs; i++) 21 { 22 if(cif->arg_types[i] == &ffi_type_double) { 23 t = *(((double**)(args))[i]); 24 } else { 25 t = *(((float**)(args))[i]); 26 } 27 r += t; 28 } 29 *((double*)ret) = r; 30 } 31 typedef double (*cls_mixed)(double, float, double, double, double, double, double, float, float, double, float, float); 32 33 int main (void) 34 { 35 ffi_cif cif; 36 ffi_closure *closure; 37 void* code; 38 ffi_type *argtypes[12] = {&ffi_type_double, &ffi_type_float, &ffi_type_double, 39 &ffi_type_double, &ffi_type_double, &ffi_type_double, 40 &ffi_type_double, &ffi_type_float, &ffi_type_float, 41 &ffi_type_double, &ffi_type_float, &ffi_type_float}; 42 43 44 closure = ffi_closure_alloc(sizeof(ffi_closure), (void**)&code); 45 if(closure ==NULL) 46 abort(); 47 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 12, &ffi_type_double, argtypes) == FFI_OK); 48 CHECK(ffi_prep_closure_loc(closure, &cif, cls_mixed_float_double_fn, NULL, code) == FFI_OK); 49 double ret = ((cls_mixed)code)(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2); 50 ffi_closure_free(closure); 51 if(fabs(ret - 7.8) < FLT_EPSILON) 52 exit(0); 53 else 54 abort(); 55 } 56