diff options
author | Richard Henderson <rth@redhat.com> | 2015-01-12 08:19:59 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2015-01-12 08:19:59 -0800 |
commit | b1760f7f915a36ee9b4636fb54719c9b3ae59356 (patch) | |
tree | 1a64d747b069bdebf651d856989dd40a54daf0cc /libffi/testsuite | |
parent | 62e22fcb7985349b93646b86351033e1fb09c46c (diff) | |
download | gcc-b1760f7f915a36ee9b4636fb54719c9b3ae59356.zip gcc-b1760f7f915a36ee9b4636fb54719c9b3ae59356.tar.gz gcc-b1760f7f915a36ee9b4636fb54719c9b3ae59356.tar.bz2 |
Merge libffi to upstream commit c82cc159426d8d4402375fa1ae3f045b9cf82e16
From-SVN: r219477
Diffstat (limited to 'libffi/testsuite')
101 files changed, 2044 insertions, 759 deletions
diff --git a/libffi/testsuite/Makefile.am b/libffi/testsuite/Makefile.am index 146fdf9..209e897 100644 --- a/libffi/testsuite/Makefile.am +++ b/libffi/testsuite/Makefile.am @@ -4,8 +4,8 @@ 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` + echo $(top_builddir)/../expect/expect ; \ + else echo expect ; fi` RUNTEST = `if [ -f $(top_srcdir)/../dejagnu/runtest ] ; then \ echo $(top_srcdir)/../dejagnu/runtest ; \ @@ -15,71 +15,80 @@ AM_RUNTESTFLAGS = CLEANFILES = *.exe core* *.log *.sum -EXTRA_DIST = config/default.exp libffi.call/cls_19byte.c \ -libffi.call/cls_align_longdouble_split.c libffi.call/closure_loc_fn0.c \ -libffi.call/cls_schar.c libffi.call/closure_fn1.c \ -libffi.call/many2_win32.c libffi.call/return_ul.c \ -libffi.call/cls_align_double.c libffi.call/return_fl2.c \ -libffi.call/cls_1_1byte.c libffi.call/cls_64byte.c \ -libffi.call/nested_struct7.c libffi.call/cls_align_sint32.c \ -libffi.call/nested_struct2.c libffi.call/ffitest.h \ -libffi.call/nested_struct4.c libffi.call/cls_multi_ushort.c \ -libffi.call/struct3.c libffi.call/cls_3byte1.c \ -libffi.call/cls_16byte.c libffi.call/struct8.c \ -libffi.call/nested_struct8.c libffi.call/cls_multi_sshort.c \ -libffi.call/cls_3byte2.c libffi.call/fastthis2_win32.c \ -libffi.call/cls_pointer.c libffi.call/err_bad_typedef.c \ -libffi.call/cls_4_1byte.c libffi.call/cls_9byte2.c \ -libffi.call/cls_multi_schar.c libffi.call/stret_medium2.c \ -libffi.call/cls_5_1_byte.c libffi.call/call.exp \ -libffi.call/cls_double.c libffi.call/cls_align_sint16.c \ -libffi.call/cls_uint.c libffi.call/return_ll1.c \ -libffi.call/nested_struct3.c libffi.call/cls_20byte1.c \ -libffi.call/closure_fn4.c libffi.call/cls_uchar.c \ -libffi.call/struct2.c libffi.call/cls_7byte.c libffi.call/strlen.c \ -libffi.call/many.c libffi.call/testclosure.c libffi.call/return_fl.c \ -libffi.call/struct5.c libffi.call/cls_12byte.c \ -libffi.call/cls_multi_sshortchar.c \ -libffi.call/cls_align_longdouble_split2.c libffi.call/return_dbl2.c \ -libffi.call/return_fl3.c libffi.call/stret_medium.c \ -libffi.call/nested_struct6.c libffi.call/a.out \ -libffi.call/closure_fn3.c libffi.call/float3.c libffi.call/many2.c \ -libffi.call/closure_stdcall.c libffi.call/cls_align_uint16.c \ -libffi.call/cls_9byte1.c libffi.call/closure_fn6.c \ -libffi.call/cls_double_va.c libffi.call/cls_align_pointer.c \ -libffi.call/cls_align_longdouble.c libffi.call/closure_fn2.c \ -libffi.call/cls_sshort.c libffi.call/many_win32.c \ -libffi.call/nested_struct.c libffi.call/cls_20byte.c \ -libffi.call/cls_longdouble.c libffi.call/cls_multi_uchar.c \ -libffi.call/return_uc.c libffi.call/closure_thiscall.c \ -libffi.call/cls_18byte.c libffi.call/cls_8byte.c \ -libffi.call/promotion.c libffi.call/struct1_win32.c \ -libffi.call/return_dbl.c libffi.call/cls_24byte.c \ -libffi.call/struct4.c libffi.call/cls_6byte.c \ -libffi.call/cls_align_uint32.c libffi.call/float.c \ -libffi.call/float1.c libffi.call/float_va.c libffi.call/negint.c \ -libffi.call/return_dbl1.c libffi.call/cls_3_1byte.c \ -libffi.call/cls_align_float.c libffi.call/return_fl1.c \ -libffi.call/nested_struct10.c libffi.call/nested_struct5.c \ -libffi.call/fastthis1_win32.c libffi.call/cls_align_sint64.c \ -libffi.call/stret_large2.c libffi.call/return_sl.c \ -libffi.call/closure_fn0.c libffi.call/cls_5byte.c \ -libffi.call/cls_2byte.c libffi.call/float2.c \ -libffi.call/cls_dbls_struct.c libffi.call/cls_sint.c \ -libffi.call/stret_large.c libffi.call/cls_ulonglong.c \ -libffi.call/cls_ushort.c libffi.call/nested_struct1.c \ -libffi.call/err_bad_abi.c libffi.call/cls_longdouble_va.c \ -libffi.call/cls_float.c libffi.call/cls_pointer_stack.c \ -libffi.call/pyobjc-tc.c libffi.call/cls_multi_ushortchar.c \ -libffi.call/struct1.c libffi.call/nested_struct9.c \ -libffi.call/huge_struct.c libffi.call/problem1.c libffi.call/float4.c \ -libffi.call/fastthis3_win32.c libffi.call/return_ldl.c \ -libffi.call/strlen2_win32.c libffi.call/closure_fn5.c \ -libffi.call/struct2_win32.c libffi.call/struct6.c \ -libffi.call/return_ll.c libffi.call/struct9.c libffi.call/return_sc.c \ -libffi.call/struct7.c libffi.call/cls_align_uint64.c \ -libffi.call/cls_4byte.c libffi.call/strlen_win32.c \ -libffi.call/cls_6_1_byte.c libffi.call/cls_7_1_byte.c \ -libffi.special/unwindtest.cc libffi.special/special.exp \ -libffi.special/unwindtest_ffi_call.cc libffi.special/ffitestcxx.h \ -lib/wrapper.exp lib/target-libpath.exp lib/libffi.exp +EXTRA_DIST = config/default.exp libffi.call/cls_19byte.c \ +libffi.call/cls_align_longdouble_split.c \ +libffi.call/closure_loc_fn0.c libffi.call/cls_schar.c \ +libffi.call/closure_fn1.c \ +libffi.call/return_ul.c libffi.call/cls_align_double.c \ +libffi.call/return_fl2.c libffi.call/cls_1_1byte.c \ +libffi.call/cls_64byte.c libffi.call/nested_struct7.c \ +libffi.call/cls_align_sint32.c libffi.call/nested_struct2.c \ +libffi.call/ffitest.h libffi.call/nested_struct4.c \ +libffi.call/cls_multi_ushort.c libffi.call/struct3.c \ +libffi.call/cls_3byte1.c libffi.call/cls_16byte.c \ +libffi.call/struct8.c libffi.call/nested_struct8.c \ +libffi.call/cls_multi_sshort.c libffi.call/cls_3byte2.c \ +libffi.call/cls_pointer.c \ +libffi.call/err_bad_typedef.c libffi.call/cls_4_1byte.c \ +libffi.call/cls_9byte2.c libffi.call/cls_multi_schar.c \ +libffi.call/stret_medium2.c libffi.call/cls_5_1_byte.c \ +libffi.call/call.exp libffi.call/cls_double.c \ +libffi.call/cls_align_sint16.c libffi.call/cls_uint.c \ +libffi.call/return_ll1.c libffi.call/nested_struct3.c \ +libffi.call/cls_20byte1.c libffi.call/closure_fn4.c \ +libffi.call/cls_uchar.c libffi.call/struct2.c libffi.call/cls_7byte.c \ +libffi.call/strlen.c libffi.call/many.c libffi.call/testclosure.c \ +libffi.call/return_fl.c libffi.call/struct5.c \ +libffi.call/cls_12byte.c libffi.call/cls_multi_sshortchar.c \ +libffi.call/cls_align_longdouble_split2.c libffi.call/return_dbl2.c \ +libffi.call/return_fl3.c libffi.call/stret_medium.c \ +libffi.call/nested_struct6.c libffi.call/closure_fn3.c \ +libffi.call/float3.c libffi.call/many2.c \ +libffi.call/closure_simple.c libffi.call/cls_align_uint16.c \ +libffi.call/cls_9byte1.c libffi.call/closure_fn6.c \ +libffi.call/cls_double_va.c libffi.call/cls_align_pointer.c \ +libffi.call/cls_align_longdouble.c libffi.call/closure_fn2.c \ +libffi.call/cls_sshort.c \ +libffi.call/nested_struct.c libffi.call/cls_20byte.c \ +libffi.call/cls_longdouble.c libffi.call/cls_multi_uchar.c \ +libffi.call/return_uc.c \ +libffi.call/cls_18byte.c libffi.call/cls_8byte.c \ +libffi.call/promotion.c \ +libffi.call/return_dbl.c libffi.call/cls_24byte.c \ +libffi.call/struct4.c libffi.call/cls_6byte.c \ +libffi.call/cls_align_uint32.c libffi.call/float.c \ +libffi.call/float1.c libffi.call/float_va.c libffi.call/negint.c \ +libffi.call/return_dbl1.c libffi.call/cls_3_1byte.c \ +libffi.call/cls_align_float.c libffi.call/return_fl1.c \ +libffi.call/nested_struct10.c libffi.call/nested_struct5.c \ +libffi.call/cls_align_sint64.c \ +libffi.call/stret_large2.c libffi.call/return_sl.c \ +libffi.call/closure_fn0.c libffi.call/cls_5byte.c \ +libffi.call/cls_2byte.c libffi.call/float2.c \ +libffi.call/cls_dbls_struct.c libffi.call/cls_sint.c \ +libffi.call/stret_large.c libffi.call/cls_ulonglong.c \ +libffi.call/cls_ushort.c libffi.call/nested_struct1.c \ +libffi.call/err_bad_abi.c libffi.call/cls_longdouble_va.c \ +libffi.call/cls_float.c libffi.call/cls_pointer_stack.c \ +libffi.call/pyobjc-tc.c libffi.call/cls_multi_ushortchar.c \ +libffi.call/struct1.c libffi.call/nested_struct9.c \ +libffi.call/huge_struct.c libffi.call/problem1.c \ +libffi.call/float4.c \ +libffi.call/return_ldl.c \ +libffi.call/closure_fn5.c \ +libffi.call/struct6.c libffi.call/return_ll.c libffi.call/struct9.c \ +libffi.call/return_sc.c libffi.call/struct7.c \ +libffi.call/cls_align_uint64.c libffi.call/cls_4byte.c \ +libffi.call/cls_6_1_byte.c \ +libffi.call/cls_7_1_byte.c libffi.call/unwindtest.cc \ +libffi.call/unwindtest_ffi_call.cc \ +lib/wrapper.exp lib/target-libpath.exp \ +lib/libffi.exp libffi.call/cls_struct_va1.c \ +libffi.call/cls_uchar_va.c libffi.call/cls_uint_va.c \ +libffi.call/cls_ulong_va.c libffi.call/cls_ushort_va.c \ +libffi.call/nested_struct11.c libffi.call/uninitialized.c \ +libffi.call/va_1.c libffi.call/va_struct1.c libffi.call/va_struct2.c \ +libffi.call/va_struct3.c \ +libffi.call/strlen2.c \ +libffi.call/strlen3.c \ +libffi.call/strlen4.c diff --git a/libffi/testsuite/Makefile.in b/libffi/testsuite/Makefile.in index 808d4cb..cbfe35b 100644 --- a/libffi/testsuite/Makefile.in +++ b/libffi/testsuite/Makefile.in @@ -74,6 +74,10 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ @@ -126,12 +130,14 @@ SHELL = @SHELL@ STRIP = @STRIP@ TARGET = @TARGET@ TARGETDIR = @TARGETDIR@ +TARGET_OBJ = @TARGET_OBJ@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ @@ -189,82 +195,91 @@ 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` + echo $(top_builddir)/../expect/expect ; \ + else echo expect ; fi` RUNTEST = `if [ -f $(top_srcdir)/../dejagnu/runtest ] ; then \ echo $(top_srcdir)/../dejagnu/runtest ; \ else echo runtest; fi` CLEANFILES = *.exe core* *.log *.sum -EXTRA_DIST = config/default.exp libffi.call/cls_19byte.c \ -libffi.call/cls_align_longdouble_split.c libffi.call/closure_loc_fn0.c \ -libffi.call/cls_schar.c libffi.call/closure_fn1.c \ -libffi.call/many2_win32.c libffi.call/return_ul.c \ -libffi.call/cls_align_double.c libffi.call/return_fl2.c \ -libffi.call/cls_1_1byte.c libffi.call/cls_64byte.c \ -libffi.call/nested_struct7.c libffi.call/cls_align_sint32.c \ -libffi.call/nested_struct2.c libffi.call/ffitest.h \ -libffi.call/nested_struct4.c libffi.call/cls_multi_ushort.c \ -libffi.call/struct3.c libffi.call/cls_3byte1.c \ -libffi.call/cls_16byte.c libffi.call/struct8.c \ -libffi.call/nested_struct8.c libffi.call/cls_multi_sshort.c \ -libffi.call/cls_3byte2.c libffi.call/fastthis2_win32.c \ -libffi.call/cls_pointer.c libffi.call/err_bad_typedef.c \ -libffi.call/cls_4_1byte.c libffi.call/cls_9byte2.c \ -libffi.call/cls_multi_schar.c libffi.call/stret_medium2.c \ -libffi.call/cls_5_1_byte.c libffi.call/call.exp \ -libffi.call/cls_double.c libffi.call/cls_align_sint16.c \ -libffi.call/cls_uint.c libffi.call/return_ll1.c \ -libffi.call/nested_struct3.c libffi.call/cls_20byte1.c \ -libffi.call/closure_fn4.c libffi.call/cls_uchar.c \ -libffi.call/struct2.c libffi.call/cls_7byte.c libffi.call/strlen.c \ -libffi.call/many.c libffi.call/testclosure.c libffi.call/return_fl.c \ -libffi.call/struct5.c libffi.call/cls_12byte.c \ -libffi.call/cls_multi_sshortchar.c \ -libffi.call/cls_align_longdouble_split2.c libffi.call/return_dbl2.c \ -libffi.call/return_fl3.c libffi.call/stret_medium.c \ -libffi.call/nested_struct6.c libffi.call/a.out \ -libffi.call/closure_fn3.c libffi.call/float3.c libffi.call/many2.c \ -libffi.call/closure_stdcall.c libffi.call/cls_align_uint16.c \ -libffi.call/cls_9byte1.c libffi.call/closure_fn6.c \ -libffi.call/cls_double_va.c libffi.call/cls_align_pointer.c \ -libffi.call/cls_align_longdouble.c libffi.call/closure_fn2.c \ -libffi.call/cls_sshort.c libffi.call/many_win32.c \ -libffi.call/nested_struct.c libffi.call/cls_20byte.c \ -libffi.call/cls_longdouble.c libffi.call/cls_multi_uchar.c \ -libffi.call/return_uc.c libffi.call/closure_thiscall.c \ -libffi.call/cls_18byte.c libffi.call/cls_8byte.c \ -libffi.call/promotion.c libffi.call/struct1_win32.c \ -libffi.call/return_dbl.c libffi.call/cls_24byte.c \ -libffi.call/struct4.c libffi.call/cls_6byte.c \ -libffi.call/cls_align_uint32.c libffi.call/float.c \ -libffi.call/float1.c libffi.call/float_va.c libffi.call/negint.c \ -libffi.call/return_dbl1.c libffi.call/cls_3_1byte.c \ -libffi.call/cls_align_float.c libffi.call/return_fl1.c \ -libffi.call/nested_struct10.c libffi.call/nested_struct5.c \ -libffi.call/fastthis1_win32.c libffi.call/cls_align_sint64.c \ -libffi.call/stret_large2.c libffi.call/return_sl.c \ -libffi.call/closure_fn0.c libffi.call/cls_5byte.c \ -libffi.call/cls_2byte.c libffi.call/float2.c \ -libffi.call/cls_dbls_struct.c libffi.call/cls_sint.c \ -libffi.call/stret_large.c libffi.call/cls_ulonglong.c \ -libffi.call/cls_ushort.c libffi.call/nested_struct1.c \ -libffi.call/err_bad_abi.c libffi.call/cls_longdouble_va.c \ -libffi.call/cls_float.c libffi.call/cls_pointer_stack.c \ -libffi.call/pyobjc-tc.c libffi.call/cls_multi_ushortchar.c \ -libffi.call/struct1.c libffi.call/nested_struct9.c \ -libffi.call/huge_struct.c libffi.call/problem1.c libffi.call/float4.c \ -libffi.call/fastthis3_win32.c libffi.call/return_ldl.c \ -libffi.call/strlen2_win32.c libffi.call/closure_fn5.c \ -libffi.call/struct2_win32.c libffi.call/struct6.c \ -libffi.call/return_ll.c libffi.call/struct9.c libffi.call/return_sc.c \ -libffi.call/struct7.c libffi.call/cls_align_uint64.c \ -libffi.call/cls_4byte.c libffi.call/strlen_win32.c \ -libffi.call/cls_6_1_byte.c libffi.call/cls_7_1_byte.c \ -libffi.special/unwindtest.cc libffi.special/special.exp \ -libffi.special/unwindtest_ffi_call.cc libffi.special/ffitestcxx.h \ -lib/wrapper.exp lib/target-libpath.exp lib/libffi.exp +EXTRA_DIST = config/default.exp libffi.call/cls_19byte.c \ +libffi.call/cls_align_longdouble_split.c \ +libffi.call/closure_loc_fn0.c libffi.call/cls_schar.c \ +libffi.call/closure_fn1.c \ +libffi.call/return_ul.c libffi.call/cls_align_double.c \ +libffi.call/return_fl2.c libffi.call/cls_1_1byte.c \ +libffi.call/cls_64byte.c libffi.call/nested_struct7.c \ +libffi.call/cls_align_sint32.c libffi.call/nested_struct2.c \ +libffi.call/ffitest.h libffi.call/nested_struct4.c \ +libffi.call/cls_multi_ushort.c libffi.call/struct3.c \ +libffi.call/cls_3byte1.c libffi.call/cls_16byte.c \ +libffi.call/struct8.c libffi.call/nested_struct8.c \ +libffi.call/cls_multi_sshort.c libffi.call/cls_3byte2.c \ +libffi.call/cls_pointer.c \ +libffi.call/err_bad_typedef.c libffi.call/cls_4_1byte.c \ +libffi.call/cls_9byte2.c libffi.call/cls_multi_schar.c \ +libffi.call/stret_medium2.c libffi.call/cls_5_1_byte.c \ +libffi.call/call.exp libffi.call/cls_double.c \ +libffi.call/cls_align_sint16.c libffi.call/cls_uint.c \ +libffi.call/return_ll1.c libffi.call/nested_struct3.c \ +libffi.call/cls_20byte1.c libffi.call/closure_fn4.c \ +libffi.call/cls_uchar.c libffi.call/struct2.c libffi.call/cls_7byte.c \ +libffi.call/strlen.c libffi.call/many.c libffi.call/testclosure.c \ +libffi.call/return_fl.c libffi.call/struct5.c \ +libffi.call/cls_12byte.c libffi.call/cls_multi_sshortchar.c \ +libffi.call/cls_align_longdouble_split2.c libffi.call/return_dbl2.c \ +libffi.call/return_fl3.c libffi.call/stret_medium.c \ +libffi.call/nested_struct6.c libffi.call/closure_fn3.c \ +libffi.call/float3.c libffi.call/many2.c \ +libffi.call/closure_simple.c libffi.call/cls_align_uint16.c \ +libffi.call/cls_9byte1.c libffi.call/closure_fn6.c \ +libffi.call/cls_double_va.c libffi.call/cls_align_pointer.c \ +libffi.call/cls_align_longdouble.c libffi.call/closure_fn2.c \ +libffi.call/cls_sshort.c \ +libffi.call/nested_struct.c libffi.call/cls_20byte.c \ +libffi.call/cls_longdouble.c libffi.call/cls_multi_uchar.c \ +libffi.call/return_uc.c \ +libffi.call/cls_18byte.c libffi.call/cls_8byte.c \ +libffi.call/promotion.c \ +libffi.call/return_dbl.c libffi.call/cls_24byte.c \ +libffi.call/struct4.c libffi.call/cls_6byte.c \ +libffi.call/cls_align_uint32.c libffi.call/float.c \ +libffi.call/float1.c libffi.call/float_va.c libffi.call/negint.c \ +libffi.call/return_dbl1.c libffi.call/cls_3_1byte.c \ +libffi.call/cls_align_float.c libffi.call/return_fl1.c \ +libffi.call/nested_struct10.c libffi.call/nested_struct5.c \ +libffi.call/cls_align_sint64.c \ +libffi.call/stret_large2.c libffi.call/return_sl.c \ +libffi.call/closure_fn0.c libffi.call/cls_5byte.c \ +libffi.call/cls_2byte.c libffi.call/float2.c \ +libffi.call/cls_dbls_struct.c libffi.call/cls_sint.c \ +libffi.call/stret_large.c libffi.call/cls_ulonglong.c \ +libffi.call/cls_ushort.c libffi.call/nested_struct1.c \ +libffi.call/err_bad_abi.c libffi.call/cls_longdouble_va.c \ +libffi.call/cls_float.c libffi.call/cls_pointer_stack.c \ +libffi.call/pyobjc-tc.c libffi.call/cls_multi_ushortchar.c \ +libffi.call/struct1.c libffi.call/nested_struct9.c \ +libffi.call/huge_struct.c libffi.call/problem1.c \ +libffi.call/float4.c \ +libffi.call/return_ldl.c \ +libffi.call/closure_fn5.c \ +libffi.call/struct6.c libffi.call/return_ll.c libffi.call/struct9.c \ +libffi.call/return_sc.c libffi.call/struct7.c \ +libffi.call/cls_align_uint64.c libffi.call/cls_4byte.c \ +libffi.call/cls_6_1_byte.c \ +libffi.call/cls_7_1_byte.c libffi.call/unwindtest.cc \ +libffi.call/unwindtest_ffi_call.cc \ +lib/wrapper.exp lib/target-libpath.exp \ +lib/libffi.exp libffi.call/cls_struct_va1.c \ +libffi.call/cls_uchar_va.c libffi.call/cls_uint_va.c \ +libffi.call/cls_ulong_va.c libffi.call/cls_ushort_va.c \ +libffi.call/nested_struct11.c libffi.call/uninitialized.c \ +libffi.call/va_1.c libffi.call/va_struct1.c libffi.call/va_struct2.c \ +libffi.call/va_struct3.c \ +libffi.call/strlen2.c \ +libffi.call/strlen3.c \ +libffi.call/strlen4.c all: all-am diff --git a/libffi/testsuite/lib/libffi.exp b/libffi/testsuite/lib/libffi.exp index ab0e0e0..b9ef4f1 100644 --- a/libffi/testsuite/lib/libffi.exp +++ b/libffi/testsuite/lib/libffi.exp @@ -1,4 +1,4 @@ -# Copyright (C) 2003, 2005, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +# Copyright (C) 2003, 2005, 2008, 2009, 2010, 2011, 2014 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 @@ -103,12 +103,15 @@ proc libffi-init { args } { global libffi_link_flags global tool_root_dir global ld_library_path + global compiler_vendor set blddirffi [lookfor_file [get_multilibs] libffi] verbose "libffi $blddirffi" set blddircxx [lookfor_file [get_multilibs] libstdc++-v3] verbose "libstdc++ $blddircxx" + set compiler_vendor "gnu" + set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a] if {$gccdir != ""} { set gccdir [file dirname $gccdir] @@ -132,6 +135,7 @@ proc libffi-init { args } { } } } + # add the library path for libffi. append ld_library_path ":${blddirffi}/.libs" # add the library path for libstdc++ as well. @@ -148,7 +152,6 @@ proc libffi-init { args } { 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" } set_ld_library_path_env_vars @@ -215,10 +218,32 @@ proc libffi_target_compile { source dest type options } { lappend options "libs= -lpthread" } + if { [string match "*.cc" $source] } { + lappend options "c++" + } + verbose "options: $options" return [target_compile $source $dest $type $options] } +# TEST should be a preprocessor condition. Returns true if it holds. +proc libffi_feature_test { test } { + set src "ffitest.c" + + set f [open $src "w"] + puts $f "#include <ffi.h>" + puts $f $test + puts $f "xyzzy" + puts $f "#endif" + close $f + + set lines [libffi_target_compile $src "" "preprocess" ""] + file delete $src + + set last [lindex $lines end] + return [regexp -- "xyzzy" $last] +} + # Utility routines. # @@ -238,7 +263,7 @@ proc search_for { file pattern } { # Modified dg-runtest that can cycle through a list of optimization options # as c-torture does. -proc libffi-dg-runtest { testcases flags default-extra-flags } { +proc libffi-dg-runtest { testcases default-extra-flags } { global runtests foreach test $testcases { @@ -259,13 +284,60 @@ proc libffi-dg-runtest { testcases flags default-extra-flags } { set nshort [file tail [file dirname $test]]/[file tail $test] - foreach flags_t $option_list { - verbose "Testing $nshort, $flags $flags_t" 1 - dg-test $test "$flags $flags_t" ${default-extra-flags} + foreach flags $option_list { + verbose "Testing $nshort, $flags" 1 + dg-test $test $flags ${default-extra-flags} } } } +proc run-many-tests { testcases extra_flags } { + global compiler_vendor + switch $compiler_vendor { + "clang" { + set common "-W -Wall" + set optimizations { "-O0" "-O1" "-O2" "-O3" "-Os" } + } + "gnu" { + set common "-W -Wall -Wno-psabi" + set optimizations { "-O0" "-O2" "-O3" "-Os" "-O2 -fomit-frame-pointer" } + } + default { + # Assume we are using the vendor compiler. + set common "" + set optimizations { "" } + } + } + + set targetabis { "" } + if [string match $compiler_vendor "gnu"] { + if [istarget "i?86-*-*"] { + set targetabis { + "" + "-DABI_NUM=FFI_STDCALL -DABI_ATTR=__STDCALL__" + "-DABI_NUM=FFI_THISCALL -DABI_ATTR=__THISCALL__" + "-DABI_NUM=FFI_FASTCALL -DABI_ATTR=__FASTCALL__" + } + } + } + + set common [ concat $common $extra_flags ] + foreach test $testcases { + set testname [file tail $test] + if [search_for $test "ABI_NUM"] { + set abis $targetabis + } else { + set abis { "" } + } + foreach opt $optimizations { + foreach abi $abis { + set options [concat $common $opt $abi] + verbose "Testing $testname, $options" 1 + dg-test $test $options "" + } + } + } +} # Like check_conditional_xfail, but callable from a dg test. diff --git a/libffi/testsuite/lib/target-libpath.exp b/libffi/testsuite/lib/target-libpath.exp new file mode 100644 index 0000000..6b7beba --- /dev/null +++ b/libffi/testsuite/lib/target-libpath.exp @@ -0,0 +1,283 @@ +# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# This file was contributed by John David Anglin (dave.anglin@nrc-cnrc.gc.ca) + +set orig_environment_saved 0 +set orig_ld_library_path_saved 0 +set orig_ld_run_path_saved 0 +set orig_shlib_path_saved 0 +set orig_ld_libraryn32_path_saved 0 +set orig_ld_library64_path_saved 0 +set orig_ld_library_path_32_saved 0 +set orig_ld_library_path_64_saved 0 +set orig_dyld_library_path_saved 0 +set orig_path_saved 0 + +####################################### +# proc set_ld_library_path_env_vars { } +####################################### + +proc set_ld_library_path_env_vars { } { + global ld_library_path + global orig_environment_saved + global orig_ld_library_path_saved + global orig_ld_run_path_saved + global orig_shlib_path_saved + global orig_ld_libraryn32_path_saved + global orig_ld_library64_path_saved + global orig_ld_library_path_32_saved + global orig_ld_library_path_64_saved + global orig_dyld_library_path_saved + global orig_path_saved + global orig_ld_library_path + global orig_ld_run_path + global orig_shlib_path + global orig_ld_libraryn32_path + global orig_ld_library64_path + global orig_ld_library_path_32 + global orig_ld_library_path_64 + global orig_dyld_library_path + global orig_path + global GCC_EXEC_PREFIX + + # Set the relocated compiler prefix, but only if the user hasn't specified one. + if { [info exists GCC_EXEC_PREFIX] && ![info exists env(GCC_EXEC_PREFIX)] } { + setenv GCC_EXEC_PREFIX "$GCC_EXEC_PREFIX" + } + + # Setting the ld library path causes trouble when testing cross-compilers. + if { [is_remote target] } { + return + } + + if { $orig_environment_saved == 0 } { + global env + + set orig_environment_saved 1 + + # Save the original environment. + if [info exists env(LD_LIBRARY_PATH)] { + set orig_ld_library_path "$env(LD_LIBRARY_PATH)" + set orig_ld_library_path_saved 1 + } + if [info exists env(LD_RUN_PATH)] { + set orig_ld_run_path "$env(LD_RUN_PATH)" + set orig_ld_run_path_saved 1 + } + if [info exists env(SHLIB_PATH)] { + set orig_shlib_path "$env(SHLIB_PATH)" + set orig_shlib_path_saved 1 + } + if [info exists env(LD_LIBRARYN32_PATH)] { + set orig_ld_libraryn32_path "$env(LD_LIBRARYN32_PATH)" + set orig_ld_libraryn32_path_saved 1 + } + if [info exists env(LD_LIBRARY64_PATH)] { + set orig_ld_library64_path "$env(LD_LIBRARY64_PATH)" + set orig_ld_library64_path_saved 1 + } + if [info exists env(LD_LIBRARY_PATH_32)] { + set orig_ld_library_path_32 "$env(LD_LIBRARY_PATH_32)" + set orig_ld_library_path_32_saved 1 + } + if [info exists env(LD_LIBRARY_PATH_64)] { + set orig_ld_library_path_64 "$env(LD_LIBRARY_PATH_64)" + set orig_ld_library_path_64_saved 1 + } + if [info exists env(DYLD_LIBRARY_PATH)] { + set orig_dyld_library_path "$env(DYLD_LIBRARY_PATH)" + set orig_dyld_library_path_saved 1 + } + if [info exists env(PATH)] { + set orig_path "$env(PATH)" + set orig_path_saved 1 + } + } + + # We need to set ld library path in the environment. Currently, + # unix.exp doesn't set the environment correctly for all systems. + # It only sets SHLIB_PATH and LD_LIBRARY_PATH when it executes a + # program. We also need the environment set for compilations, etc. + # + # On IRIX 6, we have to set variables akin to LD_LIBRARY_PATH, but + # called LD_LIBRARYN32_PATH (for the N32 ABI) and LD_LIBRARY64_PATH + # (for the 64-bit ABI). The same applies to Darwin (DYLD_LIBRARY_PATH), + # Solaris 32 bit (LD_LIBRARY_PATH_32), Solaris 64 bit (LD_LIBRARY_PATH_64), + # and HP-UX (SHLIB_PATH). In some cases, the variables are independent + # of LD_LIBRARY_PATH, and in other cases LD_LIBRARY_PATH is used if the + # variable is not defined. + # + # Doing this is somewhat of a hack as ld_library_path gets repeated in + # SHLIB_PATH and LD_LIBRARY_PATH when unix_load sets these variables. + if { $orig_ld_library_path_saved } { + setenv LD_LIBRARY_PATH "$ld_library_path:$orig_ld_library_path" + } else { + setenv LD_LIBRARY_PATH "$ld_library_path" + } + if { $orig_ld_run_path_saved } { + setenv LD_RUN_PATH "$ld_library_path:$orig_ld_run_path" + } else { + setenv LD_RUN_PATH "$ld_library_path" + } + # The default shared library dynamic path search for 64-bit + # HP-UX executables searches LD_LIBRARY_PATH before SHLIB_PATH. + # LD_LIBRARY_PATH isn't used for 32-bit executables. Thus, we + # set LD_LIBRARY_PATH and SHLIB_PATH as if they were independent. + if { $orig_shlib_path_saved } { + setenv SHLIB_PATH "$ld_library_path:$orig_shlib_path" + } else { + setenv SHLIB_PATH "$ld_library_path" + } + if { $orig_ld_libraryn32_path_saved } { + setenv LD_LIBRARYN32_PATH "$ld_library_path:$orig_ld_libraryn32_path" + } elseif { $orig_ld_library_path_saved } { + setenv LD_LIBRARYN32_PATH "$ld_library_path:$orig_ld_library_path" + } else { + setenv LD_LIBRARYN32_PATH "$ld_library_path" + } + if { $orig_ld_library64_path_saved } { + setenv LD_LIBRARY64_PATH "$ld_library_path:$orig_ld_library64_path" + } elseif { $orig_ld_library_path_saved } { + setenv LD_LIBRARY64_PATH "$ld_library_path:$orig_ld_library_path" + } else { + setenv LD_LIBRARY64_PATH "$ld_library_path" + } + if { $orig_ld_library_path_32_saved } { + setenv LD_LIBRARY_PATH_32 "$ld_library_path:$orig_ld_library_path_32" + } elseif { $orig_ld_library_path_saved } { + setenv LD_LIBRARY_PATH_32 "$ld_library_path:$orig_ld_library_path" + } else { + setenv LD_LIBRARY_PATH_32 "$ld_library_path" + } + if { $orig_ld_library_path_64_saved } { + setenv LD_LIBRARY_PATH_64 "$ld_library_path:$orig_ld_library_path_64" + } elseif { $orig_ld_library_path_saved } { + setenv LD_LIBRARY_PATH_64 "$ld_library_path:$orig_ld_library_path" + } else { + setenv LD_LIBRARY_PATH_64 "$ld_library_path" + } + if { $orig_dyld_library_path_saved } { + setenv DYLD_LIBRARY_PATH "$ld_library_path:$orig_dyld_library_path" + } else { + setenv DYLD_LIBRARY_PATH "$ld_library_path" + } + if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } { + if { $orig_path_saved } { + setenv PATH "$ld_library_path:$orig_path" + } else { + setenv PATH "$ld_library_path" + } + } + + verbose -log "set_ld_library_path_env_vars: ld_library_path=$ld_library_path" +} + +####################################### +# proc restore_ld_library_path_env_vars { } +####################################### + +proc restore_ld_library_path_env_vars { } { + global orig_environment_saved + global orig_ld_library_path_saved + global orig_ld_run_path_saved + global orig_shlib_path_saved + global orig_ld_libraryn32_path_saved + global orig_ld_library64_path_saved + global orig_ld_library_path_32_saved + global orig_ld_library_path_64_saved + global orig_dyld_library_path_saved + global orig_path_saved + global orig_ld_library_path + global orig_ld_run_path + global orig_shlib_path + global orig_ld_libraryn32_path + global orig_ld_library64_path + global orig_ld_library_path_32 + global orig_ld_library_path_64 + global orig_dyld_library_path + global orig_path + + if { $orig_environment_saved == 0 } { + return + } + + if { $orig_ld_library_path_saved } { + setenv LD_LIBRARY_PATH "$orig_ld_library_path" + } elseif [info exists env(LD_LIBRARY_PATH)] { + unsetenv LD_LIBRARY_PATH + } + if { $orig_ld_run_path_saved } { + setenv LD_RUN_PATH "$orig_ld_run_path" + } elseif [info exists env(LD_RUN_PATH)] { + unsetenv LD_RUN_PATH + } + if { $orig_shlib_path_saved } { + setenv SHLIB_PATH "$orig_shlib_path" + } elseif [info exists env(SHLIB_PATH)] { + unsetenv SHLIB_PATH + } + if { $orig_ld_libraryn32_path_saved } { + setenv LD_LIBRARYN32_PATH "$orig_ld_libraryn32_path" + } elseif [info exists env(LD_LIBRARYN32_PATH)] { + unsetenv LD_LIBRARYN32_PATH + } + if { $orig_ld_library64_path_saved } { + setenv LD_LIBRARY64_PATH "$orig_ld_library64_path" + } elseif [info exists env(LD_LIBRARY64_PATH)] { + unsetenv LD_LIBRARY64_PATH + } + if { $orig_ld_library_path_32_saved } { + setenv LD_LIBRARY_PATH_32 "$orig_ld_library_path_32" + } elseif [info exists env(LD_LIBRARY_PATH_32)] { + unsetenv LD_LIBRARY_PATH_32 + } + if { $orig_ld_library_path_64_saved } { + setenv LD_LIBRARY_PATH_64 "$orig_ld_library_path_64" + } elseif [info exists env(LD_LIBRARY_PATH_64)] { + unsetenv LD_LIBRARY_PATH_64 + } + if { $orig_dyld_library_path_saved } { + setenv DYLD_LIBRARY_PATH "$orig_dyld_library_path" + } elseif [info exists env(DYLD_LIBRARY_PATH)] { + unsetenv DYLD_LIBRARY_PATH + } + if { $orig_path_saved } { + setenv PATH "$orig_path" + } elseif [info exists env(PATH)] { + unsetenv PATH + } +} + +####################################### +# proc get_shlib_extension { } +####################################### + +proc get_shlib_extension { } { + global shlib_ext + + if { [ istarget *-*-darwin* ] } { + set shlib_ext "dylib" + } elseif { [ istarget *-*-cygwin* ] || [ istarget *-*-mingw* ] } { + set shlib_ext "dll" + } elseif { [ istarget hppa*-*-hpux* ] } { + set shlib_ext "sl" + } else { + set shlib_ext "so" + } + return $shlib_ext +} + diff --git a/libffi/testsuite/lib/wrapper.exp b/libffi/testsuite/lib/wrapper.exp new file mode 100644 index 0000000..4e5ae43 --- /dev/null +++ b/libffi/testsuite/lib/wrapper.exp @@ -0,0 +1,45 @@ +# Copyright (C) 2004, 2007 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# This file contains GCC-specifics for status wrappers for test programs. + +# ${tool}_maybe_build_wrapper -- Build wrapper object if the target +# needs it. FILENAME is the path to the wrapper file. If there are +# additional arguments, they are command-line options to provide to +# the compiler when compiling FILENAME. + +proc ${tool}_maybe_build_wrapper { filename args } { + global gluefile wrap_flags + + if { [target_info needs_status_wrapper] != "" \ + && [target_info needs_status_wrapper] != "0" \ + && ![info exists gluefile] } { + set saved_wrap_compile_flags [target_info wrap_compile_flags] + set flags [join $args " "] + # The wrapper code may contain code that gcc objects on. This + # became true for dejagnu-1.4.4. The set of warnings and code + # that gcc objects on may change, so just make sure -w is always + # passed to turn off all warnings. + set_currtarget_info wrap_compile_flags \ + "$saved_wrap_compile_flags -w $flags" + set result [build_wrapper $filename] + set_currtarget_info wrap_compile_flags "$saved_wrap_compile_flags" + if { $result != "" } { + set gluefile [lindex $result 0] + set wrap_flags [lindex $result 1] + } + } +} diff --git a/libffi/testsuite/libffi.call/call.exp b/libffi/testsuite/libffi.call/call.exp index 26acd81..46fb1eb 100644 --- a/libffi/testsuite/libffi.call/call.exp +++ b/libffi/testsuite/libffi.call/call.exp @@ -1,4 +1,4 @@ -# Copyright (C) 2003, 2006, 2009, 2010 Free Software Foundation, Inc. +# Copyright (C) 2003, 2006, 2009, 2010, 2014 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 @@ -19,11 +19,9 @@ libffi-init global srcdir subdir -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O0 -W -Wall" "" -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O2" "" -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O3" "" -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-Os" "" -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O2 -fomit-frame-pointer" "" +set tlist [lsearch -inline -all -not -glob [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]] *complex*] + +run-many-tests $tlist "" dg-finish diff --git a/libffi/testsuite/libffi.call/closure_stdcall.c b/libffi/testsuite/libffi.call/closure_simple.c index 1407f02..5a4e728 100644 --- a/libffi/testsuite/libffi.call/closure_stdcall.c +++ b/libffi/testsuite/libffi.call/closure_simple.c @@ -1,15 +1,14 @@ -/* Area: closure_call (stdcall convention) - Purpose: Check handling when caller expects stdcall callee +/* Area: closure_call + Purpose: Check simple closure handling with all ABIs Limitations: none. PR: none. Originator: <twalljava@dev.java.net> */ -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ +/* { dg-do run } */ #include "ffitest.h" static void -closure_test_stdcall(ffi_cif* cif __UNUSED__, void* resp, void** args, - void* userdata) +closure_test(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata) { *(ffi_arg*)resp = (int)*(int *)args[0] + (int)(*(int *)args[1]) @@ -23,7 +22,7 @@ closure_test_stdcall(ffi_cif* cif __UNUSED__, void* resp, void** args, } -typedef int (__stdcall *closure_test_type0)(int, int, int, int); +typedef int (ABI_ATTR *closure_test_type0)(int, int, int, int); int main (void) { @@ -32,9 +31,6 @@ int main (void) ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); ffi_type * cl_arg_types[17]; int res; - void* sp_pre; - void* sp_post; - char buf[1024]; cl_arg_types[0] = &ffi_type_uint; cl_arg_types[1] = &ffi_type_uint; @@ -43,30 +39,17 @@ int main (void) cl_arg_types[4] = NULL; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 4, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 4, &ffi_type_sint, cl_arg_types) == FFI_OK); - CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_stdcall, + CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test, (void *) 3 /* userdata */, code) == FFI_OK); -#ifdef _MSC_VER - __asm { mov sp_pre, esp } -#else - asm volatile (" movl %%esp,%0" : "=g" (sp_pre)); -#endif res = (*(closure_test_type0)code)(0, 1, 2, 3); -#ifdef _MSC_VER - __asm { mov sp_post, esp } -#else - asm volatile (" movl %%esp,%0" : "=g" (sp_post)); -#endif /* { dg-output "0 1 2 3: 9" } */ printf("res: %d\n",res); /* { dg-output "\nres: 9" } */ - sprintf(buf, "mismatch: pre=%p vs post=%p", sp_pre, sp_post); - printf("stack pointer %s\n", (sp_pre == sp_post ? "match" : buf)); - /* { dg-output "\nstack pointer match" } */ exit(0); } diff --git a/libffi/testsuite/libffi.call/closure_thiscall.c b/libffi/testsuite/libffi.call/closure_thiscall.c deleted file mode 100644 index 0f93649..0000000 --- a/libffi/testsuite/libffi.call/closure_thiscall.c +++ /dev/null @@ -1,72 +0,0 @@ -/* Area: closure_call (thiscall convention) - Purpose: Check handling when caller expects thiscall callee - Limitations: none. - PR: none. - Originator: <ktietz@redhat.com> */ - -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ -#include "ffitest.h" - -static void -closure_test_thiscall(ffi_cif* cif __UNUSED__, void* resp, void** args, - void* userdata) -{ - *(ffi_arg*)resp = - (int)*(int *)args[0] + (int)(*(int *)args[1]) - + (int)(*(int *)args[2]) + (int)(*(int *)args[3]) - + (int)(intptr_t)userdata; - - printf("%d %d %d %d: %d\n", - (int)*(int *)args[0], (int)(*(int *)args[1]), - (int)(*(int *)args[2]), (int)(*(int *)args[3]), - (int)*(ffi_arg *)resp); - -} - -typedef int (__thiscall *closure_test_type0)(int, int, int, int); - -int main (void) -{ - ffi_cif cif; - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - ffi_type * cl_arg_types[17]; - int res; - void* sp_pre; - void* sp_post; - char buf[1024]; - - cl_arg_types[0] = &ffi_type_uint; - cl_arg_types[1] = &ffi_type_uint; - cl_arg_types[2] = &ffi_type_uint; - cl_arg_types[3] = &ffi_type_uint; - cl_arg_types[4] = NULL; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_THISCALL, 4, - &ffi_type_sint, cl_arg_types) == FFI_OK); - - CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_thiscall, - (void *) 3 /* userdata */, code) == FFI_OK); - -#ifdef _MSC_VER - __asm { mov sp_pre, esp } -#else - asm volatile (" movl %%esp,%0" : "=g" (sp_pre)); -#endif - res = (*(closure_test_type0)code)(0, 1, 2, 3); -#ifdef _MSC_VER - __asm { mov sp_post, esp } -#else - asm volatile (" movl %%esp,%0" : "=g" (sp_post)); -#endif - /* { dg-output "0 1 2 3: 9" } */ - - printf("res: %d\n",res); - /* { dg-output "\nres: 9" } */ - - sprintf(buf, "mismatch: pre=%p vs post=%p", sp_pre, sp_post); - printf("stack pointer %s\n", (sp_pre == sp_post ? "match" : buf)); - /* { dg-output "\nstack pointer match" } */ - exit(0); -} diff --git a/libffi/testsuite/libffi.call/cls_align_longdouble_split.c b/libffi/testsuite/libffi.call/cls_align_longdouble_split.c index 15f9365..cc1c43b 100644 --- a/libffi/testsuite/libffi.call/cls_align_longdouble_split.c +++ b/libffi/testsuite/libffi.call/cls_align_longdouble_split.c @@ -4,10 +4,8 @@ PR: none. Originator: <hos@tamanegi.org> 20031203 */ -/* { dg-excess-errors "no long double format" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */ /* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ /* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */ -/* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */ #include "ffitest.h" diff --git a/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c b/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c index ca1c356..5d3bec0 100644 --- a/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c +++ b/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c @@ -5,10 +5,8 @@ Originator: Blake Chaffin 6/18/2007 */ -/* { dg-excess-errors "no long double format" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */ /* { dg-do run { xfail strongarm*-*-* } } */ /* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */ -/* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */ #include "ffitest.h" diff --git a/libffi/testsuite/libffi.call/cls_longdouble.c b/libffi/testsuite/libffi.call/cls_longdouble.c index e6bac1f..d24e72e 100644 --- a/libffi/testsuite/libffi.call/cls_longdouble.c +++ b/libffi/testsuite/libffi.call/cls_longdouble.c @@ -4,10 +4,10 @@ PR: none. Originator: Blake Chaffin */ -/* { dg-excess-errors "no long double format" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */ -/* { dg-do run { xfail arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* This test is known to PASS on armv7l-unknown-linux-gnueabihf, so I have + remove the xfail for arm*-*-* below, until we know more. */ +/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ /* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */ -/* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */ #include "ffitest.h" diff --git a/libffi/testsuite/libffi.call/cls_many_mixed_args.c b/libffi/testsuite/libffi.call/cls_many_mixed_args.c new file mode 100644 index 0000000..7fd6c82 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_many_mixed_args.c @@ -0,0 +1,70 @@ +/* Area: closure_call + Purpose: Check closures called with many args of mixed types + Limitations: none. + PR: none. + Originator: <david.schneider@picle.org> */ + +/* { dg-do run } */ +#include "ffitest.h" +#include <float.h> +#include <math.h> + +#define NARGS 16 + +static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + int i; + double r = 0; + double t; + for(i = 0; i < NARGS; i++) + { + if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15) + { + t = *(long int *)args[i]; + CHECK(t == i+1); + } + else + { + t = *(double *)args[i]; + CHECK(fabs(t - ((i+1) * 0.1)) < FLT_EPSILON); + } + r += t; + } + *(double *)resp = r; +} +typedef double (*cls_ret_double)(double, double, double, double, long int, +double, double, double, double, long int, double, long int, double, long int, +double, long int); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[NARGS]; + double res; + int i; + double expected = 64.9; + + for(i = 0; i < NARGS; i++) + { + if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15) + cl_arg_types[i] = &ffi_type_slong; + else + cl_arg_types[i] = &ffi_type_double; + } + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, NARGS, + &ffi_type_double, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_double_fn, NULL, code) == FFI_OK); + + res = (((cls_ret_double)code))(0.1, 0.2, 0.3, 0.4, 5, 0.6, 0.7, 0.8, 0.9, 10, + 1.1, 12, 1.3, 14, 1.5, 16); + if (fabs(res - expected) < FLT_EPSILON) + exit(0); + else + abort(); +} diff --git a/libffi/testsuite/libffi.call/cls_many_mixed_float_double.c b/libffi/testsuite/libffi.call/cls_many_mixed_float_double.c new file mode 100644 index 0000000..62b0697a --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_many_mixed_float_double.c @@ -0,0 +1,55 @@ +/* Area: closure_call + Purpose: Check register allocation for closure calls with many float and double arguments + Limitations: none. + PR: none. + Originator: <david.schneider@picle.org> */ + +/* { dg-do run } */ +#include "ffitest.h" +#include <float.h> +#include <math.h> + +#define NARGS 16 + +static void cls_mixed_float_double_fn(ffi_cif* cif , void* ret, void** args, + void* userdata __UNUSED__) +{ + double r = 0; + unsigned int i; + double t; + for(i=0; i < cif->nargs; i++) + { + if(cif->arg_types[i] == &ffi_type_double) { + t = *(((double**)(args))[i]); + } else { + t = *(((float**)(args))[i]); + } + r += t; + } + *((double*)ret) = r; +} +typedef double (*cls_mixed)(double, float, double, double, double, double, double, float, float, double, float, float); + +int main (void) +{ + ffi_cif cif; + ffi_closure *closure; + void* code; + ffi_type *argtypes[12] = {&ffi_type_double, &ffi_type_float, &ffi_type_double, + &ffi_type_double, &ffi_type_double, &ffi_type_double, + &ffi_type_double, &ffi_type_float, &ffi_type_float, + &ffi_type_double, &ffi_type_float, &ffi_type_float}; + + + closure = ffi_closure_alloc(sizeof(ffi_closure), (void**)&code); + if(closure ==NULL) + abort(); + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 12, &ffi_type_double, argtypes) == FFI_OK); + CHECK(ffi_prep_closure_loc(closure, &cif, cls_mixed_float_double_fn, NULL, code) == FFI_OK); + double ret = ((cls_mixed)code)(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2); + ffi_closure_free(closure); + if(fabs(ret - 7.8) < FLT_EPSILON) + exit(0); + else + abort(); +} diff --git a/libffi/testsuite/libffi.call/cls_pointer.c b/libffi/testsuite/libffi.call/cls_pointer.c index cf03993..d82a87a 100644 --- a/libffi/testsuite/libffi.call/cls_pointer.c +++ b/libffi/testsuite/libffi.call/cls_pointer.c @@ -35,7 +35,7 @@ int main (void) void *code; ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); void* args[3]; -// ffi_type cls_pointer_type; + /* ffi_type cls_pointer_type; */ ffi_type* arg_types[3]; /* cls_pointer_type.size = sizeof(void*); diff --git a/libffi/testsuite/libffi.call/cls_pointer_stack.c b/libffi/testsuite/libffi.call/cls_pointer_stack.c index e31139e..1f1d915 100644 --- a/libffi/testsuite/libffi.call/cls_pointer_stack.c +++ b/libffi/testsuite/libffi.call/cls_pointer_stack.c @@ -98,7 +98,7 @@ int main (void) void *code; ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); void* args[3]; -// ffi_type cls_pointer_type; + /* ffi_type cls_pointer_type; */ ffi_type* arg_types[3]; /* cls_pointer_type.size = sizeof(void*); @@ -125,18 +125,18 @@ int main (void) ffi_call(&cif, FFI_FN(cls_pointer_fn1), &res, args); printf("res: 0x%08x\n", (unsigned int) res); - // { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" } - // { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" } - // { dg-output "\nres: 0x8bf258bd" } + /* { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" } */ + /* { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" } */ + /* { dg-output "\nres: 0x8bf258bd" } */ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_pointer_gn, NULL, code) == FFI_OK); res = (ffi_arg)(uintptr_t)((void*(*)(void*, void*))(code))(arg1, arg2); printf("res: 0x%08x\n", (unsigned int) res); - // { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" } - // { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" } - // { dg-output "\nres: 0x8bf258bd" } + /* { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" } */ + /* { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" } */ + /* { dg-output "\nres: 0x8bf258bd" } */ exit(0); } diff --git a/libffi/testsuite/libffi.call/cls_struct_va1.c b/libffi/testsuite/libffi.call/cls_struct_va1.c index 7262d63..6d1fdae 100644 --- a/libffi/testsuite/libffi.call/cls_struct_va1.c +++ b/libffi/testsuite/libffi.call/cls_struct_va1.c @@ -106,9 +106,9 @@ main (void) CHECK(ffi_prep_closure_loc(pcl, &cif, test_fn, NULL, code) == FFI_OK); res = ((int (*)(int, ...))(code))(si, s1, l1, s2); - // { dg-output "4 5 6 10 11 12 13 14 20 21" } + /* { dg-output "4 5 6 10 11 12 13 14 20 21" } */ printf("res: %d\n", (int) res); - // { dg-output "\nres: 42" } + /* { dg-output "\nres: 42" } */ exit(0); } diff --git a/libffi/testsuite/libffi.call/cls_ulonglong.c b/libffi/testsuite/libffi.call/cls_ulonglong.c index 235ab44..62f2cae 100644 --- a/libffi/testsuite/libffi.call/cls_ulonglong.c +++ b/libffi/testsuite/libffi.call/cls_ulonglong.c @@ -11,7 +11,7 @@ static void cls_ret_ulonglong_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__) { - *(unsigned long long *)resp= *(unsigned long long *)args[0]; + *(unsigned long long *)resp= 0xfffffffffffffffLL ^ *(unsigned long long *)args[0]; printf("%" PRIuLL ": %" PRIuLL "\n",*(unsigned long long *)args[0], *(unsigned long long *)(resp)); @@ -34,14 +34,14 @@ int main (void) &ffi_type_uint64, cl_arg_types) == FFI_OK); CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_ulonglong_fn, NULL, code) == FFI_OK); res = (*((cls_ret_ulonglong)code))(214LL); - /* { dg-output "214: 214" } */ + /* { dg-output "214: 1152921504606846761" } */ printf("res: %" PRIdLL "\n", res); - /* { dg-output "\nres: 214" } */ + /* { dg-output "\nres: 1152921504606846761" } */ res = (*((cls_ret_ulonglong)code))(9223372035854775808LL); - /* { dg-output "\n9223372035854775808: 9223372035854775808" } */ + /* { dg-output "\n9223372035854775808: 8070450533247928831" } */ printf("res: %" PRIdLL "\n", res); - /* { dg-output "\nres: 9223372035854775808" } */ + /* { dg-output "\nres: 8070450533247928831" } */ exit(0); } diff --git a/libffi/testsuite/libffi.call/ffitest.h b/libffi/testsuite/libffi.call/ffitest.h index d81d4da..15d5e44 100644 --- a/libffi/testsuite/libffi.call/ffitest.h +++ b/libffi/testsuite/libffi.call/ffitest.h @@ -15,22 +15,25 @@ #define MAX_ARGS 256 -#define CHECK(x) !(x) ? abort() : 0 +#define CHECK(x) (void)(!(x) ? (abort(), 1) : 0) -/* Define __UNUSED__ that also other compilers than gcc can run the tests. */ +/* Define macros so that compilers other than gcc can run the tests. */ #undef __UNUSED__ #if defined(__GNUC__) #define __UNUSED__ __attribute__((__unused__)) +#define __STDCALL__ __attribute__((stdcall)) +#define __THISCALL__ __attribute__((thiscall)) +#define __FASTCALL__ __attribute__((fastcall)) #else #define __UNUSED__ +#define __STDCALL__ __stdcall +#define __THISCALL__ __thiscall +#define __FASTCALL__ __fastcall #endif -/* Define __FASTCALL__ so that other compilers than gcc can run the tests. */ -#undef __FASTCALL__ -#if defined _MSC_VER -#define __FASTCALL__ __fastcall -#else -#define __FASTCALL__ __attribute__((fastcall)) +#ifndef ABI_NUM +#define ABI_NUM FFI_DEFAULT_ABI +#define ABI_ATTR #endif /* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a @@ -127,44 +130,6 @@ #define PRId64 "I64d" #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; -} - +#ifndef PRIuPTR +#define PRIuPTR "u" #endif diff --git a/libffi/testsuite/libffi.call/float1.c b/libffi/testsuite/libffi.call/float1.c index 991d059..c48493c 100644 --- a/libffi/testsuite/libffi.call/float1.c +++ b/libffi/testsuite/libffi.call/float1.c @@ -8,6 +8,8 @@ #include "ffitest.h" #include "float.h" +#include <math.h> + typedef union { double d; @@ -47,7 +49,7 @@ int main (void) /* These are not always the same!! Check for a reasonable delta */ - CHECK(result[0].d - dblit(f) < DBL_EPSILON); + CHECK(fabs(result[0].d - dblit(f)) < DBL_EPSILON); /* Check the canary. */ for (i = 0; i < sizeof (double); ++i) diff --git a/libffi/testsuite/libffi.call/float2.c b/libffi/testsuite/libffi.call/float2.c index a0b296c..20a8c40 100644 --- a/libffi/testsuite/libffi.call/float2.c +++ b/libffi/testsuite/libffi.call/float2.c @@ -3,13 +3,13 @@ Limitations: none. PR: none. Originator: From the original ffitest.c */ - -/* { dg-excess-errors "fails" { target x86_64-*-mingw* x86_64-*-cygwin* } } */ -/* { dg-do run { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */ +/* { dg-do run } */ #include "ffitest.h" #include "float.h" +#include <math.h> + static long double ldblit(float f) { return (long double) (((long double) f)/ (long double) 3.0); @@ -49,7 +49,7 @@ int main (void) #endif /* These are not always the same!! Check for a reasonable delta */ - if (ld - ldblit(f) < LDBL_EPSILON) + if (fabsl(ld - ldblit(f)) < LDBL_EPSILON) puts("long double return value tests ok!"); else CHECK(0); diff --git a/libffi/testsuite/libffi.call/float3.c b/libffi/testsuite/libffi.call/float3.c index 76bd5f2..bab3206 100644 --- a/libffi/testsuite/libffi.call/float3.c +++ b/libffi/testsuite/libffi.call/float3.c @@ -9,6 +9,8 @@ #include "ffitest.h" #include "float.h" +#include <math.h> + static double floating_1(float a, double b, long double c) { return (double) a + b + (double) c; @@ -49,7 +51,7 @@ int main (void) ffi_call(&cif, FFI_FN(floating_1), &rd, values); - CHECK(rd - floating_1(f, d, ld) < DBL_EPSILON); + CHECK(fabs(rd - floating_1(f, d, ld)) < DBL_EPSILON); args[0] = &ffi_type_longdouble; values[0] = &ld; @@ -66,7 +68,7 @@ int main (void) ffi_call(&cif, FFI_FN(floating_2), &rd, values); - CHECK(rd - floating_2(ld, d, f) < DBL_EPSILON); + CHECK(fabs(rd - floating_2(ld, d, f)) < DBL_EPSILON); exit (0); } diff --git a/libffi/testsuite/libffi.call/float_va.c b/libffi/testsuite/libffi.call/float_va.c index aae158e..5acff91 100644 --- a/libffi/testsuite/libffi.call/float_va.c +++ b/libffi/testsuite/libffi.call/float_va.c @@ -56,9 +56,9 @@ int main (void) * different. */ /* Call it statically and then via ffi */ resfp=float_va_fn(0,2.0); - // { dg-output "0: 2.0 : total: 2.0" } + /* { dg-output "0: 2.0 : total: 2.0" } */ printf("compiled: %.1f\n", resfp); - // { dg-output "\ncompiled: 2.0" } + /* { dg-output "\ncompiled: 2.0" } */ arg_types[0] = &ffi_type_uint; arg_types[1] = &ffi_type_double; @@ -71,16 +71,16 @@ int main (void) values[0] = &firstarg; values[1] = &doubles[0]; ffi_call(&cif, FFI_FN(float_va_fn), &resfp, values); - // { dg-output "\n0: 2.0 : total: 2.0" } + /* { dg-output "\n0: 2.0 : total: 2.0" } */ printf("ffi: %.1f\n", resfp); - // { dg-output "\nffi: 2.0" } + /* { dg-output "\nffi: 2.0" } */ /* Second test, float_va_fn(2,2.0,3.0,4.0), now with variadic params */ /* Call it statically and then via ffi */ resfp=float_va_fn(2,2.0,3.0,4.0); - // { dg-output "\n2: 2.0 : 0:3.0 1:4.0 total: 11.0" } + /* { dg-output "\n2: 2.0 : 0:3.0 1:4.0 total: 11.0" } */ printf("compiled: %.1f\n", resfp); - // { dg-output "\ncompiled: 11.0" } + /* { dg-output "\ncompiled: 11.0" } */ arg_types[0] = &ffi_type_uint; arg_types[1] = &ffi_type_double; @@ -99,9 +99,9 @@ int main (void) values[2] = &doubles[1]; values[3] = &doubles[2]; ffi_call(&cif, FFI_FN(float_va_fn), &resfp, values); - // { dg-output "\n2: 2.0 : 0:3.0 1:4.0 total: 11.0" } + /* { dg-output "\n2: 2.0 : 0:3.0 1:4.0 total: 11.0" } */ printf("ffi: %.1f\n", resfp); - // { dg-output "\nffi: 11.0" } + /* { dg-output "\nffi: 11.0" } */ exit(0); } diff --git a/libffi/testsuite/libffi.call/huge_struct.c b/libffi/testsuite/libffi.call/huge_struct.c index 380fedf..187c42c 100644 --- a/libffi/testsuite/libffi.call/huge_struct.c +++ b/libffi/testsuite/libffi.call/huge_struct.c @@ -5,10 +5,9 @@ Originator: Blake Chaffin 6/18/2007 */ -/* { dg-excess-errors "" { target x86_64-*-mingw* x86_64-*-cygwin* } } */ /* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ /* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */ -/* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */ +/* { dg-options -Wformat=0 { target moxie*-*-elf } } */ #include "ffitest.h" @@ -295,7 +294,7 @@ main(int argc __UNUSED__, const char** argv __UNUSED__) CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 50, &ret_struct_type, argTypes) == FFI_OK); ffi_call(&cif, FFI_FN(test_large_fn), &retVal, argValues); - // { dg-output "1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } + /* { dg-output "1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } */ printf("res: %" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " @@ -308,7 +307,7 @@ main(int argc __UNUSED__, const char** argv __UNUSED__) retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj, retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp, retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx); - // { dg-output "\nres: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } + /* { dg-output "\nres: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } */ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_large_fn, NULL, code) == FFI_OK); @@ -323,7 +322,7 @@ main(int argc __UNUSED__, const char** argv __UNUSED__) ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p, ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p, ui8, si8); - // { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } + /* { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } */ printf("res: %" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " @@ -336,7 +335,7 @@ main(int argc __UNUSED__, const char** argv __UNUSED__) retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj, retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp, retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx); - // { dg-output "\nres: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } + /* { dg-output "\nres: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } */ return 0; } diff --git a/libffi/testsuite/libffi.call/many.c b/libffi/testsuite/libffi.call/many.c index 4869ba9..336968c 100644 --- a/libffi/testsuite/libffi.call/many.c +++ b/libffi/testsuite/libffi.call/many.c @@ -7,21 +7,11 @@ /* { dg-do run } */ #include "ffitest.h" +#include <stdlib.h> #include <float.h> +#include <math.h> -static float many(float f1, - float f2, - float f3, - float f4, - float f5, - float f6, - float f7, - float f8, - float f9, - float f10, - float f11, - float f12, - float f13) +static float ABI_ATTR 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", @@ -30,7 +20,7 @@ static float many(float f1, (double) f11, (double) f12, (double) f13); #endif - return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13); + return f1+f2+f3+f4+f5+f6+f7+f8+f9+f10+f11+f12+f13; } int main (void) @@ -50,7 +40,7 @@ int main (void) } /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 13, &ffi_type_float, args) == FFI_OK); ffi_call(&cif, FFI_FN(many), &f, values); @@ -62,7 +52,7 @@ int main (void) fa[8], fa[9], fa[10],fa[11],fa[12]); - if (f - ff < FLT_EPSILON) + if (fabs(f - ff) < FLT_EPSILON) exit(0); else abort(); diff --git a/libffi/testsuite/libffi.call/many2.c b/libffi/testsuite/libffi.call/many2.c index 1077159..1c85746 100644 --- a/libffi/testsuite/libffi.call/many2.c +++ b/libffi/testsuite/libffi.call/many2.c @@ -12,14 +12,17 @@ typedef unsigned char u8; -__attribute__((noinline)) uint8_t +#ifdef __GNUC__ +__attribute__((noinline)) +#endif +uint8_t foo (uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e, uint8_t f, uint8_t g) { return a + b + c + d + e + f + g; } -uint8_t +uint8_t ABI_ATTR bar (uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e, uint8_t f, uint8_t g) { @@ -39,7 +42,7 @@ main (void) for (i = 0; i < NARGS; ++i) ffitypes[i] = &ffi_type_uint8; - CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, NARGS, + CHECK (ffi_prep_cif (&cif, ABI_NUM, NARGS, &ffi_type_uint8, ffitypes) == FFI_OK); for (i = 0; i < NARGS; ++i) diff --git a/libffi/testsuite/libffi.call/many2_win32.c b/libffi/testsuite/libffi.call/many2_win32.c deleted file mode 100644 index 4adbe4d..0000000 --- a/libffi/testsuite/libffi.call/many2_win32.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Area: ffi_call - Purpose: Check stdcall many call on X86_WIN32 systems. - Limitations: none. - PR: none. - Originator: From the original ffitest.c */ - -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ - -#include "ffitest.h" -#include <float.h> - -static float __attribute__((fastcall)) fastcall_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_FASTCALL, 13, - &ffi_type_float, args) == FFI_OK); - - ff = fastcall_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(fastcall_many), &f, values); - - if (f - ff < FLT_EPSILON) - printf("fastcall many arg tests ok!\n"); - else - CHECK(0); - exit(0); -} diff --git a/libffi/testsuite/libffi.call/many_double.c b/libffi/testsuite/libffi.call/many_double.c new file mode 100644 index 0000000..4ef8c8a --- /dev/null +++ b/libffi/testsuite/libffi.call/many_double.c @@ -0,0 +1,70 @@ +/* Area: ffi_call + Purpose: Check return value double, with many arguments + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +#include "ffitest.h" + +#include <stdlib.h> +#include <float.h> +#include <math.h> + +static double many(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) +{ +#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]; + double fa[13]; + double f, ff; + int i; + + for (i = 0; i < 13; i++) + { + args[i] = &ffi_type_double; + values[i] = &fa[i]; + fa[i] = (double) i; + } + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, + &ffi_type_double, 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 (fabs(f - ff) < FLT_EPSILON) + exit(0); + else + abort(); +} diff --git a/libffi/testsuite/libffi.call/many_mixed.c b/libffi/testsuite/libffi.call/many_mixed.c new file mode 100644 index 0000000..85ec36e --- /dev/null +++ b/libffi/testsuite/libffi.call/many_mixed.c @@ -0,0 +1,78 @@ +/* Area: ffi_call + Purpose: Check return value double, with many arguments + Limitations: none. + PR: none. + Originator: From the original ffitest.c */ + +/* { dg-do run } */ +#include "ffitest.h" + +#include <stdlib.h> +#include <float.h> +#include <math.h> + +static double many(double f1, + double f2, + long int i1, + double f3, + double f4, + long int i2, + double f5, + double f6, + long int i3, + double f7, + double f8, + long int i4, + double f9, + double f10, + long int i5, + double f11, + double f12, + long int i6, + double f13) +{ + return ((double) (i1 + i2 + i3 + i4 + i5 + i6) + (f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13); +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[19]; + void *values[19]; + double fa[19]; + long int la[19]; + double f, ff; + int i; + + for (i = 0; i < 19; i++) + { + if( (i - 2) % 3 == 0) { + args[i] = &ffi_type_slong; + la[i] = (long int) i; + values[i] = &la[i]; + } + else { + args[i] = &ffi_type_double; + fa[i] = (double) i; + values[i] = &fa[i]; + } + } + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 19, + &ffi_type_double, args) == FFI_OK); + + ffi_call(&cif, FFI_FN(many), &f, values); + + ff = many(fa[0], fa[1], la[2], + fa[3], fa[4], la[5], + fa[6], fa[7], la[8], + fa[9], fa[10], la[11], + fa[12], fa[13], la[14], + fa[15], fa[16], la[17], + fa[18]); + if (fabs(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 deleted file mode 100644 index 1b26332..0000000 --- a/libffi/testsuite/libffi.call/many_win32.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Area: ffi_call - Purpose: Check stdcall many call on X86_WIN32 systems. - Limitations: none. - PR: none. - Originator: From the original ffitest.c */ - -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ - -#include "ffitest.h" -#include <float.h> - -static float __attribute__((stdcall)) stdcall_many(float f1, - float f2, - float f3, - float f4, - float f5, - float f6, - float f7, - float f8, - float f9, - float f10, - float f11, - float f12, - float f13) -{ - return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13); -} - -int main (void) -{ - ffi_cif cif; - ffi_type *args[13]; - void *values[13]; - float fa[13]; - float f, ff; - unsigned long ul; - - for (ul = 0; ul < 13; ul++) - { - args[ul] = &ffi_type_float; - values[ul] = &fa[ul]; - fa[ul] = (float) ul; - } - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 13, - &ffi_type_float, args) == FFI_OK); - - ff = stdcall_many(fa[0], fa[1], - fa[2], fa[3], - fa[4], fa[5], - fa[6], fa[7], - fa[8], fa[9], - fa[10], fa[11], fa[12]); - - ffi_call(&cif, FFI_FN(stdcall_many), &f, values); - - if (f - ff < FLT_EPSILON) - printf("stdcall many arg tests ok!\n"); - else - CHECK(0); - exit(0); -} diff --git a/libffi/testsuite/libffi.call/negint.c b/libffi/testsuite/libffi.call/negint.c index 3168113..6e2f26f 100644 --- a/libffi/testsuite/libffi.call/negint.c +++ b/libffi/testsuite/libffi.call/negint.c @@ -5,7 +5,6 @@ Originator: From the original ffitest.c */ /* { dg-do run } */ -/* { dg-options -O2 } */ #include "ffitest.h" diff --git a/libffi/testsuite/libffi.call/nested_struct1.c b/libffi/testsuite/libffi.call/nested_struct1.c index 1087f7b..477a6b9 100644 --- a/libffi/testsuite/libffi.call/nested_struct1.c +++ b/libffi/testsuite/libffi.call/nested_struct1.c @@ -156,6 +156,6 @@ int main (void) 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); + /* CHECK( 1 == 0); */ exit(0); } diff --git a/libffi/testsuite/libffi.call/nested_struct11.c b/libffi/testsuite/libffi.call/nested_struct11.c index fce6948..3510493 100644 --- a/libffi/testsuite/libffi.call/nested_struct11.c +++ b/libffi/testsuite/libffi.call/nested_struct11.c @@ -1,7 +1,7 @@ /* Area: ffi_call, closure_call Purpose: Check parameter passing with nested structs of a single type. This tests the special cases - for homogenous floating-point aggregates in the + for homogeneous floating-point aggregates in the AArch64 PCS. Limitations: none. PR: none. diff --git a/libffi/testsuite/libffi.call/return_dbl.c b/libffi/testsuite/libffi.call/return_dbl.c index 1aab403..fd07e50 100644 --- a/libffi/testsuite/libffi.call/return_dbl.c +++ b/libffi/testsuite/libffi.call/return_dbl.c @@ -9,6 +9,7 @@ static double return_dbl(double dbl) { + printf ("%f\n", dbl); return 2 * dbl; } int main (void) diff --git a/libffi/testsuite/libffi.call/return_ldl.c b/libffi/testsuite/libffi.call/return_ldl.c index 5c2fe65..52a92fe 100644 --- a/libffi/testsuite/libffi.call/return_ldl.c +++ b/libffi/testsuite/libffi.call/return_ldl.c @@ -3,8 +3,8 @@ Limitations: none. PR: none. Originator: <andreast@gcc.gnu.org> 20071113 */ +/* { dg-do run } */ -/* { dg-do run { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */ #include "ffitest.h" static long double return_ldl(long double ldl) diff --git a/libffi/testsuite/libffi.call/return_uc.c b/libffi/testsuite/libffi.call/return_uc.c index 07c45de..6fe5546 100644 --- a/libffi/testsuite/libffi.call/return_uc.c +++ b/libffi/testsuite/libffi.call/return_uc.c @@ -32,7 +32,7 @@ int main (void) uc < (unsigned char) '\xff'; uc++) { ffi_call(&cif, FFI_FN(return_uc), &rint, values); - CHECK(rint == (signed int) uc); + CHECK((unsigned char)rint == uc); } exit(0); } diff --git a/libffi/testsuite/libffi.call/stret_large.c b/libffi/testsuite/libffi.call/stret_large.c index f32938c..71c2469 100644 --- a/libffi/testsuite/libffi.call/stret_large.c +++ b/libffi/testsuite/libffi.call/stret_large.c @@ -9,8 +9,8 @@ /* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ #include "ffitest.h" -// 13 FPRs: 104 bytes -// 14 FPRs: 112 bytes +/* 13 FPRs: 104 bytes */ +/* 14 FPRs: 112 bytes */ typedef struct struct_108byte { double a; diff --git a/libffi/testsuite/libffi.call/stret_large2.c b/libffi/testsuite/libffi.call/stret_large2.c index 3b0ef9a..d9c750e 100644 --- a/libffi/testsuite/libffi.call/stret_large2.c +++ b/libffi/testsuite/libffi.call/stret_large2.c @@ -9,8 +9,8 @@ /* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ #include "ffitest.h" -// 13 FPRs: 104 bytes -// 14 FPRs: 112 bytes +/* 13 FPRs: 104 bytes */ +/* 14 FPRs: 112 bytes */ typedef struct struct_116byte { double a; diff --git a/libffi/testsuite/libffi.call/strlen.c b/libffi/testsuite/libffi.call/strlen.c index 3de45de..35b70ea 100644 --- a/libffi/testsuite/libffi.call/strlen.c +++ b/libffi/testsuite/libffi.call/strlen.c @@ -7,7 +7,7 @@ /* { dg-do run } */ #include "ffitest.h" -static size_t my_strlen(char *s) +static size_t ABI_ATTR my_strlen(char *s) { return (strlen(s)); } @@ -24,7 +24,7 @@ int main (void) values[0] = (void*) &s; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ffi_type_sint, args) == FFI_OK); s = "a"; diff --git a/libffi/testsuite/libffi.call/fastthis1_win32.c b/libffi/testsuite/libffi.call/strlen2.c index cbc4724..96282bc 100644 --- a/libffi/testsuite/libffi.call/fastthis1_win32.c +++ b/libffi/testsuite/libffi.call/strlen2.c @@ -1,14 +1,14 @@ /* Area: ffi_call - Purpose: Check fastcall fct call on X86_WIN32 systems. + Purpose: Check strlen function call with additional arguments. Limitations: none. PR: none. Originator: From the original ffitest.c */ -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ +/* { dg-do run } */ #include "ffitest.h" -static size_t __FASTCALL__ my_fastcall_f(char *s, float a) +static size_t ABI_ATTR my_f(char *s, float a) { return (size_t) ((int) strlen(s) + (int) a); } @@ -27,24 +27,23 @@ int main (void) values[1] = (void*) &v2; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 2, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, &ffi_type_sint, args) == FFI_OK); s = "a"; v2 = 0.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 1); s = "1234567"; v2 = -1.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 6); s = "1234567890123456789012345"; v2 = 1.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 26); - printf("fastcall fct1 tests passed\n"); exit(0); } diff --git a/libffi/testsuite/libffi.call/strlen2_win32.c b/libffi/testsuite/libffi.call/strlen2_win32.c deleted file mode 100644 index 0d81061..0000000 --- a/libffi/testsuite/libffi.call/strlen2_win32.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Area: ffi_call - Purpose: Check fastcall 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 __FASTCALL__ my_fastcall_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_FASTCALL, 1, - &ffi_type_sint, args) == FFI_OK); - - s = "a"; - ffi_call(&cif, FFI_FN(my_fastcall_strlen), &rint, values); - CHECK(rint == 1); - - s = "1234567"; - ffi_call(&cif, FFI_FN(my_fastcall_strlen), &rint, values); - CHECK(rint == 7); - - s = "1234567890123456789012345"; - ffi_call(&cif, FFI_FN(my_fastcall_strlen), &rint, values); - CHECK(rint == 25); - - printf("fastcall strlen tests passed\n"); - exit(0); -} diff --git a/libffi/testsuite/libffi.call/fastthis2_win32.c b/libffi/testsuite/libffi.call/strlen3.c index 7bdd0e1..beba86e 100644 --- a/libffi/testsuite/libffi.call/fastthis2_win32.c +++ b/libffi/testsuite/libffi.call/strlen3.c @@ -1,14 +1,14 @@ /* Area: ffi_call - Purpose: Check fastcall fct call on X86_WIN32 systems. + Purpose: Check strlen function call with additional arguments. Limitations: none. PR: none. Originator: From the original ffitest.c */ -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ +/* { dg-do run } */ #include "ffitest.h" -static size_t __FASTCALL__ my_fastcall_f(float a, char *s) +static size_t ABI_ATTR my_f(float a, char *s) { return (size_t) ((int) strlen(s) + (int) a); } @@ -27,24 +27,23 @@ int main (void) values[0] = (void*) &v2; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 2, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, &ffi_type_sint, args) == FFI_OK); s = "a"; v2 = 0.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 1); s = "1234567"; v2 = -1.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 6); s = "1234567890123456789012345"; v2 = 1.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 26); - printf("fastcall fct2 tests passed\n"); exit(0); } diff --git a/libffi/testsuite/libffi.call/fastthis3_win32.c b/libffi/testsuite/libffi.call/strlen4.c index b5d606d..d5d42b4 100644 --- a/libffi/testsuite/libffi.call/fastthis3_win32.c +++ b/libffi/testsuite/libffi.call/strlen4.c @@ -1,14 +1,14 @@ /* Area: ffi_call - Purpose: Check fastcall f call on X86_WIN32 systems. + Purpose: Check strlen function call with additional arguments. Limitations: none. PR: none. Originator: From the original ffitest.c */ -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ +/* { dg-do run } */ #include "ffitest.h" -static size_t __FASTCALL__ my_fastcall_f(float a, char *s, int i) +static size_t ABI_ATTR my_f(float a, char *s, int i) { return (size_t) ((int) strlen(s) + (int) a + i); } @@ -30,27 +30,26 @@ int main (void) values[0] = (void*) &v2; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 3, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 3, &ffi_type_sint, args) == FFI_OK); s = "a"; v1 = 1; v2 = 0.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 2); s = "1234567"; v2 = -1.0; v1 = -2; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 4); s = "1234567890123456789012345"; v2 = 1.0; v1 = 2; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 28); - printf("fastcall fct3 tests passed\n"); exit(0); } diff --git a/libffi/testsuite/libffi.call/strlen_win32.c b/libffi/testsuite/libffi.call/strlen_win32.c deleted file mode 100644 index 6fbcc87..0000000 --- a/libffi/testsuite/libffi.call/strlen_win32.c +++ /dev/null @@ -1,44 +0,0 @@ -/* 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 index bfc23f64..c13e23f 100644 --- a/libffi/testsuite/libffi.call/struct1.c +++ b/libffi/testsuite/libffi.call/struct1.c @@ -14,7 +14,7 @@ typedef struct unsigned int ui; } test_structure_1; -static test_structure_1 struct1(test_structure_1 ts) +static test_structure_1 ABI_ATTR struct1(test_structure_1 ts) { ts.uc++; ts.d--; @@ -50,7 +50,7 @@ int main (void) values[0] = &ts1_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts1_type, args) == FFI_OK); ts1_arg.uc = '\x01'; diff --git a/libffi/testsuite/libffi.call/struct1_win32.c b/libffi/testsuite/libffi.call/struct1_win32.c deleted file mode 100644 index b756f5a..0000000 --- a/libffi/testsuite/libffi.call/struct1_win32.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Area: ffi_call - Purpose: Check structures with fastcall/thiscall convention. - Limitations: none. - PR: none. - Originator: From the original ffitest.c */ - -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ -#include "ffitest.h" - -typedef struct -{ - unsigned char uc; - double d; - unsigned int ui; -} test_structure_1; - -static test_structure_1 __FASTCALL__ struct1(test_structure_1 ts) -{ - ts.uc++; - ts.d--; - ts.ui++; - - return ts; -} - -int main (void) -{ - ffi_cif cif; - ffi_type *args[MAX_ARGS]; - void *values[MAX_ARGS]; - ffi_type ts1_type; - ffi_type *ts1_type_elements[4]; - - 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)); - - 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; - - args[0] = &ts1_type; - values[0] = &ts1_arg; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 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 index d85385e..5077a5e 100644 --- a/libffi/testsuite/libffi.call/struct2.c +++ b/libffi/testsuite/libffi.call/struct2.c @@ -13,7 +13,7 @@ typedef struct double d2; } test_structure_2; -static test_structure_2 struct2(test_structure_2 ts) +static test_structure_2 ABI_ATTR struct2(test_structure_2 ts) { ts.d1--; ts.d2--; @@ -46,7 +46,7 @@ int main (void) values[0] = &ts2_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts2_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts2_type, args) == FFI_OK); ts2_arg.d1 = 5.55; ts2_arg.d2 = 6.66; diff --git a/libffi/testsuite/libffi.call/struct2_win32.c b/libffi/testsuite/libffi.call/struct2_win32.c deleted file mode 100644 index 5d02285..0000000 --- a/libffi/testsuite/libffi.call/struct2_win32.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Area: ffi_call - Purpose: Check structures in fastcall/stdcall function - Limitations: none. - PR: none. - Originator: From the original ffitest.c */ - -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ -#include "ffitest.h" - -typedef struct -{ - double d1; - double d2; -} test_structure_2; - -static test_structure_2 __FASTCALL__ 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]; - - /* This is a hack to get a properly aligned result buffer */ - test_structure_2 *ts2_result = - (test_structure_2 *) malloc (sizeof(test_structure_2)); - - 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; - - args[0] = &ts2_type; - values[0] = &ts2_arg; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 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 index de883c2..7eba0ea 100644 --- a/libffi/testsuite/libffi.call/struct3.c +++ b/libffi/testsuite/libffi.call/struct3.c @@ -12,7 +12,7 @@ typedef struct int si; } test_structure_3; -static test_structure_3 struct3(test_structure_3 ts) +static test_structure_3 ABI_ATTR struct3(test_structure_3 ts) { ts.si = -(ts.si*2); @@ -43,7 +43,7 @@ int main (void) values[0] = &ts3_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts3_type, args) == FFI_OK); ts3_arg.si = -123; diff --git a/libffi/testsuite/libffi.call/struct4.c b/libffi/testsuite/libffi.call/struct4.c index 48e0349..66a9551 100644 --- a/libffi/testsuite/libffi.call/struct4.c +++ b/libffi/testsuite/libffi.call/struct4.c @@ -14,7 +14,7 @@ typedef struct unsigned ui3; } test_structure_4; -static test_structure_4 struct4(test_structure_4 ts) +static test_structure_4 ABI_ATTR struct4(test_structure_4 ts) { ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3; @@ -48,7 +48,7 @@ int main (void) values[0] = &ts4_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts4_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts4_type, args) == FFI_OK); ts4_arg.ui1 = 2; ts4_arg.ui2 = 3; diff --git a/libffi/testsuite/libffi.call/struct5.c b/libffi/testsuite/libffi.call/struct5.c index 28b1f0c..23e2a3f 100644 --- a/libffi/testsuite/libffi.call/struct5.c +++ b/libffi/testsuite/libffi.call/struct5.c @@ -12,7 +12,7 @@ typedef struct char c2; } test_structure_5; -static test_structure_5 struct5(test_structure_5 ts1, test_structure_5 ts2) +static test_structure_5 ABI_ATTR struct5(test_structure_5 ts1, test_structure_5 ts2) { ts1.c1 += ts2.c1; ts1.c2 -= ts2.c2; @@ -48,7 +48,7 @@ int main (void) values[1] = &ts5_arg2; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ts5_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, &ts5_type, args) == FFI_OK); ts5_arg1.c1 = 2; ts5_arg1.c2 = 6; diff --git a/libffi/testsuite/libffi.call/struct6.c b/libffi/testsuite/libffi.call/struct6.c index 0e26746..173c66e 100644 --- a/libffi/testsuite/libffi.call/struct6.c +++ b/libffi/testsuite/libffi.call/struct6.c @@ -12,7 +12,7 @@ typedef struct double d; } test_structure_6; -static test_structure_6 struct6 (test_structure_6 ts) +static test_structure_6 ABI_ATTR struct6 (test_structure_6 ts) { ts.f += 1; ts.d += 1; @@ -46,7 +46,7 @@ int main (void) values[0] = &ts6_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts6_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts6_type, args) == FFI_OK); ts6_arg.f = 5.55f; ts6_arg.d = 6.66; diff --git a/libffi/testsuite/libffi.call/struct7.c b/libffi/testsuite/libffi.call/struct7.c index 8f2bbfd..badc7e0 100644 --- a/libffi/testsuite/libffi.call/struct7.c +++ b/libffi/testsuite/libffi.call/struct7.c @@ -13,7 +13,7 @@ typedef struct double d; } test_structure_7; -static test_structure_7 struct7 (test_structure_7 ts) +static test_structure_7 ABI_ATTR struct7 (test_structure_7 ts) { ts.f1 += 1; ts.f2 += 1; @@ -49,7 +49,7 @@ int main (void) values[0] = &ts7_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts7_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts7_type, args) == FFI_OK); ts7_arg.f1 = 5.55f; ts7_arg.f2 = 55.5f; diff --git a/libffi/testsuite/libffi.call/struct8.c b/libffi/testsuite/libffi.call/struct8.c index 266e1f0..ef204ec 100644 --- a/libffi/testsuite/libffi.call/struct8.c +++ b/libffi/testsuite/libffi.call/struct8.c @@ -14,7 +14,7 @@ typedef struct float f4; } test_structure_8; -static test_structure_8 struct8 (test_structure_8 ts) +static test_structure_8 ABI_ATTR struct8 (test_structure_8 ts) { ts.f1 += 1; ts.f2 += 1; @@ -52,7 +52,7 @@ int main (void) values[0] = &ts8_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts8_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts8_type, args) == FFI_OK); ts8_arg.f1 = 5.55f; ts8_arg.f2 = 55.5f; diff --git a/libffi/testsuite/libffi.call/struct9.c b/libffi/testsuite/libffi.call/struct9.c index efeb716..4a13b81 100644 --- a/libffi/testsuite/libffi.call/struct9.c +++ b/libffi/testsuite/libffi.call/struct9.c @@ -13,7 +13,7 @@ typedef struct int i; } test_structure_9; -static test_structure_9 struct9 (test_structure_9 ts) +static test_structure_9 ABI_ATTR struct9 (test_structure_9 ts) { ts.f += 1; ts.i += 1; @@ -47,7 +47,7 @@ int main (void) values[0] = &ts9_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts9_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts9_type, args) == FFI_OK); ts9_arg.f = 5.55f; ts9_arg.i = 5; diff --git a/libffi/testsuite/libffi.complex/cls_align_complex.inc b/libffi/testsuite/libffi.complex/cls_align_complex.inc new file mode 100644 index 0000000..4a812ed --- /dev/null +++ b/libffi/testsuite/libffi.complex/cls_align_complex.inc @@ -0,0 +1,91 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include <complex.h> + +typedef struct cls_struct_align { + unsigned char a; + _Complex T_C_TYPE b; + unsigned char c; +} cls_struct_align; + +cls_struct_align cls_struct_align_fn( + struct cls_struct_align a1, struct cls_struct_align a2) +{ + struct cls_struct_align result; + + result.a = a1.a + a2.a; + result.b = a1.b + a2.b; + result.c = a1.c + a2.c; + + printf("%d %f,%fi %d %d %f,%fi %d: %d %f,%fi %d\n", + a1.a, T_CONV creal (a1.b), T_CONV cimag (a1.b), a1.c, + a2.a, T_CONV creal (a2.b), T_CONV cimag (a2.b), a2.c, + result.a, T_CONV creal (result.b), T_CONV cimag (result.b), result.c); + + return result; +} + +static void +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + + struct cls_struct_align a1, a2; + + a1 = *(struct cls_struct_align*)(args[0]); + a2 = *(struct cls_struct_align*)(args[1]); + + *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args_c[5]; + ffi_type* cls_struct_fields[4]; + ffi_type cls_struct_type; + ffi_type* c_arg_types[5]; + + struct cls_struct_align g_c = { 12, 4951 + 7 * I, 127 }; + struct cls_struct_align f_c = { 1, 9320 + 1 * I, 13 }; + struct cls_struct_align res_c; + + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + + cls_struct_fields[0] = &ffi_type_uchar; + cls_struct_fields[1] = &T_FFI_TYPE; + cls_struct_fields[2] = &ffi_type_uchar; + cls_struct_fields[3] = NULL; + + c_arg_types[0] = &cls_struct_type; + c_arg_types[1] = &cls_struct_type; + c_arg_types[2] = NULL; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type, + c_arg_types) == FFI_OK); + + args_c[0] = &g_c; + args_c[1] = &f_c; + args_c[2] = NULL; + + ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_c, args_c); + /* { dg-output "12 4951,7i 127 1 9320,1i 13: 13 14271,8i 140" } */ + printf("res: %d %f,%fi %d\n", + res_c.a, T_CONV creal (res_c.b), T_CONV cimag (res_c.b), res_c.c); + /* { dg-output "\nres: 13 14271,8i 140" } */ + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK); + + res_c = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_c, f_c); + /* { dg-output "\n12 4951,7i 127 1 9320,1i 13: 13 14271,8i 140" } */ + printf("res: %d %f,%fi %d\n", + res_c.a, T_CONV creal (res_c.b), T_CONV cimag (res_c.b), res_c.c); + /* { dg-output "\nres: 13 14271,8i 140" } */ + + exit(0); +} diff --git a/libffi/testsuite/libffi.complex/cls_align_complex_double.c b/libffi/testsuite/libffi.complex/cls_align_complex_double.c new file mode 100644 index 0000000..0dff23a --- /dev/null +++ b/libffi/testsuite/libffi.complex/cls_align_complex_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "cls_align_complex.inc" diff --git a/libffi/testsuite/libffi.complex/cls_align_complex_float.c b/libffi/testsuite/libffi.complex/cls_align_complex_float.c new file mode 100644 index 0000000..0affbd0 --- /dev/null +++ b/libffi/testsuite/libffi.complex/cls_align_complex_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "cls_align_complex.inc" diff --git a/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c b/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c new file mode 100644 index 0000000..7889ba8 --- /dev/null +++ b/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Check structure alignment of complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "cls_align_complex.inc" diff --git a/libffi/testsuite/libffi.complex/cls_complex.inc b/libffi/testsuite/libffi.complex/cls_complex.inc new file mode 100644 index 0000000..f937404 --- /dev/null +++ b/libffi/testsuite/libffi.complex/cls_complex.inc @@ -0,0 +1,42 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include <complex.h> + +static void cls_ret_complex_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) + { + _Complex T_C_TYPE *pa; + _Complex T_C_TYPE *pr; + pa = (_Complex T_C_TYPE *)args[0]; + pr = (_Complex T_C_TYPE *)resp; + *pr = *pa; + + printf("%.6f,%.6fi: %.6f,%.6fi\n", + T_CONV creal (*pa), T_CONV cimag (*pa), + T_CONV creal (*pr), T_CONV cimag (*pr)); + } +typedef _Complex T_C_TYPE (*cls_ret_complex)(_Complex T_C_TYPE); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[2]; + _Complex T_C_TYPE res; + + cl_arg_types[0] = &T_FFI_TYPE; + cl_arg_types[1] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &T_FFI_TYPE, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_complex_fn, NULL, code) == FFI_OK); + + res = (*((cls_ret_complex)code))(0.125 + 128.0 * I); + printf("res: %.6f,%.6fi\n", T_CONV creal (res), T_CONV cimag (res)); + CHECK (res == (0.125 + 128.0 * I)); + + exit(0); +} diff --git a/libffi/testsuite/libffi.complex/cls_complex_double.c b/libffi/testsuite/libffi.complex/cls_complex_double.c new file mode 100644 index 0000000..05e3534 --- /dev/null +++ b/libffi/testsuite/libffi.complex/cls_complex_double.c @@ -0,0 +1,10 @@ +/* Area: closure_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "cls_complex.inc" diff --git a/libffi/testsuite/libffi.complex/cls_complex_float.c b/libffi/testsuite/libffi.complex/cls_complex_float.c new file mode 100644 index 0000000..5df7849 --- /dev/null +++ b/libffi/testsuite/libffi.complex/cls_complex_float.c @@ -0,0 +1,10 @@ +/* Area: closure_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "cls_complex.inc" diff --git a/libffi/testsuite/libffi.complex/cls_complex_longdouble.c b/libffi/testsuite/libffi.complex/cls_complex_longdouble.c new file mode 100644 index 0000000..2b1c320 --- /dev/null +++ b/libffi/testsuite/libffi.complex/cls_complex_longdouble.c @@ -0,0 +1,10 @@ +/* Area: closure_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "cls_complex.inc" diff --git a/libffi/testsuite/libffi.complex/cls_complex_struct.inc b/libffi/testsuite/libffi.complex/cls_complex_struct.inc new file mode 100644 index 0000000..df8708d --- /dev/null +++ b/libffi/testsuite/libffi.complex/cls_complex_struct.inc @@ -0,0 +1,71 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include <complex.h> + +typedef struct Cs { + _Complex T_C_TYPE x; + _Complex T_C_TYPE y; +} Cs; + +Cs gc; + +void +closure_test_fn(Cs p) +{ + printf("%.1f,%.1fi %.1f,%.1fi\n", + T_CONV creal (p.x), T_CONV cimag (p.x), + T_CONV creal (p.y), T_CONV cimag (p.y)); + gc = p; +} + +void +closure_test_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, + void** args, void* userdata __UNUSED__) +{ + closure_test_fn(*(Cs*)args[0]); +} + +int main(int argc __UNUSED__, char** argv __UNUSED__) +{ + ffi_cif cif; + + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type *cl_arg_types[1]; + + ffi_type ts1_type; + ffi_type* ts1_type_elements[4]; + + Cs arg = { 1.0 + 11.0 * I, 2.0 + 22.0 * I}; + + ts1_type.size = 0; + ts1_type.alignment = 0; + ts1_type.type = FFI_TYPE_STRUCT; + ts1_type.elements = ts1_type_elements; + + ts1_type_elements[0] = &T_FFI_TYPE; + ts1_type_elements[1] = &T_FFI_TYPE; + ts1_type_elements[2] = NULL; + + cl_arg_types[0] = &ts1_type; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_void, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_gn, NULL, code) == FFI_OK); + + gc.x = 0.0 + 0.0 * I; + gc.y = 0.0 + 0.0 * I; + ((void*(*)(Cs))(code))(arg); + /* { dg-output "1.0,11.0i 2.0,22.0i\n" } */ + CHECK (gc.x == arg.x && gc.y == arg.y); + + gc.x = 0.0 + 0.0 * I; + gc.y = 0.0 + 0.0 * I; + closure_test_fn(arg); + /* { dg-output "1.0,11.0i 2.0,22.0i\n" } */ + CHECK (gc.x == arg.x && gc.y == arg.y); + + return 0; +} diff --git a/libffi/testsuite/libffi.complex/cls_complex_struct_double.c b/libffi/testsuite/libffi.complex/cls_complex_struct_double.c new file mode 100644 index 0000000..ec71346 --- /dev/null +++ b/libffi/testsuite/libffi.complex/cls_complex_struct_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Check complex arguments in structs. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "cls_complex_struct.inc" diff --git a/libffi/testsuite/libffi.complex/cls_complex_struct_float.c b/libffi/testsuite/libffi.complex/cls_complex_struct_float.c new file mode 100644 index 0000000..96fdf750 --- /dev/null +++ b/libffi/testsuite/libffi.complex/cls_complex_struct_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Check complex arguments in structs. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "cls_complex_struct.inc" diff --git a/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c b/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c new file mode 100644 index 0000000..005b467 --- /dev/null +++ b/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Check complex arguments in structs. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "cls_complex_struct.inc" diff --git a/libffi/testsuite/libffi.complex/cls_complex_va.inc b/libffi/testsuite/libffi.complex/cls_complex_va.inc new file mode 100644 index 0000000..8a3e15f --- /dev/null +++ b/libffi/testsuite/libffi.complex/cls_complex_va.inc @@ -0,0 +1,80 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <complex.h> + +static _Complex T_C_TYPE gComplexValue1 = 1 + 2 * I; +static _Complex T_C_TYPE gComplexValue2 = 3 + 4 * I; + +static int cls_variadic(const char *format, ...) +{ + va_list ap; + _Complex T_C_TYPE p1, p2; + + va_start (ap, format); + p1 = va_arg (ap, _Complex T_C_TYPE); + p2 = va_arg (ap, _Complex T_C_TYPE); + va_end (ap); + + return printf(format, T_CONV creal (p1), T_CONV cimag (p1), + T_CONV creal (p2), T_CONV cimag (p2)); +} + +static void +cls_complex_va_fn(ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) +{ + char* format = *(char**)args[0]; + gComplexValue1 = *(_Complex T_C_TYPE*)args[1]; + gComplexValue2 = *(_Complex T_C_TYPE*)args[2]; + + *(ffi_arg*)resp = + printf(format, + T_CONV creal (gComplexValue1), T_CONV cimag (gComplexValue1), + T_CONV creal (gComplexValue2), T_CONV cimag (gComplexValue2)); +} + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + void* args[4]; + ffi_type* arg_types[4]; + char *format = "%.1f,%.1fi %.1f,%.1fi\n"; + + _Complex T_C_TYPE complexArg1 = 1.0 + 22.0 *I; + _Complex T_C_TYPE complexArg2 = 333.0 + 4444.0 *I; + ffi_arg res = 0; + + arg_types[0] = &ffi_type_pointer; + arg_types[1] = &T_FFI_TYPE; + arg_types[2] = &T_FFI_TYPE; + arg_types[3] = NULL; + + /* This printf call is variadic */ + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 3, &ffi_type_sint, + arg_types) == FFI_OK); + + args[0] = &format; + args[1] = &complexArg1; + args[2] = &complexArg2; + args[3] = NULL; + + ffi_call(&cif, FFI_FN(cls_variadic), &res, args); + printf("res: %d\n", (int) res); + CHECK (res == 24); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_complex_va_fn, NULL, code) + == FFI_OK); + + res = ((int(*)(char *, ...))(code))(format, complexArg1, complexArg2); + CHECK (gComplexValue1 == complexArg1); + CHECK (gComplexValue2 == complexArg2); + printf("res: %d\n", (int) res); + CHECK (res == 24); + + exit(0); +} diff --git a/libffi/testsuite/libffi.complex/cls_complex_va_double.c b/libffi/testsuite/libffi.complex/cls_complex_va_double.c new file mode 100644 index 0000000..879ccf3 --- /dev/null +++ b/libffi/testsuite/libffi.complex/cls_complex_va_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Test complex' passed in variable argument lists. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "cls_complex_va.inc" diff --git a/libffi/testsuite/libffi.complex/cls_complex_va_float.c b/libffi/testsuite/libffi.complex/cls_complex_va_float.c new file mode 100644 index 0000000..2b17826 --- /dev/null +++ b/libffi/testsuite/libffi.complex/cls_complex_va_float.c @@ -0,0 +1,16 @@ +/* Area: ffi_call, closure_call + Purpose: Test complex' passed in variable argument lists. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +/* Alpha splits _Complex into two arguments. It's illegal to pass + float through varargs, so _Complex float goes badly. In sort of + gets passed as _Complex double, but the compiler doesn't agree + with itself on this issue. */ +/* { dg-do run { xfail alpha*-*-* } } */ + +#include "complex_defs_float.inc" +#include "cls_complex_va.inc" diff --git a/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c b/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c new file mode 100644 index 0000000..6eca965 --- /dev/null +++ b/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call, closure_call + Purpose: Test complex' passed in variable argument lists. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "cls_complex_va.inc" diff --git a/libffi/testsuite/libffi.complex/complex.exp b/libffi/testsuite/libffi.complex/complex.exp new file mode 100644 index 0000000..4631db2 --- /dev/null +++ b/libffi/testsuite/libffi.complex/complex.exp @@ -0,0 +1,36 @@ +# Copyright (C) 2003, 2006, 2009, 2010, 2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +dg-init +libffi-init + +global srcdir subdir + +set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]] + +if { [libffi_feature_test "#ifdef FFI_TARGET_HAS_COMPLEX_TYPE"] } { + run-many-tests $tlist "" +} else { + foreach test $tlist { + unsupported "$test" + } +} + +dg-finish + +# Local Variables: +# tcl-indent-level:4 +# End: diff --git a/libffi/testsuite/libffi.complex/complex.inc b/libffi/testsuite/libffi.complex/complex.inc new file mode 100644 index 0000000..515ae3e --- /dev/null +++ b/libffi/testsuite/libffi.complex/complex.inc @@ -0,0 +1,51 @@ +/* -*-c-*-*/ +#include "ffitest.h" +#include <complex.h> + +static _Complex T_C_TYPE f_complex(_Complex T_C_TYPE c, int x, int *py) +{ + c = -(2 * creal (c)) + (cimag (c) + 1)* I; + *py += x; + + return c; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + + _Complex T_C_TYPE tc_arg; + _Complex T_C_TYPE tc_result; + int tc_int_arg_x; + int tc_y; + int *tc_ptr_arg_y = &tc_y; + + args[0] = &T_FFI_TYPE; + args[1] = &ffi_type_sint; + args[2] = &ffi_type_pointer; + values[0] = &tc_arg; + values[1] = &tc_int_arg_x; + values[2] = &tc_ptr_arg_y; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, + &T_FFI_TYPE, args) == FFI_OK); + + tc_arg = 1 + 7 * I; + tc_int_arg_x = 1234; + tc_y = 9876; + ffi_call(&cif, FFI_FN(f_complex), &tc_result, values); + + printf ("%f,%fi %f,%fi, x %d 1234, y %d 11110\n", + T_CONV creal (tc_result), T_CONV cimag (tc_result), + T_CONV creal (2.0), T_CONV creal (8.0), tc_int_arg_x, tc_y); + + CHECK (creal (tc_result) == -2); + CHECK (cimag (tc_result) == 8); + CHECK (tc_int_arg_x == 1234); + CHECK (*tc_ptr_arg_y == 11110); + + exit(0); +} diff --git a/libffi/testsuite/libffi.complex/complex_defs_double.inc b/libffi/testsuite/libffi.complex/complex_defs_double.inc new file mode 100644 index 0000000..3583e16 --- /dev/null +++ b/libffi/testsuite/libffi.complex/complex_defs_double.inc @@ -0,0 +1,7 @@ +/* -*-c-*- */ +/* Complex base type. */ +#define T_FFI_TYPE ffi_type_complex_double +/* C type corresponding to the base type. */ +#define T_C_TYPE double +/* C cast for a value of type T_C_TYPE that is passed to printf. */ +#define T_CONV diff --git a/libffi/testsuite/libffi.complex/complex_defs_float.inc b/libffi/testsuite/libffi.complex/complex_defs_float.inc new file mode 100644 index 0000000..bbd9375 --- /dev/null +++ b/libffi/testsuite/libffi.complex/complex_defs_float.inc @@ -0,0 +1,7 @@ +/* -*-c-*- */ +/* Complex base type. */ +#define T_FFI_TYPE ffi_type_complex_float +/* C type corresponding to the base type. */ +#define T_C_TYPE float +/* C cast for a value of type T_C_TYPE that is passed to printf. */ +#define T_CONV (double) diff --git a/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc b/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc new file mode 100644 index 0000000..14b9f24 --- /dev/null +++ b/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc @@ -0,0 +1,7 @@ +/* -*-c-*- */ +/* Complex base type. */ +#define T_FFI_TYPE ffi_type_complex_longdouble +/* C type corresponding to the base type. */ +#define T_C_TYPE long double +/* C cast for a value of type T_C_TYPE that is passed to printf. */ +#define T_CONV diff --git a/libffi/testsuite/libffi.complex/complex_double.c b/libffi/testsuite/libffi.complex/complex_double.c new file mode 100644 index 0000000..8a3297b --- /dev/null +++ b/libffi/testsuite/libffi.complex/complex_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check complex types. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "complex.inc" diff --git a/libffi/testsuite/libffi.complex/complex_float.c b/libffi/testsuite/libffi.complex/complex_float.c new file mode 100644 index 0000000..5044ebb --- /dev/null +++ b/libffi/testsuite/libffi.complex/complex_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check complex types. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "complex.inc" diff --git a/libffi/testsuite/libffi.complex/complex_int.c b/libffi/testsuite/libffi.complex/complex_int.c new file mode 100644 index 0000000..bac3190 --- /dev/null +++ b/libffi/testsuite/libffi.complex/complex_int.c @@ -0,0 +1,86 @@ +/* Area: ffi_call + Purpose: Check non-standard complex types. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "ffitest.h" +#include "ffi.h" +#include <complex.h> + +_Complex int f_complex(_Complex int c, int x, int *py) +{ + __real__ c = -2 * __real__ c; + __imag__ c = __imag__ c + 1; + *py += x; + return c; +} + +/* + * This macro can be used to define new complex type descriptors + * in a platform independent way. + * + * name: Name of the new descriptor is ffi_type_complex_<name>. + * type: The C base type of the complex type. + */ +#define FFI_COMPLEX_TYPEDEF(name, type, ffitype) \ + static ffi_type *ffi_elements_complex_##name [2] = { \ + (ffi_type *)(&ffitype), NULL \ + }; \ + struct struct_align_complex_##name { \ + char c; \ + _Complex type x; \ + }; \ + ffi_type ffi_type_complex_##name = { \ + sizeof(_Complex type), \ + offsetof(struct struct_align_complex_##name, x), \ + FFI_TYPE_COMPLEX, \ + (ffi_type **)ffi_elements_complex_##name \ + } + +/* Define new complex type descriptors using the macro: */ +/* ffi_type_complex_sint */ +FFI_COMPLEX_TYPEDEF(sint, int, ffi_type_sint); +/* ffi_type_complex_uchar */ +FFI_COMPLEX_TYPEDEF(uchar, unsigned char, ffi_type_uint8); + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + + _Complex int tc_arg; + _Complex int tc_result; + int tc_int_arg_x; + int tc_y; + int *tc_ptr_arg_y = &tc_y; + + args[0] = &ffi_type_complex_sint; + args[1] = &ffi_type_sint; + args[2] = &ffi_type_pointer; + values[0] = &tc_arg; + values[1] = &tc_int_arg_x; + values[2] = &tc_ptr_arg_y; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &ffi_type_complex_sint, args) + == FFI_OK); + + tc_arg = 1 + 7 * I; + tc_int_arg_x = 1234; + tc_y = 9876; + ffi_call(&cif, FFI_FN(f_complex), &tc_result, values); + + printf ("%d,%di %d,%di, x %d 1234, y %d 11110\n", + (int)tc_result, (int)(tc_result * -I), 2, 8, tc_int_arg_x, tc_y); + /* dg-output "-2,8i 2,8i, x 1234 1234, y 11110 11110" */ + CHECK (creal (tc_result) == -2); + CHECK (cimag (tc_result) == 8); + CHECK (tc_int_arg_x == 1234); + CHECK (*tc_ptr_arg_y == 11110); + + exit(0); +} diff --git a/libffi/testsuite/libffi.complex/complex_longdouble.c b/libffi/testsuite/libffi.complex/complex_longdouble.c new file mode 100644 index 0000000..7e78366 --- /dev/null +++ b/libffi/testsuite/libffi.complex/complex_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check complex types. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "complex.inc" diff --git a/libffi/testsuite/libffi.complex/ffitest.h b/libffi/testsuite/libffi.complex/ffitest.h new file mode 100644 index 0000000..d27d362 --- /dev/null +++ b/libffi/testsuite/libffi.complex/ffitest.h @@ -0,0 +1 @@ +#include "../libffi.call/ffitest.h" diff --git a/libffi/testsuite/libffi.complex/many_complex.inc b/libffi/testsuite/libffi.complex/many_complex.inc new file mode 100644 index 0000000..e37a774 --- /dev/null +++ b/libffi/testsuite/libffi.complex/many_complex.inc @@ -0,0 +1,78 @@ +/* -*-c-*- */ +#include "ffitest.h" + +#include <stdlib.h> +#include <complex.h> + +static _Complex T_C_TYPE many(_Complex T_C_TYPE c1, + _Complex T_C_TYPE c2, + _Complex T_C_TYPE c3, + _Complex T_C_TYPE c4, + _Complex T_C_TYPE c5, + _Complex T_C_TYPE c6, + _Complex T_C_TYPE c7, + _Complex T_C_TYPE c8, + _Complex T_C_TYPE c9, + _Complex T_C_TYPE c10, + _Complex T_C_TYPE c11, + _Complex T_C_TYPE c12, + _Complex T_C_TYPE c13) +{ + printf("0 :%f,%fi\n" + "1 :%f,%fi\n" + "2 :%f,%fi\n" + "3 :%f,%fi\n" + "4 :%f,%fi\n" + "5 :%f,%fi\n" + "6 :%f,%fi\n" + "7 :%f,%fi\n" + "8 :%f,%fi\n" + "9 :%f,%fi\n" + "10:%f,%fi\n" + "11:%f,%fi\n" + "12:%f,%fi\n", + T_CONV creal (c1), T_CONV cimag (c1), + T_CONV creal (c2), T_CONV cimag (c2), + T_CONV creal (c3), T_CONV cimag (c3), + T_CONV creal (c4), T_CONV cimag (c4), + T_CONV creal (c5), T_CONV cimag (c5), + T_CONV creal (c6), T_CONV cimag (c6), + T_CONV creal (c7), T_CONV cimag (c7), + T_CONV creal (c8), T_CONV cimag (c8), + T_CONV creal (c9), T_CONV cimag (c9), + T_CONV creal (c10), T_CONV cimag (c10), + T_CONV creal (c11), T_CONV cimag (c11), + T_CONV creal (c12), T_CONV cimag (c12), + T_CONV creal (c13), T_CONV cimag (c13)); + + return (c1+c2-c3-c4+c5+c6+c7-c8-c9-c10-c11+c12+c13); +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[13]; + void *values[13]; + _Complex T_C_TYPE ca[13]; + _Complex T_C_TYPE c, cc; + int i; + + for (i = 0; i < 13; i++) + { + args[i] = &T_FFI_TYPE; + values[i] = &ca[i]; + ca[i] = i + (-20 - i) * I; + } + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, &T_FFI_TYPE, args) == FFI_OK); + + ffi_call(&cif, FFI_FN(many), &c, values); + + cc = many(ca[0], ca[1], ca[2], ca[3], ca[4], ca[5], ca[6], ca[7], ca[8], + ca[9], ca[10], ca[11], ca[12]); + CHECK(creal (cc) == creal (c)); + CHECK(cimag (cc) == cimag (c)); + + exit(0); +} diff --git a/libffi/testsuite/libffi.complex/many_complex_double.c b/libffi/testsuite/libffi.complex/many_complex_double.c new file mode 100644 index 0000000..3fd53c3 --- /dev/null +++ b/libffi/testsuite/libffi.complex/many_complex_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex, with many arguments + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "many_complex.inc" diff --git a/libffi/testsuite/libffi.complex/many_complex_float.c b/libffi/testsuite/libffi.complex/many_complex_float.c new file mode 100644 index 0000000..c43d21c --- /dev/null +++ b/libffi/testsuite/libffi.complex/many_complex_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex, with many arguments + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "many_complex.inc" diff --git a/libffi/testsuite/libffi.complex/many_complex_longdouble.c b/libffi/testsuite/libffi.complex/many_complex_longdouble.c new file mode 100644 index 0000000..dbab723 --- /dev/null +++ b/libffi/testsuite/libffi.complex/many_complex_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex, with many arguments + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "many_complex.inc" diff --git a/libffi/testsuite/libffi.complex/return_complex.inc b/libffi/testsuite/libffi.complex/return_complex.inc new file mode 100644 index 0000000..8bf0c1f --- /dev/null +++ b/libffi/testsuite/libffi.complex/return_complex.inc @@ -0,0 +1,37 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include <complex.h> + +static _Complex T_C_TYPE return_c(_Complex T_C_TYPE c) +{ + printf ("%f,%fi\n", T_CONV creal (c), T_CONV cimag (c)); + return 2 * c; +} +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + _Complex T_C_TYPE c, rc, rc2; + T_C_TYPE cr, ci; + + args[0] = &T_FFI_TYPE; + values[0] = &c; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &T_FFI_TYPE, args) == FFI_OK); + + for (cr = -127.0; cr < 127; cr++) + { + ci = 1000.0 - cr; + c = cr + ci * I; + ffi_call(&cif, FFI_FN(return_c), &rc, values); + rc2 = return_c(c); + printf ("%f,%fi vs %f,%fi\n", + T_CONV creal (rc), T_CONV cimag (rc), + T_CONV creal (rc2), T_CONV cimag (rc2)); + CHECK(rc == 2 * c); + } + exit(0); +} diff --git a/libffi/testsuite/libffi.complex/return_complex1.inc b/libffi/testsuite/libffi.complex/return_complex1.inc new file mode 100644 index 0000000..7cecc0f --- /dev/null +++ b/libffi/testsuite/libffi.complex/return_complex1.inc @@ -0,0 +1,41 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include <complex.h> + +static _Complex T_C_TYPE return_c(_Complex T_C_TYPE c1, float fl2, unsigned int in3, _Complex T_C_TYPE c4) +{ + return c1 + fl2 + in3 + c4; +} +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + _Complex T_C_TYPE c1, c4, rc, rc2; + float fl2; + unsigned int in3; + args[0] = &T_FFI_TYPE; + args[1] = &ffi_type_float; + args[2] = &ffi_type_uint; + args[3] = &T_FFI_TYPE; + values[0] = &c1; + values[1] = &fl2; + values[2] = &in3; + values[3] = &c4; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, + &T_FFI_TYPE, args) == FFI_OK); + c1 = 127.0 + 255.0 * I; + fl2 = 128.0; + in3 = 255; + c4 = 512.7 + 1024.1 * I; + + ffi_call(&cif, FFI_FN(return_c), &rc, values); + rc2 = return_c(c1, fl2, in3, c4); + printf ("%f,%fi vs %f,%fi\n", + T_CONV creal (rc), T_CONV cimag (rc), + T_CONV creal (rc2), T_CONV cimag (rc2)); + CHECK(rc == rc2); + exit(0); +} diff --git a/libffi/testsuite/libffi.complex/return_complex1_double.c b/libffi/testsuite/libffi.complex/return_complex1_double.c new file mode 100644 index 0000000..727410d --- /dev/null +++ b/libffi/testsuite/libffi.complex/return_complex1_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "return_complex1.inc" diff --git a/libffi/testsuite/libffi.complex/return_complex1_float.c b/libffi/testsuite/libffi.complex/return_complex1_float.c new file mode 100644 index 0000000..a2aeada --- /dev/null +++ b/libffi/testsuite/libffi.complex/return_complex1_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "return_complex1.inc" diff --git a/libffi/testsuite/libffi.complex/return_complex1_longdouble.c b/libffi/testsuite/libffi.complex/return_complex1_longdouble.c new file mode 100644 index 0000000..103504b --- /dev/null +++ b/libffi/testsuite/libffi.complex/return_complex1_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "return_complex1.inc" diff --git a/libffi/testsuite/libffi.complex/return_complex2.inc b/libffi/testsuite/libffi.complex/return_complex2.inc new file mode 100644 index 0000000..265170b --- /dev/null +++ b/libffi/testsuite/libffi.complex/return_complex2.inc @@ -0,0 +1,44 @@ +/* -*-c-*- */ +#include "ffitest.h" +#include <complex.h> + +_Complex T_C_TYPE +return_c(_Complex T_C_TYPE c1, _Complex T_C_TYPE c2, + unsigned int in3, _Complex T_C_TYPE c4) +{ + volatile _Complex T_C_TYPE r = c1 + c2 + in3 + c4; + return r; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + _Complex T_C_TYPE c1, c2, c4, rc, rc2; + unsigned int in3; + args[0] = &T_FFI_TYPE; + args[1] = &T_FFI_TYPE; + args[2] = &ffi_type_uint; + args[3] = &T_FFI_TYPE; + values[0] = &c1; + values[1] = &c2; + values[2] = &in3; + values[3] = &c4; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, + &T_FFI_TYPE, args) == FFI_OK); + c1 = 127.0 + 255.0 * I; + c2 = 128.0 + 256.0; + in3 = 255; + c4 = 512.7 + 1024.1 * I; + + ffi_call(&cif, FFI_FN(return_c), &rc, values); + rc2 = return_c(c1, c2, in3, c4); + printf ("%f,%fi vs %f,%fi\n", + T_CONV creal (rc), T_CONV cimag (rc), + T_CONV creal (rc2), T_CONV cimag (rc2)); + CHECK(rc == rc2); + exit(0); +} diff --git a/libffi/testsuite/libffi.complex/return_complex2_double.c b/libffi/testsuite/libffi.complex/return_complex2_double.c new file mode 100644 index 0000000..ab9efac --- /dev/null +++ b/libffi/testsuite/libffi.complex/return_complex2_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "return_complex2.inc" diff --git a/libffi/testsuite/libffi.complex/return_complex2_float.c b/libffi/testsuite/libffi.complex/return_complex2_float.c new file mode 100644 index 0000000..d7f22c2 --- /dev/null +++ b/libffi/testsuite/libffi.complex/return_complex2_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "return_complex2.inc" diff --git a/libffi/testsuite/libffi.complex/return_complex2_longdouble.c b/libffi/testsuite/libffi.complex/return_complex2_longdouble.c new file mode 100644 index 0000000..3edea62 --- /dev/null +++ b/libffi/testsuite/libffi.complex/return_complex2_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "return_complex2.inc" diff --git a/libffi/testsuite/libffi.complex/return_complex_double.c b/libffi/testsuite/libffi.complex/return_complex_double.c new file mode 100644 index 0000000..e2497cc --- /dev/null +++ b/libffi/testsuite/libffi.complex/return_complex_double.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_double.inc" +#include "return_complex.inc" diff --git a/libffi/testsuite/libffi.complex/return_complex_float.c b/libffi/testsuite/libffi.complex/return_complex_float.c new file mode 100644 index 0000000..a35528f --- /dev/null +++ b/libffi/testsuite/libffi.complex/return_complex_float.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_float.inc" +#include "return_complex.inc" diff --git a/libffi/testsuite/libffi.complex/return_complex_longdouble.c b/libffi/testsuite/libffi.complex/return_complex_longdouble.c new file mode 100644 index 0000000..142d7be --- /dev/null +++ b/libffi/testsuite/libffi.complex/return_complex_longdouble.c @@ -0,0 +1,10 @@ +/* Area: ffi_call + Purpose: Check return value complex. + Limitations: none. + PR: none. + Originator: <vogt@linux.vnet.ibm.com>. */ + +/* { dg-do run } */ + +#include "complex_defs_longdouble.inc" +#include "return_complex.inc" diff --git a/libffi/testsuite/libffi.go/aa-direct.c b/libffi/testsuite/libffi.go/aa-direct.c new file mode 100644 index 0000000..b00c404 --- /dev/null +++ b/libffi/testsuite/libffi.go/aa-direct.c @@ -0,0 +1,34 @@ +/* { dg-do run } */ + +#include "static-chain.h" + +#if defined(__GNUC__) && !defined(__clang__) && defined(STATIC_CHAIN_REG) + +#include "ffitest.h" + +/* Blatent assumption here that the prologue doesn't clobber the + static chain for trivial functions. If this is not true, don't + define STATIC_CHAIN_REG, and we'll test what we can via other tests. */ +void *doit(void) +{ + register void *chain __asm__(STATIC_CHAIN_REG); + return chain; +} + +int main() +{ + ffi_cif cif; + void *result; + + CHECK(ffi_prep_cif(&cif, ABI_NUM, 0, &ffi_type_pointer, NULL) == FFI_OK); + + ffi_call_go(&cif, FFI_FN(doit), &result, NULL, &result); + + CHECK(result == &result); + + return 0; +} + +#else /* UNSUPPORTED */ +int main() { return 0; } +#endif diff --git a/libffi/testsuite/libffi.go/closure1.c b/libffi/testsuite/libffi.go/closure1.c new file mode 100644 index 0000000..7b34afc --- /dev/null +++ b/libffi/testsuite/libffi.go/closure1.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ + +#include "ffitest.h" + +void doit(ffi_cif *cif, void *rvalue, void **avalue, void *closure) +{ + (void)cif; + (void)avalue; + *(void **)rvalue = closure; +} + +typedef void * (*FN)(void); + +int main() +{ + ffi_cif cif; + ffi_go_closure cl; + void *result; + + CHECK(ffi_prep_cif(&cif, ABI_NUM, 0, &ffi_type_pointer, NULL) == FFI_OK); + CHECK(ffi_prep_go_closure(&cl, &cif, doit) == FFI_OK); + + ffi_call_go(&cif, FFI_FN(*(FN *)&cl), &result, NULL, &cl); + + CHECK(result == &cl); + + exit(0); +} diff --git a/libffi/testsuite/libffi.go/ffitest.h b/libffi/testsuite/libffi.go/ffitest.h new file mode 100644 index 0000000..d27d362 --- /dev/null +++ b/libffi/testsuite/libffi.go/ffitest.h @@ -0,0 +1 @@ +#include "../libffi.call/ffitest.h" diff --git a/libffi/testsuite/libffi.go/go.exp b/libffi/testsuite/libffi.go/go.exp new file mode 100644 index 0000000..100c5e7 --- /dev/null +++ b/libffi/testsuite/libffi.go/go.exp @@ -0,0 +1,36 @@ +# Copyright (C) 2003, 2006, 2009, 2010, 2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +dg-init +libffi-init + +global srcdir subdir + +set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]] + +if { [libffi_feature_test "#ifdef FFI_GO_CLOSURES"] } { + run-many-tests $tlist "" +} else { + foreach test $tlist { + unsupported "$test" + } +} + +dg-finish + +# Local Variables: +# tcl-indent-level:4 +# End: diff --git a/libffi/testsuite/libffi.go/static-chain.h b/libffi/testsuite/libffi.go/static-chain.h new file mode 100644 index 0000000..3675b40 --- /dev/null +++ b/libffi/testsuite/libffi.go/static-chain.h @@ -0,0 +1,19 @@ +#ifdef __aarch64__ +# define STATIC_CHAIN_REG "x18" +#elif defined(__alpha__) +# define STATIC_CHAIN_REG "$1" +#elif defined(__arm__) +# define STATIC_CHAIN_REG "ip" +#elif defined(__sparc__) +# if defined(__arch64__) || defined(__sparcv9) +# define STATIC_CHAIN_REG "g5" +# else +# define STATIC_CHAIN_REG "g2" +# endif +#elif defined(__x86_64__) +# define STATIC_CHAIN_REG "r10" +#elif defined(__i386__) +# ifndef ABI_NUM +# define STATIC_CHAIN_REG "ecx" /* FFI_DEFAULT_ABI only */ +# endif +#endif |