summaryrefslogtreecommitdiff
path: root/testsuite
diff options
context:
space:
mode:
authorDominik Vogt <vogt@linux.vnet.ibm.com>2014-09-20 06:21:19 -0400
committerAnthony Green <green@moxielogic.com>2014-09-20 06:24:41 -0400
commit6e8a4460833594d5af1b4539178025da0077df19 (patch)
tree527bc7b81f4dae521c6398e4c1d5bd20a126b174 /testsuite
parent4c5c4088aa3e4d8103ff9ca441937da64fdd849a (diff)
downloadlibffi-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')
-rw-r--r--testsuite/libffi.call/cls_align_complex.inc91
-rw-r--r--testsuite/libffi.call/cls_align_complex_double.c10
-rw-r--r--testsuite/libffi.call/cls_align_complex_float.c10
-rw-r--r--testsuite/libffi.call/cls_align_complex_longdouble.c10
-rw-r--r--testsuite/libffi.call/cls_complex.inc42
-rw-r--r--testsuite/libffi.call/cls_complex_double.c10
-rw-r--r--testsuite/libffi.call/cls_complex_float.c10
-rw-r--r--testsuite/libffi.call/cls_complex_longdouble.c10
-rw-r--r--testsuite/libffi.call/cls_complex_struct.inc71
-rw-r--r--testsuite/libffi.call/cls_complex_struct_double.c10
-rw-r--r--testsuite/libffi.call/cls_complex_struct_float.c10
-rw-r--r--testsuite/libffi.call/cls_complex_struct_longdouble.c10
-rw-r--r--testsuite/libffi.call/cls_complex_va.inc80
-rw-r--r--testsuite/libffi.call/cls_complex_va_double.c10
-rw-r--r--testsuite/libffi.call/cls_complex_va_float.c10
-rw-r--r--testsuite/libffi.call/cls_complex_va_longdouble.c10
-rw-r--r--testsuite/libffi.call/complex.inc51
-rw-r--r--testsuite/libffi.call/complex_defs_double.inc7
-rw-r--r--testsuite/libffi.call/complex_defs_float.inc7
-rw-r--r--testsuite/libffi.call/complex_defs_longdouble.inc7
-rw-r--r--testsuite/libffi.call/complex_double.c10
-rw-r--r--testsuite/libffi.call/complex_float.c10
-rw-r--r--testsuite/libffi.call/complex_int.c86
-rw-r--r--testsuite/libffi.call/complex_longdouble.c10
-rw-r--r--testsuite/libffi.call/many_complex.inc78
-rw-r--r--testsuite/libffi.call/many_complex_double.c10
-rw-r--r--testsuite/libffi.call/many_complex_float.c10
-rw-r--r--testsuite/libffi.call/many_complex_longdouble.c10
-rw-r--r--testsuite/libffi.call/return_complex.inc37
-rw-r--r--testsuite/libffi.call/return_complex1.inc41
-rw-r--r--testsuite/libffi.call/return_complex1_double.c10
-rw-r--r--testsuite/libffi.call/return_complex1_float.c10
-rw-r--r--testsuite/libffi.call/return_complex1_longdouble.c10
-rw-r--r--testsuite/libffi.call/return_complex2.inc40
-rw-r--r--testsuite/libffi.call/return_complex2_double.c10
-rw-r--r--testsuite/libffi.call/return_complex2_float.c10
-rw-r--r--testsuite/libffi.call/return_complex2_longdouble.c10
-rw-r--r--testsuite/libffi.call/return_complex_double.c10
-rw-r--r--testsuite/libffi.call/return_complex_float.c10
-rw-r--r--testsuite/libffi.call/return_complex_longdouble.c10
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"