From 181d8ded82d49d0133d9d6fd1631d9816c970bfa Mon Sep 17 00:00:00 2001 From: Matthias Benkard Date: Sat, 26 Jan 2008 12:06:34 +0100 Subject: Import libffi from PyObjC 1.3.7. darcs-hash:129bccb59266f997deac9b0353aea2d2d4049f92 --- libffi/testsuite/Makefile.am | 16 + libffi/testsuite/Makefile.in | 379 +++++++++++++++++++++ libffi/testsuite/config/default.exp | 1 + libffi/testsuite/lib/libffi-dg.exp | 271 +++++++++++++++ libffi/testsuite/libffi.call/call.exp | 32 ++ libffi/testsuite/libffi.call/closure_fn0.c | 93 +++++ libffi/testsuite/libffi.call/closure_fn1.c | 89 +++++ libffi/testsuite/libffi.call/closure_fn2.c | 89 +++++ libffi/testsuite/libffi.call/closure_fn3.c | 90 +++++ libffi/testsuite/libffi.call/closure_fn4.c | 96 ++++++ libffi/testsuite/libffi.call/closure_fn5.c | 99 ++++++ libffi/testsuite/libffi.call/cls_12byte.c | 97 ++++++ libffi/testsuite/libffi.call/cls_16byte.c | 98 ++++++ libffi/testsuite/libffi.call/cls_18byte.c | 103 ++++++ libffi/testsuite/libffi.call/cls_19byte.c | 109 ++++++ libffi/testsuite/libffi.call/cls_1_1byte.c | 94 +++++ libffi/testsuite/libffi.call/cls_20byte.c | 98 ++++++ libffi/testsuite/libffi.call/cls_20byte1.c | 98 ++++++ libffi/testsuite/libffi.call/cls_24byte.c | 120 +++++++ libffi/testsuite/libffi.call/cls_2byte.c | 97 ++++++ libffi/testsuite/libffi.call/cls_3_1byte.c | 102 ++++++ libffi/testsuite/libffi.call/cls_3byte1.c | 97 ++++++ libffi/testsuite/libffi.call/cls_3byte2.c | 97 ++++++ libffi/testsuite/libffi.call/cls_4_1byte.c | 105 ++++++ libffi/testsuite/libffi.call/cls_4byte.c | 97 ++++++ libffi/testsuite/libffi.call/cls_5byte.c | 101 ++++++ libffi/testsuite/libffi.call/cls_64byte.c | 131 +++++++ libffi/testsuite/libffi.call/cls_6byte.c | 105 ++++++ libffi/testsuite/libffi.call/cls_7byte.c | 104 ++++++ libffi/testsuite/libffi.call/cls_8byte.c | 95 ++++++ libffi/testsuite/libffi.call/cls_9byte1.c | 98 ++++++ libffi/testsuite/libffi.call/cls_9byte2.c | 99 ++++++ libffi/testsuite/libffi.call/cls_align_double.c | 98 ++++++ libffi/testsuite/libffi.call/cls_align_float.c | 98 ++++++ .../testsuite/libffi.call/cls_align_longdouble.c | 100 ++++++ libffi/testsuite/libffi.call/cls_align_pointer.c | 98 ++++++ libffi/testsuite/libffi.call/cls_align_sint16.c | 98 ++++++ libffi/testsuite/libffi.call/cls_align_sint32.c | 98 ++++++ libffi/testsuite/libffi.call/cls_align_sint64.c | 98 ++++++ libffi/testsuite/libffi.call/cls_align_uint16.c | 98 ++++++ libffi/testsuite/libffi.call/cls_align_uint32.c | 98 ++++++ libffi/testsuite/libffi.call/cls_align_uint64.c | 98 ++++++ libffi/testsuite/libffi.call/cls_double.c | 51 +++ libffi/testsuite/libffi.call/cls_float.c | 51 +++ libffi/testsuite/libffi.call/cls_multi_schar.c | 81 +++++ libffi/testsuite/libffi.call/cls_multi_sshort.c | 81 +++++ .../testsuite/libffi.call/cls_multi_sshortchar.c | 93 +++++ libffi/testsuite/libffi.call/cls_multi_uchar.c | 96 ++++++ libffi/testsuite/libffi.call/cls_multi_ushort.c | 81 +++++ .../testsuite/libffi.call/cls_multi_ushortchar.c | 93 +++++ libffi/testsuite/libffi.call/cls_schar.c | 50 +++ libffi/testsuite/libffi.call/cls_sint.c | 50 +++ libffi/testsuite/libffi.call/cls_sshort.c | 50 +++ libffi/testsuite/libffi.call/cls_uchar.c | 50 +++ libffi/testsuite/libffi.call/cls_uint.c | 51 +++ libffi/testsuite/libffi.call/cls_ulonglong.c | 54 +++ libffi/testsuite/libffi.call/cls_ushort.c | 51 +++ libffi/testsuite/libffi.call/ffitest.h | 79 +++++ libffi/testsuite/libffi.call/float.c | 64 ++++ libffi/testsuite/libffi.call/float1.c | 42 +++ libffi/testsuite/libffi.call/float2.c | 60 ++++ libffi/testsuite/libffi.call/many.c | 69 ++++ libffi/testsuite/libffi.call/many_win32.c | 63 ++++ libffi/testsuite/libffi.call/nested_struct.c | 159 +++++++++ libffi/testsuite/libffi.call/nested_struct1.c | 168 +++++++++ libffi/testsuite/libffi.call/nested_struct2.c | 127 +++++++ libffi/testsuite/libffi.call/nested_struct3.c | 118 +++++++ libffi/testsuite/libffi.call/problem1.c | 97 ++++++ libffi/testsuite/libffi.call/promotion.c | 59 ++++ libffi/testsuite/libffi.call/pyobjc-tc.c | 114 +++++++ libffi/testsuite/libffi.call/return_ll.c | 45 +++ libffi/testsuite/libffi.call/return_sc.c | 38 +++ libffi/testsuite/libffi.call/return_uc.c | 40 +++ libffi/testsuite/libffi.call/strlen.c | 44 +++ libffi/testsuite/libffi.call/strlen_win32.c | 44 +++ libffi/testsuite/libffi.call/struct1.c | 67 ++++ libffi/testsuite/libffi.call/struct2.c | 67 ++++ libffi/testsuite/libffi.call/struct3.c | 59 ++++ libffi/testsuite/libffi.call/struct4.c | 63 ++++ libffi/testsuite/libffi.call/struct5.c | 65 ++++ libffi/testsuite/libffi.call/struct6.c | 64 ++++ libffi/testsuite/libffi.call/struct7.c | 74 ++++ libffi/testsuite/libffi.call/struct8.c | 80 +++++ libffi/testsuite/libffi.call/struct9.c | 67 ++++ libffi/testsuite/libffi.special/ffitestcxx.h | 77 +++++ libffi/testsuite/libffi.special/special.exp | 36 ++ libffi/testsuite/libffi.special/unwindtest.cc | 123 +++++++ 87 files changed, 7637 insertions(+) create mode 100644 libffi/testsuite/Makefile.am create mode 100644 libffi/testsuite/Makefile.in create mode 100644 libffi/testsuite/config/default.exp create mode 100644 libffi/testsuite/lib/libffi-dg.exp create mode 100644 libffi/testsuite/libffi.call/call.exp create mode 100644 libffi/testsuite/libffi.call/closure_fn0.c create mode 100644 libffi/testsuite/libffi.call/closure_fn1.c create mode 100644 libffi/testsuite/libffi.call/closure_fn2.c create mode 100644 libffi/testsuite/libffi.call/closure_fn3.c create mode 100644 libffi/testsuite/libffi.call/closure_fn4.c create mode 100644 libffi/testsuite/libffi.call/closure_fn5.c create mode 100644 libffi/testsuite/libffi.call/cls_12byte.c create mode 100644 libffi/testsuite/libffi.call/cls_16byte.c create mode 100644 libffi/testsuite/libffi.call/cls_18byte.c create mode 100644 libffi/testsuite/libffi.call/cls_19byte.c create mode 100644 libffi/testsuite/libffi.call/cls_1_1byte.c create mode 100644 libffi/testsuite/libffi.call/cls_20byte.c create mode 100644 libffi/testsuite/libffi.call/cls_20byte1.c create mode 100644 libffi/testsuite/libffi.call/cls_24byte.c create mode 100644 libffi/testsuite/libffi.call/cls_2byte.c create mode 100644 libffi/testsuite/libffi.call/cls_3_1byte.c create mode 100644 libffi/testsuite/libffi.call/cls_3byte1.c create mode 100644 libffi/testsuite/libffi.call/cls_3byte2.c create mode 100644 libffi/testsuite/libffi.call/cls_4_1byte.c create mode 100644 libffi/testsuite/libffi.call/cls_4byte.c create mode 100644 libffi/testsuite/libffi.call/cls_5byte.c create mode 100644 libffi/testsuite/libffi.call/cls_64byte.c create mode 100644 libffi/testsuite/libffi.call/cls_6byte.c create mode 100644 libffi/testsuite/libffi.call/cls_7byte.c create mode 100644 libffi/testsuite/libffi.call/cls_8byte.c create mode 100644 libffi/testsuite/libffi.call/cls_9byte1.c create mode 100644 libffi/testsuite/libffi.call/cls_9byte2.c create mode 100644 libffi/testsuite/libffi.call/cls_align_double.c create mode 100644 libffi/testsuite/libffi.call/cls_align_float.c create mode 100644 libffi/testsuite/libffi.call/cls_align_longdouble.c create mode 100644 libffi/testsuite/libffi.call/cls_align_pointer.c create mode 100644 libffi/testsuite/libffi.call/cls_align_sint16.c create mode 100644 libffi/testsuite/libffi.call/cls_align_sint32.c create mode 100644 libffi/testsuite/libffi.call/cls_align_sint64.c create mode 100644 libffi/testsuite/libffi.call/cls_align_uint16.c create mode 100644 libffi/testsuite/libffi.call/cls_align_uint32.c create mode 100644 libffi/testsuite/libffi.call/cls_align_uint64.c create mode 100644 libffi/testsuite/libffi.call/cls_double.c create mode 100644 libffi/testsuite/libffi.call/cls_float.c create mode 100644 libffi/testsuite/libffi.call/cls_multi_schar.c create mode 100644 libffi/testsuite/libffi.call/cls_multi_sshort.c create mode 100644 libffi/testsuite/libffi.call/cls_multi_sshortchar.c create mode 100644 libffi/testsuite/libffi.call/cls_multi_uchar.c create mode 100644 libffi/testsuite/libffi.call/cls_multi_ushort.c create mode 100644 libffi/testsuite/libffi.call/cls_multi_ushortchar.c create mode 100644 libffi/testsuite/libffi.call/cls_schar.c create mode 100644 libffi/testsuite/libffi.call/cls_sint.c create mode 100644 libffi/testsuite/libffi.call/cls_sshort.c create mode 100644 libffi/testsuite/libffi.call/cls_uchar.c create mode 100644 libffi/testsuite/libffi.call/cls_uint.c create mode 100644 libffi/testsuite/libffi.call/cls_ulonglong.c create mode 100644 libffi/testsuite/libffi.call/cls_ushort.c create mode 100644 libffi/testsuite/libffi.call/ffitest.h create mode 100644 libffi/testsuite/libffi.call/float.c create mode 100644 libffi/testsuite/libffi.call/float1.c create mode 100644 libffi/testsuite/libffi.call/float2.c create mode 100644 libffi/testsuite/libffi.call/many.c create mode 100644 libffi/testsuite/libffi.call/many_win32.c create mode 100644 libffi/testsuite/libffi.call/nested_struct.c create mode 100644 libffi/testsuite/libffi.call/nested_struct1.c create mode 100644 libffi/testsuite/libffi.call/nested_struct2.c create mode 100644 libffi/testsuite/libffi.call/nested_struct3.c create mode 100644 libffi/testsuite/libffi.call/problem1.c create mode 100644 libffi/testsuite/libffi.call/promotion.c create mode 100644 libffi/testsuite/libffi.call/pyobjc-tc.c create mode 100644 libffi/testsuite/libffi.call/return_ll.c create mode 100644 libffi/testsuite/libffi.call/return_sc.c create mode 100644 libffi/testsuite/libffi.call/return_uc.c create mode 100644 libffi/testsuite/libffi.call/strlen.c create mode 100644 libffi/testsuite/libffi.call/strlen_win32.c create mode 100644 libffi/testsuite/libffi.call/struct1.c create mode 100644 libffi/testsuite/libffi.call/struct2.c create mode 100644 libffi/testsuite/libffi.call/struct3.c create mode 100644 libffi/testsuite/libffi.call/struct4.c create mode 100644 libffi/testsuite/libffi.call/struct5.c create mode 100644 libffi/testsuite/libffi.call/struct6.c create mode 100644 libffi/testsuite/libffi.call/struct7.c create mode 100644 libffi/testsuite/libffi.call/struct8.c create mode 100644 libffi/testsuite/libffi.call/struct9.c create mode 100644 libffi/testsuite/libffi.special/ffitestcxx.h create mode 100644 libffi/testsuite/libffi.special/special.exp create mode 100644 libffi/testsuite/libffi.special/unwindtest.cc (limited to 'libffi/testsuite') diff --git a/libffi/testsuite/Makefile.am b/libffi/testsuite/Makefile.am new file mode 100644 index 0000000..f94ca00 --- /dev/null +++ b/libffi/testsuite/Makefile.am @@ -0,0 +1,16 @@ +## 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 diff --git a/libffi/testsuite/Makefile.in b/libffi/testsuite/Makefile.in new file mode 100644 index 0000000..d00f50c --- /dev/null +++ b/libffi/testsuite/Makefile.in @@ -0,0 +1,379 @@ +# Makefile.in generated by automake 1.7.9 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +# 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@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +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@ +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +ALPHA_FALSE = @ALPHA_FALSE@ +ALPHA_TRUE = @ALPHA_TRUE@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ + +AM_RUNTESTFLAGS = +ARM_FALSE = @ARM_FALSE@ +ARM_TRUE = @ARM_TRUE@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@ +IA64_FALSE = @IA64_FALSE@ +IA64_TRUE = @IA64_TRUE@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +M68K_FALSE = @M68K_FALSE@ +M68K_TRUE = @M68K_TRUE@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +MIPS_IRIX_FALSE = @MIPS_IRIX_FALSE@ +MIPS_IRIX_TRUE = @MIPS_IRIX_TRUE@ +MIPS_LINUX_FALSE = @MIPS_LINUX_FALSE@ +MIPS_LINUX_TRUE = @MIPS_LINUX_TRUE@ +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@ +POWERPC_AIX_FALSE = @POWERPC_AIX_FALSE@ +POWERPC_AIX_TRUE = @POWERPC_AIX_TRUE@ +POWERPC_DARWIN_FALSE = @POWERPC_DARWIN_FALSE@ +POWERPC_DARWIN_TRUE = @POWERPC_DARWIN_TRUE@ +POWERPC_FALSE = @POWERPC_FALSE@ +POWERPC_TRUE = @POWERPC_TRUE@ +RANLIB = @RANLIB@ +S390_FALSE = @S390_FALSE@ +S390_TRUE = @S390_TRUE@ +SET_MAKE = @SET_MAKE@ +SH64_FALSE = @SH64_FALSE@ +SH64_TRUE = @SH64_TRUE@ +SHELL = @SHELL@ +SH_FALSE = @SH_FALSE@ +SH_TRUE = @SH_TRUE@ +SPARC_FALSE = @SPARC_FALSE@ +SPARC_TRUE = @SPARC_TRUE@ +STRIP = @STRIP@ +TARGET = @TARGET@ +TARGETDIR = @TARGETDIR@ +TESTSUBDIR_FALSE = @TESTSUBDIR_FALSE@ +TESTSUBDIR_TRUE = @TESTSUBDIR_TRUE@ +VERSION = @VERSION@ +X86_64_FALSE = @X86_64_FALSE@ +X86_64_TRUE = @X86_64_TRUE@ +X86_FALSE = @X86_FALSE@ +X86_TRUE = @X86_TRUE@ +X86_WIN32_FALSE = @X86_WIN32_FALSE@ +X86_WIN32_TRUE = @X86_WIN32_TRUE@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +gcc_version = @gcc_version@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +multi_basedir = @multi_basedir@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +tool_include_dir = @tool_include_dir@ +toolexecdir = @toolexecdir@ +toolexeclibdir = @toolexeclibdir@ + +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 +subdir = testsuite +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/fficonfig.h +CONFIG_CLEAN_FILES = +DIST_SOURCES = +DIST_COMMON = $(srcdir)/Makefile.in Makefile.am +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign testsuite/Makefile +Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + +RUNTESTFLAGS = +DEJATOOL = $(PACKAGE) +RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir + +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 \ + l='$(DEJATOOL)'; for tool in $$l; do \ + $$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \ + done; \ + else echo "WARNING: could not find \`runtest'" 1>&2; :;\ + fi +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 +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = .. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + 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: + -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 \ + distclean-libtool + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +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: uninstall-info-am + +.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 info info-am install \ + install-am install-data install-data-am install-exec \ + install-exec-am install-info install-info-am install-man \ + 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 uninstall-info-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/testsuite/config/default.exp b/libffi/testsuite/config/default.exp new file mode 100644 index 0000000..90967cc --- /dev/null +++ b/libffi/testsuite/config/default.exp @@ -0,0 +1 @@ +load_lib "standard.exp" diff --git a/libffi/testsuite/lib/libffi-dg.exp b/libffi/testsuite/lib/libffi-dg.exp new file mode 100644 index 0000000..f7dd5fd --- /dev/null +++ b/libffi/testsuite/lib/libffi-dg.exp @@ -0,0 +1,271 @@ +# Copyright (C) 2003 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. + +load_lib dg.exp +load_lib libgloss.exp + + + +# Define libffi callbacks for dg.exp. + +proc libffi-dg-test-1 { target_compile prog do_what extra_tool_flags } { + # 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 blddircxx + global TOOL_OPTIONS + global ld_library_path + global libffi_include + global libffi_link_flags + global tool_root_dir + + set blddirffi [lookfor_file [get_multilibs] libffi] + verbose "libffi $blddirffi" + set blddircxx [lookfor_file [get_multilibs] libstdc++-v3] + verbose "libstdc++ $blddircxx" + + 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" + # add the library path for libstdc++ as well. + append ld_library_path ":${blddircxx}/src/.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" + lappend libffi_link_flags "-L${blddircxx}/src/.libs" + } + + # 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 right way to do this would be to modify + # unix.exp -- but that's not an option since it's part of DejaGNU + # proper, so we do it here. + # 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). + setenv LD_LIBRARY_PATH $ld_library_path + setenv SHLIB_PATH $ld_library_path + setenv LD_LIBRARYN32_PATH $ld_library_path + setenv LD_LIBRARY64_PATH $ld_library_path + setenv LD_LIBRARY_PATH_32 $ld_library_path + setenv LD_LIBRARY_PATH_64 $ld_library_path + setenv DYLD_LIBRARY_PATH $ld_library_path +} + +proc libffi_target_compile { source dest type options } { + global gluefile wrap_flags; + global srcdir + global blddirffi + global TOOL_OPTIONS + global ld_library_path + 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 { [string match "powerpc-*-darwin*" $target_triplet] } { + lappend options "libs= -lgcc_s" + } + + 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/testsuite/libffi.call/call.exp b/libffi/testsuite/libffi.call/call.exp new file mode 100644 index 0000000..3b0bd32 --- /dev/null +++ b/libffi/testsuite/libffi.call/call.exp @@ -0,0 +1,32 @@ +# Copyright (C) 2003 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. + +# 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\]]] "" "" + +dg-finish + +# Local Variables: +# tcl-indent-level:4 +# End: diff --git a/libffi/testsuite/libffi.call/closure_fn0.c b/libffi/testsuite/libffi.call/closure_fn0.c new file mode 100644 index 0000000..6d9b2cb --- /dev/null +++ b/libffi/testsuite/libffi.call/closure_fn0.c @@ -0,0 +1,93 @@ +/* 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: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +static void +closure_test_fn0(ffi_cif* cif,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_uint; + cl_arg_types[2] = &ffi_type_uint64; + cl_arg_types[3] = &ffi_type_uint; + cl_arg_types[4] = &ffi_type_sshort; + cl_arg_types[5] = &ffi_type_uint64; + cl_arg_types[6] = &ffi_type_uint; + 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_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/testsuite/libffi.call/closure_fn1.c b/libffi/testsuite/libffi.call/closure_fn1.c new file mode 100644 index 0000000..41818ad --- /dev/null +++ b/libffi/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: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + + +static void closure_test_fn1(ffi_cif* cif,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_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); + + 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/testsuite/libffi.call/closure_fn2.c b/libffi/testsuite/libffi.call/closure_fn2.c new file mode 100644 index 0000000..2a98f96 --- /dev/null +++ b/libffi/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: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +static void closure_test_fn2(ffi_cif* cif,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_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_float; + 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_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/testsuite/libffi.call/closure_fn3.c b/libffi/testsuite/libffi.call/closure_fn3.c new file mode 100644 index 0000000..4f744c8 --- /dev/null +++ b/libffi/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: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +static void closure_test_fn3(ffi_cif* cif,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_uint; + cl_arg_types[10] = &ffi_type_float; + cl_arg_types[11] = &ffi_type_float; + cl_arg_types[12] = &ffi_type_uint; + cl_arg_types[13] = &ffi_type_float; + cl_arg_types[14] = &ffi_type_float; + 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_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/testsuite/libffi.call/closure_fn4.c b/libffi/testsuite/libffi.call/closure_fn4.c new file mode 100644 index 0000000..cbaaf30 --- /dev/null +++ b/libffi/testsuite/libffi.call/closure_fn4.c @@ -0,0 +1,96 @@ +/* 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: 20031026 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ + +#include "ffitest.h" + +static void +closure_test_fn0(ffi_cif* cif,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_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_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/testsuite/libffi.call/closure_fn5.c b/libffi/testsuite/libffi.call/closure_fn5.c new file mode 100644 index 0000000..6a4fc67 --- /dev/null +++ b/libffi/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: 20031026 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ + +#include "ffitest.h" + +static void +closure_test_fn5(ffi_cif* cif,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_uint; + for (i = 11; i < 15; i++) { + cl_arg_types[i] = &ffi_type_uint64; + } + 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_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/testsuite/libffi.call/cls_12byte.c b/libffi/testsuite/libffi.call/cls_12byte.c new file mode 100644 index 0000000..f8a87ec --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_12byte.c @@ -0,0 +1,97 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + 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_uint32; + cls_struct_fields[1] = &ffi_type_uint32; + cls_struct_fields[2] = &ffi_type_uint32; + 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 = ((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/testsuite/libffi.call/cls_16byte.c b/libffi/testsuite/libffi.call/cls_16byte.c new file mode 100644 index 0000000..f8a3b57 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_16byte.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: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + 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_uint32; + cls_struct_fields[1] = &ffi_type_double; + cls_struct_fields[2] = &ffi_type_uint32; + 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" } */ + + 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/testsuite/libffi.call/cls_18byte.c b/libffi/testsuite/libffi.call/cls_18byte.c new file mode 100644 index 0000000..50ce9ff --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_18byte.c @@ -0,0 +1,103 @@ +/* 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: 20030915 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + 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/testsuite/libffi.call/cls_19byte.c b/libffi/testsuite/libffi.call/cls_19byte.c new file mode 100644 index 0000000..3bef938 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_19byte.c @@ -0,0 +1,109 @@ +/* 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: 20030915 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + 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/testsuite/libffi.call/cls_1_1byte.c b/libffi/testsuite/libffi.call/cls_1_1byte.c new file mode 100644 index 0000000..cdf4963 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_1_1byte.c @@ -0,0 +1,94 @@ +/* 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: 20030902 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + + 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/testsuite/libffi.call/cls_20byte.c b/libffi/testsuite/libffi.call/cls_20byte.c new file mode 100644 index 0000000..b02b84d --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_20byte.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: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + 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_uint32; + 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/testsuite/libffi.call/cls_20byte1.c b/libffi/testsuite/libffi.call/cls_20byte1.c new file mode 100644 index 0000000..41866fe --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_20byte1.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: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + 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_uint32; + 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/testsuite/libffi.call/cls_24byte.c b/libffi/testsuite/libffi.call/cls_24byte.c new file mode 100644 index 0000000..ff0f841 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_24byte.c @@ -0,0 +1,120 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Check overlapping. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + 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_uint32; + 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/testsuite/libffi.call/cls_2byte.c b/libffi/testsuite/libffi.call/cls_2byte.c new file mode 100644 index 0000000..2e38177 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_2byte.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: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + + 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/testsuite/libffi.call/cls_3_1byte.c b/libffi/testsuite/libffi.call/cls_3_1byte.c new file mode 100644 index 0000000..8e3044f --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_3_1byte.c @@ -0,0 +1,102 @@ +/* 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: 20030902 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + + 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/testsuite/libffi.call/cls_3byte1.c b/libffi/testsuite/libffi.call/cls_3byte1.c new file mode 100644 index 0000000..294067f --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_3byte1.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. Check overlapping. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + + 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/testsuite/libffi.call/cls_3byte2.c b/libffi/testsuite/libffi.call/cls_3byte2.c new file mode 100644 index 0000000..c429958 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_3byte2.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. Check overlapping. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + + 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/testsuite/libffi.call/cls_4_1byte.c b/libffi/testsuite/libffi.call/cls_4_1byte.c new file mode 100644 index 0000000..008e24a --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_4_1byte.c @@ -0,0 +1,105 @@ +/* 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: 20030902 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + + 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/testsuite/libffi.call/cls_4byte.c b/libffi/testsuite/libffi.call/cls_4byte.c new file mode 100644 index 0000000..ecb2ce9 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_4byte.c @@ -0,0 +1,97 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Check overlapping. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ + +#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, void* resp, void** args, void* userdata) +{ + + 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/testsuite/libffi.call/cls_5byte.c b/libffi/testsuite/libffi.call/cls_5byte.c new file mode 100644 index 0000000..6274a19 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_5byte.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: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + + 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; + + 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" } */ + + 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/testsuite/libffi.call/cls_64byte.c b/libffi/testsuite/libffi.call/cls_64byte.c new file mode 100644 index 0000000..cc1b771 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_64byte.c @@ -0,0 +1,131 @@ +/* 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: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + 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/testsuite/libffi.call/cls_6byte.c b/libffi/testsuite/libffi.call/cls_6byte.c new file mode 100644 index 0000000..0c1ab28 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_6byte.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: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + + 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/testsuite/libffi.call/cls_7byte.c b/libffi/testsuite/libffi.call/cls_7byte.c new file mode 100644 index 0000000..a7998dd --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_7byte.c @@ -0,0 +1,104 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Check overlapping. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + + 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/testsuite/libffi.call/cls_8byte.c b/libffi/testsuite/libffi.call/cls_8byte.c new file mode 100644 index 0000000..efa1afc --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_8byte.c @@ -0,0 +1,95 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Depending on the ABI. Check overlapping. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + + 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_uint32; + 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/testsuite/libffi.call/cls_9byte1.c b/libffi/testsuite/libffi.call/cls_9byte1.c new file mode 100644 index 0000000..6994570 --- /dev/null +++ b/libffi/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: 20030914 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, + void* userdata) +{ + 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_uint32; + 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/testsuite/libffi.call/cls_9byte2.c b/libffi/testsuite/libffi.call/cls_9byte2.c new file mode 100644 index 0000000..976ed59 --- /dev/null +++ b/libffi/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: 20030914 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, + void* userdata) +{ + 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_uint32; + 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/testsuite/libffi.call/cls_align_double.c b/libffi/testsuite/libffi.call/cls_align_double.c new file mode 100644 index 0000000..826b6a8 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_align_double.c @@ -0,0 +1,98 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of double. + Limitations: none. + PR: none. + Originator: 20031203 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + + 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/testsuite/libffi.call/cls_align_float.c b/libffi/testsuite/libffi.call/cls_align_float.c new file mode 100644 index 0000000..6deff30 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_align_float.c @@ -0,0 +1,98 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of float. + Limitations: none. + PR: none. + Originator: 20031203 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + + 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/testsuite/libffi.call/cls_align_longdouble.c b/libffi/testsuite/libffi.call/cls_align_longdouble.c new file mode 100644 index 0000000..aacfcba --- /dev/null +++ b/libffi/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: 20031203 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-options -mlong-double-128 { target powerpc64*-*-* } } */ + +#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, void* resp, void** args, void* userdata) +{ + + 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/testsuite/libffi.call/cls_align_pointer.c b/libffi/testsuite/libffi.call/cls_align_pointer.c new file mode 100644 index 0000000..9fb42b4 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_align_pointer.c @@ -0,0 +1,98 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of pointer. + Limitations: none. + PR: none. + Originator: 20031203 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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 *)((size_t)a1.b + (size_t)a2.b); + result.c = a1.c + a2.c; + + printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, (size_t)a1.b, a1.c, a2.a, (size_t)a2.b, a2.c, result.a, (size_t)result.b, result.c); + + return result; +} + +static void +cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +{ + + 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 %d %d\n", res_dbl.a, (size_t)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, (size_t)res_dbl.b, res_dbl.c); + /* { dg-output "\nres: 13 14271 140" } */ + + exit(0); +} diff --git a/libffi/testsuite/libffi.call/cls_align_sint16.c b/libffi/testsuite/libffi.call/cls_align_sint16.c new file mode 100644 index 0000000..611d5a3 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_align_sint16.c @@ -0,0 +1,98 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of sint16. + Limitations: none. + PR: none. + Originator: 20031203 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + + 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_sint16; + 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/testsuite/libffi.call/cls_align_sint32.c b/libffi/testsuite/libffi.call/cls_align_sint32.c new file mode 100644 index 0000000..fcfae03 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_align_sint32.c @@ -0,0 +1,98 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of sint32. + Limitations: none. + PR: none. + Originator: 20031203 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + + 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_sint32; + 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/testsuite/libffi.call/cls_align_sint64.c b/libffi/testsuite/libffi.call/cls_align_sint64.c new file mode 100644 index 0000000..fd88e7c --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_align_sint64.c @@ -0,0 +1,98 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of sint64. + Limitations: none. + PR: none. + Originator: 20031203 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + + 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/testsuite/libffi.call/cls_align_uint16.c b/libffi/testsuite/libffi.call/cls_align_uint16.c new file mode 100644 index 0000000..bad9cd8 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_align_uint16.c @@ -0,0 +1,98 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of uint16. + Limitations: none. + PR: none. + Originator: 20031203 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + + 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_uint16; + 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/testsuite/libffi.call/cls_align_uint32.c b/libffi/testsuite/libffi.call/cls_align_uint32.c new file mode 100644 index 0000000..d6d0fe0 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_align_uint32.c @@ -0,0 +1,98 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of uint32. + Limitations: none. + PR: none. + Originator: 20031203 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + + 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_uint32; + 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/testsuite/libffi.call/cls_align_uint64.c b/libffi/testsuite/libffi.call/cls_align_uint64.c new file mode 100644 index 0000000..69dc7b5 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_align_uint64.c @@ -0,0 +1,98 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of uint64. + Limitations: none. + PR: none. + Originator: 20031203 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + + 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/testsuite/libffi.call/cls_double.c b/libffi/testsuite/libffi.call/cls_double.c new file mode 100644 index 0000000..3df6cf3 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_double.c @@ -0,0 +1,51 @@ +/* Area: closure_call + Purpose: Check return value double. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +static void cls_ret_double_fn(ffi_cif* cif,void* resp,void** args, + void* userdata) + { + *(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/testsuite/libffi.call/cls_float.c b/libffi/testsuite/libffi.call/cls_float.c new file mode 100644 index 0000000..ac4ec48 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_float.c @@ -0,0 +1,51 @@ +/* Area: closure_call + Purpose: Check return value float. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +static void cls_ret_float_fn(ffi_cif* cif,void* resp,void** args, + void* userdata) + { + *(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/testsuite/libffi.call/cls_multi_schar.c b/libffi/testsuite/libffi.call/cls_multi_schar.c new file mode 100644 index 0000000..30a89e6 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_multi_schar.c @@ -0,0 +1,81 @@ +/* Area: ffi_call, closure_call + Purpose: Check passing of multiple signed char values. + Limitations: none. + PR: PR13221. + Originator: 20031129 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void *rval, void **avals, void *data) +{ + 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", 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/testsuite/libffi.call/cls_multi_sshort.c b/libffi/testsuite/libffi.call/cls_multi_sshort.c new file mode 100644 index 0000000..e19c8b8 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_multi_sshort.c @@ -0,0 +1,81 @@ +/* Area: ffi_call, closure_call + Purpose: Check passing of multiple signed short values. + Limitations: none. + PR: PR13221. + Originator: 20031129 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void *rval, void **avals, void *data) +{ + 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", 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/testsuite/libffi.call/cls_multi_sshortchar.c b/libffi/testsuite/libffi.call/cls_multi_sshortchar.c new file mode 100644 index 0000000..ae5ce7f --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_multi_sshortchar.c @@ -0,0 +1,93 @@ +/* Area: ffi_call, closure_call + Purpose: Check passing of multiple signed short/char values. + Limitations: none. + PR: PR13221. + Originator: 20031129 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void *rval, void **avals, void *data) +{ + 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", 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/testsuite/libffi.call/cls_multi_uchar.c b/libffi/testsuite/libffi.call/cls_multi_uchar.c new file mode 100644 index 0000000..0b00bc3 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_multi_uchar.c @@ -0,0 +1,96 @@ +/* Area: ffi_call, closure_call + Purpose: Check passing of multiple unsigned char values. + Limitations: none. + PR: PR13221. + Originator: 20031129 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void *rval, void **avals, void *data) +{ + 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, void *rval, void **avals, void *data) +{ + 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", 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/testsuite/libffi.call/cls_multi_ushort.c b/libffi/testsuite/libffi.call/cls_multi_ushort.c new file mode 100644 index 0000000..7ef7b00 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_multi_ushort.c @@ -0,0 +1,81 @@ +/* Area: ffi_call, closure_call + Purpose: Check passing of multiple unsigned short values. + Limitations: none. + PR: PR13221. + Originator: 20031129 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void *rval, void **avals, void *data) +{ + 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", 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/testsuite/libffi.call/cls_multi_ushortchar.c b/libffi/testsuite/libffi.call/cls_multi_ushortchar.c new file mode 100644 index 0000000..2458fc5 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_multi_ushortchar.c @@ -0,0 +1,93 @@ +/* Area: ffi_call, closure_call + Purpose: Check passing of multiple unsigned short/char values. + Limitations: none. + PR: PR13221. + Originator: 20031129 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void *rval, void **avals, void *data) +{ + 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", 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/testsuite/libffi.call/cls_schar.c b/libffi/testsuite/libffi.call/cls_schar.c new file mode 100644 index 0000000..1e607ab --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_schar.c @@ -0,0 +1,50 @@ +/* Area: closure_call + Purpose: Check return value schar. + Limitations: none. + PR: none. + Originator: 20031108 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +static void cls_ret_schar_fn(ffi_cif* cif,void* resp,void** args, + void* userdata) +{ + *(ffi_arg*)resp = *(signed char *)args[0]; + printf("%d: %d\n",*(signed char *)args[0], + *(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/testsuite/libffi.call/cls_sint.c b/libffi/testsuite/libffi.call/cls_sint.c new file mode 100644 index 0000000..c85067b --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_sint.c @@ -0,0 +1,50 @@ +/* Area: closure_call + Purpose: Check return value sint32. + Limitations: none. + PR: none. + Originator: 20031108 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +static void cls_ret_sint_fn(ffi_cif* cif,void* resp,void** args, + void* userdata) +{ + *(ffi_arg*)resp = *(signed int *)args[0]; + printf("%d: %d\n",*(signed int *)args[0], + *(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_sint32; + cl_arg_types[1] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_sint32, 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/testsuite/libffi.call/cls_sshort.c b/libffi/testsuite/libffi.call/cls_sshort.c new file mode 100644 index 0000000..65e6872 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_sshort.c @@ -0,0 +1,50 @@ +/* Area: closure_call + Purpose: Check return value sshort. + Limitations: none. + PR: none. + Originator: 20031108 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +static void cls_ret_sshort_fn(ffi_cif* cif,void* resp,void** args, + void* userdata) +{ + *(ffi_arg*)resp = *(signed short *)args[0]; + printf("%d: %d\n",*(signed short *)args[0], + *(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_sint16; + cl_arg_types[1] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_sint16, 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/testsuite/libffi.call/cls_uchar.c b/libffi/testsuite/libffi.call/cls_uchar.c new file mode 100644 index 0000000..6a1e637 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_uchar.c @@ -0,0 +1,50 @@ +/* Area: closure_call + Purpose: Check return value uchar. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +static void cls_ret_uchar_fn(ffi_cif* cif,void* resp,void** args, + void* userdata) +{ + *(ffi_arg*)resp = *(unsigned char *)args[0]; + printf("%d: %d\n",*(unsigned char *)args[0], + *(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/testsuite/libffi.call/cls_uint.c b/libffi/testsuite/libffi.call/cls_uint.c new file mode 100644 index 0000000..e24e7bd --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_uint.c @@ -0,0 +1,51 @@ +/* Area: closure_call + Purpose: Check return value uint. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +static void cls_ret_uint_fn(ffi_cif* cif,void* resp,void** args, + void* userdata) + { + *(ffi_arg *)resp = *(unsigned int *)args[0]; + + printf("%d: %d\n",*(unsigned int *)args[0], + *(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_uint32; + cl_arg_types[1] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_uint32, 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/testsuite/libffi.call/cls_ulonglong.c b/libffi/testsuite/libffi.call/cls_ulonglong.c new file mode 100644 index 0000000..072da8c --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_ulonglong.c @@ -0,0 +1,54 @@ +/* Area: closure_call + Purpose: Check return value long long. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +static void cls_ret_ulonglong_fn(ffi_cif* cif,void* resp,void** args, + void* userdata) + { + *(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/testsuite/libffi.call/cls_ushort.c b/libffi/testsuite/libffi.call/cls_ushort.c new file mode 100644 index 0000000..f6626b9 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_ushort.c @@ -0,0 +1,51 @@ +/* Area: closure_call + Purpose: Check return value ushort. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +static void cls_ret_ushort_fn(ffi_cif* cif,void* resp,void** args, + void* userdata) + { + *(ffi_arg*)resp = *(unsigned short *)args[0]; + + printf("%d: %d\n",*(unsigned short *)args[0], + *(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/testsuite/libffi.call/ffitest.h b/libffi/testsuite/libffi.call/ffitest.h new file mode 100644 index 0000000..b41e14b --- /dev/null +++ b/libffi/testsuite/libffi.call/ffitest.h @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include +#include "fficonfig.h" + +#define MAX_ARGS 256 + +#define CHECK(x) !(x) ? abort() : 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 +# 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 +# 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/testsuite/libffi.call/float.c b/libffi/testsuite/libffi.call/float.c new file mode 100644 index 0000000..d712fb1 --- /dev/null +++ b/libffi/testsuite/libffi.call/float.c @@ -0,0 +1,64 @@ +/* Area: ffi_call + Purpose: Check return value float. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +/* { dg-options -mlong-double-128 { target powerpc64*-*-* } } */ + +#include "ffitest.h" + +static int floating(int a, float b, double c, long double d, int e) +{ + 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; + signed int si2; + + 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; + args[4] = &ffi_type_sint; + values[4] = &si2; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 5, + &ffi_type_sint, args) == FFI_OK); + + si1 = 6; + f = 3.14159; + d = (double)1.0/(double)3.0; + ld = 2.71828182846L; + si2 = 10; + + floating (si1, f, d, ld, si2); + + ffi_call(&cif, FFI_FN(floating), &rint, values); + + printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld, si2)); + + CHECK(rint == floating(si1, f, d, ld, si2)); + + exit (0); +} diff --git a/libffi/testsuite/libffi.call/float1.c b/libffi/testsuite/libffi.call/float1.c new file mode 100644 index 0000000..94636a2 --- /dev/null +++ b/libffi/testsuite/libffi.call/float1.c @@ -0,0 +1,42 @@ +/* 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" + +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; + double d; + + + 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; + + ffi_call(&cif, FFI_FN(dblit), &d, values); + + /* These are not always the same!! Check for a reasonable delta */ + + CHECK(d - dblit(f) < DBL_EPSILON); + + exit(0); + +} diff --git a/libffi/testsuite/libffi.call/float2.c b/libffi/testsuite/libffi.call/float2.c new file mode 100644 index 0000000..4de41d3 --- /dev/null +++ b/libffi/testsuite/libffi.call/float2.c @@ -0,0 +1,60 @@ +/* Area: ffi_call + Purpose: Check return value long double. + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +/* { dg-options -mlong-double-128 { target powerpc64*-*-* } } */ + +#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 */ + /*@-realcompare@*/ + if (ld - ldblit(f) < LDBL_EPSILON) + /*@=realcompare@*/ + puts("long double return value tests ok!"); + else + CHECK(0); + + exit(0); +} diff --git a/libffi/testsuite/libffi.call/many.c b/libffi/testsuite/libffi.call/many.c new file mode 100644 index 0000000..4869ba9 --- /dev/null +++ b/libffi/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 + +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/testsuite/libffi.call/many_win32.c b/libffi/testsuite/libffi.call/many_win32.c new file mode 100644 index 0000000..7cb5336 --- /dev/null +++ b/libffi/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 + +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/testsuite/libffi.call/nested_struct.c b/libffi/testsuite/libffi.call/nested_struct.c new file mode 100644 index 0000000..86d685a --- /dev/null +++ b/libffi/testsuite/libffi.call/nested_struct.c @@ -0,0 +1,159 @@ +/* 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: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + 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_uint32; + cls_struct_fields[3] = NULL; + + cls_struct_fields1[0] = &ffi_type_uint32; + 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/testsuite/libffi.call/nested_struct1.c b/libffi/testsuite/libffi.call/nested_struct1.c new file mode 100644 index 0000000..1d87945 --- /dev/null +++ b/libffi/testsuite/libffi.call/nested_struct1.c @@ -0,0 +1,168 @@ +/* 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: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + 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_uint32; + cls_struct_fields[3] = NULL; + + cls_struct_fields1[0] = &ffi_type_uint32; + 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/testsuite/libffi.call/nested_struct2.c b/libffi/testsuite/libffi.call/nested_struct2.c new file mode 100644 index 0000000..3572a4c --- /dev/null +++ b/libffi/testsuite/libffi.call/nested_struct2.c @@ -0,0 +1,127 @@ +/* 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: 20030911 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#include "ffitest.h" + +#if LONG_MAX == 2147483647 +#define ffi_type_mylong ffi_type_uint32 +#else +#if LONG_MAX == 9223372036854775807 +#define ffi_type_mylong ffi_type_uint64 +#else +#error "Error, size LONG not defined as expected" +#endif +#endif + +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("%d %d %d %d %d: %d %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, void* resp, void** args, void* userdata) +{ + 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_mylong; + 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/testsuite/libffi.call/nested_struct3.c b/libffi/testsuite/libffi.call/nested_struct3.c new file mode 100644 index 0000000..95cf2f3 --- /dev/null +++ b/libffi/testsuite/libffi.call/nested_struct3.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: 20030911 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + 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/testsuite/libffi.call/problem1.c b/libffi/testsuite/libffi.call/problem1.c new file mode 100644 index 0000000..5b6397f --- /dev/null +++ b/libffi/testsuite/libffi.call/problem1.c @@ -0,0 +1,97 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure passing with different structure size. + Limitations: none. + PR: none. + Originator: 20030828 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#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, void* resp, void** args, void* userdata) +{ + 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/testsuite/libffi.call/promotion.c b/libffi/testsuite/libffi.call/promotion.c new file mode 100644 index 0000000..75e8421 --- /dev/null +++ b/libffi/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] = ≻ + 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; /*@-type@*/ sc += 1 /*@=type@*/) + for (ss = -30000; ss <= 30000; ss += 10000) + for (uc = (unsigned char) 0; + uc <= (unsigned char) 200; /*@-type@*/ uc += 20 /*@=type@*/) + 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/testsuite/libffi.call/pyobjc-tc.c b/libffi/testsuite/libffi.call/pyobjc-tc.c new file mode 100644 index 0000000..017323c --- /dev/null +++ b/libffi/testsuite/libffi.call/pyobjc-tc.c @@ -0,0 +1,114 @@ +/* Area: ffi_call + Purpose: Check different structures. + Limitations: none. + PR: none. + Originator: Ronald Oussoren 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", result); + + } + exit(0); +} diff --git a/libffi/testsuite/libffi.call/return_ll.c b/libffi/testsuite/libffi.call/return_ll.c new file mode 100644 index 0000000..b95cac4 --- /dev/null +++ b/libffi/testsuite/libffi.call/return_ll.c @@ -0,0 +1,45 @@ +/* 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; + unsigned long ul; + + + args[0] = &ffi_type_sint64; + values[0] = ≪ + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_sint64, args) == FFI_OK); + + for (ll = 0LL; ll < 100LL; ll++) + { + ul++; + ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values); + CHECK(rlonglong == ll); + } + + for (ll = 55555555555000LL; ll < 55555555555100LL; ll++) + { + ul++; + ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values); + CHECK(rlonglong == ll); + } + exit(0); +} diff --git a/libffi/testsuite/libffi.call/return_sc.c b/libffi/testsuite/libffi.call/return_sc.c new file mode 100644 index 0000000..e528a84 --- /dev/null +++ b/libffi/testsuite/libffi.call/return_sc.c @@ -0,0 +1,38 @@ +/* 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; + unsigned long ul; + + args[0] = &ffi_type_schar; + values[0] = ≻ + + /* 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++) + { + ul++; + ffi_call(&cif, FFI_FN(return_sc), &rint, values); + CHECK(rint == (ffi_arg) sc); + } + exit(0); +} diff --git a/libffi/testsuite/libffi.call/return_uc.c b/libffi/testsuite/libffi.call/return_uc.c new file mode 100644 index 0000000..c943d48 --- /dev/null +++ b/libffi/testsuite/libffi.call/return_uc.c @@ -0,0 +1,40 @@ +/* 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; + unsigned long ul; + + 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++) + { + ul++; + ffi_call(&cif, FFI_FN(return_uc), &rint, values); + CHECK(rint == (signed int) uc); + } + exit(0); +} diff --git a/libffi/testsuite/libffi.call/strlen.c b/libffi/testsuite/libffi.call/strlen.c new file mode 100644 index 0000000..3de45de --- /dev/null +++ b/libffi/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/testsuite/libffi.call/strlen_win32.c b/libffi/testsuite/libffi.call/strlen_win32.c new file mode 100644 index 0000000..6fbcc87 --- /dev/null +++ b/libffi/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/testsuite/libffi.call/struct1.c b/libffi/testsuite/libffi.call/struct1.c new file mode 100644 index 0000000..99c5d3b --- /dev/null +++ b/libffi/testsuite/libffi.call/struct1.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 +{ + unsigned char uc; + double d; + unsigned int ui; +} test_structure_1; + +static test_structure_1 struct1(test_structure_1 ts) +{ + /*@-type@*/ + ts.uc++; + /*@=type@*/ + 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/testsuite/libffi.call/struct2.c b/libffi/testsuite/libffi.call/struct2.c new file mode 100644 index 0000000..14bc9fd --- /dev/null +++ b/libffi/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/testsuite/libffi.call/struct3.c b/libffi/testsuite/libffi.call/struct3.c new file mode 100644 index 0000000..e0bb09b --- /dev/null +++ b/libffi/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/testsuite/libffi.call/struct4.c b/libffi/testsuite/libffi.call/struct4.c new file mode 100644 index 0000000..0ad0a83 --- /dev/null +++ b/libffi/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/testsuite/libffi.call/struct5.c b/libffi/testsuite/libffi.call/struct5.c new file mode 100644 index 0000000..c03cc97 --- /dev/null +++ b/libffi/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/testsuite/libffi.call/struct6.c b/libffi/testsuite/libffi.call/struct6.c new file mode 100644 index 0000000..83db9af --- /dev/null +++ b/libffi/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/testsuite/libffi.call/struct7.c b/libffi/testsuite/libffi.call/struct7.c new file mode 100644 index 0000000..58aac4c --- /dev/null +++ b/libffi/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/testsuite/libffi.call/struct8.c b/libffi/testsuite/libffi.call/struct8.c new file mode 100644 index 0000000..c773ac7 --- /dev/null +++ b/libffi/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/testsuite/libffi.call/struct9.c b/libffi/testsuite/libffi.call/struct9.c new file mode 100644 index 0000000..f30091f --- /dev/null +++ b/libffi/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/testsuite/libffi.special/ffitestcxx.h b/libffi/testsuite/libffi.special/ffitestcxx.h new file mode 100644 index 0000000..01414cc --- /dev/null +++ b/libffi/testsuite/libffi.special/ffitestcxx.h @@ -0,0 +1,77 @@ +#include +#include +#include +#include +#include "fficonfig.h" + +#define MAX_ARGS 256 + +#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 +# 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 +# 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/testsuite/libffi.special/special.exp b/libffi/testsuite/libffi.special/special.exp new file mode 100644 index 0000000..df96d03 --- /dev/null +++ b/libffi/testsuite/libffi.special/special.exp @@ -0,0 +1,36 @@ +# Copyright (C) 2003 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. + +# 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 " -lstdc++" + +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "" + +dg-finish + +# Local Variables: +# tcl-indent-level:4 +# End: diff --git a/libffi/testsuite/libffi.special/unwindtest.cc b/libffi/testsuite/libffi.special/unwindtest.cc new file mode 100644 index 0000000..4fec44c --- /dev/null +++ b/libffi/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 */ + +/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +#include "ffitestcxx.h" + +void +closure_test_fn(ffi_cif* cif, void* resp, void** args, void* userdata) +{ + throw 9; +} + +typedef void (*closure_test_type)(); + +void closure_test_fn1(ffi_cif* cif,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); + + 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]; + int res; +#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); +} -- cgit v1.2.3