diff options
author | Dominik Vogt <vogt@linux.vnet.ibm.com> | 2014-09-20 06:21:19 -0400 |
---|---|---|
committer | Anthony Green <green@moxielogic.com> | 2014-09-20 06:24:41 -0400 |
commit | 6e8a4460833594d5af1b4539178025da0077df19 (patch) | |
tree | 527bc7b81f4dae521c6398e4c1d5bd20a126b174 /testsuite | |
parent | 4c5c4088aa3e4d8103ff9ca441937da64fdd849a (diff) | |
download | libffi-6e8a4460833594d5af1b4539178025da0077df19.tar.gz |
2014-07-22 Dominik Vogt <vogt@linux.vnet.ibm.com>
* src/types.c (FFI_TYPEDEF, FFI_NONCONST_TYPEDEF): Merge the macros by
adding another argument that controls whether the result is const or not
(FFI_LDBL_CONST): Temporary macro to reduce ifdef confusion
* src/prep_cif.c (ffi_prep_cif_core): Replace list of systems with new
macro FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
* src/pa/ffitarget.h (FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION):
Define.
* src/s390/ffitarget.h (FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION):
Define.
* src/x86/ffitarget.h (FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION):
Define.
2014-07-22 Dominik Vogt <vogt@linux.vnet.ibm.com>
* doc/libffi.texi (Primitive Types): Document ffi_type_complex_float,
ffi_type_complex_double and ffi_type_complex_longdouble
(Complex Types): New subsection.
(Complex Type Example): Ditto.
* testsuite/libffi.call/cls_align_complex_double.c: New
FFI_TYPE_COMPLEX test.
* testsuite/libffi.call/cls_align_complex_float.c: Ditto.
* testsuite/libffi.call/cls_align_complex_longdouble.c: Ditto.
* testsuite/libffi.call/cls_complex_double.c: Ditto.
* testsuite/libffi.call/cls_complex_float.c: Ditto.
* testsuite/libffi.call/cls_complex_longdouble.c: Ditto.
* testsuite/libffi.call/cls_complex_struct_double.c: Ditto.
* testsuite/libffi.call/cls_complex_struct_float.c: Ditto.
* testsuite/libffi.call/cls_complex_struct_longdouble.c: Ditto.
* testsuite/libffi.call/cls_complex_va_double.c: Ditto.
* testsuite/libffi.call/cls_complex_va_float.c: Ditto.
* testsuite/libffi.call/cls_complex_va_longdouble.c: Ditto.
* testsuite/libffi.call/complex_double.c: Ditto.
* testsuite/libffi.call/complex_defs_double.c: Ditto.
* testsuite/libffi.call/complex_float.c: Ditto.
* testsuite/libffi.call/complex_defs_float.c: Ditto.
* testsuite/libffi.call/complex_longdouble.c: Ditto.
* testsuite/libffi.call/complex_defs_longdouble.c: Ditto.
* testsuite/libffi.call/complex_int.c: Ditto.
* testsuite/libffi.call/many_complex_double.c: Ditto.
* testsuite/libffi.call/many_complex_float.c: Ditto.
* testsuite/libffi.call/many_complex_longdouble.c: Ditto.
* testsuite/libffi.call/return_complex1_double.c: Ditto.
* testsuite/libffi.call/return_complex1_float.c: Ditto.
* testsuite/libffi.call/return_complex1_longdouble.c: Ditto.
* testsuite/libffi.call/return_complex2_double.c: Ditto.
* testsuite/libffi.call/return_complex2_float.c: Ditto.
* testsuite/libffi.call/return_complex2_longdouble.c: Ditto.
* testsuite/libffi.call/return_complex_double.c: Ditto.
* testsuite/libffi.call/return_complex_float.c: Ditto.
* testsuite/libffi.call/return_complex_longdouble.c: Ditto.
* src/raw_api.c (ffi_raw_to_ptrarray): Handle FFI_TYPE_COMPLEX
(ffi_ptrarray_to_raw): Ditto.
* src/prep_cif.c (ffi_prep_cif_core): Abort if FFI_TYPE_COMPLEX is not
implemented in libffi for the target.
* src/java_raw_api.c (ffi_java_raw_size): FFI_TYPE_COMPLEX not supported
yet (abort).
(ffi_java_raw_to_ptrarray): Ditto.
(ffi_java_rvalue_to_raw): Ditto.
(ffi_java_raw_to_rvalue): Ditto.
* src/debug.c (ffi_type_test): Add debug tests for complex types.
* include/ffi.h.in (FFI_TYPE_COMPLEX): Add new FFI_TYPE_COMPLEX.
(FFI_TYPE_LAST): Bump.
(ffi_type_complex_float): Add new ffi_type_....
(ffi_type_complex_double): Ditto.
(ffi_type_complex_longdouble): Ditto.
2014-07-22 Dominik Vogt <vogt@linux.vnet.ibm.com>
* src/s390/ffitarget.h (FFI_TARGET_HAS_COMPLEX_TYPE): Define to provide
FFI_TYPE_COMPLEX support.
* src/s390/ffi.c (ffi_check_struct_type): Implement FFI_TYPE_COMPLEX
(ffi_prep_args): Ditto.
(ffi_prep_cif_machdep): Ditto.
(ffi_closure_helper_SYSV): Ditto.
Diffstat (limited to 'testsuite')
40 files changed, 908 insertions, 0 deletions
diff --git a/testsuite/libffi.call/cls_align_complex.inc b/testsuite/libffi.call/cls_align_complex.inc new file mode 100644 index 0000000..4a812ed --- /dev/null +++ b/testsuite/libffi.call/cls_align_complex.inc @@ -0,0 +1,91 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include <complex.h> + +typedef struct cls_struct_align { + unsigned char a; + _Complex T_C_TYPE b; + unsigned char c; +} cls_struct_align; + +cls_struct_align cls_struct_align_fn( + struct cls_struct_align a1, struct cls_struct_align a2) +{ + struct cls_struct_align result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + + printf("%d %f,%fi %d %d %f,%fi %d: %d %f,%fi %d\n", + a1.a, T_CONV creal (a1.b), T_CONV cimag (a1.b), a1.c, + a2.a, T_CONV creal (a2.b), T_CONV cimag (a2.b), a2.c, + result.a, T_CONV creal (result.b), T_CONV cimag (result.b), result.c); + + return result; +} + +static void +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_align a1, a2; + + a1 = *(struct cls_struct_align*)(args[0]); + a2 = *(struct cls_struct_align*)(args[1]); + + *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_c[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* c_arg_types[5]; + + struct cls_struct_align g_c = { 12, 4951 + 7 * I, 127 }; + struct cls_struct_align f_c = { 1, 9320 + 1 * I, 13 }; + struct cls_struct_align res_c; + + 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_uchar; + cls_struct_fields[1] = &T_FFI_TYPE; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = NULL; + + c_arg_types[0] = &cls_struct_type; + c_arg_types[1] = &cls_struct_type; + c_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + c_arg_types) == FFI_OK); + + args_c[0] = &g_c; + args_c[1] = &f_c; + args_c[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_c, args_c); + /* { dg-output "12 4951,7i 127 1 9320,1i 13: 13 14271,8i 140" } */ + printf("res: %d %f,%fi %d\n", + res_c.a, T_CONV creal (res_c.b), T_CONV cimag (res_c.b), res_c.c); + /* { dg-output "\nres: 13 14271,8i 140" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK); + + res_c = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_c, f_c); + /* { dg-output "\n12 4951,7i 127 1 9320,1i 13: 13 14271,8i 140" } */ + printf("res: %d %f,%fi %d\n", + res_c.a, T_CONV creal (res_c.b), T_CONV cimag (res_c.b), res_c.c); + /* { dg-output "\nres: 13 14271,8i 140" } */ + + exit(0); +} diff --git a/testsuite/libffi.call/cls_align_complex_double.c b/testsuite/libffi.call/cls_align_complex_double.c new file mode 100644 index 0000000..0dff23a --- /dev/null +++ b/testsuite/libffi.call/cls_align_complex_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "cls_align_complex.inc" diff --git a/testsuite/libffi.call/cls_align_complex_float.c b/testsuite/libffi.call/cls_align_complex_float.c new file mode 100644 index 0000000..0affbd0 --- /dev/null +++ b/testsuite/libffi.call/cls_align_complex_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "cls_align_complex.inc" diff --git a/testsuite/libffi.call/cls_align_complex_longdouble.c b/testsuite/libffi.call/cls_align_complex_longdouble.c new file mode 100644 index 0000000..7889ba8 --- /dev/null +++ b/testsuite/libffi.call/cls_align_complex_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "cls_align_complex.inc" diff --git a/testsuite/libffi.call/cls_complex.inc b/testsuite/libffi.call/cls_complex.inc new file mode 100644 index 0000000..f937404 --- /dev/null +++ b/testsuite/libffi.call/cls_complex.inc @@ -0,0 +1,42 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include <complex.h> + +static void cls_ret_complex_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) + { + _Complex T_C_TYPE *pa; + _Complex T_C_TYPE *pr; + pa = (_Complex T_C_TYPE *)args[0]; + pr = (_Complex T_C_TYPE *)resp; + *pr = *pa; + + printf("%.6f,%.6fi: %.6f,%.6fi\n", + T_CONV creal (*pa), T_CONV cimag (*pa), + T_CONV creal (*pr), T_CONV cimag (*pr)); + } +typedef _Complex T_C_TYPE (*cls_ret_complex)(_Complex T_C_TYPE); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[2]; + _Complex T_C_TYPE res; + + cl_arg_types[0] = &T_FFI_TYPE; + cl_arg_types[1] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &T_FFI_TYPE, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_complex_fn, NULL, code) == FFI_OK); + + res = (*((cls_ret_complex)code))(0.125 + 128.0 * I); + printf("res: %.6f,%.6fi\n", T_CONV creal (res), T_CONV cimag (res)); + CHECK (res == (0.125 + 128.0 * I)); + + exit(0); +} diff --git a/testsuite/libffi.call/cls_complex_double.c b/testsuite/libffi.call/cls_complex_double.c new file mode 100644 index 0000000..05e3534 --- /dev/null +++ b/testsuite/libffi.call/cls_complex_double.c @@ -0,0 +1,10 @@ +/* Area: closure_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "cls_complex.inc" diff --git a/testsuite/libffi.call/cls_complex_float.c b/testsuite/libffi.call/cls_complex_float.c new file mode 100644 index 0000000..5df7849 --- /dev/null +++ b/testsuite/libffi.call/cls_complex_float.c @@ -0,0 +1,10 @@ +/* Area: closure_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "cls_complex.inc" diff --git a/testsuite/libffi.call/cls_complex_longdouble.c b/testsuite/libffi.call/cls_complex_longdouble.c new file mode 100644 index 0000000..2b1c320 --- /dev/null +++ b/testsuite/libffi.call/cls_complex_longdouble.c @@ -0,0 +1,10 @@ +/* Area: closure_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "cls_complex.inc" diff --git a/testsuite/libffi.call/cls_complex_struct.inc b/testsuite/libffi.call/cls_complex_struct.inc new file mode 100644 index 0000000..df8708d --- /dev/null +++ b/testsuite/libffi.call/cls_complex_struct.inc @@ -0,0 +1,71 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include <complex.h> + +typedef struct Cs { + _Complex T_C_TYPE x; + _Complex T_C_TYPE y; +} Cs; + +Cs gc; + +void +closure_test_fn(Cs p) +{ + printf("%.1f,%.1fi %.1f,%.1fi\n", + T_CONV creal (p.x), T_CONV cimag (p.x), + T_CONV creal (p.y), T_CONV cimag (p.y)); + gc = p; +} + +void +closure_test_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, + void** args, void* userdata __UNUSED__) +{ + closure_test_fn(*(Cs*)args[0]); +} + +int main(int argc __UNUSED__, char** argv __UNUSED__) +{ + ffi_cif cif; + + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type *cl_arg_types[1]; + + ffi_type ts1_type; + ffi_type* ts1_type_elements[4]; + + Cs arg = { 1.0 + 11.0 * I, 2.0 + 22.0 * I}; + + ts1_type.size = 0; + ts1_type.alignment = 0; + ts1_type.type = FFI_TYPE_STRUCT; + ts1_type.elements = ts1_type_elements; + + ts1_type_elements[0] = &T_FFI_TYPE; + ts1_type_elements[1] = &T_FFI_TYPE; + ts1_type_elements[2] = NULL; + + cl_arg_types[0] = &ts1_type; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_void, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_gn, NULL, code) == FFI_OK); + + gc.x = 0.0 + 0.0 * I; + gc.y = 0.0 + 0.0 * I; + ((void*(*)(Cs))(code))(arg); + /* { dg-output "1.0,11.0i 2.0,22.0i\n" } */ + CHECK (gc.x == arg.x && gc.y == arg.y); + + gc.x = 0.0 + 0.0 * I; + gc.y = 0.0 + 0.0 * I; + closure_test_fn(arg); + /* { dg-output "1.0,11.0i 2.0,22.0i\n" } */ + CHECK (gc.x == arg.x && gc.y == arg.y); + + return 0; +} diff --git a/testsuite/libffi.call/cls_complex_struct_double.c b/testsuite/libffi.call/cls_complex_struct_double.c new file mode 100644 index 0000000..ec71346 --- /dev/null +++ b/testsuite/libffi.call/cls_complex_struct_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Check complex arguments in structs. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "cls_complex_struct.inc" diff --git a/testsuite/libffi.call/cls_complex_struct_float.c b/testsuite/libffi.call/cls_complex_struct_float.c new file mode 100644 index 0000000..96fdf75 --- /dev/null +++ b/testsuite/libffi.call/cls_complex_struct_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Check complex arguments in structs. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "cls_complex_struct.inc" diff --git a/testsuite/libffi.call/cls_complex_struct_longdouble.c b/testsuite/libffi.call/cls_complex_struct_longdouble.c new file mode 100644 index 0000000..005b467 --- /dev/null +++ b/testsuite/libffi.call/cls_complex_struct_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Check complex arguments in structs. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "cls_complex_struct.inc" diff --git a/testsuite/libffi.call/cls_complex_va.inc b/testsuite/libffi.call/cls_complex_va.inc new file mode 100644 index 0000000..8a3e15f --- /dev/null +++ b/testsuite/libffi.call/cls_complex_va.inc @@ -0,0 +1,80 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <complex.h> + +static _Complex T_C_TYPE gComplexValue1 = 1 + 2 * I; +static _Complex T_C_TYPE gComplexValue2 = 3 + 4 * I; + +static int cls_variadic(const char *format, ...) +{ + va_list ap; + _Complex T_C_TYPE p1, p2; + + va_start (ap, format); + p1 = va_arg (ap, _Complex T_C_TYPE); + p2 = va_arg (ap, _Complex T_C_TYPE); + va_end (ap); + + return printf(format, T_CONV creal (p1), T_CONV cimag (p1), + T_CONV creal (p2), T_CONV cimag (p2)); +} + +static void +cls_complex_va_fn(ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) +{ + char* format = *(char**)args[0]; + gComplexValue1 = *(_Complex T_C_TYPE*)args[1]; + gComplexValue2 = *(_Complex T_C_TYPE*)args[2]; + + *(ffi_arg*)resp = + printf(format, + T_CONV creal (gComplexValue1), T_CONV cimag (gComplexValue1), + T_CONV creal (gComplexValue2), T_CONV cimag (gComplexValue2)); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args[4]; + ffi_type* arg_types[4]; + char *format = "%.1f,%.1fi %.1f,%.1fi\n"; + + _Complex T_C_TYPE complexArg1 = 1.0 + 22.0 *I; + _Complex T_C_TYPE complexArg2 = 333.0 + 4444.0 *I; + ffi_arg res = 0; + + arg_types[0] = &ffi_type_pointer; + arg_types[1] = &T_FFI_TYPE; + arg_types[2] = &T_FFI_TYPE; + arg_types[3] = NULL; + + /* This printf call is variadic */ + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 3, &ffi_type_sint, + arg_types) == FFI_OK); + + args[0] = &format; + args[1] = &complexArg1; + args[2] = &complexArg2; + args[3] = NULL; + + ffi_call(&cif, FFI_FN(cls_variadic), &res, args); + printf("res: %d\n", (int) res); + CHECK (res == 24); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_complex_va_fn, NULL, code) + == FFI_OK); + + res = ((int(*)(char *, ...))(code))(format, complexArg1, complexArg2); + CHECK (gComplexValue1 == complexArg1); + CHECK (gComplexValue2 == complexArg2); + printf("res: %d\n", (int) res); + CHECK (res == 24); + + exit(0); +} diff --git a/testsuite/libffi.call/cls_complex_va_double.c b/testsuite/libffi.call/cls_complex_va_double.c new file mode 100644 index 0000000..879ccf3 --- /dev/null +++ b/testsuite/libffi.call/cls_complex_va_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Test complex' passed in variable argument lists. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "cls_complex_va.inc" diff --git a/testsuite/libffi.call/cls_complex_va_float.c b/testsuite/libffi.call/cls_complex_va_float.c new file mode 100644 index 0000000..0b79979 --- /dev/null +++ b/testsuite/libffi.call/cls_complex_va_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Test complex' passed in variable argument lists. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "cls_complex_va.inc" diff --git a/testsuite/libffi.call/cls_complex_va_longdouble.c b/testsuite/libffi.call/cls_complex_va_longdouble.c new file mode 100644 index 0000000..6eca965 --- /dev/null +++ b/testsuite/libffi.call/cls_complex_va_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Test complex' passed in variable argument lists. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "cls_complex_va.inc" diff --git a/testsuite/libffi.call/complex.inc b/testsuite/libffi.call/complex.inc new file mode 100644 index 0000000..515ae3e --- /dev/null +++ b/testsuite/libffi.call/complex.inc @@ -0,0 +1,51 @@ +/* -*-c-*-*/ +#include "ffitest.h" +#include <complex.h> + +static _Complex T_C_TYPE f_complex(_Complex T_C_TYPE c, int x, int *py) +{ + c = -(2 * creal (c)) + (cimag (c) + 1)* I; + *py += x; + + return c; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + + _Complex T_C_TYPE tc_arg; + _Complex T_C_TYPE tc_result; + int tc_int_arg_x; + int tc_y; + int *tc_ptr_arg_y = &tc_y; + + args[0] = &T_FFI_TYPE; + args[1] = &ffi_type_sint; + args[2] = &ffi_type_pointer; + values[0] = &tc_arg; + values[1] = &tc_int_arg_x; + values[2] = &tc_ptr_arg_y; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, + &T_FFI_TYPE, args) == FFI_OK); + + tc_arg = 1 + 7 * I; + tc_int_arg_x = 1234; + tc_y = 9876; + ffi_call(&cif, FFI_FN(f_complex), &tc_result, values); + + printf ("%f,%fi %f,%fi, x %d 1234, y %d 11110\n", + T_CONV creal (tc_result), T_CONV cimag (tc_result), + T_CONV creal (2.0), T_CONV creal (8.0), tc_int_arg_x, tc_y); + + CHECK (creal (tc_result) == -2); + CHECK (cimag (tc_result) == 8); + CHECK (tc_int_arg_x == 1234); + CHECK (*tc_ptr_arg_y == 11110); + + exit(0); +} diff --git a/testsuite/libffi.call/complex_defs_double.inc b/testsuite/libffi.call/complex_defs_double.inc new file mode 100644 index 0000000..3583e16 --- /dev/null +++ b/testsuite/libffi.call/complex_defs_double.inc @@ -0,0 +1,7 @@ +/* -*-c-*- */ +/* Complex base type. */ +#define T_FFI_TYPE ffi_type_complex_double +/* C type corresponding to the base type. */ +#define T_C_TYPE double +/* C cast for a value of type T_C_TYPE that is passed to printf. */ +#define T_CONV diff --git a/testsuite/libffi.call/complex_defs_float.inc b/testsuite/libffi.call/complex_defs_float.inc new file mode 100644 index 0000000..bbd9375 --- /dev/null +++ b/testsuite/libffi.call/complex_defs_float.inc @@ -0,0 +1,7 @@ +/* -*-c-*- */ +/* Complex base type. */ +#define T_FFI_TYPE ffi_type_complex_float +/* C type corresponding to the base type. */ +#define T_C_TYPE float +/* C cast for a value of type T_C_TYPE that is passed to printf. */ +#define T_CONV (double) diff --git a/testsuite/libffi.call/complex_defs_longdouble.inc b/testsuite/libffi.call/complex_defs_longdouble.inc new file mode 100644 index 0000000..14b9f24 --- /dev/null +++ b/testsuite/libffi.call/complex_defs_longdouble.inc @@ -0,0 +1,7 @@ +/* -*-c-*- */ +/* Complex base type. */ +#define T_FFI_TYPE ffi_type_complex_longdouble +/* C type corresponding to the base type. */ +#define T_C_TYPE long double +/* C cast for a value of type T_C_TYPE that is passed to printf. */ +#define T_CONV diff --git a/testsuite/libffi.call/complex_double.c b/testsuite/libffi.call/complex_double.c new file mode 100644 index 0000000..8a3297b --- /dev/null +++ b/testsuite/libffi.call/complex_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check complex types. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "complex.inc" diff --git a/testsuite/libffi.call/complex_float.c b/testsuite/libffi.call/complex_float.c new file mode 100644 index 0000000..5044ebb --- /dev/null +++ b/testsuite/libffi.call/complex_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check complex types. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "complex.inc" diff --git a/testsuite/libffi.call/complex_int.c b/testsuite/libffi.call/complex_int.c new file mode 100644 index 0000000..4c8e864 --- /dev/null +++ b/testsuite/libffi.call/complex_int.c @@ -0,0 +1,86 @@ +/* Area: ffi_call + Purpose: Check non-standard complex types. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "ffitest.h" +#include "ffi.h" +#include <complex.h> + +_Complex int f_complex(_Complex int c, int x, int *py) +{ + c = -(2 * creal (c)) + (cimag (c) + 1)* I; + *py += x; + + return c; +} + +/* + * This macro can be used to define new complex type descriptors + * in a platform independent way. + * + * name: Name of the new descriptor is ffi_type_complex_<name>. + * type: The C base type of the complex type. + */ +#define FFI_COMPLEX_TYPEDEF(name, type, ffitype) \ + static ffi_type *ffi_elements_complex_##name [2] = { \ + (ffi_type *)(&ffitype), NULL \ + }; \ + struct struct_align_complex_##name { \ + char c; \ + _Complex type x; \ + }; \ + ffi_type ffi_type_complex_##name = { \ + sizeof(_Complex type), \ + offsetof(struct struct_align_complex_##name, x), \ + FFI_TYPE_COMPLEX, \ + (ffi_type **)ffi_elements_complex_##name \ + } + +/* Define new complex type descriptors using the macro: */ +/* ffi_type_complex_sint */ +FFI_COMPLEX_TYPEDEF(sint, int, ffi_type_sint); +/* ffi_type_complex_uchar */ +FFI_COMPLEX_TYPEDEF(uchar, unsigned char, ffi_type_uint8); + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + + _Complex int tc_arg; + _Complex int tc_result; + int tc_int_arg_x; + int tc_y; + int *tc_ptr_arg_y = &tc_y; + + args[0] = &ffi_type_complex_sint; + args[1] = &ffi_type_sint; + args[2] = &ffi_type_pointer; + values[0] = &tc_arg; + values[1] = &tc_int_arg_x; + values[2] = &tc_ptr_arg_y; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &ffi_type_complex_sint, args) + == FFI_OK); + + tc_arg = 1 + 7 * I; + tc_int_arg_x = 1234; + tc_y = 9876; + ffi_call(&cif, FFI_FN(f_complex), &tc_result, values); + + printf ("%d,%di %d,%di, x %d 1234, y %d 11110\n", + (int)tc_result, (int)(tc_result * -I), 2, 8, tc_int_arg_x, tc_y); + /* dg-output "-2,8i 2,8i, x 1234 1234, y 11110 11110" */ + CHECK (creal (tc_result) == -2); + CHECK (cimag (tc_result) == 8); + CHECK (tc_int_arg_x == 1234); + CHECK (*tc_ptr_arg_y == 11110); + + exit(0); +} diff --git a/testsuite/libffi.call/complex_longdouble.c b/testsuite/libffi.call/complex_longdouble.c new file mode 100644 index 0000000..7e78366 --- /dev/null +++ b/testsuite/libffi.call/complex_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check complex types. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "complex.inc" diff --git a/testsuite/libffi.call/many_complex.inc b/testsuite/libffi.call/many_complex.inc new file mode 100644 index 0000000..e37a774 --- /dev/null +++ b/testsuite/libffi.call/many_complex.inc @@ -0,0 +1,78 @@ +/* -*-c-*- */ +#include "ffitest.h" + +#include <stdlib.h> +#include <complex.h> + +static _Complex T_C_TYPE many(_Complex T_C_TYPE c1, + _Complex T_C_TYPE c2, + _Complex T_C_TYPE c3, + _Complex T_C_TYPE c4, + _Complex T_C_TYPE c5, + _Complex T_C_TYPE c6, + _Complex T_C_TYPE c7, + _Complex T_C_TYPE c8, + _Complex T_C_TYPE c9, + _Complex T_C_TYPE c10, + _Complex T_C_TYPE c11, + _Complex T_C_TYPE c12, + _Complex T_C_TYPE c13) +{ + printf("0 :%f,%fi\n" + "1 :%f,%fi\n" + "2 :%f,%fi\n" + "3 :%f,%fi\n" + "4 :%f,%fi\n" + "5 :%f,%fi\n" + "6 :%f,%fi\n" + "7 :%f,%fi\n" + "8 :%f,%fi\n" + "9 :%f,%fi\n" + "10:%f,%fi\n" + "11:%f,%fi\n" + "12:%f,%fi\n", + T_CONV creal (c1), T_CONV cimag (c1), + T_CONV creal (c2), T_CONV cimag (c2), + T_CONV creal (c3), T_CONV cimag (c3), + T_CONV creal (c4), T_CONV cimag (c4), + T_CONV creal (c5), T_CONV cimag (c5), + T_CONV creal (c6), T_CONV cimag (c6), + T_CONV creal (c7), T_CONV cimag (c7), + T_CONV creal (c8), T_CONV cimag (c8), + T_CONV creal (c9), T_CONV cimag (c9), + T_CONV creal (c10), T_CONV cimag (c10), + T_CONV creal (c11), T_CONV cimag (c11), + T_CONV creal (c12), T_CONV cimag (c12), + T_CONV creal (c13), T_CONV cimag (c13)); + + return (c1+c2-c3-c4+c5+c6+c7-c8-c9-c10-c11+c12+c13); +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[13]; + void *values[13]; + _Complex T_C_TYPE ca[13]; + _Complex T_C_TYPE c, cc; + int i; + + for (i = 0; i < 13; i++) + { + args[i] = &T_FFI_TYPE; + values[i] = &ca[i]; + ca[i] = i + (-20 - i) * I; + } + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, &T_FFI_TYPE, args) == FFI_OK); + + ffi_call(&cif, FFI_FN(many), &c, values); + + cc = many(ca[0], ca[1], ca[2], ca[3], ca[4], ca[5], ca[6], ca[7], ca[8], + ca[9], ca[10], ca[11], ca[12]); + CHECK(creal (cc) == creal (c)); + CHECK(cimag (cc) == cimag (c)); + + exit(0); +} diff --git a/testsuite/libffi.call/many_complex_double.c b/testsuite/libffi.call/many_complex_double.c new file mode 100644 index 0000000..3fd53c3 --- /dev/null +++ b/testsuite/libffi.call/many_complex_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex, with many arguments + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "many_complex.inc" diff --git a/testsuite/libffi.call/many_complex_float.c b/testsuite/libffi.call/many_complex_float.c new file mode 100644 index 0000000..c43d21c --- /dev/null +++ b/testsuite/libffi.call/many_complex_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex, with many arguments + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "many_complex.inc" diff --git a/testsuite/libffi.call/many_complex_longdouble.c b/testsuite/libffi.call/many_complex_longdouble.c new file mode 100644 index 0000000..dbab723 --- /dev/null +++ b/testsuite/libffi.call/many_complex_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex, with many arguments + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "many_complex.inc" diff --git a/testsuite/libffi.call/return_complex.inc b/testsuite/libffi.call/return_complex.inc new file mode 100644 index 0000000..8bf0c1f --- /dev/null +++ b/testsuite/libffi.call/return_complex.inc @@ -0,0 +1,37 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include <complex.h> + +static _Complex T_C_TYPE return_c(_Complex T_C_TYPE c) +{ + printf ("%f,%fi\n", T_CONV creal (c), T_CONV cimag (c)); + return 2 * c; +} +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + _Complex T_C_TYPE c, rc, rc2; + T_C_TYPE cr, ci; + + args[0] = &T_FFI_TYPE; + values[0] = &c; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &T_FFI_TYPE, args) == FFI_OK); + + for (cr = -127.0; cr < 127; cr++) + { + ci = 1000.0 - cr; + c = cr + ci * I; + ffi_call(&cif, FFI_FN(return_c), &rc, values); + rc2 = return_c(c); + printf ("%f,%fi vs %f,%fi\n", + T_CONV creal (rc), T_CONV cimag (rc), + T_CONV creal (rc2), T_CONV cimag (rc2)); + CHECK(rc == 2 * c); + } + exit(0); +} diff --git a/testsuite/libffi.call/return_complex1.inc b/testsuite/libffi.call/return_complex1.inc new file mode 100644 index 0000000..7cecc0f --- /dev/null +++ b/testsuite/libffi.call/return_complex1.inc @@ -0,0 +1,41 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include <complex.h> + +static _Complex T_C_TYPE return_c(_Complex T_C_TYPE c1, float fl2, unsigned int in3, _Complex T_C_TYPE c4) +{ + return c1 + fl2 + in3 + c4; +} +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + _Complex T_C_TYPE c1, c4, rc, rc2; + float fl2; + unsigned int in3; + args[0] = &T_FFI_TYPE; + args[1] = &ffi_type_float; + args[2] = &ffi_type_uint; + args[3] = &T_FFI_TYPE; + values[0] = &c1; + values[1] = &fl2; + values[2] = &in3; + values[3] = &c4; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, + &T_FFI_TYPE, args) == FFI_OK); + c1 = 127.0 + 255.0 * I; + fl2 = 128.0; + in3 = 255; + c4 = 512.7 + 1024.1 * I; + + ffi_call(&cif, FFI_FN(return_c), &rc, values); + rc2 = return_c(c1, fl2, in3, c4); + printf ("%f,%fi vs %f,%fi\n", + T_CONV creal (rc), T_CONV cimag (rc), + T_CONV creal (rc2), T_CONV cimag (rc2)); + CHECK(rc == rc2); + exit(0); +} diff --git a/testsuite/libffi.call/return_complex1_double.c b/testsuite/libffi.call/return_complex1_double.c new file mode 100644 index 0000000..727410d --- /dev/null +++ b/testsuite/libffi.call/return_complex1_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "return_complex1.inc" diff --git a/testsuite/libffi.call/return_complex1_float.c b/testsuite/libffi.call/return_complex1_float.c new file mode 100644 index 0000000..a2aeada --- /dev/null +++ b/testsuite/libffi.call/return_complex1_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "return_complex1.inc" diff --git a/testsuite/libffi.call/return_complex1_longdouble.c b/testsuite/libffi.call/return_complex1_longdouble.c new file mode 100644 index 0000000..103504b --- /dev/null +++ b/testsuite/libffi.call/return_complex1_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "return_complex1.inc" diff --git a/testsuite/libffi.call/return_complex2.inc b/testsuite/libffi.call/return_complex2.inc new file mode 100644 index 0000000..dad4a0f --- /dev/null +++ b/testsuite/libffi.call/return_complex2.inc @@ -0,0 +1,40 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include <complex.h> + +static _Complex T_C_TYPE return_c(_Complex T_C_TYPE c1, _Complex T_C_TYPE c2, unsigned int in3, _Complex T_C_TYPE c4) +{ + return c1 + c2 + in3 + c4; +} +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + _Complex T_C_TYPE c1, c2, c4, rc, rc2; + unsigned int in3; + args[0] = &T_FFI_TYPE; + args[1] = &T_FFI_TYPE; + args[2] = &ffi_type_uint; + args[3] = &T_FFI_TYPE; + values[0] = &c1; + values[1] = &c2; + values[2] = &in3; + values[3] = &c4; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, + &T_FFI_TYPE, args) == FFI_OK); + c1 = 127.0 + 255.0 * I; + c2 = 128.0 + 256.0; + in3 = 255; + c4 = 512.7 + 1024.1 * I; + + ffi_call(&cif, FFI_FN(return_c), &rc, values); + rc2 = return_c(c1, c2, in3, c4); + printf ("%f,%fi vs %f,%fi\n", + T_CONV creal (rc), T_CONV cimag (rc), + T_CONV creal (rc2), T_CONV cimag (rc2)); + CHECK(rc == c1 + c2 + in3 + c4); + exit(0); +} diff --git a/testsuite/libffi.call/return_complex2_double.c b/testsuite/libffi.call/return_complex2_double.c new file mode 100644 index 0000000..ab9efac --- /dev/null +++ b/testsuite/libffi.call/return_complex2_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "return_complex2.inc" diff --git a/testsuite/libffi.call/return_complex2_float.c b/testsuite/libffi.call/return_complex2_float.c new file mode 100644 index 0000000..d7f22c2 --- /dev/null +++ b/testsuite/libffi.call/return_complex2_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "return_complex2.inc" diff --git a/testsuite/libffi.call/return_complex2_longdouble.c b/testsuite/libffi.call/return_complex2_longdouble.c new file mode 100644 index 0000000..3edea62 --- /dev/null +++ b/testsuite/libffi.call/return_complex2_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "return_complex2.inc" diff --git a/testsuite/libffi.call/return_complex_double.c b/testsuite/libffi.call/return_complex_double.c new file mode 100644 index 0000000..e2497cc --- /dev/null +++ b/testsuite/libffi.call/return_complex_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "return_complex.inc" diff --git a/testsuite/libffi.call/return_complex_float.c b/testsuite/libffi.call/return_complex_float.c new file mode 100644 index 0000000..a35528f --- /dev/null +++ b/testsuite/libffi.call/return_complex_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "return_complex.inc" diff --git a/testsuite/libffi.call/return_complex_longdouble.c b/testsuite/libffi.call/return_complex_longdouble.c new file mode 100644 index 0000000..142d7be --- /dev/null +++ b/testsuite/libffi.call/return_complex_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "return_complex.inc" |