summaryrefslogtreecommitdiff
path: root/libffi-3.0.4/testsuite
diff options
context:
space:
mode:
Diffstat (limited to 'libffi-3.0.4/testsuite')
-rw-r--r--libffi-3.0.4/testsuite/Makefile.am71
-rw-r--r--libffi-3.0.4/testsuite/Makefile.in447
-rw-r--r--libffi-3.0.4/testsuite/config/default.exp1
-rw-r--r--libffi-3.0.4/testsuite/lib/libffi-dg.exp289
-rw-r--r--libffi-3.0.4/testsuite/lib/target-libpath.exp263
-rw-r--r--libffi-3.0.4/testsuite/lib/wrapper.exp45
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/call.exp36
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/closure_fn0.c97
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/closure_fn1.c89
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/closure_fn2.c89
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/closure_fn3.c90
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/closure_fn4.c97
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/closure_fn5.c99
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/closure_fn6.c98
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/closure_stdcall.c72
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_12byte.c102
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_16byte.c103
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_18byte.c104
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_19byte.c110
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_1_1byte.c97
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_20byte.c99
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_20byte1.c101
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_24byte.c121
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_2byte.c98
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_3_1byte.c103
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_3byte1.c98
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_3byte2.c98
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_4_1byte.c106
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_4byte.c98
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_5_1_byte.c117
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_5byte.c106
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_64byte.c132
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_6_1_byte.c121
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_6byte.c107
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_7_1_byte.c125
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_7byte.c105
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_8byte.c96
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_9byte1.c98
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_9byte2.c99
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_align_double.c101
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_align_float.c99
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_align_longdouble.c100
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_align_pointer.c101
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_align_sint16.c99
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_align_sint32.c99
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_align_sint64.c99
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_align_uint16.c99
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_align_uint32.c99
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_align_uint64.c100
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_double.c51
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_float.c51
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_multi_schar.c82
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_multi_sshort.c82
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_multi_sshortchar.c94
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_multi_uchar.c99
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_multi_ushort.c82
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_multi_ushortchar.c94
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_schar.c52
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_sint.c50
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_sshort.c50
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_uchar.c50
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_uint.c51
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_ulonglong.c54
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/cls_ushort.c51
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/ffitest.h86
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/float.c59
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/float1.c58
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/float2.c57
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/float3.c72
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/float4.c62
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/many.c69
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/many_win32.c63
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/negint.c53
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/nested_struct.c160
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/nested_struct1.c169
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/nested_struct10.c141
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/nested_struct2.c118
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/nested_struct3.c119
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/nested_struct4.c119
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/nested_struct5.c120
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/nested_struct6.c139
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/nested_struct7.c119
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/nested_struct8.c139
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/nested_struct9.c139
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/problem1.c98
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/promotion.c59
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/pyobjc-tc.c114
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/return_dbl.c35
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/return_dbl1.c43
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/return_dbl2.c42
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/return_fl.c35
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/return_fl1.c36
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/return_fl2.c49
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/return_fl3.c42
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/return_ldl.c34
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/return_ll.c41
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/return_ll1.c42
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/return_sc.c36
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/return_sl.c38
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/return_uc.c38
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/return_ul.c38
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/strlen.c44
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/strlen_win32.c44
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/struct1.c65
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/struct2.c67
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/struct3.c59
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/struct4.c63
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/struct5.c65
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/struct6.c64
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/struct7.c74
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/struct8.c80
-rw-r--r--libffi-3.0.4/testsuite/libffi.call/struct9.c67
-rw-r--r--libffi-3.0.4/testsuite/libffi.special/ffitestcxx.h86
-rw-r--r--libffi-3.0.4/testsuite/libffi.special/special.exp38
-rw-r--r--libffi-3.0.4/testsuite/libffi.special/unwindtest.cc123
-rw-r--r--libffi-3.0.4/testsuite/libffi.special/unwindtest_ffi_call.cc53
116 files changed, 10289 insertions, 0 deletions
diff --git a/libffi-3.0.4/testsuite/Makefile.am b/libffi-3.0.4/testsuite/Makefile.am
new file mode 100644
index 0000000..3ec24bd
--- /dev/null
+++ b/libffi-3.0.4/testsuite/Makefile.am
@@ -0,0 +1,71 @@
+## Process this file with automake to produce Makefile.in.
+
+AUTOMAKE_OPTIONS = foreign dejagnu
+
+# Setup the testing framework, if you have one
+EXPECT = `if [ -f $(top_builddir)/../expect/expect ] ; then \
+ echo $(top_builddir)/../expect/expect ; \
+ else echo expect ; fi`
+
+RUNTEST = `if [ -f $(top_srcdir)/../dejagnu/runtest ] ; then \
+ echo $(top_srcdir)/../dejagnu/runtest ; \
+ else echo runtest; fi`
+
+AM_RUNTESTFLAGS =
+
+CLEANFILES = *.exe core* *.log *.sum
+
+EXTRA_DIST = config/default.exp lib/libffi-dg.exp \
+ lib/target-libpath.exp lib/wrapper.exp libffi.call/call.exp \
+ libffi.call/closure_fn0.c libffi.call/closure_fn1.c \
+ libffi.call/closure_fn2.c libffi.call/closure_fn3.c \
+ libffi.call/closure_fn4.c libffi.call/closure_fn5.c \
+ libffi.call/closure_fn6.c libffi.call/closure_stdcall.c \
+ libffi.call/cls_1_1byte.c libffi.call/cls_12byte.c \
+ libffi.call/cls_16byte.c libffi.call/cls_18byte.c \
+ libffi.call/cls_19byte.c libffi.call/cls_20byte1.c \
+ libffi.call/cls_20byte.c libffi.call/cls_24byte.c \
+ libffi.call/cls_2byte.c libffi.call/cls_3_1byte.c \
+ libffi.call/cls_3byte1.c libffi.call/cls_3byte2.c \
+ libffi.call/cls_4_1byte.c libffi.call/cls_4byte.c \
+ libffi.call/cls_5_1_byte.c libffi.call/cls_5byte.c \
+ libffi.call/cls_6_1_byte.c libffi.call/cls_64byte.c \
+ libffi.call/cls_6byte.c libffi.call/cls_7_1_byte.c \
+ libffi.call/cls_7byte.c libffi.call/cls_8byte.c \
+ libffi.call/cls_9byte1.c libffi.call/cls_9byte2.c \
+ libffi.call/cls_align_double.c libffi.call/cls_align_float.c \
+ libffi.call/cls_align_longdouble.c libffi.call/cls_align_pointer.c \
+ libffi.call/cls_align_sint16.c libffi.call/cls_align_sint32.c \
+ libffi.call/cls_align_sint64.c libffi.call/cls_align_uint16.c \
+ libffi.call/cls_align_uint32.c libffi.call/cls_align_uint64.c \
+ libffi.call/cls_double.c libffi.call/cls_float.c \
+ libffi.call/cls_multi_schar.c libffi.call/cls_multi_sshort.c \
+ libffi.call/cls_multi_sshortchar.c libffi.call/cls_multi_uchar.c \
+ libffi.call/cls_multi_ushort.c libffi.call/cls_multi_ushortchar.c \
+ libffi.call/cls_schar.c libffi.call/cls_sint.c \
+ libffi.call/cls_sshort.c libffi.call/cls_uchar.c \
+ libffi.call/cls_uint.c libffi.call/cls_ulonglong.c \
+ libffi.call/cls_ushort.c libffi.call/ffitest.h libffi.call/float1.c \
+ libffi.call/float2.c libffi.call/float3.c libffi.call/float4.c \
+ libffi.call/float.c libffi.call/many.c libffi.call/many_win32.c \
+ libffi.call/negint.c libffi.call/nested_struct10.c \
+ libffi.call/nested_struct1.c libffi.call/nested_struct2.c \
+ libffi.call/nested_struct3.c libffi.call/nested_struct4.c \
+ libffi.call/nested_struct5.c libffi.call/nested_struct6.c \
+ libffi.call/nested_struct7.c libffi.call/nested_struct8.c \
+ libffi.call/nested_struct9.c libffi.call/nested_struct.c \
+ libffi.call/problem1.c libffi.call/promotion.c \
+ libffi.call/pyobjc-tc.c libffi.call/return_dbl1.c \
+ libffi.call/return_dbl2.c libffi.call/return_dbl.c \
+ libffi.call/return_fl1.c libffi.call/return_fl2.c \
+ libffi.call/return_fl3.c libffi.call/return_fl.c \
+ libffi.call/return_ldl.c libffi.call/return_ll1.c \
+ libffi.call/return_ll.c libffi.call/return_sc.c \
+ libffi.call/return_sl.c libffi.call/return_uc.c \
+ libffi.call/return_ul.c libffi.call/strlen.c \
+ libffi.call/strlen_win32.c libffi.call/struct1.c \
+ libffi.call/struct2.c libffi.call/struct3.c libffi.call/struct4.c \
+ libffi.call/struct5.c libffi.call/struct6.c libffi.call/struct7.c \
+ libffi.call/struct8.c libffi.call/struct9.c \
+ libffi.special/ffitestcxx.h libffi.special/special.exp \
+ libffi.special/unwindtest.cc libffi.special/unwindtest_ffi_call.cc
diff --git a/libffi-3.0.4/testsuite/Makefile.in b/libffi-3.0.4/testsuite/Makefile.in
new file mode 100644
index 0000000..63fb4c2
--- /dev/null
+++ b/libffi-3.0.4/testsuite/Makefile.in
@@ -0,0 +1,447 @@
+# Makefile.in generated by automake 1.10 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = testsuite
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/fficonfig.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+DEJATOOL = $(PACKAGE)
+RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_RUNTESTFLAGS =
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GREP = @GREP@
+HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TARGET = @TARGET@
+TARGETDIR = @TARGETDIR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+toolexecdir = @toolexecdir@
+toolexeclibdir = @toolexeclibdir@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = foreign dejagnu
+
+# Setup the testing framework, if you have one
+EXPECT = `if [ -f $(top_builddir)/../expect/expect ] ; then \
+ echo $(top_builddir)/../expect/expect ; \
+ else echo expect ; fi`
+
+RUNTEST = `if [ -f $(top_srcdir)/../dejagnu/runtest ] ; then \
+ echo $(top_srcdir)/../dejagnu/runtest ; \
+ else echo runtest; fi`
+
+CLEANFILES = *.exe core* *.log *.sum
+EXTRA_DIST = config/default.exp lib/libffi-dg.exp \
+ lib/target-libpath.exp lib/wrapper.exp libffi.call/call.exp \
+ libffi.call/closure_fn0.c libffi.call/closure_fn1.c \
+ libffi.call/closure_fn2.c libffi.call/closure_fn3.c \
+ libffi.call/closure_fn4.c libffi.call/closure_fn5.c \
+ libffi.call/closure_fn6.c libffi.call/closure_stdcall.c \
+ libffi.call/cls_1_1byte.c libffi.call/cls_12byte.c \
+ libffi.call/cls_16byte.c libffi.call/cls_18byte.c \
+ libffi.call/cls_19byte.c libffi.call/cls_20byte1.c \
+ libffi.call/cls_20byte.c libffi.call/cls_24byte.c \
+ libffi.call/cls_2byte.c libffi.call/cls_3_1byte.c \
+ libffi.call/cls_3byte1.c libffi.call/cls_3byte2.c \
+ libffi.call/cls_4_1byte.c libffi.call/cls_4byte.c \
+ libffi.call/cls_5_1_byte.c libffi.call/cls_5byte.c \
+ libffi.call/cls_6_1_byte.c libffi.call/cls_64byte.c \
+ libffi.call/cls_6byte.c libffi.call/cls_7_1_byte.c \
+ libffi.call/cls_7byte.c libffi.call/cls_8byte.c \
+ libffi.call/cls_9byte1.c libffi.call/cls_9byte2.c \
+ libffi.call/cls_align_double.c libffi.call/cls_align_float.c \
+ libffi.call/cls_align_longdouble.c libffi.call/cls_align_pointer.c \
+ libffi.call/cls_align_sint16.c libffi.call/cls_align_sint32.c \
+ libffi.call/cls_align_sint64.c libffi.call/cls_align_uint16.c \
+ libffi.call/cls_align_uint32.c libffi.call/cls_align_uint64.c \
+ libffi.call/cls_double.c libffi.call/cls_float.c \
+ libffi.call/cls_multi_schar.c libffi.call/cls_multi_sshort.c \
+ libffi.call/cls_multi_sshortchar.c libffi.call/cls_multi_uchar.c \
+ libffi.call/cls_multi_ushort.c libffi.call/cls_multi_ushortchar.c \
+ libffi.call/cls_schar.c libffi.call/cls_sint.c \
+ libffi.call/cls_sshort.c libffi.call/cls_uchar.c \
+ libffi.call/cls_uint.c libffi.call/cls_ulonglong.c \
+ libffi.call/cls_ushort.c libffi.call/ffitest.h libffi.call/float1.c \
+ libffi.call/float2.c libffi.call/float3.c libffi.call/float4.c \
+ libffi.call/float.c libffi.call/many.c libffi.call/many_win32.c \
+ libffi.call/negint.c libffi.call/nested_struct10.c \
+ libffi.call/nested_struct1.c libffi.call/nested_struct2.c \
+ libffi.call/nested_struct3.c libffi.call/nested_struct4.c \
+ libffi.call/nested_struct5.c libffi.call/nested_struct6.c \
+ libffi.call/nested_struct7.c libffi.call/nested_struct8.c \
+ libffi.call/nested_struct9.c libffi.call/nested_struct.c \
+ libffi.call/problem1.c libffi.call/promotion.c \
+ libffi.call/pyobjc-tc.c libffi.call/return_dbl1.c \
+ libffi.call/return_dbl2.c libffi.call/return_dbl.c \
+ libffi.call/return_fl1.c libffi.call/return_fl2.c \
+ libffi.call/return_fl3.c libffi.call/return_fl.c \
+ libffi.call/return_ldl.c libffi.call/return_ll1.c \
+ libffi.call/return_ll.c libffi.call/return_sc.c \
+ libffi.call/return_sl.c libffi.call/return_uc.c \
+ libffi.call/return_ul.c libffi.call/strlen.c \
+ libffi.call/strlen_win32.c libffi.call/struct1.c \
+ libffi.call/struct2.c libffi.call/struct3.c libffi.call/struct4.c \
+ libffi.call/struct5.c libffi.call/struct6.c libffi.call/struct7.c \
+ libffi.call/struct8.c libffi.call/struct9.c \
+ libffi.special/ffitestcxx.h libffi.special/special.exp \
+ libffi.special/unwindtest.cc libffi.special/unwindtest_ffi_call.cc
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign testsuite/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign testsuite/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+check-DEJAGNU: site.exp
+ srcdir=`$(am__cd) $(srcdir) && pwd`; export srcdir; \
+ EXPECT=$(EXPECT); export EXPECT; \
+ runtest=$(RUNTEST); \
+ if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
+ exit_status=0; l='$(DEJATOOL)'; for tool in $$l; do \
+ if $$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \
+ then :; else exit_status=1; fi; \
+ done; \
+ else echo "WARNING: could not find \`runtest'" 1>&2; :;\
+ fi; \
+ exit $$exit_status
+site.exp: Makefile
+ @echo 'Making a new site.exp file...'
+ @echo '## these variables are automatically generated by make ##' >site.tmp
+ @echo '# Do not edit here. If you wish to override these values' >>site.tmp
+ @echo '# edit the last section' >>site.tmp
+ @echo 'set srcdir $(srcdir)' >>site.tmp
+ @echo "set objdir `pwd`" >>site.tmp
+ @echo 'set build_alias "$(build_alias)"' >>site.tmp
+ @echo 'set build_triplet $(build_triplet)' >>site.tmp
+ @echo 'set host_alias "$(host_alias)"' >>site.tmp
+ @echo 'set host_triplet $(host_triplet)' >>site.tmp
+ @echo 'set target_alias "$(target_alias)"' >>site.tmp
+ @echo 'set target_triplet $(target_triplet)' >>site.tmp
+ @echo '## All variables above are generated by configure. Do Not Edit ##' >>site.tmp
+ @test ! -f site.exp || \
+ sed '1,/^## All variables above are.*##/ d' site.exp >> site.tmp
+ @-rm -f site.bak
+ @test ! -f site.exp || mv site.exp site.bak
+ @mv site.tmp site.exp
+
+distclean-DEJAGNU:
+ -rm -f site.exp site.bak
+ -l='$(DEJATOOL)'; for tool in $$l; do \
+ rm -f $$tool.sum $$tool.log; \
+ done
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-DEJAGNU distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-DEJAGNU check-am clean clean-generic \
+ clean-libtool distclean distclean-DEJAGNU distclean-generic \
+ distclean-libtool distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ uninstall uninstall-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libffi-3.0.4/testsuite/config/default.exp b/libffi-3.0.4/testsuite/config/default.exp
new file mode 100644
index 0000000..90967cc
--- /dev/null
+++ b/libffi-3.0.4/testsuite/config/default.exp
@@ -0,0 +1 @@
+load_lib "standard.exp"
diff --git a/libffi-3.0.4/testsuite/lib/libffi-dg.exp b/libffi-3.0.4/testsuite/lib/libffi-dg.exp
new file mode 100644
index 0000000..226893d
--- /dev/null
+++ b/libffi-3.0.4/testsuite/lib/libffi-dg.exp
@@ -0,0 +1,289 @@
+# Copyright (C) 2003, 2005, 2008 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+proc load_gcc_lib { filename } {
+ global srcdir
+ load_file $srcdir/lib/$filename
+}
+
+load_lib dg.exp
+load_lib libgloss.exp
+load_gcc_lib target-libpath.exp
+load_gcc_lib wrapper.exp
+
+
+# Define libffi callbacks for dg.exp.
+
+proc libffi-dg-test-1 { target_compile prog do_what extra_tool_flags } {
+
+ # To get all \n in dg-output test strings to match printf output
+ # in a system that outputs it as \015\012 (i.e. not just \012), we
+ # need to change all \n into \r?\n. As there is no dejagnu flag
+ # or hook to do that, we simply change the text being tested.
+ # Unfortunately, we have to know that the variable is called
+ # dg-output-text and lives in the caller of libffi-dg-test, which
+ # is two calls up. Overriding proc dg-output would be longer and
+ # would necessarily have the same assumption.
+ upvar 2 dg-output-text output_match
+
+ if { [llength $output_match] > 1 } {
+ regsub -all "\n" [lindex $output_match 1] "\r?\n" x
+ set output_match [lreplace $output_match 1 1 $x]
+ }
+
+ # Set up the compiler flags, based on what we're going to do.
+
+ set options [list]
+ switch $do_what {
+ "compile" {
+ set compile_type "assembly"
+ set output_file "[file rootname [file tail $prog]].s"
+ }
+ "link" {
+ set compile_type "executable"
+ set output_file "[file rootname [file tail $prog]].exe"
+ # The following line is needed for targets like the i960 where
+ # the default output file is b.out. Sigh.
+ }
+ "run" {
+ set compile_type "executable"
+ # FIXME: "./" is to cope with "." not being in $PATH.
+ # Should this be handled elsewhere?
+ # YES.
+ set output_file "./[file rootname [file tail $prog]].exe"
+ # This is the only place where we care if an executable was
+ # created or not. If it was, dg.exp will try to run it.
+ remote_file build delete $output_file;
+ }
+ default {
+ perror "$do_what: not a valid dg-do keyword"
+ return ""
+ }
+ }
+
+ if { $extra_tool_flags != "" } {
+ lappend options "additional_flags=$extra_tool_flags"
+ }
+
+ set comp_output [libffi_target_compile "$prog" "$output_file" "$compile_type" $options];
+
+
+ return [list $comp_output $output_file]
+}
+
+
+proc libffi-dg-test { prog do_what extra_tool_flags } {
+ return [libffi-dg-test-1 target_compile $prog $do_what $extra_tool_flags]
+}
+
+proc libffi-init { args } {
+ global gluefile wrap_flags;
+ global srcdir
+ global blddirffi
+ global objdir
+ global TOOL_OPTIONS
+ global tool
+ global libffi_include
+ global libffi_link_flags
+ global tool_root_dir
+ global ld_library_path
+
+ set blddirffi [pwd]/..
+ verbose "libffi $blddirffi"
+
+ set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a]
+ if {$gccdir != ""} {
+ set gccdir [file dirname $gccdir]
+ }
+ verbose "gccdir $gccdir"
+
+ set ld_library_path "."
+ append ld_library_path ":${gccdir}"
+
+ set compiler "${gccdir}/xgcc"
+ if { [is_remote host] == 0 && [which $compiler] != 0 } {
+ foreach i "[exec $compiler --print-multi-lib]" {
+ set mldir ""
+ regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir
+ set mldir [string trimright $mldir "\;@"]
+ if { "$mldir" == "." } {
+ continue
+ }
+ if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] >= 1 } {
+ append ld_library_path ":${gccdir}/${mldir}"
+ }
+ }
+ }
+ # add the library path for libffi.
+ append ld_library_path ":${blddirffi}/.libs"
+
+ verbose "ld_library_path: $ld_library_path"
+
+ # Point to the Libffi headers in libffi.
+ set libffi_include "${blddirffi}/include"
+ verbose "libffi_include $libffi_include"
+
+ set libffi_dir "${blddirffi}/.libs"
+ verbose "libffi_dir $libffi_dir"
+ if { $libffi_dir != "" } {
+ set libffi_dir [file dirname ${libffi_dir}]
+ set libffi_link_flags "-L${libffi_dir}/.libs"
+ }
+
+ set_ld_library_path_env_vars
+ libffi_maybe_build_wrapper "${objdir}/testglue.o"
+}
+
+proc libffi_exit { } {
+ global gluefile;
+
+ if [info exists gluefile] {
+ file_on_build delete $gluefile;
+ unset gluefile;
+ }
+}
+
+proc libffi_target_compile { source dest type options } {
+ global gluefile wrap_flags;
+ global srcdir
+ global blddirffi
+ global TOOL_OPTIONS
+ global libffi_link_flags
+ global libffi_include
+ global target_triplet
+
+
+ if { [target_info needs_status_wrapper]!="" && [info exists gluefile] } {
+ lappend options "libs=${gluefile}"
+ lappend options "ldflags=$wrap_flags"
+ }
+
+ # TOOL_OPTIONS must come first, so that it doesn't override testcase
+ # specific options.
+ if [info exists TOOL_OPTIONS] {
+ lappend options [concat "additional_flags=$TOOL_OPTIONS" $options];
+ }
+
+ # search for ffi_mips.h in srcdir, too
+ lappend options "additional_flags=-I${libffi_include} -I${srcdir}/../include -I${libffi_include}/.."
+ lappend options "additional_flags=${libffi_link_flags}"
+
+ # If you're building the compiler with --prefix set to a place
+ # where it's not yet installed, then the linker won't be able to
+ # find the libgcc used by libffi.dylib. We could pass the
+ # -dylib_file option, but that's complicated, and it's much easier
+ # to just make the linker find libgcc using -L options.
+ if { [string match "*-*-darwin*" $target_triplet] } {
+ lappend options "libs= -shared-libgcc"
+ }
+
+ lappend options "libs= -lffi"
+
+ verbose "options: $options"
+ return [target_compile $source $dest $type $options]
+}
+
+# Utility routines.
+
+#
+# search_for -- looks for a string match in a file
+#
+proc search_for { file pattern } {
+ set fd [open $file r]
+ while { [gets $fd cur_line]>=0 } {
+ if [string match "*$pattern*" $cur_line] then {
+ close $fd
+ return 1
+ }
+ }
+ close $fd
+ return 0
+}
+
+# Modified dg-runtest that can cycle through a list of optimization options
+# as c-torture does.
+proc libffi-dg-runtest { testcases default-extra-flags } {
+ global runtests
+
+ foreach test $testcases {
+ # If we're only testing specific files and this isn't one of
+ # them, skip it.
+ if ![runtest_file_p $runtests $test] {
+ continue
+ }
+
+ # Look for a loop within the source code - if we don't find one,
+ # don't pass -funroll[-all]-loops.
+ global torture_with_loops torture_without_loops
+ if [expr [search_for $test "for*("]+[search_for $test "while*("]] {
+ set option_list $torture_with_loops
+ } else {
+ set option_list $torture_without_loops
+ }
+
+ set nshort [file tail [file dirname $test]]/[file tail $test]
+
+ foreach flags $option_list {
+ verbose "Testing $nshort, $flags" 1
+ dg-test $test $flags ${default-extra-flags}
+ }
+ }
+}
+
+
+# Like check_conditional_xfail, but callable from a dg test.
+
+proc dg-xfail-if { args } {
+ set args [lreplace $args 0 0]
+ set selector "target [join [lindex $args 1]]"
+ if { [dg-process-target $selector] == "S" } {
+ global compiler_conditional_xfail_data
+ set compiler_conditional_xfail_data $args
+ }
+}
+
+
+# We need to make sure that additional_files and additional_sources
+# are both cleared out after every test. It is not enough to clear
+# them out *before* the next test run because gcc-target-compile gets
+# run directly from some .exp files (outside of any test). (Those
+# uses should eventually be eliminated.)
+
+# Because the DG framework doesn't provide a hook that is run at the
+# end of a test, we must replace dg-test with a wrapper.
+
+if { [info procs saved-dg-test] == [list] } {
+ rename dg-test saved-dg-test
+
+ proc dg-test { args } {
+ global additional_files
+ global additional_sources
+ global errorInfo
+
+ if { [ catch { eval saved-dg-test $args } errmsg ] } {
+ set saved_info $errorInfo
+ set additional_files ""
+ set additional_sources ""
+ error $errmsg $saved_info
+ }
+ set additional_files ""
+ set additional_sources ""
+ }
+}
+
+# Local Variables:
+# tcl-indent-level:4
+# End:
diff --git a/libffi-3.0.4/testsuite/lib/target-libpath.exp b/libffi-3.0.4/testsuite/lib/target-libpath.exp
new file mode 100644
index 0000000..8999aa4
--- /dev/null
+++ b/libffi-3.0.4/testsuite/lib/target-libpath.exp
@@ -0,0 +1,263 @@
+# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# This file was contributed by John David Anglin (dave.anglin@nrc-cnrc.gc.ca)
+
+set orig_environment_saved 0
+set orig_ld_library_path_saved 0
+set orig_ld_run_path_saved 0
+set orig_shlib_path_saved 0
+set orig_ld_libraryn32_path_saved 0
+set orig_ld_library64_path_saved 0
+set orig_ld_library_path_32_saved 0
+set orig_ld_library_path_64_saved 0
+set orig_dyld_library_path_saved 0
+
+
+#######################################
+# proc set_ld_library_path_env_vars { }
+#######################################
+
+proc set_ld_library_path_env_vars { } {
+ global ld_library_path
+ global orig_environment_saved
+ global orig_ld_library_path_saved
+ global orig_ld_run_path_saved
+ global orig_shlib_path_saved
+ global orig_ld_libraryn32_path_saved
+ global orig_ld_library64_path_saved
+ global orig_ld_library_path_32_saved
+ global orig_ld_library_path_64_saved
+ global orig_dyld_library_path_saved
+ global orig_ld_library_path
+ global orig_ld_run_path
+ global orig_shlib_path
+ global orig_ld_libraryn32_path
+ global orig_ld_library64_path
+ global orig_ld_library_path_32
+ global orig_ld_library_path_64
+ global orig_dyld_library_path
+ global GCC_EXEC_PREFIX
+
+ # Set the relocated compiler prefix, but only if the user hasn't specified one.
+ if { [info exists GCC_EXEC_PREFIX] && ![info exists env(GCC_EXEC_PREFIX)] } {
+ setenv GCC_EXEC_PREFIX "$GCC_EXEC_PREFIX"
+ }
+
+ # Setting the ld library path causes trouble when testing cross-compilers.
+ if { [is_remote target] } {
+ return
+ }
+
+ if { $orig_environment_saved == 0 } {
+ global env
+
+ set orig_environment_saved 1
+
+ # Save the original environment.
+ if [info exists env(LD_LIBRARY_PATH)] {
+ set orig_ld_library_path "$env(LD_LIBRARY_PATH)"
+ set orig_ld_library_path_saved 1
+ }
+ if [info exists env(LD_RUN_PATH)] {
+ set orig_ld_run_path "$env(LD_RUN_PATH)"
+ set orig_ld_run_path_saved 1
+ }
+ if [info exists env(SHLIB_PATH)] {
+ set orig_shlib_path "$env(SHLIB_PATH)"
+ set orig_shlib_path_saved 1
+ }
+ if [info exists env(LD_LIBRARYN32_PATH)] {
+ set orig_ld_libraryn32_path "$env(LD_LIBRARYN32_PATH)"
+ set orig_ld_libraryn32_path_saved 1
+ }
+ if [info exists env(LD_LIBRARY64_PATH)] {
+ set orig_ld_library64_path "$env(LD_LIBRARY64_PATH)"
+ set orig_ld_library64_path_saved 1
+ }
+ if [info exists env(LD_LIBRARY_PATH_32)] {
+ set orig_ld_library_path_32 "$env(LD_LIBRARY_PATH_32)"
+ set orig_ld_library_path_32_saved 1
+ }
+ if [info exists env(LD_LIBRARY_PATH_64)] {
+ set orig_ld_library_path_64 "$env(LD_LIBRARY_PATH_64)"
+ set orig_ld_library_path_64_saved 1
+ }
+ if [info exists env(DYLD_LIBRARY_PATH)] {
+ set orig_dyld_library_path "$env(DYLD_LIBRARY_PATH)"
+ set orig_dyld_library_path_saved 1
+ }
+ }
+
+ # We need to set ld library path in the environment. Currently,
+ # unix.exp doesn't set the environment correctly for all systems.
+ # It only sets SHLIB_PATH and LD_LIBRARY_PATH when it executes a
+ # program. We also need the environment set for compilations, etc.
+ #
+ # On IRIX 6, we have to set variables akin to LD_LIBRARY_PATH, but
+ # called LD_LIBRARYN32_PATH (for the N32 ABI) and LD_LIBRARY64_PATH
+ # (for the 64-bit ABI). The same applies to Darwin (DYLD_LIBRARY_PATH),
+ # Solaris 32 bit (LD_LIBRARY_PATH_32), Solaris 64 bit (LD_LIBRARY_PATH_64),
+ # and HP-UX (SHLIB_PATH). In some cases, the variables are independent
+ # of LD_LIBRARY_PATH, and in other cases LD_LIBRARY_PATH is used if the
+ # variable is not defined.
+ #
+ # Doing this is somewhat of a hack as ld_library_path gets repeated in
+ # SHLIB_PATH and LD_LIBRARY_PATH when unix_load sets these variables.
+ if { $orig_ld_library_path_saved } {
+ setenv LD_LIBRARY_PATH "$ld_library_path:$orig_ld_library_path"
+ } else {
+ setenv LD_LIBRARY_PATH "$ld_library_path"
+ }
+ if { $orig_ld_run_path_saved } {
+ setenv LD_RUN_PATH "$ld_library_path:$orig_ld_run_path"
+ } else {
+ setenv LD_RUN_PATH "$ld_library_path"
+ }
+ # The default shared library dynamic path search for 64-bit
+ # HP-UX executables searches LD_LIBRARY_PATH before SHLIB_PATH.
+ # LD_LIBRARY_PATH isn't used for 32-bit executables. Thus, we
+ # set LD_LIBRARY_PATH and SHLIB_PATH as if they were independent.
+ if { $orig_shlib_path_saved } {
+ setenv SHLIB_PATH "$ld_library_path:$orig_shlib_path"
+ } else {
+ setenv SHLIB_PATH "$ld_library_path"
+ }
+ if { $orig_ld_libraryn32_path_saved } {
+ setenv LD_LIBRARYN32_PATH "$ld_library_path:$orig_ld_libraryn32_path"
+ } elseif { $orig_ld_library_path_saved } {
+ setenv LD_LIBRARYN32_PATH "$ld_library_path:$orig_ld_library_path"
+ } else {
+ setenv LD_LIBRARYN32_PATH "$ld_library_path"
+ }
+ if { $orig_ld_library64_path_saved } {
+ setenv LD_LIBRARY64_PATH "$ld_library_path:$orig_ld_library64_path"
+ } elseif { $orig_ld_library_path_saved } {
+ setenv LD_LIBRARY64_PATH "$ld_library_path:$orig_ld_library_path"
+ } else {
+ setenv LD_LIBRARY64_PATH "$ld_library_path"
+ }
+ if { $orig_ld_library_path_32_saved } {
+ setenv LD_LIBRARY_PATH_32 "$ld_library_path:$orig_ld_library_path_32"
+ } elseif { $orig_ld_library_path_saved } {
+ setenv LD_LIBRARY_PATH_32 "$ld_library_path:$orig_ld_library_path"
+ } else {
+ setenv LD_LIBRARY_PATH_32 "$ld_library_path"
+ }
+ if { $orig_ld_library_path_64_saved } {
+ setenv LD_LIBRARY_PATH_64 "$ld_library_path:$orig_ld_library_path_64"
+ } elseif { $orig_ld_library_path_saved } {
+ setenv LD_LIBRARY_PATH_64 "$ld_library_path:$orig_ld_library_path"
+ } else {
+ setenv LD_LIBRARY_PATH_64 "$ld_library_path"
+ }
+ if { $orig_dyld_library_path_saved } {
+ setenv DYLD_LIBRARY_PATH "$ld_library_path:$orig_dyld_library_path"
+ } else {
+ setenv DYLD_LIBRARY_PATH "$ld_library_path"
+ }
+
+ verbose -log "set_ld_library_path_env_vars: ld_library_path=$ld_library_path"
+}
+
+#######################################
+# proc restore_ld_library_path_env_vars { }
+#######################################
+
+proc restore_ld_library_path_env_vars { } {
+ global orig_environment_saved
+ global orig_ld_library_path_saved
+ global orig_ld_run_path_saved
+ global orig_shlib_path_saved
+ global orig_ld_libraryn32_path_saved
+ global orig_ld_library64_path_saved
+ global orig_ld_library_path_32_saved
+ global orig_ld_library_path_64_saved
+ global orig_dyld_library_path_saved
+ global orig_ld_library_path
+ global orig_ld_run_path
+ global orig_shlib_path
+ global orig_ld_libraryn32_path
+ global orig_ld_library64_path
+ global orig_ld_library_path_32
+ global orig_ld_library_path_64
+ global orig_dyld_library_path
+
+ if { $orig_environment_saved == 0 } {
+ return
+ }
+
+ if { $orig_ld_library_path_saved } {
+ setenv LD_LIBRARY_PATH "$orig_ld_library_path"
+ } elseif [info exists env(LD_LIBRARY_PATH)] {
+ unsetenv LD_LIBRARY_PATH
+ }
+ if { $orig_ld_run_path_saved } {
+ setenv LD_RUN_PATH "$orig_ld_run_path"
+ } elseif [info exists env(LD_RUN_PATH)] {
+ unsetenv LD_RUN_PATH
+ }
+ if { $orig_shlib_path_saved } {
+ setenv SHLIB_PATH "$orig_shlib_path"
+ } elseif [info exists env(SHLIB_PATH)] {
+ unsetenv SHLIB_PATH
+ }
+ if { $orig_ld_libraryn32_path_saved } {
+ setenv LD_LIBRARYN32_PATH "$orig_ld_libraryn32_path"
+ } elseif [info exists env(LD_LIBRARYN32_PATH)] {
+ unsetenv LD_LIBRARYN32_PATH
+ }
+ if { $orig_ld_library64_path_saved } {
+ setenv LD_LIBRARY64_PATH "$orig_ld_library64_path"
+ } elseif [info exists env(LD_LIBRARY64_PATH)] {
+ unsetenv LD_LIBRARY64_PATH
+ }
+ if { $orig_ld_library_path_32_saved } {
+ setenv LD_LIBRARY_PATH_32 "$orig_ld_library_path_32"
+ } elseif [info exists env(LD_LIBRARY_PATH_32)] {
+ unsetenv LD_LIBRARY_PATH_32
+ }
+ if { $orig_ld_library_path_64_saved } {
+ setenv LD_LIBRARY_PATH_64 "$orig_ld_library_path_64"
+ } elseif [info exists env(LD_LIBRARY_PATH_64)] {
+ unsetenv LD_LIBRARY_PATH_64
+ }
+ if { $orig_dyld_library_path_saved } {
+ setenv DYLD_LIBRARY_PATH "$orig_dyld_library_path"
+ } elseif [info exists env(DYLD_LIBRARY_PATH)] {
+ unsetenv DYLD_LIBRARY_PATH
+ }
+}
+
+#######################################
+# proc get_shlib_extension { }
+#######################################
+
+proc get_shlib_extension { } {
+ global shlib_ext
+
+ if { [ istarget *-*-darwin* ] } {
+ set shlib_ext "dylib"
+ } elseif { [ istarget *-*-cygwin* ] || [ istarget *-*-mingw* ] } {
+ set shlib_ext "dll"
+ } elseif { [ istarget hppa*-*-hpux* ] } {
+ set shlib_ext "sl"
+ } else {
+ set shlib_ext "so"
+ }
+ return $shlib_ext
+}
+
diff --git a/libffi-3.0.4/testsuite/lib/wrapper.exp b/libffi-3.0.4/testsuite/lib/wrapper.exp
new file mode 100644
index 0000000..4e5ae43
--- /dev/null
+++ b/libffi-3.0.4/testsuite/lib/wrapper.exp
@@ -0,0 +1,45 @@
+# Copyright (C) 2004, 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# This file contains GCC-specifics for status wrappers for test programs.
+
+# ${tool}_maybe_build_wrapper -- Build wrapper object if the target
+# needs it. FILENAME is the path to the wrapper file. If there are
+# additional arguments, they are command-line options to provide to
+# the compiler when compiling FILENAME.
+
+proc ${tool}_maybe_build_wrapper { filename args } {
+ global gluefile wrap_flags
+
+ if { [target_info needs_status_wrapper] != "" \
+ && [target_info needs_status_wrapper] != "0" \
+ && ![info exists gluefile] } {
+ set saved_wrap_compile_flags [target_info wrap_compile_flags]
+ set flags [join $args " "]
+ # The wrapper code may contain code that gcc objects on. This
+ # became true for dejagnu-1.4.4. The set of warnings and code
+ # that gcc objects on may change, so just make sure -w is always
+ # passed to turn off all warnings.
+ set_currtarget_info wrap_compile_flags \
+ "$saved_wrap_compile_flags -w $flags"
+ set result [build_wrapper $filename]
+ set_currtarget_info wrap_compile_flags "$saved_wrap_compile_flags"
+ if { $result != "" } {
+ set gluefile [lindex $result 0]
+ set wrap_flags [lindex $result 1]
+ }
+ }
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/call.exp b/libffi-3.0.4/testsuite/libffi.call/call.exp
new file mode 100644
index 0000000..25e0109
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/call.exp
@@ -0,0 +1,36 @@
+# Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# libffi testsuite that uses the 'dg.exp' driver.
+
+load_lib libffi-dg.exp
+
+dg-init
+libffi-init
+
+global srcdir subdir
+
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O0 -W -Wall" ""
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O2" ""
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O3" ""
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-Os" ""
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O2 -fomit-frame-pointer" ""
+
+dg-finish
+
+# Local Variables:
+# tcl-indent-level:4
+# End:
diff --git a/libffi-3.0.4/testsuite/libffi.call/closure_fn0.c b/libffi-3.0.4/testsuite/libffi.call/closure_fn0.c
new file mode 100644
index 0000000..e487527
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/closure_fn0.c
@@ -0,0 +1,97 @@
+/* Area: closure_call
+ Purpose: Check multiple values passing from different type.
+ Also, exceed the limit of gpr and fpr registers on PowerPC
+ Darwin.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void
+closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata)
+{
+ *(ffi_arg*)resp =
+ (int)*(unsigned long long *)args[0] + (int)(*(int *)args[1]) +
+ (int)(*(unsigned long long *)args[2]) + (int)*(int *)args[3] +
+ (int)(*(signed short *)args[4]) +
+ (int)(*(unsigned long long *)args[5]) +
+ (int)*(int *)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)(long)userdata;
+
+ printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+ (int)*(unsigned long long *)args[0], (int)(*(int *)args[1]),
+ (int)(*(unsigned long long *)args[2]),
+ (int)*(int *)args[3], (int)(*(signed short *)args[4]),
+ (int)(*(unsigned long long *)args[5]),
+ (int)*(int *)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)(long)userdata, (int)*(ffi_arg *)resp);
+
+}
+
+typedef int (*closure_test_type0)(unsigned long long, int, unsigned long long,
+ int, signed short, unsigned long long, int,
+ int, double, int, int, float, int, int,
+ int, int);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ ffi_type * cl_arg_types[17];
+ int res;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cl_arg_types[0] = &ffi_type_uint64;
+ cl_arg_types[1] = &ffi_type_sint;
+ cl_arg_types[2] = &ffi_type_uint64;
+ cl_arg_types[3] = &ffi_type_sint;
+ cl_arg_types[4] = &ffi_type_sshort;
+ cl_arg_types[5] = &ffi_type_uint64;
+ cl_arg_types[6] = &ffi_type_sint;
+ cl_arg_types[7] = &ffi_type_sint;
+ cl_arg_types[8] = &ffi_type_double;
+ cl_arg_types[9] = &ffi_type_sint;
+ cl_arg_types[10] = &ffi_type_sint;
+ cl_arg_types[11] = &ffi_type_float;
+ cl_arg_types[12] = &ffi_type_sint;
+ cl_arg_types[13] = &ffi_type_sint;
+ cl_arg_types[14] = &ffi_type_sint;
+ cl_arg_types[15] = &ffi_type_sint;
+ 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(pcl, &cif, closure_test_fn0,
+ (void *) 3 /* userdata */) == FFI_OK);
+
+ res = (*((closure_test_type0)pcl))
+ (1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13,
+ 19, 21, 1);
+ /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 680" } */
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/closure_fn1.c b/libffi-3.0.4/testsuite/libffi.call/closure_fn1.c
new file mode 100644
index 0000000..db26c42
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/closure_fn1.c
@@ -0,0 +1,89 @@
+/* Area: closure_call.
+ Purpose: Check multiple values passing from different type.
+ Also, exceed the limit of gpr and fpr registers on PowerPC
+ Darwin.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+
+static void closure_test_fn1(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata)
+{
+ *(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)(long)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)(long)userdata, (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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ ffi_type * cl_arg_types[17];
+ int res;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ 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_sint;
+ cl_arg_types[8] = &ffi_type_double;
+ cl_arg_types[9] = &ffi_type_sint;
+ cl_arg_types[10] = &ffi_type_sint;
+ cl_arg_types[11] = &ffi_type_float;
+ cl_arg_types[12] = &ffi_type_sint;
+ cl_arg_types[13] = &ffi_type_sint;
+ cl_arg_types[14] = &ffi_type_sint;
+ cl_arg_types[15] = &ffi_type_sint;
+ 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(pcl, &cif, closure_test_fn1,
+ (void *) 3 /* userdata */) == FFI_OK);
+
+ res = (*((closure_test_type1)pcl))
+ (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 "1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 255" } */
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/closure_fn2.c b/libffi-3.0.4/testsuite/libffi.call/closure_fn2.c
new file mode 100644
index 0000000..cbf7385
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/closure_fn2.c
@@ -0,0 +1,89 @@
+/* Area: closure_call
+ Purpose: Check multiple values passing from different type.
+ Also, exceed the limit of gpr and fpr registers on PowerPC
+ Darwin.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void closure_test_fn2(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata)
+{
+ *(ffi_arg*)resp =
+ (int)*(double *)args[0] +(int)(*(double *)args[1]) +
+ (int)(*(double *)args[2]) + (int)*(double *)args[3] +
+ (int)(*(signed short *)args[4]) + (int)(*(double *)args[5]) +
+ (int)*(double *)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)(*(float *)args[13]) +
+ (int)(*(int *)args[14]) + *(int *)args[15] + (int)(long)userdata;
+
+ printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+ (int)*(double *)args[0], (int)(*(double *)args[1]),
+ (int)(*(double *)args[2]), (int)*(double *)args[3],
+ (int)(*(signed short *)args[4]), (int)(*(double *)args[5]),
+ (int)*(double *)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)(*(float *)args[13]),
+ (int)(*(int *)args[14]), *(int *)args[15], (int)(long)userdata,
+ (int)*(ffi_arg *)resp);
+}
+
+typedef int (*closure_test_type2)(double, double, double, double, signed short,
+ double, double, int, double, int, int, float,
+ int, float, int, int);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ ffi_type * cl_arg_types[17];
+ int res;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cl_arg_types[0] = &ffi_type_double;
+ cl_arg_types[1] = &ffi_type_double;
+ cl_arg_types[2] = &ffi_type_double;
+ cl_arg_types[3] = &ffi_type_double;
+ cl_arg_types[4] = &ffi_type_sshort;
+ cl_arg_types[5] = &ffi_type_double;
+ cl_arg_types[6] = &ffi_type_double;
+ cl_arg_types[7] = &ffi_type_sint;
+ cl_arg_types[8] = &ffi_type_double;
+ cl_arg_types[9] = &ffi_type_sint;
+ cl_arg_types[10] = &ffi_type_sint;
+ cl_arg_types[11] = &ffi_type_float;
+ cl_arg_types[12] = &ffi_type_sint;
+ cl_arg_types[13] = &ffi_type_float;
+ cl_arg_types[14] = &ffi_type_sint;
+ cl_arg_types[15] = &ffi_type_sint;
+ 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(pcl, &cif, closure_test_fn2,
+ (void *) 3 /* userdata */) == FFI_OK);
+
+ res = (*((closure_test_type2)pcl))
+ (1, 2, 3, 4, 127, 5, 6, 8, 9, 10, 11, 12.0, 13,
+ 19.0, 21, 1);
+ /* { dg-output "1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 255" } */
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/closure_fn3.c b/libffi-3.0.4/testsuite/libffi.call/closure_fn3.c
new file mode 100644
index 0000000..1fb32a8
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/closure_fn3.c
@@ -0,0 +1,90 @@
+/* Area: closure_call
+ Purpose: Check multiple values passing from different type.
+ Also, exceed the limit of gpr and fpr registers on PowerPC
+ Darwin.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void closure_test_fn3(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata)
+ {
+ *(ffi_arg*)resp =
+ (int)*(float *)args[0] +(int)(*(float *)args[1]) +
+ (int)(*(float *)args[2]) + (int)*(float *)args[3] +
+ (int)(*(float *)args[4]) + (int)(*(float *)args[5]) +
+ (int)*(float *)args[6] + (int)(*(float *)args[7]) +
+ (int)(*(double *)args[8]) + (int)*(int *)args[9] +
+ (int)(*(float *)args[10]) + (int)(*(float *)args[11]) +
+ (int)*(int *)args[12] + (int)(*(float *)args[13]) +
+ (int)(*(float *)args[14]) + *(int *)args[15] + (int)(long)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)(*(float *)args[4]), (int)(*(float *)args[5]),
+ (int)*(float *)args[6], (int)(*(float *)args[7]),
+ (int)(*(double *)args[8]), (int)*(int *)args[9],
+ (int)(*(float *)args[10]), (int)(*(float *)args[11]),
+ (int)*(int *)args[12], (int)(*(float *)args[13]),
+ (int)(*(float *)args[14]), *(int *)args[15], (int)(long)userdata,
+ (int)*(ffi_arg *)resp);
+
+ }
+
+typedef int (*closure_test_type3)(float, float, float, float, float, float,
+ float, float, double, int, float, float, int,
+ float, float, int);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ ffi_type * cl_arg_types[17];
+ int res;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ 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_float;
+ cl_arg_types[5] = &ffi_type_float;
+ cl_arg_types[6] = &ffi_type_float;
+ cl_arg_types[7] = &ffi_type_float;
+ cl_arg_types[8] = &ffi_type_double;
+ cl_arg_types[9] = &ffi_type_sint;
+ cl_arg_types[10] = &ffi_type_float;
+ cl_arg_types[11] = &ffi_type_float;
+ cl_arg_types[12] = &ffi_type_sint;
+ cl_arg_types[13] = &ffi_type_float;
+ cl_arg_types[14] = &ffi_type_float;
+ cl_arg_types[15] = &ffi_type_sint;
+ 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(pcl, &cif, closure_test_fn3,
+ (void *) 3 /* userdata */) == FFI_OK);
+
+ res = (*((closure_test_type3)pcl))
+ (1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9, 10, 11.11, 12.0, 13,
+ 19.19, 21.21, 1);
+ /* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 19 21 1 3: 135" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 135" } */
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/closure_fn4.c b/libffi-3.0.4/testsuite/libffi.call/closure_fn4.c
new file mode 100644
index 0000000..74506f3
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/closure_fn4.c
@@ -0,0 +1,97 @@
+/* Area: closure_call
+ Purpose: Check multiple long long values passing.
+ Also, exceed the limit of gpr and fpr registers on PowerPC
+ Darwin.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20031026 */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+static void
+closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata)
+{
+ *(ffi_arg*)resp =
+ (int)*(unsigned long long *)args[0] + (int)*(unsigned long long *)args[1] +
+ (int)*(unsigned long long *)args[2] + (int)*(unsigned long long *)args[3] +
+ (int)*(unsigned long long *)args[4] + (int)*(unsigned long long *)args[5] +
+ (int)*(unsigned long long *)args[6] + (int)*(unsigned long long *)args[7] +
+ (int)*(unsigned long long *)args[8] + (int)*(unsigned long long *)args[9] +
+ (int)*(unsigned long long *)args[10] +
+ (int)*(unsigned long long *)args[11] +
+ (int)*(unsigned long long *)args[12] +
+ (int)*(unsigned long long *)args[13] +
+ (int)*(unsigned long long *)args[14] +
+ *(int *)args[15] + (int)(long)userdata;
+
+ printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+ (int)*(unsigned long long *)args[0],
+ (int)*(unsigned long long *)args[1],
+ (int)*(unsigned long long *)args[2],
+ (int)*(unsigned long long *)args[3],
+ (int)*(unsigned long long *)args[4],
+ (int)*(unsigned long long *)args[5],
+ (int)*(unsigned long long *)args[6],
+ (int)*(unsigned long long *)args[7],
+ (int)*(unsigned long long *)args[8],
+ (int)*(unsigned long long *)args[9],
+ (int)*(unsigned long long *)args[10],
+ (int)*(unsigned long long *)args[11],
+ (int)*(unsigned long long *)args[12],
+ (int)*(unsigned long long *)args[13],
+ (int)*(unsigned long long *)args[14],
+ *(int *)args[15],
+ (int)(long)userdata, (int)*(ffi_arg *)resp);
+
+}
+
+typedef int (*closure_test_type0)(unsigned long long, unsigned long long,
+ unsigned long long, unsigned long long,
+ unsigned long long, unsigned long long,
+ unsigned long long, unsigned long long,
+ unsigned long long, unsigned long long,
+ unsigned long long, unsigned long long,
+ unsigned long long, unsigned long long,
+ unsigned long long, int);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ ffi_type * cl_arg_types[17];
+ int i, res;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ for (i = 0; i < 15; i++) {
+ cl_arg_types[i] = &ffi_type_uint64;
+ }
+ cl_arg_types[15] = &ffi_type_sint;
+ 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(pcl, &cif, closure_test_fn0,
+ (void *) 3 /* userdata */) == FFI_OK);
+
+ res = (*((closure_test_type0)pcl))
+ (1LL, 2LL, 3LL, 4LL, 127LL, 429LL, 7LL, 8LL, 9LL, 10LL, 11LL, 12LL,
+ 13LL, 19LL, 21LL, 1);
+ /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 680" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/closure_fn5.c b/libffi-3.0.4/testsuite/libffi.call/closure_fn5.c
new file mode 100644
index 0000000..c64ee8d
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/closure_fn5.c
@@ -0,0 +1,99 @@
+/* Area: closure_call
+ Purpose: Check multiple long long values passing.
+ Exceed the limit of gpr registers on PowerPC
+ Darwin.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20031026 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void
+closure_test_fn5(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata)
+{
+ *(ffi_arg*)resp =
+ (int)*(unsigned long long *)args[0] + (int)*(unsigned long long *)args[1] +
+ (int)*(unsigned long long *)args[2] + (int)*(unsigned long long *)args[3] +
+ (int)*(unsigned long long *)args[4] + (int)*(unsigned long long *)args[5] +
+ (int)*(unsigned long long *)args[6] + (int)*(unsigned long long *)args[7] +
+ (int)*(unsigned long long *)args[8] + (int)*(unsigned long long *)args[9] +
+ (int)*(int *)args[10] +
+ (int)*(unsigned long long *)args[11] +
+ (int)*(unsigned long long *)args[12] +
+ (int)*(unsigned long long *)args[13] +
+ (int)*(unsigned long long *)args[14] +
+ *(int *)args[15] + (int)(long)userdata;
+
+ printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+ (int)*(unsigned long long *)args[0],
+ (int)*(unsigned long long *)args[1],
+ (int)*(unsigned long long *)args[2],
+ (int)*(unsigned long long *)args[3],
+ (int)*(unsigned long long *)args[4],
+ (int)*(unsigned long long *)args[5],
+ (int)*(unsigned long long *)args[6],
+ (int)*(unsigned long long *)args[7],
+ (int)*(unsigned long long *)args[8],
+ (int)*(unsigned long long *)args[9],
+ (int)*(int *)args[10],
+ (int)*(unsigned long long *)args[11],
+ (int)*(unsigned long long *)args[12],
+ (int)*(unsigned long long *)args[13],
+ (int)*(unsigned long long *)args[14],
+ *(int *)args[15],
+ (int)(long)userdata, (int)*(ffi_arg *)resp);
+
+}
+
+typedef int (*closure_test_type0)(unsigned long long, unsigned long long,
+ unsigned long long, unsigned long long,
+ unsigned long long, unsigned long long,
+ unsigned long long, unsigned long long,
+ unsigned long long, unsigned long long,
+ int, unsigned long long,
+ unsigned long long, unsigned long long,
+ unsigned long long, int);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ ffi_type * cl_arg_types[17];
+ int i, res;
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ for (i = 0; i < 10; i++) {
+ cl_arg_types[i] = &ffi_type_uint64;
+ }
+ cl_arg_types[10] = &ffi_type_sint;
+ for (i = 11; i < 15; i++) {
+ cl_arg_types[i] = &ffi_type_uint64;
+ }
+ cl_arg_types[15] = &ffi_type_sint;
+ 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(pcl, &cif, closure_test_fn5,
+ (void *) 3 /* userdata */) == FFI_OK);
+
+ res = (*((closure_test_type0)pcl))
+ (1LL, 2LL, 3LL, 4LL, 127LL, 429LL, 7LL, 8LL, 9LL, 10LL, 11, 12LL,
+ 13LL, 19LL, 21LL, 1);
+ /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 680" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/closure_fn6.c b/libffi-3.0.4/testsuite/libffi.call/closure_fn6.c
new file mode 100644
index 0000000..16c52fd
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/closure_fn6.c
@@ -0,0 +1,98 @@
+/* Area: closure_call
+ Purpose: Check multiple values passing from different type.
+ Also, exceed the limit of gpr and fpr registers on PowerPC.
+ Limitations: none.
+ PR: PR23404
+ Originator: <andreast@gcc.gnu.org> 20050830 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void
+closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata)
+{
+ *(ffi_arg*)resp =
+ (int)*(unsigned long long *)args[0] +
+ (int)(*(unsigned long long *)args[1]) +
+ (int)(*(unsigned long long *)args[2]) +
+ (int)*(unsigned long long *)args[3] +
+ (int)(*(int *)args[4]) + (int)(*(double *)args[5]) +
+ (int)*(double *)args[6] + (int)(*(float *)args[7]) +
+ (int)(*(double *)args[8]) + (int)*(double *)args[9] +
+ (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
+ (int)*(int *)args[12] + (int)(*(int *)args[13]) +
+ (int)(*(double *)args[14]) + (int)*(double *)args[15] +
+ (int)(long)userdata;
+
+ printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+ (int)*(unsigned long long *)args[0],
+ (int)(*(unsigned long long *)args[1]),
+ (int)(*(unsigned long long *)args[2]),
+ (int)*(unsigned long long *)args[3],
+ (int)(*(int *)args[4]), (int)(*(double *)args[5]),
+ (int)*(double *)args[6], (int)(*(float *)args[7]),
+ (int)(*(double *)args[8]), (int)*(double *)args[9],
+ (int)(*(int *)args[10]), (int)(*(float *)args[11]),
+ (int)*(int *)args[12], (int)(*(int *)args[13]),
+ (int)(*(double *)args[14]), (int)(*(double *)args[15]),
+ (int)(long)userdata, (int)*(ffi_arg *)resp);
+
+}
+
+typedef int (*closure_test_type0)(unsigned long long,
+ unsigned long long,
+ unsigned long long,
+ unsigned long long,
+ int, double, double, float, double, double,
+ int, float, int, int, double, double);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ ffi_type * cl_arg_types[17];
+ int res;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cl_arg_types[0] = &ffi_type_uint64;
+ cl_arg_types[1] = &ffi_type_uint64;
+ cl_arg_types[2] = &ffi_type_uint64;
+ cl_arg_types[3] = &ffi_type_uint64;
+ cl_arg_types[4] = &ffi_type_sint;
+ cl_arg_types[5] = &ffi_type_double;
+ cl_arg_types[6] = &ffi_type_double;
+ cl_arg_types[7] = &ffi_type_float;
+ cl_arg_types[8] = &ffi_type_double;
+ cl_arg_types[9] = &ffi_type_double;
+ cl_arg_types[10] = &ffi_type_sint;
+ cl_arg_types[11] = &ffi_type_float;
+ cl_arg_types[12] = &ffi_type_sint;
+ cl_arg_types[13] = &ffi_type_sint;
+ cl_arg_types[14] = &ffi_type_double;
+ cl_arg_types[15] = &ffi_type_double;
+ 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(pcl, &cif, closure_test_fn0,
+ (void *) 3 /* userdata */) == FFI_OK);
+
+ res = (*((closure_test_type0)pcl))
+ (1, 2, 3, 4, 127, 429., 7., 8., 9.5, 10., 11, 12., 13,
+ 19, 21., 1.);
+ /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 680" } */
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/closure_stdcall.c b/libffi-3.0.4/testsuite/libffi.call/closure_stdcall.c
new file mode 100644
index 0000000..e80b10b
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/closure_stdcall.c
@@ -0,0 +1,72 @@
+/* Area: closure_call (stdcall convention)
+ Purpose: Check handling when caller expects stdcall callee
+ Limitations: none.
+ PR: none.
+ Originator: <twalljava@dev.java.net> */
+
+/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
+#include "ffitest.h"
+
+static void
+closure_test_stdcall(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata)
+{
+ *(ffi_arg*)resp =
+ (int)*(int *)args[0] + (int)(*(int *)args[1])
+ + (int)(*(int *)args[2]) + (int)(*(int *)args[3])
+ + (int)(long)userdata;
+
+ printf("%d %d %d %d: %d\n",
+ (int)*(int *)args[0], (int)(*(int *)args[1]),
+ (int)(*(int *)args[2]), (int)(*(int *)args[3]),
+ (int)*(ffi_arg *)resp);
+
+}
+
+typedef int (__stdcall *closure_test_type0)(int, int, int, int);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ ffi_type * cl_arg_types[17];
+ int res;
+ void* sp_pre;
+ void* sp_post;
+ char buf[1024];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cl_arg_types[0] = &ffi_type_uint;
+ cl_arg_types[1] = &ffi_type_uint;
+ cl_arg_types[2] = &ffi_type_uint;
+ cl_arg_types[3] = &ffi_type_uint;
+ cl_arg_types[4] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 4,
+ &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure(pcl, &cif, closure_test_stdcall,
+ (void *) 3 /* userdata */) == FFI_OK);
+
+ asm volatile (" movl %%esp,%0" : "=g" (sp_pre));
+ res = (*(closure_test_type0)pcl)(0, 1, 2, 3);
+ asm volatile (" movl %%esp,%0" : "=g" (sp_post));
+ /* { dg-output "0 1 2 3: 9" } */
+
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 9" } */
+
+ sprintf(buf, "mismatch: pre=%p vs post=%p", sp_pre, sp_post);
+ printf("stack pointer %s\n", (sp_pre == sp_post ? "match" : buf));
+ /* { dg-output "\nstack pointer match" } */
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_12byte.c b/libffi-3.0.4/testsuite/libffi.call/cls_12byte.c
new file mode 100644
index 0000000..92530d5
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_12byte.c
@@ -0,0 +1,102 @@
+/* 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 cls_struct_12byte {
+ int a;
+ int b;
+ int c;
+} cls_struct_12byte;
+
+cls_struct_12byte cls_struct_12byte_fn(struct cls_struct_12byte b1,
+ struct cls_struct_12byte b2)
+{
+ struct cls_struct_12byte result;
+
+ result.a = b1.a + b2.a;
+ result.b = b1.b + b2.b;
+ result.c = b1.c + b2.c;
+
+ printf("%d %d %d %d %d %d: %d %d %d\n", b1.a, b1.b, b1.c, b2.a, b2.b, b2.c,
+ result.a, result.b, result.c);
+
+ return result;
+}
+
+static void cls_struct_12byte_gn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args , void* userdata __UNUSED__)
+{
+ struct cls_struct_12byte b1, b2;
+
+ b1 = *(struct cls_struct_12byte*)(args[0]);
+ b2 = *(struct cls_struct_12byte*)(args[1]);
+
+ *(cls_struct_12byte*)resp = cls_struct_12byte_fn(b1, b2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_12byte h_dbl = { 7, 4, 9 };
+ struct cls_struct_12byte j_dbl = { 1, 5, 3 };
+ struct cls_struct_12byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_sint;
+ cls_struct_fields[1] = &ffi_type_sint;
+ cls_struct_fields[2] = &ffi_type_sint;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &h_dbl;
+ args_dbl[1] = &j_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_12byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "7 4 9 1 5 3: 8 9 12" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 8 9 12" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_12byte_gn, NULL) == FFI_OK);
+
+ res_dbl.a = 0;
+ res_dbl.b = 0;
+ res_dbl.c = 0;
+
+ res_dbl = ((cls_struct_12byte(*)(cls_struct_12byte, cls_struct_12byte))(pcl))(h_dbl, j_dbl);
+ /* { dg-output "\n7 4 9 1 5 3: 8 9 12" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 8 9 12" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_16byte.c b/libffi-3.0.4/testsuite/libffi.call/cls_16byte.c
new file mode 100644
index 0000000..f3c314a
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_16byte.c
@@ -0,0 +1,103 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_16byte {
+ int a;
+ double b;
+ int c;
+} cls_struct_16byte;
+
+cls_struct_16byte cls_struct_16byte_fn(struct cls_struct_16byte b1,
+ struct cls_struct_16byte b2)
+{
+ struct cls_struct_16byte result;
+
+ result.a = b1.a + b2.a;
+ result.b = b1.b + b2.b;
+ result.c = b1.c + b2.c;
+
+ printf("%d %g %d %d %g %d: %d %g %d\n", b1.a, b1.b, b1.c, b2.a, b2.b, b2.c,
+ result.a, result.b, result.c);
+
+ return result;
+}
+
+static void cls_struct_16byte_gn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+{
+ struct cls_struct_16byte b1, b2;
+
+ b1 = *(struct cls_struct_16byte*)(args[0]);
+ b2 = *(struct cls_struct_16byte*)(args[1]);
+
+ *(cls_struct_16byte*)resp = cls_struct_16byte_fn(b1, b2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_16byte h_dbl = { 7, 8.0, 9 };
+ struct cls_struct_16byte j_dbl = { 1, 9.0, 3 };
+ struct cls_struct_16byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_sint;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = &ffi_type_sint;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &h_dbl;
+ args_dbl[1] = &j_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_16byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "7 8 9 1 9 3: 8 17 12" } */
+ printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 8 17 12" } */
+
+ res_dbl.a = 0;
+ res_dbl.b = 0.0;
+ res_dbl.c = 0;
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_16byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_16byte(*)(cls_struct_16byte, cls_struct_16byte))(pcl))(h_dbl, j_dbl);
+ /* { dg-output "\n7 8 9 1 9 3: 8 17 12" } */
+ printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 8 17 12" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_18byte.c b/libffi-3.0.4/testsuite/libffi.call/cls_18byte.c
new file mode 100644
index 0000000..9016580
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_18byte.c
@@ -0,0 +1,104 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Double alignment check on darwin.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030915 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_18byte {
+ double a;
+ unsigned char b;
+ unsigned char c;
+ double d;
+} cls_struct_18byte;
+
+cls_struct_18byte cls_struct_18byte_fn(struct cls_struct_18byte a1,
+ struct cls_struct_18byte a2)
+{
+ struct cls_struct_18byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+ result.d = a1.d + a2.d;
+
+
+ printf("%g %d %d %g %g %d %d %g: %g %d %d %g\n", a1.a, a1.b, a1.c, a1.d,
+ a2.a, a2.b, a2.c, a2.d,
+ result.a, result.b, result.c, result.d);
+ return result;
+}
+
+static void
+cls_struct_18byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct cls_struct_18byte a1, a2;
+
+ a1 = *(struct cls_struct_18byte*)(args[0]);
+ a2 = *(struct cls_struct_18byte*)(args[1]);
+
+ *(cls_struct_18byte*)resp = cls_struct_18byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[3];
+ ffi_type* cls_struct_fields[5];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[3];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_18byte g_dbl = { 1.0, 127, 126, 3.0 };
+ struct cls_struct_18byte f_dbl = { 4.0, 125, 124, 5.0 };
+ struct cls_struct_18byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = &ffi_type_double;
+ cls_struct_fields[4] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_18byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 127 126 3 4 125 124 5: 5 252 250 8" } */
+ printf("res: %g %d %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+ /* { dg-output "\nres: 5 252 250 8" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_18byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_18byte(*)(cls_struct_18byte, cls_struct_18byte))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n1 127 126 3 4 125 124 5: 5 252 250 8" } */
+ printf("res: %g %d %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+ /* { dg-output "\nres: 5 252 250 8" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_19byte.c b/libffi-3.0.4/testsuite/libffi.call/cls_19byte.c
new file mode 100644
index 0000000..8af5834
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_19byte.c
@@ -0,0 +1,110 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Double alignment check on darwin.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030915 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_19byte {
+ double a;
+ unsigned char b;
+ unsigned char c;
+ double d;
+ unsigned char e;
+} cls_struct_19byte;
+
+cls_struct_19byte cls_struct_19byte_fn(struct cls_struct_19byte a1,
+ struct cls_struct_19byte a2)
+{
+ struct cls_struct_19byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+ result.d = a1.d + a2.d;
+ result.e = a1.e + a2.e;
+
+
+ printf("%g %d %d %g %d %g %d %d %g %d: %g %d %d %g %d\n",
+ a1.a, a1.b, a1.c, a1.d, a1.e,
+ a2.a, a2.b, a2.c, a2.d, a2.e,
+ result.a, result.b, result.c, result.d, result.e);
+ return result;
+}
+
+static void
+cls_struct_19byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct cls_struct_19byte a1, a2;
+
+ a1 = *(struct cls_struct_19byte*)(args[0]);
+ a2 = *(struct cls_struct_19byte*)(args[1]);
+
+ *(cls_struct_19byte*)resp = cls_struct_19byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[3];
+ ffi_type* cls_struct_fields[6];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[3];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_19byte g_dbl = { 1.0, 127, 126, 3.0, 120 };
+ struct cls_struct_19byte f_dbl = { 4.0, 125, 124, 5.0, 119 };
+ struct cls_struct_19byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = &ffi_type_double;
+ cls_struct_fields[4] = &ffi_type_uchar;
+ cls_struct_fields[5] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_19byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 127 126 3 120 4 125 124 5 119: 5 252 250 8 239" } */
+ printf("res: %g %d %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e);
+ /* { dg-output "\nres: 5 252 250 8 239" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_19byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_19byte(*)(cls_struct_19byte, cls_struct_19byte))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n1 127 126 3 120 4 125 124 5 119: 5 252 250 8 239" } */
+ printf("res: %g %d %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e);
+ /* { dg-output "\nres: 5 252 250 8 239" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_1_1byte.c b/libffi-3.0.4/testsuite/libffi.call/cls_1_1byte.c
new file mode 100644
index 0000000..0fcc8c6
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_1_1byte.c
@@ -0,0 +1,97 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Especially with small structures which may fit in one
+ register. Depending on the ABI.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030902 */
+
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_1_1byte {
+ unsigned char a;
+} cls_struct_1_1byte;
+
+cls_struct_1_1byte cls_struct_1_1byte_fn(struct cls_struct_1_1byte a1,
+ struct cls_struct_1_1byte a2)
+{
+ struct cls_struct_1_1byte result;
+
+ result.a = a1.a + a2.a;
+
+ printf("%d %d: %d\n", a1.a, a2.a, result.a);
+
+ return result;
+}
+
+static void
+cls_struct_1_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_1_1byte a1, a2;
+
+ a1 = *(struct cls_struct_1_1byte*)(args[0]);
+ a2 = *(struct cls_struct_1_1byte*)(args[1]);
+
+ *(cls_struct_1_1byte*)resp = cls_struct_1_1byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[2];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_1_1byte g_dbl = { 12 };
+ struct cls_struct_1_1byte f_dbl = { 178 };
+ struct cls_struct_1_1byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_1_1byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 178: 190" } */
+ printf("res: %d\n", res_dbl.a);
+ /* { dg-output "\nres: 190" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_1_1byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_1_1byte(*)(cls_struct_1_1byte, cls_struct_1_1byte))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n12 178: 190" } */
+ printf("res: %d\n", res_dbl.a);
+ /* { dg-output "\nres: 190" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_20byte.c b/libffi-3.0.4/testsuite/libffi.call/cls_20byte.c
new file mode 100644
index 0000000..fa5f81a
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_20byte.c
@@ -0,0 +1,99 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_20byte {
+ double a;
+ double b;
+ int c;
+} cls_struct_20byte;
+
+cls_struct_20byte cls_struct_20byte_fn(struct cls_struct_20byte a1,
+ struct cls_struct_20byte a2)
+{
+ struct cls_struct_20byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+
+ printf("%g %g %d %g %g %d: %g %g %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c,
+ result.a, result.b, result.c);
+ return result;
+}
+
+static void
+cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct cls_struct_20byte a1, a2;
+
+ a1 = *(struct cls_struct_20byte*)(args[0]);
+ a2 = *(struct cls_struct_20byte*)(args[1]);
+
+ *(cls_struct_20byte*)resp = cls_struct_20byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_20byte g_dbl = { 1.0, 2.0, 3 };
+ struct cls_struct_20byte f_dbl = { 4.0, 5.0, 7 };
+ struct cls_struct_20byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = &ffi_type_sint;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_20byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 2 3 4 5 7: 5 7 10" } */
+ printf("res: %g %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 5 7 10" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_20byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n1 2 3 4 5 7: 5 7 10" } */
+ printf("res: %g %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 5 7 10" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_20byte1.c b/libffi-3.0.4/testsuite/libffi.call/cls_20byte1.c
new file mode 100644
index 0000000..072bafc
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_20byte1.c
@@ -0,0 +1,101 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_20byte {
+ int a;
+ double b;
+ double c;
+} cls_struct_20byte;
+
+cls_struct_20byte cls_struct_20byte_fn(struct cls_struct_20byte a1,
+ struct cls_struct_20byte a2)
+{
+ struct cls_struct_20byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+
+ printf("%d %g %g %d %g %g: %d %g %g\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c,
+ result.a, result.b, result.c);
+ return result;
+}
+
+static void
+cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct cls_struct_20byte a1, a2;
+
+ a1 = *(struct cls_struct_20byte*)(args[0]);
+ a2 = *(struct cls_struct_20byte*)(args[1]);
+
+ *(cls_struct_20byte*)resp = cls_struct_20byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[3];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[3];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_20byte g_dbl = { 1, 2.0, 3.0 };
+ struct cls_struct_20byte f_dbl = { 4, 5.0, 7.0 };
+ struct cls_struct_20byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_sint;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = &ffi_type_double;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_20byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 2 3 4 5 7: 5 7 10" } */
+ printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 5 7 10" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_20byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n1 2 3 4 5 7: 5 7 10" } */
+ printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 5 7 10" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_24byte.c b/libffi-3.0.4/testsuite/libffi.call/cls_24byte.c
new file mode 100644
index 0000000..22e1690
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_24byte.c
@@ -0,0 +1,121 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_24byte {
+ double a;
+ double b;
+ int c;
+ float d;
+} cls_struct_24byte;
+
+cls_struct_24byte cls_struct_24byte_fn(struct cls_struct_24byte b0,
+ struct cls_struct_24byte b1,
+ struct cls_struct_24byte b2,
+ struct cls_struct_24byte b3)
+{
+ struct cls_struct_24byte 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;
+
+ printf("%g %g %d %g %g %g %d %g %g %g %d %g %g %g %d %g: %g %g %d %g\n",
+ b0.a, b0.b, b0.c, b0.d,
+ b1.a, b1.b, b1.c, b1.d,
+ b2.a, b2.b, b2.c, b2.d,
+ b3.a, b3.b, b3.c, b2.d,
+ result.a, result.b, result.c, result.d);
+
+ return result;
+}
+
+static void
+cls_struct_24byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct cls_struct_24byte b0, b1, b2, b3;
+
+ b0 = *(struct cls_struct_24byte*)(args[0]);
+ b1 = *(struct cls_struct_24byte*)(args[1]);
+ b2 = *(struct cls_struct_24byte*)(args[2]);
+ b3 = *(struct cls_struct_24byte*)(args[3]);
+
+ *(cls_struct_24byte*)resp = cls_struct_24byte_fn(b0, b1, b2, b3);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[5];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_24byte e_dbl = { 9.0, 2.0, 6, 5.0 };
+ struct cls_struct_24byte f_dbl = { 1.0, 2.0, 3, 7.0 };
+ struct cls_struct_24byte g_dbl = { 4.0, 5.0, 7, 9.0 };
+ struct cls_struct_24byte h_dbl = { 8.0, 6.0, 1, 4.0 };
+ struct cls_struct_24byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = &ffi_type_sint;
+ cls_struct_fields[3] = &ffi_type_float;
+ cls_struct_fields[4] = 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_24byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "9 2 6 5 1 2 3 7 4 5 7 9 8 6 1 9: 22 15 17 25" } */
+ printf("res: %g %g %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+ /* { dg-output "\nres: 22 15 17 25" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_24byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_24byte(*)(cls_struct_24byte,
+ cls_struct_24byte,
+ cls_struct_24byte,
+ cls_struct_24byte))
+ (pcl))(e_dbl, f_dbl, g_dbl, h_dbl);
+ /* { dg-output "\n9 2 6 5 1 2 3 7 4 5 7 9 8 6 1 9: 22 15 17 25" } */
+ printf("res: %g %g %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+ /* { dg-output "\nres: 22 15 17 25" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_2byte.c b/libffi-3.0.4/testsuite/libffi.call/cls_2byte.c
new file mode 100644
index 0000000..5b91a09
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_2byte.c
@@ -0,0 +1,98 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Especially with small structures which may fit in one
+ register. Depending on the ABI.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_2byte {
+ unsigned char a;
+ unsigned char b;
+} cls_struct_2byte;
+
+cls_struct_2byte cls_struct_2byte_fn(struct cls_struct_2byte a1,
+ struct cls_struct_2byte a2)
+{
+ struct cls_struct_2byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+
+ printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
+
+ return result;
+}
+
+static void
+cls_struct_2byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_2byte a1, a2;
+
+ a1 = *(struct cls_struct_2byte*)(args[0]);
+ a2 = *(struct cls_struct_2byte*)(args[1]);
+
+ *(cls_struct_2byte*)resp = cls_struct_2byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_2byte g_dbl = { 12, 127 };
+ struct cls_struct_2byte f_dbl = { 1, 13 };
+ struct cls_struct_2byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_2byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 127 1 13: 13 140" } */
+ printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 13 140" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_2byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_2byte(*)(cls_struct_2byte, cls_struct_2byte))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n12 127 1 13: 13 140" } */
+ printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 13 140" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_3_1byte.c b/libffi-3.0.4/testsuite/libffi.call/cls_3_1byte.c
new file mode 100644
index 0000000..93fe911
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_3_1byte.c
@@ -0,0 +1,103 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Especially with small structures which may fit in one
+ register. Depending on the ABI.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030902 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_3_1byte {
+ unsigned char a;
+ unsigned char b;
+ unsigned char c;
+} cls_struct_3_1byte;
+
+cls_struct_3_1byte cls_struct_3_1byte_fn(struct cls_struct_3_1byte a1,
+ struct cls_struct_3_1byte a2)
+{
+ struct cls_struct_3_1byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+
+ printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c,
+ a2.a, a2.b, a2.c,
+ result.a, result.b, result.c);
+
+ return result;
+}
+
+static void
+cls_struct_3_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_3_1byte a1, a2;
+
+ a1 = *(struct cls_struct_3_1byte*)(args[0]);
+ a2 = *(struct cls_struct_3_1byte*)(args[1]);
+
+ *(cls_struct_3_1byte*)resp = cls_struct_3_1byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_3_1byte g_dbl = { 12, 13, 14 };
+ struct cls_struct_3_1byte f_dbl = { 178, 179, 180 };
+ struct cls_struct_3_1byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_3_1byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 13 14 178 179 180: 190 192 194" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 190 192 194" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_3_1byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_3_1byte(*)(cls_struct_3_1byte, cls_struct_3_1byte))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n12 13 14 178 179 180: 190 192 194" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 190 192 194" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_3byte1.c b/libffi-3.0.4/testsuite/libffi.call/cls_3byte1.c
new file mode 100644
index 0000000..b772691
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_3byte1.c
@@ -0,0 +1,98 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Especially with small structures which may fit in one
+ register. Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_3byte {
+ unsigned short a;
+ unsigned char b;
+} cls_struct_3byte;
+
+cls_struct_3byte cls_struct_3byte_fn(struct cls_struct_3byte a1,
+ struct cls_struct_3byte a2)
+{
+ struct cls_struct_3byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+
+ printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
+
+ return result;
+}
+
+static void
+cls_struct_3byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_3byte a1, a2;
+
+ a1 = *(struct cls_struct_3byte*)(args[0]);
+ a2 = *(struct cls_struct_3byte*)(args[1]);
+
+ *(cls_struct_3byte*)resp = cls_struct_3byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_3byte g_dbl = { 12, 119 };
+ struct cls_struct_3byte f_dbl = { 1, 15 };
+ struct cls_struct_3byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_ushort;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_3byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 119 1 15: 13 134" } */
+ printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 13 134" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_3byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_3byte(*)(cls_struct_3byte, cls_struct_3byte))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n12 119 1 15: 13 134" } */
+ printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 13 134" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_3byte2.c b/libffi-3.0.4/testsuite/libffi.call/cls_3byte2.c
new file mode 100644
index 0000000..51128cc
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_3byte2.c
@@ -0,0 +1,98 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Especially with small structures which may fit in one
+ register. Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_3byte_1 {
+ unsigned char a;
+ unsigned short b;
+} cls_struct_3byte_1;
+
+cls_struct_3byte_1 cls_struct_3byte_fn1(struct cls_struct_3byte_1 a1,
+ struct cls_struct_3byte_1 a2)
+{
+ struct cls_struct_3byte_1 result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+
+ printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
+
+ return result;
+}
+
+static void
+cls_struct_3byte_gn1(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_3byte_1 a1, a2;
+
+ a1 = *(struct cls_struct_3byte_1*)(args[0]);
+ a2 = *(struct cls_struct_3byte_1*)(args[1]);
+
+ *(cls_struct_3byte_1*)resp = cls_struct_3byte_fn1(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_3byte_1 g_dbl = { 15, 125 };
+ struct cls_struct_3byte_1 f_dbl = { 9, 19 };
+ struct cls_struct_3byte_1 res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_ushort;
+ cls_struct_fields[2] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_3byte_fn1), &res_dbl, args_dbl);
+ /* { dg-output "15 125 9 19: 24 144" } */
+ printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 24 144" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_3byte_gn1, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_3byte_1(*)(cls_struct_3byte_1, cls_struct_3byte_1))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n15 125 9 19: 24 144" } */
+ printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 24 144" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_4_1byte.c b/libffi-3.0.4/testsuite/libffi.call/cls_4_1byte.c
new file mode 100644
index 0000000..a378d19
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_4_1byte.c
@@ -0,0 +1,106 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Especially with small structures which may fit in one
+ register. Depending on the ABI.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030902 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_4_1byte {
+ unsigned char a;
+ unsigned char b;
+ unsigned char c;
+ unsigned char d;
+} cls_struct_4_1byte;
+
+cls_struct_4_1byte cls_struct_4_1byte_fn(struct cls_struct_4_1byte a1,
+ struct cls_struct_4_1byte a2)
+{
+ struct cls_struct_4_1byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+ result.d = a1.d + a2.d;
+
+ printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d,
+ a2.a, a2.b, a2.c, a2.d,
+ result.a, result.b, result.c, result.d);
+
+ return result;
+}
+
+static void
+cls_struct_4_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_4_1byte a1, a2;
+
+ a1 = *(struct cls_struct_4_1byte*)(args[0]);
+ a2 = *(struct cls_struct_4_1byte*)(args[1]);
+
+ *(cls_struct_4_1byte*)resp = cls_struct_4_1byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[5];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_4_1byte g_dbl = { 12, 13, 14, 15 };
+ struct cls_struct_4_1byte f_dbl = { 178, 179, 180, 181 };
+ struct cls_struct_4_1byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = &ffi_type_uchar;
+ cls_struct_fields[4] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_4_1byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 13 14 15 178 179 180 181: 190 192 194 196" } */
+ printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+ /* { dg-output "\nres: 190 192 194 196" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_4_1byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_4_1byte(*)(cls_struct_4_1byte, cls_struct_4_1byte))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n12 13 14 15 178 179 180 181: 190 192 194 196" } */
+ printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+ /* { dg-output "\nres: 190 192 194 196" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_4byte.c b/libffi-3.0.4/testsuite/libffi.call/cls_4byte.c
new file mode 100644
index 0000000..b2c951d
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_4byte.c
@@ -0,0 +1,98 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+typedef struct cls_struct_4byte {
+ unsigned short a;
+ unsigned short b;
+} cls_struct_4byte;
+
+cls_struct_4byte cls_struct_4byte_fn(struct cls_struct_4byte a1,
+ struct cls_struct_4byte a2)
+{
+ struct cls_struct_4byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+
+ printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
+
+ return result;
+}
+
+static void
+cls_struct_4byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_4byte a1, a2;
+
+ a1 = *(struct cls_struct_4byte*)(args[0]);
+ a2 = *(struct cls_struct_4byte*)(args[1]);
+
+ *(cls_struct_4byte*)resp = cls_struct_4byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_4byte g_dbl = { 127, 120 };
+ struct cls_struct_4byte f_dbl = { 12, 128 };
+ struct cls_struct_4byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_ushort;
+ cls_struct_fields[1] = &ffi_type_ushort;
+ cls_struct_fields[2] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_4byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "127 120 12 128: 139 248" } */
+ printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 139 248" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_4byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_4byte(*)(cls_struct_4byte, cls_struct_4byte))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n127 120 12 128: 139 248" } */
+ printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 139 248" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_5_1_byte.c b/libffi-3.0.4/testsuite/libffi.call/cls_5_1_byte.c
new file mode 100644
index 0000000..40d2e64
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_5_1_byte.c
@@ -0,0 +1,117 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20050708 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_5byte {
+ unsigned char a;
+ unsigned char b;
+ unsigned char c;
+ unsigned char d;
+ unsigned char e;
+} cls_struct_5byte;
+
+cls_struct_5byte cls_struct_5byte_fn(struct cls_struct_5byte a1,
+ struct cls_struct_5byte a2)
+{
+ struct cls_struct_5byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+ result.d = a1.d + a2.d;
+ result.e = a1.e + a2.e;
+
+ printf("%d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d\n",
+ a1.a, a1.b, a1.c, a1.d, a1.e,
+ a2.a, a2.b, a2.c, a2.d, a2.e,
+ result.a, result.b, result.c, result.d, result.e);
+
+ return result;
+}
+
+static void
+cls_struct_5byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_5byte a1, a2;
+
+ a1 = *(struct cls_struct_5byte*)(args[0]);
+ a2 = *(struct cls_struct_5byte*)(args[1]);
+
+ *(cls_struct_5byte*)resp = cls_struct_5byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[6];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_5byte g_dbl = { 127, 120, 1, 3, 4 };
+ struct cls_struct_5byte f_dbl = { 12, 128, 9, 3, 4 };
+ struct cls_struct_5byte res_dbl = { 0, 0, 0, 0, 0 };
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = &ffi_type_uchar;
+ cls_struct_fields[4] = &ffi_type_uchar;
+ cls_struct_fields[5] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_5byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "127 120 1 3 4 12 128 9 3 4: 139 248 10 6 8" } */
+ printf("res: %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e);
+ /* { dg-output "\nres: 139 248 10 6 8" } */
+
+ res_dbl.a = 0;
+ res_dbl.b = 0;
+ res_dbl.c = 0;
+ res_dbl.d = 0;
+ res_dbl.e = 0;
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_5byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_5byte(*)(cls_struct_5byte, cls_struct_5byte))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n127 120 1 3 4 12 128 9 3 4: 139 248 10 6 8" } */
+ printf("res: %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e);
+ /* { dg-output "\nres: 139 248 10 6 8" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_5byte.c b/libffi-3.0.4/testsuite/libffi.call/cls_5byte.c
new file mode 100644
index 0000000..0307e51
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_5byte.c
@@ -0,0 +1,106 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_5byte {
+ unsigned short a;
+ unsigned short b;
+ unsigned char c;
+} cls_struct_5byte;
+
+cls_struct_5byte cls_struct_5byte_fn(struct cls_struct_5byte a1,
+ struct cls_struct_5byte a2)
+{
+ struct cls_struct_5byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+
+ printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c,
+ a2.a, a2.b, a2.c,
+ result.a, result.b, result.c);
+
+ return result;
+}
+
+static void
+cls_struct_5byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_5byte a1, a2;
+
+ a1 = *(struct cls_struct_5byte*)(args[0]);
+ a2 = *(struct cls_struct_5byte*)(args[1]);
+
+ *(cls_struct_5byte*)resp = cls_struct_5byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_5byte g_dbl = { 127, 120, 1 };
+ struct cls_struct_5byte f_dbl = { 12, 128, 9 };
+ struct cls_struct_5byte res_dbl = { 0, 0, 0 };
+
+ cls_struct_fields[0] = &ffi_type_ushort;
+ cls_struct_fields[1] = &ffi_type_ushort;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_5byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "127 120 1 12 128 9: 139 248 10" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 139 248 10" } */
+
+ res_dbl.a = 0;
+ res_dbl.b = 0;
+ res_dbl.c = 0;
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_5byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_5byte(*)(cls_struct_5byte, cls_struct_5byte))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n127 120 1 12 128 9: 139 248 10" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 139 248 10" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_64byte.c b/libffi-3.0.4/testsuite/libffi.call/cls_64byte.c
new file mode 100644
index 0000000..1329c6f
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_64byte.c
@@ -0,0 +1,132 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing 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: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_64byte {
+ double a;
+ double b;
+ double c;
+ double d;
+ double e;
+ double f;
+ double g;
+ double h;
+} cls_struct_64byte;
+
+cls_struct_64byte cls_struct_64byte_fn(struct cls_struct_64byte b0,
+ struct cls_struct_64byte b1,
+ struct cls_struct_64byte b2,
+ struct cls_struct_64byte b3)
+{
+ struct cls_struct_64byte 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;
+
+ printf("%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);
+
+ return result;
+}
+
+static void
+cls_struct_64byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct cls_struct_64byte b0, b1, b2, b3;
+
+ b0 = *(struct cls_struct_64byte*)(args[0]);
+ b1 = *(struct cls_struct_64byte*)(args[1]);
+ b2 = *(struct cls_struct_64byte*)(args[2]);
+ b3 = *(struct cls_struct_64byte*)(args[3]);
+
+ *(cls_struct_64byte*)resp = cls_struct_64byte_fn(b0, b1, b2, b3);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[9];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_64byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0 };
+ struct cls_struct_64byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0 };
+ struct cls_struct_64byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0 };
+ struct cls_struct_64byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0 };
+ struct cls_struct_64byte res_dbl;
+
+ 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] = 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_64byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "22 15 17 25 6 13 19 18" } */
+ printf("res: %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);
+ /* { dg-output "\nres: 22 15 17 25 6 13 19 18" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_64byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_64byte(*)(cls_struct_64byte,
+ cls_struct_64byte,
+ cls_struct_64byte,
+ cls_struct_64byte))
+ (pcl))(e_dbl, f_dbl, g_dbl, h_dbl);
+ /* { dg-output "\n22 15 17 25 6 13 19 18" } */
+ printf("res: %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);
+ /* { dg-output "\nres: 22 15 17 25 6 13 19 18" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_6_1_byte.c b/libffi-3.0.4/testsuite/libffi.call/cls_6_1_byte.c
new file mode 100644
index 0000000..7ddb586
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_6_1_byte.c
@@ -0,0 +1,121 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20050708 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_6byte {
+ unsigned char a;
+ unsigned char b;
+ unsigned char c;
+ unsigned char d;
+ unsigned char e;
+ unsigned char f;
+} cls_struct_6byte;
+
+cls_struct_6byte cls_struct_6byte_fn(struct cls_struct_6byte a1,
+ struct cls_struct_6byte a2)
+{
+ struct cls_struct_6byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+ result.d = a1.d + a2.d;
+ result.e = a1.e + a2.e;
+ result.f = a1.f + a2.f;
+
+ printf("%d %d %d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d %d\n",
+ a1.a, a1.b, a1.c, a1.d, a1.e, a1.f,
+ a2.a, a2.b, a2.c, a2.d, a2.e, a2.f,
+ result.a, result.b, result.c, result.d, result.e, result.f);
+
+ return result;
+}
+
+static void
+cls_struct_6byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_6byte a1, a2;
+
+ a1 = *(struct cls_struct_6byte*)(args[0]);
+ a2 = *(struct cls_struct_6byte*)(args[1]);
+
+ *(cls_struct_6byte*)resp = cls_struct_6byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[7];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_6byte g_dbl = { 127, 120, 1, 3, 4, 5 };
+ struct cls_struct_6byte f_dbl = { 12, 128, 9, 3, 4, 5 };
+ struct cls_struct_6byte res_dbl = { 0, 0, 0, 0, 0, 0 };
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = &ffi_type_uchar;
+ cls_struct_fields[4] = &ffi_type_uchar;
+ cls_struct_fields[5] = &ffi_type_uchar;
+ cls_struct_fields[6] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_6byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "127 120 1 3 4 5 12 128 9 3 4 5: 139 248 10 6 8 10" } */
+ printf("res: %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e, res_dbl.f);
+ /* { dg-output "\nres: 139 248 10 6 8 10" } */
+
+ res_dbl.a = 0;
+ res_dbl.b = 0;
+ res_dbl.c = 0;
+ res_dbl.d = 0;
+ res_dbl.e = 0;
+ res_dbl.f = 0;
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_6byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_6byte(*)(cls_struct_6byte, cls_struct_6byte))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n127 120 1 3 4 5 12 128 9 3 4 5: 139 248 10 6 8 10" } */
+ printf("res: %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e, res_dbl.f);
+ /* { dg-output "\nres: 139 248 10 6 8 10" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_6byte.c b/libffi-3.0.4/testsuite/libffi.call/cls_6byte.c
new file mode 100644
index 0000000..24fd63b
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_6byte.c
@@ -0,0 +1,107 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_6byte {
+ unsigned short a;
+ unsigned short b;
+ unsigned char c;
+ unsigned char d;
+} cls_struct_6byte;
+
+cls_struct_6byte cls_struct_6byte_fn(struct cls_struct_6byte a1,
+ struct cls_struct_6byte a2)
+{
+ struct cls_struct_6byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+ result.d = a1.d + a2.d;
+
+ printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d,
+ a2.a, a2.b, a2.c, a2.d,
+ result.a, result.b, result.c, result.d);
+
+ return result;
+}
+
+static void
+cls_struct_6byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_6byte a1, a2;
+
+ a1 = *(struct cls_struct_6byte*)(args[0]);
+ a2 = *(struct cls_struct_6byte*)(args[1]);
+
+ *(cls_struct_6byte*)resp = cls_struct_6byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[5];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_6byte g_dbl = { 127, 120, 1, 128 };
+ struct cls_struct_6byte f_dbl = { 12, 128, 9, 127 };
+ struct cls_struct_6byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_ushort;
+ cls_struct_fields[1] = &ffi_type_ushort;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = &ffi_type_uchar;
+ cls_struct_fields[4] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_6byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "127 120 1 128 12 128 9 127: 139 248 10 255" } */
+ printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+ /* { dg-output "\nres: 139 248 10 255" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_6byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_6byte(*)(cls_struct_6byte, cls_struct_6byte))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n127 120 1 128 12 128 9 127: 139 248 10 255" } */
+ printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+ /* { dg-output "\nres: 139 248 10 255" } */
+
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_7_1_byte.c b/libffi-3.0.4/testsuite/libffi.call/cls_7_1_byte.c
new file mode 100644
index 0000000..0cf1371
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_7_1_byte.c
@@ -0,0 +1,125 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20050708 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_7byte {
+ unsigned char a;
+ unsigned char b;
+ unsigned char c;
+ unsigned char d;
+ unsigned char e;
+ unsigned char f;
+ unsigned char g;
+} cls_struct_7byte;
+
+cls_struct_7byte cls_struct_7byte_fn(struct cls_struct_7byte a1,
+ struct cls_struct_7byte a2)
+{
+ struct cls_struct_7byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+ result.d = a1.d + a2.d;
+ result.e = a1.e + a2.e;
+ result.f = a1.f + a2.f;
+ result.g = a1.g + a2.g;
+
+ printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d %d %d\n",
+ a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
+ a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g,
+ result.a, result.b, result.c, result.d, result.e, result.f, result.g);
+
+ return result;
+}
+
+static void
+cls_struct_7byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_7byte a1, a2;
+
+ a1 = *(struct cls_struct_7byte*)(args[0]);
+ a2 = *(struct cls_struct_7byte*)(args[1]);
+
+ *(cls_struct_7byte*)resp = cls_struct_7byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[8];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_7byte g_dbl = { 127, 120, 1, 3, 4, 5, 6 };
+ struct cls_struct_7byte f_dbl = { 12, 128, 9, 3, 4, 5, 6 };
+ struct cls_struct_7byte res_dbl = { 0, 0, 0, 0, 0, 0, 0 };
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_uchar;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = &ffi_type_uchar;
+ cls_struct_fields[4] = &ffi_type_uchar;
+ cls_struct_fields[5] = &ffi_type_uchar;
+ cls_struct_fields[6] = &ffi_type_uchar;
+ cls_struct_fields[7] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_7byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "127 120 1 3 4 5 6 12 128 9 3 4 5 6: 139 248 10 6 8 10 12" } */
+ printf("res: %d %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
+ /* { dg-output "\nres: 139 248 10 6 8 10 12" } */
+
+ res_dbl.a = 0;
+ res_dbl.b = 0;
+ res_dbl.c = 0;
+ res_dbl.d = 0;
+ res_dbl.e = 0;
+ res_dbl.f = 0;
+ res_dbl.g = 0;
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_7byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_7byte(*)(cls_struct_7byte, cls_struct_7byte))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n127 120 1 3 4 5 6 12 128 9 3 4 5 6: 139 248 10 6 8 10 12" } */
+ printf("res: %d %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
+ /* { dg-output "\nres: 139 248 10 6 8 10 12" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_7byte.c b/libffi-3.0.4/testsuite/libffi.call/cls_7byte.c
new file mode 100644
index 0000000..7785862
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_7byte.c
@@ -0,0 +1,105 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_7byte {
+ unsigned short a;
+ unsigned short b;
+ unsigned char c;
+ unsigned short d;
+} cls_struct_7byte;
+
+cls_struct_7byte cls_struct_7byte_fn(struct cls_struct_7byte a1,
+ struct cls_struct_7byte a2)
+{
+ struct cls_struct_7byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+ result.c = a1.c + a2.c;
+ result.d = a1.d + a2.d;
+
+ printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d,
+ a2.a, a2.b, a2.c, a2.d,
+ result.a, result.b, result.c, result.d);
+
+ return result;
+}
+
+static void
+cls_struct_7byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_7byte a1, a2;
+
+ a1 = *(struct cls_struct_7byte*)(args[0]);
+ a2 = *(struct cls_struct_7byte*)(args[1]);
+
+ *(cls_struct_7byte*)resp = cls_struct_7byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[5];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_7byte g_dbl = { 127, 120, 1, 254 };
+ struct cls_struct_7byte f_dbl = { 12, 128, 9, 255 };
+ struct cls_struct_7byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_ushort;
+ cls_struct_fields[1] = &ffi_type_ushort;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = &ffi_type_ushort;
+ cls_struct_fields[4] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_7byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "127 120 1 254 12 128 9 255: 139 248 10 509" } */
+ printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+ /* { dg-output "\nres: 139 248 10 509" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_7byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_7byte(*)(cls_struct_7byte, cls_struct_7byte))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n127 120 1 254 12 128 9 255: 139 248 10 509" } */
+ printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+ /* { dg-output "\nres: 139 248 10 509" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_8byte.c b/libffi-3.0.4/testsuite/libffi.call/cls_8byte.c
new file mode 100644
index 0000000..75326b8
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_8byte.c
@@ -0,0 +1,96 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Check overlapping.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_8byte {
+ int a;
+ float b;
+} cls_struct_8byte;
+
+cls_struct_8byte cls_struct_8byte_fn(struct cls_struct_8byte a1,
+ struct cls_struct_8byte a2)
+{
+ struct cls_struct_8byte result;
+
+ result.a = a1.a + a2.a;
+ result.b = a1.b + a2.b;
+
+ printf("%d %g %d %g: %d %g\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
+
+ return result;
+}
+
+static void
+cls_struct_8byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+
+ struct cls_struct_8byte a1, a2;
+
+ a1 = *(struct cls_struct_8byte*)(args[0]);
+ a2 = *(struct cls_struct_8byte*)(args[1]);
+
+ *(cls_struct_8byte*)resp = cls_struct_8byte_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_8byte g_dbl = { 1, 2.0 };
+ struct cls_struct_8byte f_dbl = { 4, 5.0 };
+ struct cls_struct_8byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_sint;
+ cls_struct_fields[1] = &ffi_type_float;
+ cls_struct_fields[2] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_8byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 2 4 5: 5 7" } */
+ printf("res: %d %g\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 5 7" } */
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_8byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_8byte(*)(cls_struct_8byte, cls_struct_8byte))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n1 2 4 5: 5 7" } */
+ printf("res: %d %g\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 5 7" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_9byte1.c b/libffi-3.0.4/testsuite/libffi.call/cls_9byte1.c
new file mode 100644
index 0000000..0b3de9d
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_9byte1.c
@@ -0,0 +1,98 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Darwin/AIX do double-word
+ alignment of the struct if the first element is a double.
+ Check that it does not here.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030914 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_9byte {
+ int a;
+ double b;
+} cls_struct_9byte;
+
+cls_struct_9byte cls_struct_9byte_fn(struct cls_struct_9byte b1,
+ struct cls_struct_9byte b2)
+{
+ struct cls_struct_9byte result;
+
+ result.a = b1.a + b2.a;
+ result.b = b1.b + b2.b;
+
+ printf("%d %g %d %g: %d %g\n", b1.a, b1.b, b2.a, b2.b,
+ result.a, result.b);
+
+ return result;
+}
+
+static void cls_struct_9byte_gn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+{
+ struct cls_struct_9byte b1, b2;
+
+ b1 = *(struct cls_struct_9byte*)(args[0]);
+ b2 = *(struct cls_struct_9byte*)(args[1]);
+
+ *(cls_struct_9byte*)resp = cls_struct_9byte_fn(b1, b2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[3];
+ ffi_type* cls_struct_fields[3];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[3];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_9byte h_dbl = { 7, 8.0};
+ struct cls_struct_9byte j_dbl = { 1, 9.0};
+ struct cls_struct_9byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_sint;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &h_dbl;
+ args_dbl[1] = &j_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_9byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "7 8 1 9: 8 17" } */
+ printf("res: %d %g\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 8 17" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_9byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_9byte(*)(cls_struct_9byte, cls_struct_9byte))(pcl))(h_dbl, j_dbl);
+ /* { dg-output "\n7 8 1 9: 8 17" } */
+ printf("res: %d %g\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 8 17" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_9byte2.c b/libffi-3.0.4/testsuite/libffi.call/cls_9byte2.c
new file mode 100644
index 0000000..8cafc8a
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_9byte2.c
@@ -0,0 +1,99 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing with different structure size.
+ Depending on the ABI. Darwin/AIX do double-word
+ alignment of the struct if the first element is a double.
+ Check that it does here.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030914 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_9byte {
+ double a;
+ int b;
+} cls_struct_9byte;
+
+cls_struct_9byte cls_struct_9byte_fn(struct cls_struct_9byte b1,
+ struct cls_struct_9byte b2)
+{
+ struct cls_struct_9byte result;
+
+ result.a = b1.a + b2.a;
+ result.b = b1.b + b2.b;
+
+ printf("%g %d %g %d: %g %d\n", b1.a, b1.b, b2.a, b2.b,
+ result.a, result.b);
+
+ return result;
+}
+
+static void cls_struct_9byte_gn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+{
+ struct cls_struct_9byte b1, b2;
+
+ b1 = *(struct cls_struct_9byte*)(args[0]);
+ b2 = *(struct cls_struct_9byte*)(args[1]);
+
+ *(cls_struct_9byte*)resp = cls_struct_9byte_fn(b1, b2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[3];
+ ffi_type* cls_struct_fields[3];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[3];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_9byte h_dbl = { 7.0, 8};
+ struct cls_struct_9byte j_dbl = { 1.0, 9};
+ struct cls_struct_9byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_sint;
+ cls_struct_fields[2] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &h_dbl;
+ args_dbl[1] = &j_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_9byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "7 8 1 9: 8 17" } */
+ printf("res: %g %d\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 8 17" } */
+
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_9byte_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_9byte(*)(cls_struct_9byte, cls_struct_9byte))(pcl))(h_dbl, j_dbl);
+ /* { dg-output "\n7 8 1 9: 8 17" } */
+ printf("res: %g %d\n", res_dbl.a, res_dbl.b);
+ /* { dg-output "\nres: 8 17" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_align_double.c b/libffi-3.0.4/testsuite/libffi.call/cls_align_double.c
new file mode 100644
index 0000000..5ba2301
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_align_double.c
@@ -0,0 +1,101 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of double.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ double 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 %g %d %d %g %d: %d %g %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, 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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_align g_dbl = { 12, 4951, 127 };
+ struct cls_struct_align f_dbl = { 1, 9320, 13 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_align_float.c b/libffi-3.0.4/testsuite/libffi.call/cls_align_float.c
new file mode 100644
index 0000000..996e1ab
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_align_float.c
@@ -0,0 +1,99 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of float.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ float 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 %g %d %d %g %d: %d %g %d\n", a1.a, (double)a1.b, a1.c, a2.a, (double)a2.b, a2.c, result.a, (double)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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_align g_dbl = { 12, 4951, 127 };
+ struct cls_struct_align f_dbl = { 1, 9320, 13 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_float;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_align_longdouble.c b/libffi-3.0.4/testsuite/libffi.call/cls_align_longdouble.c
new file mode 100644
index 0000000..cb60395
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_align_longdouble.c
@@ -0,0 +1,100 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of long double.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ long double 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 %g %d %d %g %d: %d %g %d\n", a1.a, (double)a1.b, a1.c, a2.a, (double)a2.b, a2.c, result.a, (double)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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_align g_dbl = { 12, 4951, 127 };
+ struct cls_struct_align f_dbl = { 1, 9320, 13 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_longdouble;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_align_pointer.c b/libffi-3.0.4/testsuite/libffi.call/cls_align_pointer.c
new file mode 100644
index 0000000..441edcb
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_align_pointer.c
@@ -0,0 +1,101 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of pointer.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ void *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 = (void *)((unsigned long)a1.b + (unsigned long)a2.b);
+ result.c = a1.c + a2.c;
+
+ printf("%d %lu %d %d %lu %d: %d %lu %d\n", a1.a, (unsigned long)a1.b, a1.c,
+ a2.a, (unsigned long)a2.b, a2.c, result.a, (unsigned long)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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_align g_dbl = { 12, (void *)4951, 127 };
+ struct cls_struct_align f_dbl = { 1, (void *)9320, 13 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_pointer;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %lu %d\n", res_dbl.a, (unsigned long)res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %lu %d\n", res_dbl.a, (unsigned long)res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_align_sint16.c b/libffi-3.0.4/testsuite/libffi.call/cls_align_sint16.c
new file mode 100644
index 0000000..fe4fe09
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_align_sint16.c
@@ -0,0 +1,99 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of sint16.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ signed short 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 %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, 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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_align g_dbl = { 12, 4951, 127 };
+ struct cls_struct_align f_dbl = { 1, 9320, 13 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_sshort;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_align_sint32.c b/libffi-3.0.4/testsuite/libffi.call/cls_align_sint32.c
new file mode 100644
index 0000000..c059da8
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_align_sint32.c
@@ -0,0 +1,99 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of sint32.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ signed int 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 %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, 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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_align g_dbl = { 12, 4951, 127 };
+ struct cls_struct_align f_dbl = { 1, 9320, 13 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_sint;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_align_sint64.c b/libffi-3.0.4/testsuite/libffi.call/cls_align_sint64.c
new file mode 100644
index 0000000..f5e9746
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_align_sint64.c
@@ -0,0 +1,99 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of sint64.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ signed long long 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 %lld %d %d %lld %d: %d %lld %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, 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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_align g_dbl = { 12, 4951, 127 };
+ struct cls_struct_align f_dbl = { 1, 9320, 13 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_sint64;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %lld %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %lld %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_align_uint16.c b/libffi-3.0.4/testsuite/libffi.call/cls_align_uint16.c
new file mode 100644
index 0000000..c861bee
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_align_uint16.c
@@ -0,0 +1,99 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of uint16.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ unsigned short 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 %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, 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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_align g_dbl = { 12, 4951, 127 };
+ struct cls_struct_align f_dbl = { 1, 9320, 13 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_ushort;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_align_uint32.c b/libffi-3.0.4/testsuite/libffi.call/cls_align_uint32.c
new file mode 100644
index 0000000..d680d8a
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_align_uint32.c
@@ -0,0 +1,99 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of uint32.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ unsigned int 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 %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, 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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_align g_dbl = { 12, 4951, 127 };
+ struct cls_struct_align f_dbl = { 1, 9320, 13 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_uint;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_align_uint64.c b/libffi-3.0.4/testsuite/libffi.call/cls_align_uint64.c
new file mode 100644
index 0000000..0737ba2
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_align_uint64.c
@@ -0,0 +1,100 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of uint64.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ unsigned char a;
+ unsigned long long 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 %lld %d %d %lld %d: %d %lld %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, 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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[4];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_align g_dbl = { 12, 4951, 127 };
+ struct cls_struct_align f_dbl = { 1, 9320, 13 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_uchar;
+ cls_struct_fields[1] = &ffi_type_uint64;
+ cls_struct_fields[2] = &ffi_type_uchar;
+ cls_struct_fields[3] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %lld %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
+ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+ printf("res: %d %lld %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ /* { dg-output "\nres: 13 14271 140" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_double.c b/libffi-3.0.4/testsuite/libffi.call/cls_double.c
new file mode 100644
index 0000000..ee77add
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_double.c
@@ -0,0 +1,51 @@
+/* Area: closure_call
+ Purpose: Check return value double.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+ {
+ *(double *)resp = *(double *)args[0];
+
+ printf("%f: %f\n",*(double *)args[0],
+ *(double *)resp);
+ }
+typedef double (*cls_ret_double)(double);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ ffi_type * cl_arg_types[2];
+ double res;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cl_arg_types[0] = &ffi_type_double;
+ cl_arg_types[1] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_double, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_ret_double_fn, NULL) == FFI_OK);
+
+ res = (*((cls_ret_double)pcl))(21474.789);
+ /* { dg-output "21474.789000: 21474.789000" } */
+ printf("res: %.6f\n", res);
+ /* { dg-output "\nres: 21474.789000" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_float.c b/libffi-3.0.4/testsuite/libffi.call/cls_float.c
new file mode 100644
index 0000000..8bed628
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_float.c
@@ -0,0 +1,51 @@
+/* Area: closure_call
+ Purpose: Check return value float.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_float_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+ {
+ *(float *)resp = *(float *)args[0];
+
+ printf("%g: %g\n",*(float *)args[0],
+ *(float *)resp);
+ }
+
+typedef float (*cls_ret_float)(float);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ ffi_type * cl_arg_types[2];
+ float res;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+
+ cl_arg_types[0] = &ffi_type_float;
+ cl_arg_types[1] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_float, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_ret_float_fn, NULL) == FFI_OK);
+ res = ((((cls_ret_float)pcl)(-2122.12)));
+ /* { dg-output "\\-2122.12: \\-2122.12" } */
+ printf("res: %.6f\n", res);
+ /* { dg-output "\nres: \-2122.120117" } */
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_multi_schar.c b/libffi-3.0.4/testsuite/libffi.call/cls_multi_schar.c
new file mode 100644
index 0000000..713c318
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_multi_schar.c
@@ -0,0 +1,82 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check passing of multiple signed char values.
+ Limitations: none.
+ PR: PR13221.
+ Originator: <hos@tamanegi.org> 20031129 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+signed char test_func_fn(signed char a1, signed char a2)
+{
+ signed char result;
+
+ result = a1 + a2;
+
+ printf("%d %d: %d\n", a1, a2, result);
+
+ return result;
+
+}
+
+static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
+ void *data __UNUSED__)
+{
+ signed char a1, a2;
+
+ a1 = *(signed char *)avals[0];
+ a2 = *(signed char *)avals[1];
+
+ *(ffi_arg *)rval = test_func_fn(a1, a2);
+
+}
+
+typedef signed char (*test_type)(signed char, signed char);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void * args_dbl[3];
+ ffi_type * cl_arg_types[3];
+ ffi_arg res_call;
+ signed char a, b, res_closure;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ a = 2;
+ b = 125;
+
+ args_dbl[0] = &a;
+ args_dbl[1] = &b;
+ args_dbl[2] = NULL;
+
+ cl_arg_types[0] = &ffi_type_schar;
+ cl_arg_types[1] = &ffi_type_schar;
+ cl_arg_types[2] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
+ &ffi_type_schar, cl_arg_types) == FFI_OK);
+
+ ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
+ /* { dg-output "2 125: 127" } */
+ printf("res: %d\n", (signed char)res_call);
+ /* { dg-output "\nres: 127" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK);
+
+ res_closure = (*((test_type)pcl))(2, 125);
+ /* { dg-output "\n2 125: 127" } */
+ printf("res: %d\n", res_closure);
+ /* { dg-output "\nres: 127" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_multi_sshort.c b/libffi-3.0.4/testsuite/libffi.call/cls_multi_sshort.c
new file mode 100644
index 0000000..852fdf7
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_multi_sshort.c
@@ -0,0 +1,82 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check passing of multiple signed short values.
+ Limitations: none.
+ PR: PR13221.
+ Originator: <andreast@gcc.gnu.org> 20031129 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+signed short test_func_fn(signed short a1, signed short a2)
+{
+ signed short result;
+
+ result = a1 + a2;
+
+ printf("%d %d: %d\n", a1, a2, result);
+
+ return result;
+
+}
+
+static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
+ void *data __UNUSED__)
+{
+ signed short a1, a2;
+
+ a1 = *(signed short *)avals[0];
+ a2 = *(signed short *)avals[1];
+
+ *(ffi_arg *)rval = test_func_fn(a1, a2);
+
+}
+
+typedef signed short (*test_type)(signed short, signed short);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void * args_dbl[3];
+ ffi_type * cl_arg_types[3];
+ ffi_arg res_call;
+ unsigned short a, b, res_closure;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ a = 2;
+ b = 32765;
+
+ args_dbl[0] = &a;
+ args_dbl[1] = &b;
+ args_dbl[2] = NULL;
+
+ cl_arg_types[0] = &ffi_type_sshort;
+ cl_arg_types[1] = &ffi_type_sshort;
+ cl_arg_types[2] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
+ &ffi_type_sshort, cl_arg_types) == FFI_OK);
+
+ ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
+ /* { dg-output "2 32765: 32767" } */
+ printf("res: %d\n", (unsigned short)res_call);
+ /* { dg-output "\nres: 32767" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK);
+
+ res_closure = (*((test_type)pcl))(2, 32765);
+ /* { dg-output "\n2 32765: 32767" } */
+ printf("res: %d\n", res_closure);
+ /* { dg-output "\nres: 32767" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_multi_sshortchar.c b/libffi-3.0.4/testsuite/libffi.call/cls_multi_sshortchar.c
new file mode 100644
index 0000000..e4e92ef
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_multi_sshortchar.c
@@ -0,0 +1,94 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check passing of multiple signed short/char values.
+ Limitations: none.
+ PR: PR13221.
+ Originator: <andreast@gcc.gnu.org> 20031129 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+signed short test_func_fn(signed char a1, signed short a2,
+ signed char a3, signed short a4)
+{
+ signed short result;
+
+ result = a1 + a2 + a3 + a4;
+
+ printf("%d %d %d %d: %d\n", a1, a2, a3, a4, result);
+
+ return result;
+
+}
+
+static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
+ void *data __UNUSED__)
+{
+ signed char a1, a3;
+ signed short a2, a4;
+
+ a1 = *(signed char *)avals[0];
+ a2 = *(signed short *)avals[1];
+ a3 = *(signed char *)avals[2];
+ a4 = *(signed short *)avals[3];
+
+ *(ffi_arg *)rval = test_func_fn(a1, a2, a3, a4);
+
+}
+
+typedef signed short (*test_type)(signed char, signed short,
+ signed char, signed short);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void * args_dbl[5];
+ ffi_type * cl_arg_types[5];
+ ffi_arg res_call;
+ signed char a, c;
+ signed short b, d, res_closure;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ a = 1;
+ b = 32765;
+ c = 127;
+ d = -128;
+
+ args_dbl[0] = &a;
+ args_dbl[1] = &b;
+ args_dbl[2] = &c;
+ args_dbl[3] = &d;
+ args_dbl[4] = NULL;
+
+ cl_arg_types[0] = &ffi_type_schar;
+ cl_arg_types[1] = &ffi_type_sshort;
+ cl_arg_types[2] = &ffi_type_schar;
+ cl_arg_types[3] = &ffi_type_sshort;
+ cl_arg_types[4] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &ffi_type_sshort, cl_arg_types) == FFI_OK);
+
+ ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
+ /* { dg-output "1 32765 127 -128: 32765" } */
+ printf("res: %d\n", (signed short)res_call);
+ /* { dg-output "\nres: 32765" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK);
+
+ res_closure = (*((test_type)pcl))(1, 32765, 127, -128);
+ /* { dg-output "\n1 32765 127 -128: 32765" } */
+ printf("res: %d\n", res_closure);
+ /* { dg-output "\nres: 32765" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_multi_uchar.c b/libffi-3.0.4/testsuite/libffi.call/cls_multi_uchar.c
new file mode 100644
index 0000000..2c84aef
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_multi_uchar.c
@@ -0,0 +1,99 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check passing of multiple unsigned char values.
+ Limitations: none.
+ PR: PR13221.
+ Originator: <andreast@gcc.gnu.org> 20031129 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+unsigned char test_func_fn(unsigned char a1, unsigned char a2,
+ unsigned char a3, unsigned char a4)
+{
+ unsigned char result;
+
+ result = a1 + a2 + a3 + a4;
+
+ printf("%d %d %d %d: %d\n", a1, a2, a3, a4, result);
+
+ return result;
+
+}
+
+static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
+ void *data __UNUSED__)
+{
+ unsigned char a1, a2, a3, a4;
+
+ a1 = *(unsigned char *)avals[0];
+ a2 = *(unsigned char *)avals[1];
+ a3 = *(unsigned char *)avals[2];
+ a4 = *(unsigned char *)avals[3];
+
+ *(ffi_arg *)rval = test_func_fn(a1, a2, a3, a4);
+
+}
+
+typedef unsigned char (*test_type)(unsigned char, unsigned char,
+ unsigned char, unsigned char);
+
+void test_func(ffi_cif *cif __UNUSED__, void *rval __UNUSED__, void **avals,
+ void *data __UNUSED__)
+{
+ printf("%d %d %d %d\n", *(unsigned char *)avals[0],
+ *(unsigned char *)avals[1], *(unsigned char *)avals[2],
+ *(unsigned char *)avals[3]);
+}
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void * args_dbl[5];
+ ffi_type * cl_arg_types[5];
+ ffi_arg res_call;
+ unsigned char a, b, c, d, res_closure;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ a = 1;
+ b = 2;
+ c = 127;
+ d = 125;
+
+ args_dbl[0] = &a;
+ args_dbl[1] = &b;
+ args_dbl[2] = &c;
+ args_dbl[3] = &d;
+ args_dbl[4] = NULL;
+
+ cl_arg_types[0] = &ffi_type_uchar;
+ cl_arg_types[1] = &ffi_type_uchar;
+ cl_arg_types[2] = &ffi_type_uchar;
+ cl_arg_types[3] = &ffi_type_uchar;
+ cl_arg_types[4] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &ffi_type_uchar, cl_arg_types) == FFI_OK);
+
+ ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
+ /* { dg-output "1 2 127 125: 255" } */
+ printf("res: %d\n", (unsigned char)res_call);
+ /* { dg-output "\nres: 255" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK);
+
+ res_closure = (*((test_type)pcl))(1, 2, 127, 125);
+ /* { dg-output "\n1 2 127 125: 255" } */
+ printf("res: %d\n", res_closure);
+ /* { dg-output "\nres: 255" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_multi_ushort.c b/libffi-3.0.4/testsuite/libffi.call/cls_multi_ushort.c
new file mode 100644
index 0000000..215fef8
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_multi_ushort.c
@@ -0,0 +1,82 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check passing of multiple unsigned short values.
+ Limitations: none.
+ PR: PR13221.
+ Originator: <andreast@gcc.gnu.org> 20031129 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+unsigned short test_func_fn(unsigned short a1, unsigned short a2)
+{
+ unsigned short result;
+
+ result = a1 + a2;
+
+ printf("%d %d: %d\n", a1, a2, result);
+
+ return result;
+
+}
+
+static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
+ void *data __UNUSED__)
+{
+ unsigned short a1, a2;
+
+ a1 = *(unsigned short *)avals[0];
+ a2 = *(unsigned short *)avals[1];
+
+ *(ffi_arg *)rval = test_func_fn(a1, a2);
+
+}
+
+typedef unsigned short (*test_type)(unsigned short, unsigned short);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void * args_dbl[3];
+ ffi_type * cl_arg_types[3];
+ ffi_arg res_call;
+ unsigned short a, b, res_closure;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ a = 2;
+ b = 32765;
+
+ args_dbl[0] = &a;
+ args_dbl[1] = &b;
+ args_dbl[2] = NULL;
+
+ cl_arg_types[0] = &ffi_type_ushort;
+ cl_arg_types[1] = &ffi_type_ushort;
+ cl_arg_types[2] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
+ &ffi_type_ushort, cl_arg_types) == FFI_OK);
+
+ ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
+ /* { dg-output "2 32765: 32767" } */
+ printf("res: %d\n", (unsigned short)res_call);
+ /* { dg-output "\nres: 32767" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK);
+
+ res_closure = (*((test_type)pcl))(2, 32765);
+ /* { dg-output "\n2 32765: 32767" } */
+ printf("res: %d\n", res_closure);
+ /* { dg-output "\nres: 32767" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_multi_ushortchar.c b/libffi-3.0.4/testsuite/libffi.call/cls_multi_ushortchar.c
new file mode 100644
index 0000000..1cde84a
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_multi_ushortchar.c
@@ -0,0 +1,94 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check passing of multiple unsigned short/char values.
+ Limitations: none.
+ PR: PR13221.
+ Originator: <andreast@gcc.gnu.org> 20031129 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+unsigned short test_func_fn(unsigned char a1, unsigned short a2,
+ unsigned char a3, unsigned short a4)
+{
+ unsigned short result;
+
+ result = a1 + a2 + a3 + a4;
+
+ printf("%d %d %d %d: %d\n", a1, a2, a3, a4, result);
+
+ return result;
+
+}
+
+static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
+ void *data __UNUSED__)
+{
+ unsigned char a1, a3;
+ unsigned short a2, a4;
+
+ a1 = *(unsigned char *)avals[0];
+ a2 = *(unsigned short *)avals[1];
+ a3 = *(unsigned char *)avals[2];
+ a4 = *(unsigned short *)avals[3];
+
+ *(ffi_arg *)rval = test_func_fn(a1, a2, a3, a4);
+
+}
+
+typedef unsigned short (*test_type)(unsigned char, unsigned short,
+ unsigned char, unsigned short);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void * args_dbl[5];
+ ffi_type * cl_arg_types[5];
+ ffi_arg res_call;
+ unsigned char a, c;
+ unsigned short b, d, res_closure;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ a = 1;
+ b = 2;
+ c = 127;
+ d = 128;
+
+ args_dbl[0] = &a;
+ args_dbl[1] = &b;
+ args_dbl[2] = &c;
+ args_dbl[3] = &d;
+ args_dbl[4] = NULL;
+
+ cl_arg_types[0] = &ffi_type_uchar;
+ cl_arg_types[1] = &ffi_type_ushort;
+ cl_arg_types[2] = &ffi_type_uchar;
+ cl_arg_types[3] = &ffi_type_ushort;
+ cl_arg_types[4] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &ffi_type_ushort, cl_arg_types) == FFI_OK);
+
+ ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
+ /* { dg-output "1 2 127 128: 258" } */
+ printf("res: %d\n", (unsigned short)res_call);
+ /* { dg-output "\nres: 258" } */
+
+ CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK);
+
+ res_closure = (*((test_type)pcl))(1, 2, 127, 128);
+ /* { dg-output "\n1 2 127 128: 258" } */
+ printf("res: %d\n", res_closure);
+ /* { dg-output "\nres: 258" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_schar.c b/libffi-3.0.4/testsuite/libffi.call/cls_schar.c
new file mode 100644
index 0000000..bb1f2c6
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_schar.c
@@ -0,0 +1,52 @@
+/* Area: closure_call
+ Purpose: Check return value schar.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20031108 */
+
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_schar_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ *(ffi_arg*)resp = *(signed char *)args[0];
+ printf("%d: %d\n",*(signed char *)args[0],
+ (int)*(ffi_arg *)(resp));
+}
+typedef signed char (*cls_ret_schar)(signed char);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ ffi_type * cl_arg_types[2];
+ signed char res;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cl_arg_types[0] = &ffi_type_schar;
+ cl_arg_types[1] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_schar, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_ret_schar_fn, NULL) == FFI_OK);
+
+ res = (*((cls_ret_schar)pcl))(127);
+ /* { dg-output "127: 127" } */
+ printf("res: %d\n", res);
+ /* { dg-output "\nres: 127" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_sint.c b/libffi-3.0.4/testsuite/libffi.call/cls_sint.c
new file mode 100644
index 0000000..cf21bf8
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_sint.c
@@ -0,0 +1,50 @@
+/* Area: closure_call
+ Purpose: Check return value sint32.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20031108 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_sint_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ *(ffi_arg*)resp = *(signed int *)args[0];
+ printf("%d: %d\n",*(signed int *)args[0],
+ (int)*(ffi_arg *)(resp));
+}
+typedef signed int (*cls_ret_sint)(signed int);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ ffi_type * cl_arg_types[2];
+ signed int res;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cl_arg_types[0] = &ffi_type_sint;
+ cl_arg_types[1] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_ret_sint_fn, NULL) == FFI_OK);
+
+ res = (*((cls_ret_sint)pcl))(65534);
+ /* { dg-output "65534: 65534" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 65534" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_sshort.c b/libffi-3.0.4/testsuite/libffi.call/cls_sshort.c
new file mode 100644
index 0000000..8d63413
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_sshort.c
@@ -0,0 +1,50 @@
+/* Area: closure_call
+ Purpose: Check return value sshort.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20031108 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_sshort_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ *(ffi_arg*)resp = *(signed short *)args[0];
+ printf("%d: %d\n",*(signed short *)args[0],
+ (int)*(ffi_arg *)(resp));
+}
+typedef signed short (*cls_ret_sshort)(signed short);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ ffi_type * cl_arg_types[2];
+ signed short res;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cl_arg_types[0] = &ffi_type_sshort;
+ cl_arg_types[1] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_sshort, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_ret_sshort_fn, NULL) == FFI_OK);
+
+ res = (*((cls_ret_sshort)pcl))(255);
+ /* { dg-output "255: 255" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 255" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_uchar.c b/libffi-3.0.4/testsuite/libffi.call/cls_uchar.c
new file mode 100644
index 0000000..ea78ce5
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_uchar.c
@@ -0,0 +1,50 @@
+/* Area: closure_call
+ Purpose: Check return value uchar.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_uchar_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ *(ffi_arg*)resp = *(unsigned char *)args[0];
+ printf("%d: %d\n",*(unsigned char *)args[0],
+ (int)*(ffi_arg *)(resp));
+}
+typedef unsigned char (*cls_ret_uchar)(unsigned char);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ ffi_type * cl_arg_types[2];
+ unsigned char res;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cl_arg_types[0] = &ffi_type_uchar;
+ cl_arg_types[1] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_uchar, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_ret_uchar_fn, NULL) == FFI_OK);
+
+ res = (*((cls_ret_uchar)pcl))(127);
+ /* { dg-output "127: 127" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 127" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_uint.c b/libffi-3.0.4/testsuite/libffi.call/cls_uint.c
new file mode 100644
index 0000000..e31e41a
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_uint.c
@@ -0,0 +1,51 @@
+/* Area: closure_call
+ Purpose: Check return value uint.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_uint_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ *(ffi_arg *)resp = *(unsigned int *)args[0];
+
+ printf("%d: %d\n",*(unsigned int *)args[0],
+ (int)*(ffi_arg *)(resp));
+}
+typedef unsigned int (*cls_ret_uint)(unsigned int);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ ffi_type * cl_arg_types[2];
+ unsigned int res;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cl_arg_types[0] = &ffi_type_uint;
+ cl_arg_types[1] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_uint, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_ret_uint_fn, NULL) == FFI_OK);
+
+ res = (*((cls_ret_uint)pcl))(2147483647);
+ /* { dg-output "2147483647: 2147483647" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 2147483647" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_ulonglong.c b/libffi-3.0.4/testsuite/libffi.call/cls_ulonglong.c
new file mode 100644
index 0000000..1cc0a38
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_ulonglong.c
@@ -0,0 +1,54 @@
+/* Area: closure_call
+ Purpose: Check return value long long.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_ulonglong_fn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+{
+ *(unsigned long long *)resp= *(unsigned long long *)args[0];
+
+ printf("%llu: %llu\n",*(unsigned long long *)args[0],
+ *(unsigned long long *)(resp));
+}
+typedef unsigned long long (*cls_ret_ulonglong)(unsigned long long);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ ffi_type * cl_arg_types[2];
+ unsigned long long res;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cl_arg_types[0] = &ffi_type_uint64;
+ cl_arg_types[1] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_uint64, cl_arg_types) == FFI_OK);
+ CHECK(ffi_prep_closure(pcl, &cif, cls_ret_ulonglong_fn, NULL) == FFI_OK);
+ res = (*((cls_ret_ulonglong)pcl))(214LL);
+ /* { dg-output "214: 214" } */
+ printf("res: %lld\n", res);
+ /* { dg-output "\nres: 214" } */
+
+ res = (*((cls_ret_ulonglong)pcl))(9223372035854775808LL);
+ /* { dg-output "\n9223372035854775808: 9223372035854775808" } */
+ printf("res: %lld\n", res);
+ /* { dg-output "\nres: 9223372035854775808" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/cls_ushort.c b/libffi-3.0.4/testsuite/libffi.call/cls_ushort.c
new file mode 100644
index 0000000..81f9848
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/cls_ushort.c
@@ -0,0 +1,51 @@
+/* Area: closure_call
+ Purpose: Check return value ushort.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_ushort_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ *(ffi_arg*)resp = *(unsigned short *)args[0];
+
+ printf("%d: %d\n",*(unsigned short *)args[0],
+ (int)*(ffi_arg *)(resp));
+}
+typedef unsigned short (*cls_ret_ushort)(unsigned short);
+
+int main (void)
+{
+ ffi_cif cif;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ ffi_type * cl_arg_types[2];
+ unsigned short res;
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ cl_arg_types[0] = &ffi_type_ushort;
+ cl_arg_types[1] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_ushort, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure(pcl, &cif, cls_ret_ushort_fn, NULL) == FFI_OK);
+
+ res = (*((cls_ret_ushort)pcl))(65535);
+ /* { dg-output "65535: 65535" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 65535" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/ffitest.h b/libffi-3.0.4/testsuite/libffi.call/ffitest.h
new file mode 100644
index 0000000..e73f758
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/ffitest.h
@@ -0,0 +1,86 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <ffi.h>
+#include "fficonfig.h"
+
+#define MAX_ARGS 256
+
+#define CHECK(x) !(x) ? abort() : 0
+
+/* Define __UNUSED__ that also other compilers than gcc can run the tests. */
+#undef __UNUSED__
+#if defined(__GNUC__)
+#define __UNUSED__ __attribute__((__unused__))
+#else
+#define __UNUSED__
+#endif
+
+/* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a
+ file open. */
+#ifdef HAVE_MMAP_ANON
+# undef HAVE_MMAP_DEV_ZERO
+
+# include <sys/mman.h>
+# ifndef MAP_FAILED
+# define MAP_FAILED -1
+# endif
+# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
+# define MAP_ANONYMOUS MAP_ANON
+# endif
+# define USING_MMAP
+
+#endif
+
+#ifdef HAVE_MMAP_DEV_ZERO
+
+# include <sys/mman.h>
+# ifndef MAP_FAILED
+# define MAP_FAILED -1
+# endif
+# define USING_MMAP
+
+#endif
+
+#ifdef USING_MMAP
+static inline void *
+allocate_mmap (size_t size)
+{
+ void *page;
+#if defined (HAVE_MMAP_DEV_ZERO)
+ static int dev_zero_fd = -1;
+#endif
+
+#ifdef HAVE_MMAP_DEV_ZERO
+ if (dev_zero_fd == -1)
+ {
+ dev_zero_fd = open ("/dev/zero", O_RDONLY);
+ if (dev_zero_fd == -1)
+ {
+ perror ("open /dev/zero: %m");
+ exit (1);
+ }
+ }
+#endif
+
+
+#ifdef HAVE_MMAP_ANON
+ page = mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+#endif
+#ifdef HAVE_MMAP_DEV_ZERO
+ page = mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE, dev_zero_fd, 0);
+#endif
+
+ if (page == (void *) MAP_FAILED)
+ {
+ perror ("virtual memory exhausted");
+ exit (1);
+ }
+
+ return page;
+}
+
+#endif
diff --git a/libffi-3.0.4/testsuite/libffi.call/float.c b/libffi-3.0.4/testsuite/libffi.call/float.c
new file mode 100644
index 0000000..fbc272d
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/float.c
@@ -0,0 +1,59 @@
+/* Area: ffi_call
+ Purpose: Check return value float.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+static int floating(int a, float b, double c, long double d)
+{
+ int i;
+
+ i = (int) ((float)a/b + ((float)c/(float)d));
+
+ return i;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg rint;
+
+ float f;
+ signed int si1;
+ double d;
+ long double ld;
+
+ args[0] = &ffi_type_sint;
+ values[0] = &si1;
+ args[1] = &ffi_type_float;
+ values[1] = &f;
+ args[2] = &ffi_type_double;
+ values[2] = &d;
+ args[3] = &ffi_type_longdouble;
+ values[3] = &ld;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &ffi_type_sint, args) == FFI_OK);
+
+ si1 = 6;
+ f = 3.14159;
+ d = (double)1.0/(double)3.0;
+ ld = 2.71828182846L;
+
+ floating (si1, f, d, ld);
+
+ ffi_call(&cif, FFI_FN(floating), &rint, values);
+
+ printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld));
+
+ CHECK((int)rint == floating(si1, f, d, ld));
+
+ exit (0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/float1.c b/libffi-3.0.4/testsuite/libffi.call/float1.c
new file mode 100644
index 0000000..991d059
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/float1.c
@@ -0,0 +1,58 @@
+/* Area: ffi_call
+ Purpose: Check return value double.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+#include "float.h"
+
+typedef union
+{
+ double d;
+ unsigned char c[sizeof (double)];
+} value_type;
+
+#define CANARY 0xba
+
+static double dblit(float f)
+{
+ return f/3.0;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ float f;
+ value_type result[2];
+ unsigned int i;
+
+ args[0] = &ffi_type_float;
+ values[0] = &f;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_double, args) == FFI_OK);
+
+ f = 3.14159;
+
+ /* Put a canary in the return array. This is a regression test for
+ a buffer overrun. */
+ memset(result[1].c, CANARY, sizeof (double));
+
+ ffi_call(&cif, FFI_FN(dblit), &result[0].d, values);
+
+ /* These are not always the same!! Check for a reasonable delta */
+
+ CHECK(result[0].d - dblit(f) < DBL_EPSILON);
+
+ /* Check the canary. */
+ for (i = 0; i < sizeof (double); ++i)
+ CHECK(result[1].c[i] == CANARY);
+
+ exit(0);
+
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/float2.c b/libffi-3.0.4/testsuite/libffi.call/float2.c
new file mode 100644
index 0000000..fa9dd31
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/float2.c
@@ -0,0 +1,57 @@
+/* Area: ffi_call
+ Purpose: Check return value long double.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+#include "float.h"
+
+static long double ldblit(float f)
+{
+ return (long double) (((long double) f)/ (long double) 3.0);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ float f;
+ long double ld;
+
+ args[0] = &ffi_type_float;
+ values[0] = &f;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_longdouble, args) == FFI_OK);
+
+ f = 3.14159;
+
+#if 1
+ /* This is ifdef'd out for now. long double support under SunOS/gcc
+ is pretty much non-existent. You'll get the odd bus error in library
+ routines like printf(). */
+ printf ("%Lf\n", ldblit(f));
+#endif
+ ld = 666;
+ ffi_call(&cif, FFI_FN(ldblit), &ld, values);
+
+#if 1
+ /* This is ifdef'd out for now. long double support under SunOS/gcc
+ is pretty much non-existent. You'll get the odd bus error in library
+ routines like printf(). */
+ printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON);
+#endif
+
+ /* These are not always the same!! Check for a reasonable delta */
+ if (ld - ldblit(f) < LDBL_EPSILON)
+ puts("long double return value tests ok!");
+ else
+ CHECK(0);
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/float3.c b/libffi-3.0.4/testsuite/libffi.call/float3.c
new file mode 100644
index 0000000..76bd5f2
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/float3.c
@@ -0,0 +1,72 @@
+/* Area: ffi_call
+ Purpose: Check float arguments with different orders.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+#include "float.h"
+
+static double floating_1(float a, double b, long double c)
+{
+ return (double) a + b + (double) c;
+}
+
+static double floating_2(long double a, double b, float c)
+{
+ return (double) a + b + (double) c;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ double rd;
+
+ float f;
+ double d;
+ long double ld;
+
+ args[0] = &ffi_type_float;
+ values[0] = &f;
+ args[1] = &ffi_type_double;
+ values[1] = &d;
+ args[2] = &ffi_type_longdouble;
+ values[2] = &ld;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
+ &ffi_type_double, args) == FFI_OK);
+
+ f = 3.14159;
+ d = (double)1.0/(double)3.0;
+ ld = 2.71828182846L;
+
+ floating_1 (f, d, ld);
+
+ ffi_call(&cif, FFI_FN(floating_1), &rd, values);
+
+ CHECK(rd - floating_1(f, d, ld) < DBL_EPSILON);
+
+ args[0] = &ffi_type_longdouble;
+ values[0] = &ld;
+ args[1] = &ffi_type_double;
+ values[1] = &d;
+ args[2] = &ffi_type_float;
+ values[2] = &f;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
+ &ffi_type_double, args) == FFI_OK);
+
+ floating_2 (ld, d, f);
+
+ ffi_call(&cif, FFI_FN(floating_2), &rd, values);
+
+ CHECK(rd - floating_2(ld, d, f) < DBL_EPSILON);
+
+ exit (0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/float4.c b/libffi-3.0.4/testsuite/libffi.call/float4.c
new file mode 100644
index 0000000..0dd6d85
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/float4.c
@@ -0,0 +1,62 @@
+/* Area: ffi_call
+ Purpose: Check denorm double value.
+ Limitations: none.
+ PR: PR26483.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+/* { dg-options "-mieee" { target alpha*-*-* } } */
+
+#include "ffitest.h"
+#include "float.h"
+
+typedef union
+{
+ double d;
+ unsigned char c[sizeof (double)];
+} value_type;
+
+#define CANARY 0xba
+
+static double dblit(double d)
+{
+ return d;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ double d;
+ value_type result[2];
+ unsigned int i;
+
+ args[0] = &ffi_type_double;
+ values[0] = &d;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_double, args) == FFI_OK);
+
+ d = DBL_MIN / 2;
+
+ /* Put a canary in the return array. This is a regression test for
+ a buffer overrun. */
+ memset(result[1].c, CANARY, sizeof (double));
+
+ ffi_call(&cif, FFI_FN(dblit), &result[0].d, values);
+
+ /* The standard delta check doesn't work for denorms. Since we didn't do
+ any arithmetic, we should get the original result back, and hence an
+ exact check should be OK here. */
+
+ CHECK(result[0].d == dblit(d));
+
+ /* Check the canary. */
+ for (i = 0; i < sizeof (double); ++i)
+ CHECK(result[1].c[i] == CANARY);
+
+ exit(0);
+
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/many.c b/libffi-3.0.4/testsuite/libffi.call/many.c
new file mode 100644
index 0000000..4869ba9
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/many.c
@@ -0,0 +1,69 @@
+/* Area: ffi_call
+ Purpose: Check return value float, with many arguments
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+#include <float.h>
+
+static float many(float f1,
+ float f2,
+ float f3,
+ float f4,
+ float f5,
+ float f6,
+ float f7,
+ float f8,
+ float f9,
+ float f10,
+ float f11,
+ float f12,
+ float f13)
+{
+#if 0
+ printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n",
+ (double) f1, (double) f2, (double) f3, (double) f4, (double) f5,
+ (double) f6, (double) f7, (double) f8, (double) f9, (double) f10,
+ (double) f11, (double) f12, (double) f13);
+#endif
+
+ return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[13];
+ void *values[13];
+ float fa[13];
+ float f, ff;
+ int i;
+
+ for (i = 0; i < 13; i++)
+ {
+ args[i] = &ffi_type_float;
+ values[i] = &fa[i];
+ fa[i] = (float) i;
+ }
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13,
+ &ffi_type_float, args) == FFI_OK);
+
+ ffi_call(&cif, FFI_FN(many), &f, values);
+
+ ff = many(fa[0], fa[1],
+ fa[2], fa[3],
+ fa[4], fa[5],
+ fa[6], fa[7],
+ fa[8], fa[9],
+ fa[10],fa[11],fa[12]);
+
+ if (f - ff < FLT_EPSILON)
+ exit(0);
+ else
+ abort();
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/many_win32.c b/libffi-3.0.4/testsuite/libffi.call/many_win32.c
new file mode 100644
index 0000000..1b26332
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/many_win32.c
@@ -0,0 +1,63 @@
+/* Area: ffi_call
+ Purpose: Check stdcall many call on X86_WIN32 systems.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
+
+#include "ffitest.h"
+#include <float.h>
+
+static float __attribute__((stdcall)) stdcall_many(float f1,
+ float f2,
+ float f3,
+ float f4,
+ float f5,
+ float f6,
+ float f7,
+ float f8,
+ float f9,
+ float f10,
+ float f11,
+ float f12,
+ float f13)
+{
+ return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[13];
+ void *values[13];
+ float fa[13];
+ float f, ff;
+ unsigned long ul;
+
+ for (ul = 0; ul < 13; ul++)
+ {
+ args[ul] = &ffi_type_float;
+ values[ul] = &fa[ul];
+ fa[ul] = (float) ul;
+ }
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 13,
+ &ffi_type_float, args) == FFI_OK);
+
+ ff = stdcall_many(fa[0], fa[1],
+ fa[2], fa[3],
+ fa[4], fa[5],
+ fa[6], fa[7],
+ fa[8], fa[9],
+ fa[10], fa[11], fa[12]);
+
+ ffi_call(&cif, FFI_FN(stdcall_many), &f, values);
+
+ if (f - ff < FLT_EPSILON)
+ printf("stdcall many arg tests ok!\n");
+ else
+ CHECK(0);
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/negint.c b/libffi-3.0.4/testsuite/libffi.call/negint.c
new file mode 100644
index 0000000..3168113
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/negint.c
@@ -0,0 +1,53 @@
+/* Area: ffi_call
+ Purpose: Check that negative integers are passed correctly.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+/* { dg-options -O2 } */
+
+#include "ffitest.h"
+
+static int checking(int a, short b, signed char c)
+{
+
+ return (a < 0 && b < 0 && c < 0);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg rint;
+
+ signed int si;
+ signed short ss;
+ signed char sc;
+
+ args[0] = &ffi_type_sint;
+ values[0] = &si;
+ args[1] = &ffi_type_sshort;
+ values[1] = &ss;
+ args[2] = &ffi_type_schar;
+ values[2] = &sc;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
+ &ffi_type_sint, args) == FFI_OK);
+
+ si = -6;
+ ss = -12;
+ sc = -1;
+
+ checking (si, ss, sc);
+
+ ffi_call(&cif, FFI_FN(checking), &rint, values);
+
+ printf ("%d vs %d\n", (int)rint, checking (si, ss, sc));
+
+ CHECK(rint != 0);
+
+ exit (0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/nested_struct.c b/libffi-3.0.4/testsuite/libffi.call/nested_struct.c
new file mode 100644
index 0000000..adce7ba
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/nested_struct.c
@@ -0,0 +1,160 @@
+/* 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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ 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];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ 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;
+
+ 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_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(pcl, &cif, cls_struct_combined_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1,
+ cls_struct_16byte2,
+ cls_struct_combined))
+ (pcl))(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);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/nested_struct1.c b/libffi-3.0.4/testsuite/libffi.call/nested_struct1.c
new file mode 100644
index 0000000..f7fe72e
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/nested_struct1.c
@@ -0,0 +1,169 @@
+/* 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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ 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];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ 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;
+
+ 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_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(pcl, &cif, cls_struct_combined_gn, NULL) == FFI_OK);
+
+ res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1,
+ cls_struct_16byte2,
+ cls_struct_combined,
+ cls_struct_16byte1))
+ (pcl))(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);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/nested_struct10.c b/libffi-3.0.4/testsuite/libffi.call/nested_struct10.c
new file mode 100644
index 0000000..8d9aba2
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/nested_struct10.c
@@ -0,0 +1,141 @@
+/* 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;
+
+ 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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ 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];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ 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;
+
+ 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_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(pcl, &cif, B_gn, NULL) == FFI_OK);
+
+ res_dbl = ((B(*)(A, B, C))(pcl))(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);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/nested_struct2.c b/libffi-3.0.4/testsuite/libffi.call/nested_struct2.c
new file mode 100644
index 0000000..821fcc4
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/nested_struct2.c
@@ -0,0 +1,118 @@
+/* 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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ 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];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ 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;
+
+ struct A e_dbl = { 1, 7};
+ struct B f_dbl = {{12 , 127}, 99};
+
+ struct B res_dbl;
+
+ 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(pcl, &cif, B_gn, NULL) == FFI_OK);
+
+ res_dbl = ((B(*)(A, B))(pcl))(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);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/nested_struct3.c b/libffi-3.0.4/testsuite/libffi.call/nested_struct3.c
new file mode 100644
index 0000000..f11aff4
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/nested_struct3.c
@@ -0,0 +1,119 @@
+/* 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 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("%d %d %d %d %d: %d %d %d\n", (int)b0.a, b0.b,
+ (int)b1.x.a, b1.x.b, b1.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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ 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];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ 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;
+
+ struct A e_dbl = { 1LL, 7};
+ struct B f_dbl = {{12LL , 127}, 99};
+
+ struct B res_dbl;
+
+ 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(pcl, &cif, B_gn, NULL) == FFI_OK);
+
+ res_dbl = ((B(*)(A, B))(pcl))(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);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/nested_struct4.c b/libffi-3.0.4/testsuite/libffi.call/nested_struct4.c
new file mode 100644
index 0000000..0553ce8
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/nested_struct4.c
@@ -0,0 +1,119 @@
+/* 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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ 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];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ 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;
+
+ struct A e_dbl = { 1.0, 7};
+ struct B f_dbl = {{12.0 , 127}, 99};
+
+ struct B res_dbl;
+
+ 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(pcl, &cif, B_gn, NULL) == FFI_OK);
+
+ res_dbl = ((B(*)(A, B))(pcl))(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);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/nested_struct5.c b/libffi-3.0.4/testsuite/libffi.call/nested_struct5.c
new file mode 100644
index 0000000..a77931b
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/nested_struct5.c
@@ -0,0 +1,120 @@
+/* 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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ 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];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ 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;
+
+ struct A e_dbl = { 1.0, 7};
+ struct B f_dbl = {{12.0 , 127}, 99};
+
+ struct B res_dbl;
+
+ 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(pcl, &cif, B_gn, NULL) == FFI_OK);
+
+ res_dbl = ((B(*)(A, B))(pcl))(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);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/nested_struct6.c b/libffi-3.0.4/testsuite/libffi.call/nested_struct6.c
new file mode 100644
index 0000000..af2821c
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/nested_struct6.c
@@ -0,0 +1,139 @@
+/* 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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ 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];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ 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;
+
+ 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_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(pcl, &cif, B_gn, NULL) == FFI_OK);
+
+ res_dbl = ((B(*)(A, B, C))(pcl))(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);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/nested_struct7.c b/libffi-3.0.4/testsuite/libffi.call/nested_struct7.c
new file mode 100644
index 0000000..c7dd4f7
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/nested_struct7.c
@@ -0,0 +1,119 @@
+/* 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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ 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];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ 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;
+
+ struct A e_dbl = { 1LL, 7};
+ struct B f_dbl = {{12.0 , 127}, 99};
+
+ struct B res_dbl;
+
+ 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(pcl, &cif, B_gn, NULL) == FFI_OK);
+
+ res_dbl = ((B(*)(A, B))(pcl))(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);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/nested_struct8.c b/libffi-3.0.4/testsuite/libffi.call/nested_struct8.c
new file mode 100644
index 0000000..775ff70
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/nested_struct8.c
@@ -0,0 +1,139 @@
+/* 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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ 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];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ 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;
+
+ 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_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(pcl, &cif, B_gn, NULL) == FFI_OK);
+
+ res_dbl = ((B(*)(A, B, C))(pcl))(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);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/nested_struct9.c b/libffi-3.0.4/testsuite/libffi.call/nested_struct9.c
new file mode 100644
index 0000000..70332de
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/nested_struct9.c
@@ -0,0 +1,139 @@
+/* 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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ 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];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ 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;
+
+ 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_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(pcl, &cif, B_gn, NULL) == FFI_OK);
+
+ res_dbl = ((B(*)(A, B, C))(pcl))(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);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/problem1.c b/libffi-3.0.4/testsuite/libffi.call/problem1.c
new file mode 100644
index 0000000..ca70cc8
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/problem1.c
@@ -0,0 +1,98 @@
+/* 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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ void* args[4];
+ ffi_type* arg_types[3];
+
+#ifdef USING_MMAP
+ pcl = allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ 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(pcl, &cif, stub, NULL) == FFI_OK);
+
+ res = ((my_ffi_struct(*)(struct my_ffi_struct, struct my_ffi_struct))(pcl))(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);;
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/promotion.c b/libffi-3.0.4/testsuite/libffi.call/promotion.c
new file mode 100644
index 0000000..4456161
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/promotion.c
@@ -0,0 +1,59 @@
+/* Area: ffi_call
+ Purpose: Promotion test.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+static int promotion(signed char sc, signed short ss,
+ unsigned char uc, unsigned short us)
+{
+ int r = (int) sc + (int) ss + (int) uc + (int) us;
+
+ return r;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg rint;
+ signed char sc;
+ unsigned char uc;
+ signed short ss;
+ unsigned short us;
+ unsigned long ul;
+
+ args[0] = &ffi_type_schar;
+ args[1] = &ffi_type_sshort;
+ args[2] = &ffi_type_uchar;
+ args[3] = &ffi_type_ushort;
+ values[0] = &sc;
+ values[1] = &ss;
+ values[2] = &uc;
+ values[3] = &us;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &ffi_type_sint, args) == FFI_OK);
+
+ us = 0;
+ ul = 0;
+
+ for (sc = (signed char) -127;
+ sc <= (signed char) 120; sc += 1)
+ for (ss = -30000; ss <= 30000; ss += 10000)
+ for (uc = (unsigned char) 0;
+ uc <= (unsigned char) 200; uc += 20)
+ for (us = 0; us <= 60000; us += 10000)
+ {
+ ul++;
+ ffi_call(&cif, FFI_FN(promotion), &rint, values);
+ CHECK((int)rint == (signed char) sc + (signed short) ss +
+ (unsigned char) uc + (unsigned short) us);
+ }
+ printf("%lu promotion tests run\n", ul);
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/pyobjc-tc.c b/libffi-3.0.4/testsuite/libffi.call/pyobjc-tc.c
new file mode 100644
index 0000000..e29bd6c
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/pyobjc-tc.c
@@ -0,0 +1,114 @@
+/* Area: ffi_call
+ Purpose: Check different structures.
+ Limitations: none.
+ PR: none.
+ Originator: Ronald Oussoren <oussoren@cistron.nl> 20030824 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct Point {
+ float x;
+ float y;
+} Point;
+
+typedef struct Size {
+ float h;
+ float w;
+} Size;
+
+typedef struct Rect {
+ Point o;
+ Size s;
+} Rect;
+
+int doit(int o, char* s, Point p, Rect r, int last)
+{
+ printf("CALLED WITH %d %s {%f %f} {{%f %f} {%f %f}} %d\n",
+ o, s, p.x, p.y, r.o.x, r.o.y, r.s.h, r.s.w, last);
+ return 42;
+}
+
+
+int main(void)
+{
+ ffi_type point_type;
+ ffi_type size_type;
+ ffi_type rect_type;
+ ffi_cif cif;
+ ffi_type* arglist[6];
+ void* values[6];
+ int r;
+
+ /*
+ * First set up FFI types for the 3 struct types
+ */
+
+ point_type.size = 0; /*sizeof(Point);*/
+ point_type.alignment = 0; /*__alignof__(Point);*/
+ point_type.type = FFI_TYPE_STRUCT;
+ point_type.elements = malloc(3 * sizeof(ffi_type*));
+ point_type.elements[0] = &ffi_type_float;
+ point_type.elements[1] = &ffi_type_float;
+ point_type.elements[2] = NULL;
+
+ size_type.size = 0;/* sizeof(Size);*/
+ size_type.alignment = 0;/* __alignof__(Size);*/
+ size_type.type = FFI_TYPE_STRUCT;
+ size_type.elements = malloc(3 * sizeof(ffi_type*));
+ size_type.elements[0] = &ffi_type_float;
+ size_type.elements[1] = &ffi_type_float;
+ size_type.elements[2] = NULL;
+
+ rect_type.size = 0;/*sizeof(Rect);*/
+ rect_type.alignment =0;/* __alignof__(Rect);*/
+ rect_type.type = FFI_TYPE_STRUCT;
+ rect_type.elements = malloc(3 * sizeof(ffi_type*));
+ rect_type.elements[0] = &point_type;
+ rect_type.elements[1] = &size_type;
+ rect_type.elements[2] = NULL;
+
+ /*
+ * Create a CIF
+ */
+ arglist[0] = &ffi_type_sint;
+ arglist[1] = &ffi_type_pointer;
+ arglist[2] = &point_type;
+ arglist[3] = &rect_type;
+ arglist[4] = &ffi_type_sint;
+ arglist[5] = NULL;
+
+ r = ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
+ 5, &ffi_type_sint, arglist);
+ if (r != FFI_OK) {
+ abort();
+ }
+
+
+ /* And call the function through the CIF */
+
+ {
+ Point p = { 1.0, 2.0 };
+ Rect r = { { 9.0, 10.0}, { -1.0, -2.0 } };
+ int o = 0;
+ int l = 42;
+ char* m = "myMethod";
+ ffi_arg result;
+
+ values[0] = &o;
+ values[1] = &m;
+ values[2] = &p;
+ values[3] = &r;
+ values[4] = &l;
+ values[5] = NULL;
+
+ printf("CALLING WITH %d %s {%f %f} {{%f %f} {%f %f}} %d\n",
+ o, m, p.x, p.y, r.o.x, r.o.y, r.s.h, r.s.w, l);
+
+ ffi_call(&cif, FFI_FN(doit), &result, values);
+
+ printf ("The result is %d\n", (int)result);
+
+ }
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/return_dbl.c b/libffi-3.0.4/testsuite/libffi.call/return_dbl.c
new file mode 100644
index 0000000..1aab403
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/return_dbl.c
@@ -0,0 +1,35 @@
+/* Area: ffi_call
+ Purpose: Check return value double.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20050212 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static double return_dbl(double dbl)
+{
+ return 2 * dbl;
+}
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ double dbl, rdbl;
+
+ args[0] = &ffi_type_double;
+ values[0] = &dbl;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_double, args) == FFI_OK);
+
+ for (dbl = -127.3; dbl < 127; dbl++)
+ {
+ ffi_call(&cif, FFI_FN(return_dbl), &rdbl, values);
+ printf ("%f vs %f\n", rdbl, return_dbl(dbl));
+ CHECK(rdbl == 2 * dbl);
+ }
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/return_dbl1.c b/libffi-3.0.4/testsuite/libffi.call/return_dbl1.c
new file mode 100644
index 0000000..0ea5d50
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/return_dbl1.c
@@ -0,0 +1,43 @@
+/* Area: ffi_call
+ Purpose: Check return value double.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20050212 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static double return_dbl(double dbl1, float fl2, unsigned int in3, double dbl4)
+{
+ return dbl1 + fl2 + in3 + dbl4;
+}
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ double dbl1, dbl4, rdbl;
+ float fl2;
+ unsigned int in3;
+ args[0] = &ffi_type_double;
+ args[1] = &ffi_type_float;
+ args[2] = &ffi_type_uint;
+ args[3] = &ffi_type_double;
+ values[0] = &dbl1;
+ values[1] = &fl2;
+ values[2] = &in3;
+ values[3] = &dbl4;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &ffi_type_double, args) == FFI_OK);
+ dbl1 = 127.0;
+ fl2 = 128.0;
+ in3 = 255;
+ dbl4 = 512.7;
+
+ ffi_call(&cif, FFI_FN(return_dbl), &rdbl, values);
+ printf ("%f vs %f\n", rdbl, return_dbl(dbl1, fl2, in3, dbl4));
+ CHECK(rdbl == dbl1 + fl2 + in3 + dbl4);
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/return_dbl2.c b/libffi-3.0.4/testsuite/libffi.call/return_dbl2.c
new file mode 100644
index 0000000..b3818f8
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/return_dbl2.c
@@ -0,0 +1,42 @@
+/* Area: ffi_call
+ Purpose: Check return value double.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20050212 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static double return_dbl(double dbl1, double dbl2, unsigned int in3, double dbl4)
+{
+ return dbl1 + dbl2 + in3 + dbl4;
+}
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ double dbl1, dbl2, dbl4, rdbl;
+ unsigned int in3;
+ args[0] = &ffi_type_double;
+ args[1] = &ffi_type_double;
+ args[2] = &ffi_type_uint;
+ args[3] = &ffi_type_double;
+ values[0] = &dbl1;
+ values[1] = &dbl2;
+ values[2] = &in3;
+ values[3] = &dbl4;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &ffi_type_double, args) == FFI_OK);
+ dbl1 = 127.0;
+ dbl2 = 128.0;
+ in3 = 255;
+ dbl4 = 512.7;
+
+ ffi_call(&cif, FFI_FN(return_dbl), &rdbl, values);
+ printf ("%f vs %f\n", rdbl, return_dbl(dbl1, dbl2, in3, dbl4));
+ CHECK(rdbl == dbl1 + dbl2 + in3 + dbl4);
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/return_fl.c b/libffi-3.0.4/testsuite/libffi.call/return_fl.c
new file mode 100644
index 0000000..fb8a09e
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/return_fl.c
@@ -0,0 +1,35 @@
+/* Area: ffi_call
+ Purpose: Check return value float.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20050212 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static float return_fl(float fl)
+{
+ return 2 * fl;
+}
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ float fl, rfl;
+
+ args[0] = &ffi_type_float;
+ values[0] = &fl;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_float, args) == FFI_OK);
+
+ for (fl = -127.0; fl < 127; fl++)
+ {
+ ffi_call(&cif, FFI_FN(return_fl), &rfl, values);
+ printf ("%f vs %f\n", rfl, return_fl(fl));
+ CHECK(rfl == 2 * fl);
+ }
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/return_fl1.c b/libffi-3.0.4/testsuite/libffi.call/return_fl1.c
new file mode 100644
index 0000000..c3d92c2
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/return_fl1.c
@@ -0,0 +1,36 @@
+/* Area: ffi_call
+ Purpose: Check return value float.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20050212 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static float return_fl(float fl1, float fl2)
+{
+ return fl1 + fl2;
+}
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ float fl1, fl2, rfl;
+
+ args[0] = &ffi_type_float;
+ args[1] = &ffi_type_float;
+ values[0] = &fl1;
+ values[1] = &fl2;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
+ &ffi_type_float, args) == FFI_OK);
+ fl1 = 127.0;
+ fl2 = 128.0;
+
+ ffi_call(&cif, FFI_FN(return_fl), &rfl, values);
+ printf ("%f vs %f\n", rfl, return_fl(fl1, fl2));
+ CHECK(rfl == fl1 + fl2);
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/return_fl2.c b/libffi-3.0.4/testsuite/libffi.call/return_fl2.c
new file mode 100644
index 0000000..ddb976c
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/return_fl2.c
@@ -0,0 +1,49 @@
+/* Area: ffi_call
+ Purpose: Check return value float.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20050212 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+/* Use volatile float to avoid false negative on ix86. See PR target/323. */
+static float return_fl(float fl1, float fl2, float fl3, float fl4)
+{
+ volatile float sum;
+
+ sum = fl1 + fl2 + fl3 + fl4;
+ return sum;
+}
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ float fl1, fl2, fl3, fl4, rfl;
+ volatile float sum;
+
+ args[0] = &ffi_type_float;
+ args[1] = &ffi_type_float;
+ args[2] = &ffi_type_float;
+ args[3] = &ffi_type_float;
+ values[0] = &fl1;
+ values[1] = &fl2;
+ values[2] = &fl3;
+ values[3] = &fl4;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &ffi_type_float, args) == FFI_OK);
+ fl1 = 127.0;
+ fl2 = 128.0;
+ fl3 = 255.1;
+ fl4 = 512.7;
+
+ ffi_call(&cif, FFI_FN(return_fl), &rfl, values);
+ printf ("%f vs %f\n", rfl, return_fl(fl1, fl2, fl3, fl4));
+
+ sum = fl1 + fl2 + fl3 + fl4;
+ CHECK(rfl == sum);
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/return_fl3.c b/libffi-3.0.4/testsuite/libffi.call/return_fl3.c
new file mode 100644
index 0000000..c37877b
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/return_fl3.c
@@ -0,0 +1,42 @@
+/* Area: ffi_call
+ Purpose: Check return value float.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20050212 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static float return_fl(float fl1, float fl2, unsigned int in3, float fl4)
+{
+ return fl1 + fl2 + in3 + fl4;
+}
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ float fl1, fl2, fl4, rfl;
+ unsigned int in3;
+ args[0] = &ffi_type_float;
+ args[1] = &ffi_type_float;
+ args[2] = &ffi_type_uint;
+ args[3] = &ffi_type_float;
+ values[0] = &fl1;
+ values[1] = &fl2;
+ values[2] = &in3;
+ values[3] = &fl4;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &ffi_type_float, args) == FFI_OK);
+ fl1 = 127.0;
+ fl2 = 128.0;
+ in3 = 255;
+ fl4 = 512.7;
+
+ ffi_call(&cif, FFI_FN(return_fl), &rfl, values);
+ printf ("%f vs %f\n", rfl, return_fl(fl1, fl2, in3, fl4));
+ CHECK(rfl == fl1 + fl2 + in3 + fl4);
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/return_ldl.c b/libffi-3.0.4/testsuite/libffi.call/return_ldl.c
new file mode 100644
index 0000000..413bf94
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/return_ldl.c
@@ -0,0 +1,34 @@
+/* Area: ffi_call
+ Purpose: Check return value long double.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20071113 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static long double return_ldl(long double ldl)
+{
+ return 2*ldl;
+}
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ long double ldl, rldl;
+
+ args[0] = &ffi_type_longdouble;
+ values[0] = &ldl;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_longdouble, args) == FFI_OK);
+
+ for (ldl = -127.0; ldl < 127.0; ldl++)
+ {
+ ffi_call(&cif, FFI_FN(return_ldl), &rldl, values);
+ CHECK(rldl == 2 * ldl);
+ }
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/return_ll.c b/libffi-3.0.4/testsuite/libffi.call/return_ll.c
new file mode 100644
index 0000000..ea4a1e4
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/return_ll.c
@@ -0,0 +1,41 @@
+/* Area: ffi_call
+ Purpose: Check return value long long.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+static long long return_ll(long long ll)
+{
+ return ll;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ long long rlonglong;
+ long long ll;
+
+ args[0] = &ffi_type_sint64;
+ values[0] = &ll;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_sint64, args) == FFI_OK);
+
+ for (ll = 0LL; ll < 100LL; ll++)
+ {
+ ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
+ CHECK(rlonglong == ll);
+ }
+
+ for (ll = 55555555555000LL; ll < 55555555555100LL; ll++)
+ {
+ ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
+ CHECK(rlonglong == ll);
+ }
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/return_ll1.c b/libffi-3.0.4/testsuite/libffi.call/return_ll1.c
new file mode 100644
index 0000000..5681d84
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/return_ll1.c
@@ -0,0 +1,42 @@
+/* Area: ffi_call
+ Purpose: Check if long long are passed in the corresponding regs on ppc.
+ Limitations: none.
+ PR: 20104.
+ Originator: <andreast@gcc.gnu.org> 20050222 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+static long long return_ll(int ll0, long long ll1, int ll2)
+{
+ return ll0 + ll1 + ll2;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ long long rlonglong;
+ long long ll1;
+ unsigned ll0, ll2;
+
+ args[0] = &ffi_type_sint;
+ args[1] = &ffi_type_sint64;
+ args[2] = &ffi_type_sint;
+ values[0] = &ll0;
+ values[1] = &ll1;
+ values[2] = &ll2;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
+ &ffi_type_sint64, args) == FFI_OK);
+
+ ll0 = 11111111;
+ ll1 = 11111111111000LL;
+ ll2 = 11111111;
+
+ ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
+ printf("res: %lld, %lld\n", rlonglong, ll0 + ll1 + ll2);
+ /* { dg-output "res: 11111133333222, 11111133333222" } */
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/return_sc.c b/libffi-3.0.4/testsuite/libffi.call/return_sc.c
new file mode 100644
index 0000000..19608ee
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/return_sc.c
@@ -0,0 +1,36 @@
+/* Area: ffi_call
+ Purpose: Check return value signed char.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static signed char return_sc(signed char sc)
+{
+ return sc;
+}
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg rint;
+ signed char sc;
+
+ args[0] = &ffi_type_schar;
+ values[0] = &sc;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_schar, args) == FFI_OK);
+
+ for (sc = (signed char) -127;
+ sc < (signed char) 127; sc++)
+ {
+ ffi_call(&cif, FFI_FN(return_sc), &rint, values);
+ CHECK(rint == (ffi_arg) sc);
+ }
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/return_sl.c b/libffi-3.0.4/testsuite/libffi.call/return_sl.c
new file mode 100644
index 0000000..f0fd345
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/return_sl.c
@@ -0,0 +1,38 @@
+/* Area: ffi_call
+ Purpose: Check if long as return type is handled correctly.
+ Limitations: none.
+ PR: none.
+ */
+
+/* { dg-do run } */
+#include "ffitest.h"
+static long return_sl(long l1, long l2)
+{
+ return l1 - l2;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg res;
+ unsigned long l1, l2;
+
+ args[0] = &ffi_type_slong;
+ args[1] = &ffi_type_slong;
+ values[0] = &l1;
+ values[1] = &l2;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
+ &ffi_type_slong, args) == FFI_OK);
+
+ l1 = 1073741823L;
+ l2 = 1073741824L;
+
+ ffi_call(&cif, FFI_FN(return_sl), &res, values);
+ printf("res: %ld, %ld\n", (long)res, l1 - l2);
+ /* { dg-output "res: -1, -1" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/return_uc.c b/libffi-3.0.4/testsuite/libffi.call/return_uc.c
new file mode 100644
index 0000000..07c45de
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/return_uc.c
@@ -0,0 +1,38 @@
+/* Area: ffi_call
+ Purpose: Check return value unsigned char.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static unsigned char return_uc(unsigned char uc)
+{
+ return uc;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg rint;
+
+ unsigned char uc;
+
+ args[0] = &ffi_type_uchar;
+ values[0] = &uc;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_uchar, args) == FFI_OK);
+
+ for (uc = (unsigned char) '\x00';
+ uc < (unsigned char) '\xff'; uc++)
+ {
+ ffi_call(&cif, FFI_FN(return_uc), &rint, values);
+ CHECK(rint == (signed int) uc);
+ }
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/return_ul.c b/libffi-3.0.4/testsuite/libffi.call/return_ul.c
new file mode 100644
index 0000000..12b266f
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/return_ul.c
@@ -0,0 +1,38 @@
+/* Area: ffi_call
+ Purpose: Check if unsigned long as return type is handled correctly.
+ Limitations: none.
+ PR: none.
+ Originator: <kaffeetisch at gmx dot de> 20060724 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+static unsigned long return_ul(unsigned long ul1, unsigned long ul2)
+{
+ return ul1 + ul2;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg res;
+ unsigned long ul1, ul2;
+
+ args[0] = &ffi_type_ulong;
+ args[1] = &ffi_type_ulong;
+ values[0] = &ul1;
+ values[1] = &ul2;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
+ &ffi_type_ulong, args) == FFI_OK);
+
+ ul1 = 1073741823L;
+ ul2 = 1073741824L;
+
+ ffi_call(&cif, FFI_FN(return_ul), &res, values);
+ printf("res: %lu, %lu\n", (unsigned long)res, ul1 + ul2);
+ /* { dg-output "res: 2147483647, 2147483647" } */
+
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/strlen.c b/libffi-3.0.4/testsuite/libffi.call/strlen.c
new file mode 100644
index 0000000..3de45de
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/strlen.c
@@ -0,0 +1,44 @@
+/* Area: ffi_call
+ Purpose: Check strlen function call.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static size_t my_strlen(char *s)
+{
+ return (strlen(s));
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg rint;
+ char *s;
+
+ args[0] = &ffi_type_pointer;
+ values[0] = (void*) &s;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_sint, args) == FFI_OK);
+
+ s = "a";
+ ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
+ CHECK(rint == 1);
+
+ s = "1234567";
+ ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
+ CHECK(rint == 7);
+
+ s = "1234567890123456789012345";
+ ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
+ CHECK(rint == 25);
+
+ exit (0);
+}
+
diff --git a/libffi-3.0.4/testsuite/libffi.call/strlen_win32.c b/libffi-3.0.4/testsuite/libffi.call/strlen_win32.c
new file mode 100644
index 0000000..6fbcc87
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/strlen_win32.c
@@ -0,0 +1,44 @@
+/* Area: ffi_call
+ Purpose: Check stdcall strlen call on X86_WIN32 systems.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
+
+#include "ffitest.h"
+
+static size_t __attribute__((stdcall)) my_stdcall_strlen(char *s)
+{
+ return (strlen(s));
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg rint;
+ char *s;
+ args[0] = &ffi_type_pointer;
+ values[0] = (void*) &s;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 1,
+ &ffi_type_sint, args) == FFI_OK);
+
+ s = "a";
+ ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
+ CHECK(rint == 1);
+
+ s = "1234567";
+ ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
+ CHECK(rint == 7);
+
+ s = "1234567890123456789012345";
+ ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
+ CHECK(rint == 25);
+
+ printf("stdcall strlen tests passed\n");
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/struct1.c b/libffi-3.0.4/testsuite/libffi.call/struct1.c
new file mode 100644
index 0000000..ea76c85
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/struct1.c
@@ -0,0 +1,65 @@
+/* Area: ffi_call
+ Purpose: Check structures.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct
+{
+ unsigned char uc;
+ double d;
+ unsigned int ui;
+} test_structure_1;
+
+static test_structure_1 struct1(test_structure_1 ts)
+{
+ ts.uc++;
+ ts.d--;
+ ts.ui++;
+
+ return ts;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_type ts1_type;
+ ffi_type *ts1_type_elements[4];
+ ts1_type.size = 0;
+ ts1_type.alignment = 0;
+ ts1_type.type = FFI_TYPE_STRUCT;
+ ts1_type.elements = ts1_type_elements;
+ ts1_type_elements[0] = &ffi_type_uchar;
+ ts1_type_elements[1] = &ffi_type_double;
+ ts1_type_elements[2] = &ffi_type_uint;
+ ts1_type_elements[3] = NULL;
+
+ test_structure_1 ts1_arg;
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_1 *ts1_result =
+ (test_structure_1 *) malloc (sizeof(test_structure_1));
+
+ args[0] = &ts1_type;
+ values[0] = &ts1_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ts1_type, args) == FFI_OK);
+
+ ts1_arg.uc = '\x01';
+ ts1_arg.d = 3.14159;
+ ts1_arg.ui = 555;
+
+ ffi_call(&cif, FFI_FN(struct1), ts1_result, values);
+
+ CHECK(ts1_result->ui == 556);
+ CHECK(ts1_result->d == 3.14159 - 1);
+
+ free (ts1_result);
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/struct2.c b/libffi-3.0.4/testsuite/libffi.call/struct2.c
new file mode 100644
index 0000000..14bc9fd
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/struct2.c
@@ -0,0 +1,67 @@
+/* Area: ffi_call
+ Purpose: Check structures.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct
+{
+ double d1;
+ double d2;
+} test_structure_2;
+
+static test_structure_2 struct2(test_structure_2 ts)
+{
+ ts.d1--;
+ ts.d2--;
+
+ return ts;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ test_structure_2 ts2_arg;
+ ffi_type ts2_type;
+ ffi_type *ts2_type_elements[3];
+ ts2_type.size = 0;
+ ts2_type.alignment = 0;
+ ts2_type.type = FFI_TYPE_STRUCT;
+ ts2_type.elements = ts2_type_elements;
+ ts2_type_elements[0] = &ffi_type_double;
+ ts2_type_elements[1] = &ffi_type_double;
+ ts2_type_elements[2] = NULL;
+
+
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_2 *ts2_result =
+ (test_structure_2 *) malloc (sizeof(test_structure_2));
+
+ args[0] = &ts2_type;
+ values[0] = &ts2_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts2_type, args) == FFI_OK);
+
+ ts2_arg.d1 = 5.55;
+ ts2_arg.d2 = 6.66;
+
+ printf ("%g\n", ts2_arg.d1);
+ printf ("%g\n", ts2_arg.d2);
+
+ ffi_call(&cif, FFI_FN(struct2), ts2_result, values);
+
+ printf ("%g\n", ts2_result->d1);
+ printf ("%g\n", ts2_result->d2);
+
+ CHECK(ts2_result->d1 == 5.55 - 1);
+ CHECK(ts2_result->d2 == 6.66 - 1);
+
+ free (ts2_result);
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/struct3.c b/libffi-3.0.4/testsuite/libffi.call/struct3.c
new file mode 100644
index 0000000..e0bb09b
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/struct3.c
@@ -0,0 +1,59 @@
+/* Area: ffi_call
+ Purpose: Check structures.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct
+{
+ int si;
+} test_structure_3;
+
+static test_structure_3 struct3(test_structure_3 ts)
+{
+ ts.si = -(ts.si*2);
+
+ return ts;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ int compare_value;
+ ffi_type ts3_type;
+ ffi_type *ts3_type_elements[2];
+ ts3_type.size = 0;
+ ts3_type.alignment = 0;
+ ts3_type.type = FFI_TYPE_STRUCT;
+ ts3_type.elements = ts3_type_elements;
+ ts3_type_elements[0] = &ffi_type_sint;
+ ts3_type_elements[1] = NULL;
+
+ test_structure_3 ts3_arg;
+ test_structure_3 *ts3_result =
+ (test_structure_3 *) malloc (sizeof(test_structure_3));
+
+ args[0] = &ts3_type;
+ values[0] = &ts3_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ts3_type, args) == FFI_OK);
+
+ ts3_arg.si = -123;
+ compare_value = ts3_arg.si;
+
+ ffi_call(&cif, FFI_FN(struct3), ts3_result, values);
+
+ printf ("%d %d\n", ts3_result->si, -(compare_value*2));
+
+ CHECK(ts3_result->si == -(compare_value*2));
+
+ free (ts3_result);
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/struct4.c b/libffi-3.0.4/testsuite/libffi.call/struct4.c
new file mode 100644
index 0000000..0ad0a83
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/struct4.c
@@ -0,0 +1,63 @@
+/* Area: ffi_call
+ Purpose: Check structures.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct
+{
+ unsigned ui1;
+ unsigned ui2;
+ unsigned ui3;
+} test_structure_4;
+
+static test_structure_4 struct4(test_structure_4 ts)
+{
+ ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3;
+
+ return ts;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_type ts4_type;
+ ffi_type *ts4_type_elements[4];
+ ts4_type.size = 0;
+ ts4_type.alignment = 0;
+ ts4_type.type = FFI_TYPE_STRUCT;
+ test_structure_4 ts4_arg;
+ ts4_type.elements = ts4_type_elements;
+ ts4_type_elements[0] = &ffi_type_uint;
+ ts4_type_elements[1] = &ffi_type_uint;
+ ts4_type_elements[2] = &ffi_type_uint;
+ ts4_type_elements[3] = NULL;
+
+
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_4 *ts4_result =
+ (test_structure_4 *) malloc (sizeof(test_structure_4));
+
+ args[0] = &ts4_type;
+ values[0] = &ts4_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts4_type, args) == FFI_OK);
+
+ ts4_arg.ui1 = 2;
+ ts4_arg.ui2 = 3;
+ ts4_arg.ui3 = 4;
+
+ ffi_call (&cif, FFI_FN(struct4), ts4_result, values);
+
+ CHECK(ts4_result->ui3 == 2U * 3U * 4U);
+
+
+ free (ts4_result);
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/struct5.c b/libffi-3.0.4/testsuite/libffi.call/struct5.c
new file mode 100644
index 0000000..c03cc97
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/struct5.c
@@ -0,0 +1,65 @@
+/* Area: ffi_call
+ Purpose: Check structures.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+typedef struct
+{
+ char c1;
+ char c2;
+} test_structure_5;
+
+static test_structure_5 struct5(test_structure_5 ts1, test_structure_5 ts2)
+{
+ ts1.c1 += ts2.c1;
+ ts1.c2 -= ts2.c2;
+
+ return ts1;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_type ts5_type;
+ ffi_type *ts5_type_elements[3];
+ ts5_type.size = 0;
+ ts5_type.alignment = 0;
+ ts5_type.type = FFI_TYPE_STRUCT;
+ ts5_type.elements = ts5_type_elements;
+ ts5_type_elements[0] = &ffi_type_schar;
+ ts5_type_elements[1] = &ffi_type_schar;
+ ts5_type_elements[2] = NULL;
+
+ test_structure_5 ts5_arg1, ts5_arg2;
+
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_5 *ts5_result =
+ (test_structure_5 *) malloc (sizeof(test_structure_5));
+
+ args[0] = &ts5_type;
+ args[1] = &ts5_type;
+ values[0] = &ts5_arg1;
+ values[1] = &ts5_arg2;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ts5_type, args) == FFI_OK);
+
+ ts5_arg1.c1 = 2;
+ ts5_arg1.c2 = 6;
+ ts5_arg2.c1 = 5;
+ ts5_arg2.c2 = 3;
+
+ ffi_call (&cif, FFI_FN(struct5), ts5_result, values);
+
+ CHECK(ts5_result->c1 == 7);
+ CHECK(ts5_result->c2 == 3);
+
+
+ free (ts5_result);
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/struct6.c b/libffi-3.0.4/testsuite/libffi.call/struct6.c
new file mode 100644
index 0000000..83db9af
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/struct6.c
@@ -0,0 +1,64 @@
+/* Area: ffi_call
+ Purpose: Check structures.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+typedef struct
+{
+ float f;
+ double d;
+} test_structure_6;
+
+static test_structure_6 struct6 (test_structure_6 ts)
+{
+ ts.f += 1;
+ ts.d += 1;
+
+ return ts;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_type ts6_type;
+ ffi_type *ts6_type_elements[3];
+ ts6_type.size = 0;
+ ts6_type.alignment = 0;
+ ts6_type.type = FFI_TYPE_STRUCT;
+ ts6_type.elements = ts6_type_elements;
+ ts6_type_elements[0] = &ffi_type_float;
+ ts6_type_elements[1] = &ffi_type_double;
+ ts6_type_elements[2] = NULL;
+
+
+ test_structure_6 ts6_arg;
+
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_6 *ts6_result =
+ (test_structure_6 *) malloc (sizeof(test_structure_6));
+
+ args[0] = &ts6_type;
+ values[0] = &ts6_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts6_type, args) == FFI_OK);
+
+ ts6_arg.f = 5.55f;
+ ts6_arg.d = 6.66;
+
+ printf ("%g\n", ts6_arg.f);
+ printf ("%g\n", ts6_arg.d);
+
+ ffi_call(&cif, FFI_FN(struct6), ts6_result, values);
+
+ CHECK(ts6_result->f == 5.55f + 1);
+ CHECK(ts6_result->d == 6.66 + 1);
+
+ free (ts6_result);
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/struct7.c b/libffi-3.0.4/testsuite/libffi.call/struct7.c
new file mode 100644
index 0000000..58aac4c
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/struct7.c
@@ -0,0 +1,74 @@
+/* Area: ffi_call
+ Purpose: Check structures.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+typedef struct
+{
+ float f1;
+ float f2;
+ double d;
+} test_structure_7;
+
+static test_structure_7 struct7 (test_structure_7 ts)
+{
+ ts.f1 += 1;
+ ts.f2 += 1;
+ ts.d += 1;
+
+ return ts;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_type ts7_type;
+ ffi_type *ts7_type_elements[4];
+ ts7_type.size = 0;
+ ts7_type.alignment = 0;
+ ts7_type.type = FFI_TYPE_STRUCT;
+ ts7_type.elements = ts7_type_elements;
+ ts7_type_elements[0] = &ffi_type_float;
+ ts7_type_elements[1] = &ffi_type_float;
+ ts7_type_elements[2] = &ffi_type_double;
+ ts7_type_elements[3] = NULL;
+
+
+ test_structure_7 ts7_arg;
+
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_7 *ts7_result =
+ (test_structure_7 *) malloc (sizeof(test_structure_7));
+
+ args[0] = &ts7_type;
+ values[0] = &ts7_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts7_type, args) == FFI_OK);
+
+ ts7_arg.f1 = 5.55f;
+ ts7_arg.f2 = 55.5f;
+ ts7_arg.d = 6.66;
+
+ printf ("%g\n", ts7_arg.f1);
+ printf ("%g\n", ts7_arg.f2);
+ printf ("%g\n", ts7_arg.d);
+
+ ffi_call(&cif, FFI_FN(struct7), ts7_result, values);
+
+ printf ("%g\n", ts7_result->f1);
+ printf ("%g\n", ts7_result->f2);
+ printf ("%g\n", ts7_result->d);
+
+ CHECK(ts7_result->f1 == 5.55f + 1);
+ CHECK(ts7_result->f2 == 55.5f + 1);
+ CHECK(ts7_result->d == 6.66 + 1);
+
+ free (ts7_result);
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/struct8.c b/libffi-3.0.4/testsuite/libffi.call/struct8.c
new file mode 100644
index 0000000..c773ac7
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/struct8.c
@@ -0,0 +1,80 @@
+/* Area: ffi_call
+ Purpose: Check structures.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+typedef struct
+{
+ float f1;
+ float f2;
+ float f3;
+ float f4;
+} test_structure_8;
+
+static test_structure_8 struct8 (test_structure_8 ts)
+{
+ ts.f1 += 1;
+ ts.f2 += 1;
+ ts.f3 += 1;
+ ts.f4 += 1;
+
+ return ts;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_type ts8_type;
+ ffi_type *ts8_type_elements[5];
+ ts8_type.size = 0;
+ ts8_type.alignment = 0;
+ ts8_type.type = FFI_TYPE_STRUCT;
+ ts8_type.elements = ts8_type_elements;
+ ts8_type_elements[0] = &ffi_type_float;
+ ts8_type_elements[1] = &ffi_type_float;
+ ts8_type_elements[2] = &ffi_type_float;
+ ts8_type_elements[3] = &ffi_type_float;
+ ts8_type_elements[4] = NULL;
+
+ test_structure_8 ts8_arg;
+
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_8 *ts8_result =
+ (test_structure_8 *) malloc (sizeof(test_structure_8));
+
+ args[0] = &ts8_type;
+ values[0] = &ts8_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts8_type, args) == FFI_OK);
+
+ ts8_arg.f1 = 5.55f;
+ ts8_arg.f2 = 55.5f;
+ ts8_arg.f3 = -5.55f;
+ ts8_arg.f4 = -55.5f;
+
+ printf ("%g\n", ts8_arg.f1);
+ printf ("%g\n", ts8_arg.f2);
+ printf ("%g\n", ts8_arg.f3);
+ printf ("%g\n", ts8_arg.f4);
+
+ ffi_call(&cif, FFI_FN(struct8), ts8_result, values);
+
+ printf ("%g\n", ts8_result->f1);
+ printf ("%g\n", ts8_result->f2);
+ printf ("%g\n", ts8_result->f3);
+ printf ("%g\n", ts8_result->f4);
+
+ CHECK(ts8_result->f1 == 5.55f + 1);
+ CHECK(ts8_result->f2 == 55.5f + 1);
+ CHECK(ts8_result->f3 == -5.55f + 1);
+ CHECK(ts8_result->f4 == -55.5f + 1);
+
+ free (ts8_result);
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.call/struct9.c b/libffi-3.0.4/testsuite/libffi.call/struct9.c
new file mode 100644
index 0000000..f30091f
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.call/struct9.c
@@ -0,0 +1,67 @@
+/* Area: ffi_call
+ Purpose: Check structures.
+ Limitations: none.
+ PR: none.
+ Originator: From the original ffitest.c */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct
+{
+ float f;
+ int i;
+} test_structure_9;
+
+static test_structure_9 struct9 (test_structure_9 ts)
+{
+ ts.f += 1;
+ ts.i += 1;
+
+ return ts;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_type ts9_type;
+ ffi_type *ts9_type_elements[3];
+ ts9_type.size = 0;
+ ts9_type.alignment = 0;
+ ts9_type.type = FFI_TYPE_STRUCT;
+ ts9_type.elements = ts9_type_elements;
+ ts9_type_elements[0] = &ffi_type_float;
+ ts9_type_elements[1] = &ffi_type_sint;
+ ts9_type_elements[2] = NULL;
+
+ test_structure_9 ts9_arg;
+
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_9 *ts9_result =
+ (test_structure_9 *) malloc (sizeof(test_structure_9));
+
+ args[0] = &ts9_type;
+ values[0] = &ts9_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts9_type, args) == FFI_OK);
+
+ ts9_arg.f = 5.55f;
+ ts9_arg.i = 5;
+
+ printf ("%g\n", ts9_arg.f);
+ printf ("%d\n", ts9_arg.i);
+
+ ffi_call(&cif, FFI_FN(struct9), ts9_result, values);
+
+ printf ("%g\n", ts9_result->f);
+ printf ("%d\n", ts9_result->i);
+
+ CHECK(ts9_result->f == 5.55f + 1);
+ CHECK(ts9_result->i == 5 + 1);
+
+ free (ts9_result);
+ exit(0);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.special/ffitestcxx.h b/libffi-3.0.4/testsuite/libffi.special/ffitestcxx.h
new file mode 100644
index 0000000..b9f0d48
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.special/ffitestcxx.h
@@ -0,0 +1,86 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <ffi.h>
+#include "fficonfig.h"
+
+#define MAX_ARGS 256
+
+
+/* Define __UNUSED__ that also other compilers than gcc can run the tests. */
+#undef __UNUSED__
+#if defined(__GNUC__)
+#define __UNUSED__ __attribute__((__unused__))
+#else
+#define __UNUSED__
+#endif
+
+#define CHECK(x) (!(x) ? abort() : (void)0)
+
+/* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a
+ file open. */
+#ifdef HAVE_MMAP_ANON
+# undef HAVE_MMAP_DEV_ZERO
+
+# include <sys/mman.h>
+# ifndef MAP_FAILED
+# define MAP_FAILED -1
+# endif
+# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
+# define MAP_ANONYMOUS MAP_ANON
+# endif
+# define USING_MMAP
+
+#endif
+
+#ifdef HAVE_MMAP_DEV_ZERO
+
+# include <sys/mman.h>
+# ifndef MAP_FAILED
+# define MAP_FAILED -1
+# endif
+# define USING_MMAP
+
+#endif
+
+#ifdef USING_MMAP
+static inline void *
+allocate_mmap (size_t size)
+{
+ void *page;
+#if defined (HAVE_MMAP_DEV_ZERO)
+ static int dev_zero_fd = -1;
+#endif
+
+#ifdef HAVE_MMAP_DEV_ZERO
+ if (dev_zero_fd == -1)
+ {
+ dev_zero_fd = open ("/dev/zero", O_RDONLY);
+ if (dev_zero_fd == -1)
+ {
+ perror ("open /dev/zero: %m");
+ exit (1);
+ }
+ }
+#endif
+
+
+#ifdef HAVE_MMAP_ANON
+ page = mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+#endif
+#ifdef HAVE_MMAP_DEV_ZERO
+ page = mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE, dev_zero_fd, 0);
+#endif
+
+ if (page == MAP_FAILED)
+ {
+ perror ("virtual memory exhausted");
+ exit (1);
+ }
+
+ return page;
+}
+
+#endif
diff --git a/libffi-3.0.4/testsuite/libffi.special/special.exp b/libffi-3.0.4/testsuite/libffi.special/special.exp
new file mode 100644
index 0000000..b7d31da
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.special/special.exp
@@ -0,0 +1,38 @@
+# Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+# libffi testsuite that uses the 'dg.exp' driver.
+
+load_lib libffi-dg.exp
+
+dg-init
+libffi-init
+
+global srcdir subdir
+
+global cxx_options
+
+set cxx_options " -shared-libgcc -lstdc++"
+
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "-O0 -W -Wall"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "-O2"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "-O3"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "-Os"
+
+dg-finish
+
+# Local Variables:
+# tcl-indent-level:4
+# End:
diff --git a/libffi-3.0.4/testsuite/libffi.special/unwindtest.cc b/libffi-3.0.4/testsuite/libffi.special/unwindtest.cc
new file mode 100644
index 0000000..a3d8037
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.special/unwindtest.cc
@@ -0,0 +1,123 @@
+/* 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 } */
+#include "ffitestcxx.h"
+
+void
+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)(long)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)(long)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;
+#ifndef USING_MMAP
+ static ffi_closure cl;
+#endif
+ ffi_closure *pcl;
+ ffi_type * cl_arg_types[17];
+#ifdef USING_MMAP
+ pcl = (ffi_closure *) allocate_mmap (sizeof(ffi_closure));
+#else
+ pcl = &cl;
+#endif
+
+ {
+ 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(pcl, &cif, closure_test_fn, NULL) == FFI_OK);
+
+ try
+ {
+ (*((closure_test_type)(pcl)))();
+ } 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(pcl, &cif, closure_test_fn1,
+ (void *) 3 /* userdata */) == FFI_OK);
+ try
+ {
+ (*((closure_test_type1)pcl))
+ (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);
+}
diff --git a/libffi-3.0.4/testsuite/libffi.special/unwindtest_ffi_call.cc b/libffi-3.0.4/testsuite/libffi.special/unwindtest_ffi_call.cc
new file mode 100644
index 0000000..29739cd
--- /dev/null
+++ b/libffi-3.0.4/testsuite/libffi.special/unwindtest_ffi_call.cc
@@ -0,0 +1,53 @@
+/* Area: ffi_call, unwind info
+ Purpose: Check if the unwind information is passed correctly.
+ Limitations: none.
+ PR: none.
+ Originator: Andreas Tobler <andreast@gcc.gnu.org> 20061213 */
+
+/* { dg-do run } */
+#include "ffitestcxx.h"
+
+static int checking(int a __UNUSED__, short b __UNUSED__,
+ signed char c __UNUSED__)
+{
+ throw 9;
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ ffi_arg rint;
+
+ signed int si;
+ signed short ss;
+ signed char sc;
+
+ args[0] = &ffi_type_sint;
+ values[0] = &si;
+ args[1] = &ffi_type_sshort;
+ values[1] = &ss;
+ args[2] = &ffi_type_schar;
+ values[2] = &sc;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
+ &ffi_type_sint, args) == FFI_OK);
+
+ si = -6;
+ ss = -12;
+ sc = -1;
+ {
+ try
+ {
+ ffi_call(&cif, FFI_FN(checking), &rint, values);
+ } catch (int exception_code)
+ {
+ CHECK(exception_code == 9);
+ }
+ printf("part one OK\n");
+ /* { dg-output "part one OK" } */
+ }
+ exit(0);
+}