1 /* Area: ffi_call 2 Purpose: Check non-standard complex types. 3 Limitations: none. 4 PR: none. 5 Originator: <vogt (at) linux.vnet.ibm.com>. */ 6 7 /* { dg-do run } */ 8 9 #include "ffitest.h" 10 #include "ffi.h" 11 #include <complex.h> 12 13 _Complex int f_complex(_Complex int c, int x, int *py) 14 { 15 c = -(2 * creal (c)) + (cimag (c) + 1)* I; 16 *py += x; 17 18 return c; 19 } 20 21 /* 22 * This macro can be used to define new complex type descriptors 23 * in a platform independent way. 24 * 25 * name: Name of the new descriptor is ffi_type_complex_<name>. 26 * type: The C base type of the complex type. 27 */ 28 #define FFI_COMPLEX_TYPEDEF(name, type, ffitype) \ 29 static ffi_type *ffi_elements_complex_##name [2] = { \ 30 (ffi_type *)(&ffitype), NULL \ 31 }; \ 32 struct struct_align_complex_##name { \ 33 char c; \ 34 _Complex type x; \ 35 }; \ 36 ffi_type ffi_type_complex_##name = { \ 37 sizeof(_Complex type), \ 38 offsetof(struct struct_align_complex_##name, x), \ 39 FFI_TYPE_COMPLEX, \ 40 (ffi_type **)ffi_elements_complex_##name \ 41 } 42 43 /* Define new complex type descriptors using the macro: */ 44 /* ffi_type_complex_sint */ 45 FFI_COMPLEX_TYPEDEF(sint, int, ffi_type_sint); 46 /* ffi_type_complex_uchar */ 47 FFI_COMPLEX_TYPEDEF(uchar, unsigned char, ffi_type_uint8); 48 49 int main (void) 50 { 51 ffi_cif cif; 52 ffi_type *args[MAX_ARGS]; 53 void *values[MAX_ARGS]; 54 55 _Complex int tc_arg; 56 _Complex int tc_result; 57 int tc_int_arg_x; 58 int tc_y; 59 int *tc_ptr_arg_y = &tc_y; 60 61 args[0] = &ffi_type_complex_sint; 62 args[1] = &ffi_type_sint; 63 args[2] = &ffi_type_pointer; 64 values[0] = &tc_arg; 65 values[1] = &tc_int_arg_x; 66 values[2] = &tc_ptr_arg_y; 67 68 /* Initialize the cif */ 69 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &ffi_type_complex_sint, args) 70 == FFI_OK); 71 72 tc_arg = 1 + 7 * I; 73 tc_int_arg_x = 1234; 74 tc_y = 9876; 75 ffi_call(&cif, FFI_FN(f_complex), &tc_result, values); 76 77 printf ("%d,%di %d,%di, x %d 1234, y %d 11110\n", 78 (int)tc_result, (int)(tc_result * -I), 2, 8, tc_int_arg_x, tc_y); 79 /* dg-output "-2,8i 2,8i, x 1234 1234, y 11110 11110" */ 80 CHECK (creal (tc_result) == -2); 81 CHECK (cimag (tc_result) == 8); 82 CHECK (tc_int_arg_x == 1234); 83 CHECK (*tc_ptr_arg_y == 11110); 84 85 exit(0); 86 } 87