From 77175b3f7234e4875a4ef554ed1fe9fdc4133794 Mon Sep 17 00:00:00 2001 From: green Date: Tue, 29 Jan 2008 15:15:20 +0000 Subject: [PATCH] Latest gcc svn sources --- libffi/ChangeLog | 1019 ++++++++++++++++++++ libffi/Makefile.am | 31 +- libffi/Makefile.in | 88 +- libffi/README | 11 +- libffi/configure | 409 +++++--- libffi/configure.ac | 183 ++-- libffi/fficonfig.h.in | 13 +- libffi/include/Makefile.am | 10 +- libffi/include/Makefile.in | 123 ++- libffi/include/ffi.h.in | 155 ++- libffi/include/ffi_common.h | 17 +- libffi/src/alpha/ffi.c | 65 +- libffi/src/alpha/ffitarget.h | 5 +- libffi/src/alpha/osf.S | 10 +- libffi/src/arm/ffi.c | 177 +++- libffi/src/arm/ffitarget.h | 3 +- libffi/src/arm/sysv.S | 86 ++ libffi/src/cris/ffi.c | 12 +- libffi/src/debug.c | 5 +- libffi/src/frv/eabi.S | 2 - libffi/src/frv/ffi.c | 17 +- libffi/src/ia64/ffi.c | 99 +- libffi/src/java_raw_api.c | 96 +- libffi/src/m32r/ffi.c | 24 +- libffi/src/m68k/ffi.c | 214 ++-- libffi/src/m68k/ffitarget.h | 3 +- libffi/src/m68k/sysv.S | 138 ++- libffi/src/mips/ffi.c | 574 ++++++++--- libffi/src/mips/ffitarget.h | 59 +- libffi/src/mips/n32.S | 261 ++++- libffi/src/mips/o32.S | 160 +-- libffi/src/pa/ffi.c | 396 +++++--- libffi/src/pa/ffitarget.h | 33 +- libffi/src/pa/linux.S | 247 +++-- libffi/src/powerpc/ffi.c | 883 +++++++++++------ libffi/src/powerpc/ffi_darwin.c | 117 ++- libffi/src/powerpc/ffitarget.h | 21 +- libffi/src/powerpc/linux64.S | 13 +- libffi/src/powerpc/ppc_closure.S | 257 +++-- libffi/src/powerpc/sysv.S | 22 +- libffi/src/prep_cif.c | 45 +- libffi/src/raw_api.c | 47 +- libffi/src/s390/ffi.c | 44 +- libffi/src/sh/ffi.c | 48 +- libffi/src/sh/sysv.S | 10 +- libffi/src/sparc/ffi.c | 13 +- libffi/src/types.c | 20 +- libffi/src/x86/darwin.S | 149 +-- libffi/src/x86/ffi.c | 137 ++- libffi/src/x86/ffi64.c | 13 +- libffi/src/x86/ffitarget.h | 6 +- libffi/src/x86/sysv.S | 90 +- libffi/testsuite/lib/libffi-dg.exp | 2 +- libffi/testsuite/libffi.call/call.exp | 13 +- libffi/testsuite/libffi.call/closure_fn0.c | 28 +- libffi/testsuite/libffi.call/closure_fn1.c | 18 +- libffi/testsuite/libffi.call/closure_fn2.c | 16 +- libffi/testsuite/libffi.call/closure_fn3.c | 10 +- libffi/testsuite/libffi.call/closure_fn4.c | 7 +- libffi/testsuite/libffi.call/closure_fn5.c | 10 +- libffi/testsuite/libffi.call/closure_fn6.c | 10 +- libffi/testsuite/libffi.call/cls_12byte.c | 11 +- libffi/testsuite/libffi.call/cls_16byte.c | 9 +- libffi/testsuite/libffi.call/cls_18byte.c | 5 +- libffi/testsuite/libffi.call/cls_19byte.c | 5 +- libffi/testsuite/libffi.call/cls_1_1byte.c | 7 +- libffi/testsuite/libffi.call/cls_20byte.c | 7 +- libffi/testsuite/libffi.call/cls_20byte1.c | 9 +- libffi/testsuite/libffi.call/cls_24byte.c | 7 +- libffi/testsuite/libffi.call/cls_2byte.c | 5 +- libffi/testsuite/libffi.call/cls_3_1byte.c | 5 +- libffi/testsuite/libffi.call/cls_3byte1.c | 5 +- libffi/testsuite/libffi.call/cls_3byte2.c | 5 +- libffi/testsuite/libffi.call/cls_4_1byte.c | 5 +- libffi/testsuite/libffi.call/cls_4byte.c | 5 +- libffi/testsuite/libffi.call/cls_5_1_byte.c | 5 +- libffi/testsuite/libffi.call/cls_5byte.c | 5 +- libffi/testsuite/libffi.call/cls_64byte.c | 5 +- libffi/testsuite/libffi.call/cls_6_1_byte.c | 5 +- libffi/testsuite/libffi.call/cls_6byte.c | 6 +- libffi/testsuite/libffi.call/cls_7_1_byte.c | 5 +- libffi/testsuite/libffi.call/cls_7byte.c | 5 +- libffi/testsuite/libffi.call/cls_8byte.c | 7 +- libffi/testsuite/libffi.call/cls_9byte1.c | 8 +- libffi/testsuite/libffi.call/cls_9byte2.c | 8 +- libffi/testsuite/libffi.call/cls_align_double.c | 7 +- libffi/testsuite/libffi.call/cls_align_float.c | 5 +- .../testsuite/libffi.call/cls_align_longdouble.c | 5 +- libffi/testsuite/libffi.call/cls_align_pointer.c | 17 +- libffi/testsuite/libffi.call/cls_align_sint16.c | 7 +- libffi/testsuite/libffi.call/cls_align_sint32.c | 7 +- libffi/testsuite/libffi.call/cls_align_sint64.c | 5 +- libffi/testsuite/libffi.call/cls_align_uint16.c | 7 +- libffi/testsuite/libffi.call/cls_align_uint32.c | 7 +- libffi/testsuite/libffi.call/cls_align_uint64.c | 6 +- libffi/testsuite/libffi.call/cls_double.c | 6 +- libffi/testsuite/libffi.call/cls_float.c | 6 +- libffi/testsuite/libffi.call/cls_multi_schar.c | 7 +- libffi/testsuite/libffi.call/cls_multi_sshort.c | 7 +- .../testsuite/libffi.call/cls_multi_sshortchar.c | 7 +- libffi/testsuite/libffi.call/cls_multi_uchar.c | 11 +- libffi/testsuite/libffi.call/cls_multi_ushort.c | 7 +- .../testsuite/libffi.call/cls_multi_ushortchar.c | 7 +- libffi/testsuite/libffi.call/cls_schar.c | 10 +- libffi/testsuite/libffi.call/cls_sint.c | 12 +- libffi/testsuite/libffi.call/cls_sshort.c | 12 +- libffi/testsuite/libffi.call/cls_uchar.c | 8 +- libffi/testsuite/libffi.call/cls_uint.c | 20 +- libffi/testsuite/libffi.call/cls_ulonglong.c | 16 +- libffi/testsuite/libffi.call/cls_ushort.c | 16 +- libffi/testsuite/libffi.call/ffitest.h | 7 + libffi/testsuite/libffi.call/float.c | 14 +- libffi/testsuite/libffi.call/float1.c | 14 +- libffi/testsuite/libffi.call/float2.c | 2 - libffi/testsuite/libffi.call/float4.c | 2 + libffi/testsuite/libffi.call/negint.c | 1 - libffi/testsuite/libffi.call/nested_struct.c | 9 +- libffi/testsuite/libffi.call/nested_struct1.c | 9 +- libffi/testsuite/libffi.call/nested_struct10.c | 4 +- libffi/testsuite/libffi.call/nested_struct2.c | 21 +- libffi/testsuite/libffi.call/nested_struct3.c | 5 +- libffi/testsuite/libffi.call/nested_struct4.c | 2 +- libffi/testsuite/libffi.call/nested_struct5.c | 2 +- libffi/testsuite/libffi.call/nested_struct6.c | 4 +- libffi/testsuite/libffi.call/nested_struct7.c | 2 +- libffi/testsuite/libffi.call/nested_struct8.c | 2 +- libffi/testsuite/libffi.call/nested_struct9.c | 4 +- libffi/testsuite/libffi.call/problem1.c | 5 +- libffi/testsuite/libffi.call/promotion.c | 4 +- libffi/testsuite/libffi.call/pyobjc-tc.c | 2 +- libffi/testsuite/libffi.call/return_dbl1.c | 2 +- libffi/testsuite/libffi.call/return_dbl2.c | 2 +- libffi/testsuite/libffi.call/return_fl2.c | 16 +- libffi/testsuite/libffi.call/return_fl3.c | 2 +- libffi/testsuite/libffi.call/return_ll1.c | 4 +- libffi/testsuite/libffi.call/return_ul.c | 4 +- libffi/testsuite/libffi.call/struct1.c | 2 - libffi/testsuite/libffi.special/ffitestcxx.h | 9 + libffi/testsuite/libffi.special/special.exp | 14 +- libffi/testsuite/libffi.special/unwindtest.cc | 10 +- .../libffi.special/unwindtest_ffi_call.cc | 2 +- 141 files changed, 5187 insertions(+), 2163 deletions(-) diff --git a/libffi/ChangeLog b/libffi/ChangeLog index 7c9c97e..7026706 100644 --- a/libffi/ChangeLog +++ b/libffi/ChangeLog @@ -1,3 +1,1022 @@ +2008-01-24 David Edelsohn + + * configure: Regenerate. + +2008-01-06 Andreas Tobler + + * src/x86/ffi.c (ffi_prep_cif_machdep): Fix thinko. + +2008-01-05 Andreas Tobler + + PR testsuite/32843 + * src/x86/ffi.c (ffi_prep_cif_machdep): Add code for + signed/unsigned int8/16 for X86_DARWIN. + Updated copyright info. + Handle one and two byte structs with special cif->flags. + * src/x86/ffitarget.h: Add special types for one and two byte structs. + Updated copyright info. + * src/x86/darwin.S (ffi_call_SYSV): Rewrite to use a jump table like + sysv.S + Remove code to pop args from the stack after call. + Special-case signed/unsigned for int8/16, one and two byte structs. + (ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8, + FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32, + FFI_TYPE_SINT32. + Updated copyright info. + +2007-12-08 David Daney + + * src/mips/n32.S (ffi_call_N32): Replace dadd with ADDU, dsub with + SUBU, add with ADDU and use smaller code sequences. + +2007-12-07 David Daney + + * src/mips/ffi.c (ffi_prep_cif_machdep): Handle long double return + type. + +2007-12-06 David Daney + + * include/ffi.h.in (FFI_SIZEOF_JAVA_RAW): Define if not already + defined. + (ffi_java_raw): New typedef. + (ffi_java_raw_call, ffi_java_ptrarray_to_raw, + ffi_java_raw_to_ptrarray): Change parameter types from ffi_raw to + ffi_java_raw. + (ffi_java_raw_closure) : Same. + (ffi_prep_java_raw_closure, ffi_prep_java_raw_closure_loc): Change + parameter types. + * src/java_raw_api.c (ffi_java_raw_size): Replace FFI_SIZEOF_ARG with + FFI_SIZEOF_JAVA_RAW. + (ffi_java_raw_to_ptrarray): Change type of raw to ffi_java_raw. + Replace FFI_SIZEOF_ARG with FFI_SIZEOF_JAVA_RAW. Use + sizeof(ffi_java_raw) for alignment calculations. + (ffi_java_ptrarray_to_raw): Same. + (ffi_java_rvalue_to_raw): Add special handling for FFI_TYPE_POINTER + if FFI_SIZEOF_JAVA_RAW == 4. + (ffi_java_raw_to_rvalue): Same. + (ffi_java_raw_call): Change type of raw to ffi_java_raw. + (ffi_java_translate_args): Same. + (ffi_prep_java_raw_closure_loc, ffi_prep_java_raw_closure): Change + parameter types. + * src/mips/ffitarget.h (FFI_SIZEOF_JAVA_RAW): Define for N32 ABI. + +2007-12-06 David Daney + + * src/mips/n32.S (ffi_closure_N32): Use 64-bit add instruction on + pointer values. + +2007-12-01 Andreas Tobler + + PR libffi/31937 + * src/powerpc/ffitarget.h: Introduce new ABI FFI_LINUX_SOFT_FLOAT. + Add local FFI_TYPE_UINT128 to handle soft-float long-double-128. + * src/powerpc/ffi.c: Distinguish between __NO_FPRS__ and not and + set the NUM_FPR_ARG_REGISTERS according to. + Add support for potential soft-float support under hard-float + architecture. + (ffi_prep_args_SYSV): Set NUM_FPR_ARG_REGISTERS to 0 in case of + FFI_LINUX_SOFT_FLOAT, handle float, doubles and long-doubles according + to the FFI_LINUX_SOFT_FLOAT ABI. + (ffi_prep_cif_machdep): Likewise. + (ffi_closure_helper_SYSV): Likewise. + * src/powerpc/ppc_closure.S: Make sure not to store float/double + on archs where __NO_FPRS__ is true. + Add FFI_TYPE_UINT128 support. + * src/powerpc/sysv.S: Add support for soft-float long-double-128. + Adjust copyright notice. + +2007-11-25 Andreas Tobler + + * src/closures.c: Move defintion of MAYBE_UNUSED from here to ... + * include/ffi_common.h: ... here. + Update copyright. + +2007-11-17 Andreas Tobler + + * src/powerpc/sysv.S: Load correct cr to compare if we have long double. + * src/powerpc/linux64.S: Likewise. + * src/powerpc/ffi.c: Add a comment to show which part goes into cr6. + * testsuite/libffi.call/return_ldl.c: New test. + +2007-09-04 + + * src/arm/sysv.S (UNWIND): New. + (Whole file): Conditionally compile unwinder directives. + * src/arm/sysv.S: Add unwinder directives. + + * src/arm/ffi.c (ffi_prep_args): Align structs by at least 4 bytes. + Only treat r0 as a struct address if we're actually returning a + struct by address. + Only copy the bytes that are actually within a struct. + (ffi_prep_cif_machdep): A Composite Type not larger than 4 bytes + is returned in r0, not passed by address. + (ffi_call): Allocate a word-sized temporary for the case where + a composite is returned in r0. + (ffi_prep_incoming_args_SYSV): Align as necessary. + +2007-08-05 Steven Newbury + + * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Use __clear_cache instead of + directly using the sys_cacheflush syscall. + +2007-07-27 Andrew Haley + + * src/arm/sysv.S (ffi_closure_SYSV): Add soft-float. + +2007-09-03 Maciej W. Rozycki + + * Makefile.am: Unify MIPS_IRIX and MIPS_LINUX into MIPS. + * configure.ac: Likewise. + * Makefile.in: Regenerate. + * include/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + * configure: Likewise. + +2007-08-24 David Daney + + * testsuite/libffi.call/return_sl.c: New test. + +2007-08-10 David Daney + + * testsuite/libffi.call/cls_multi_ushort.c, + testsuite/libffi.call/cls_align_uint16.c, + testsuite/libffi.call/nested_struct1.c, + testsuite/libffi.call/nested_struct3.c, + testsuite/libffi.call/cls_7_1_byte.c, + testsuite/libffi.call/nested_struct5.c, + testsuite/libffi.call/cls_double.c, + testsuite/libffi.call/nested_struct7.c, + testsuite/libffi.call/cls_sint.c, + testsuite/libffi.call/nested_struct9.c, + testsuite/libffi.call/cls_20byte1.c, + testsuite/libffi.call/cls_multi_sshortchar.c, + testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_3byte2.c, + testsuite/libffi.call/cls_multi_schar.c, + testsuite/libffi.call/cls_multi_uchar.c, + testsuite/libffi.call/cls_19byte.c, + testsuite/libffi.call/cls_9byte1.c, + testsuite/libffi.call/cls_align_float.c, + testsuite/libffi.call/closure_fn1.c, + testsuite/libffi.call/problem1.c, + testsuite/libffi.call/closure_fn3.c, + testsuite/libffi.call/cls_sshort.c, + testsuite/libffi.call/closure_fn5.c, + testsuite/libffi.call/cls_align_double.c, + testsuite/libffi.call/nested_struct.c, + testsuite/libffi.call/cls_2byte.c, + testsuite/libffi.call/nested_struct10.c, + testsuite/libffi.call/cls_4byte.c, + testsuite/libffi.call/cls_6byte.c, + testsuite/libffi.call/cls_8byte.c, + testsuite/libffi.call/cls_multi_sshort.c, + testsuite/libffi.call/cls_align_sint16.c, + testsuite/libffi.call/cls_align_uint32.c, + testsuite/libffi.call/cls_20byte.c, + testsuite/libffi.call/cls_float.c, + testsuite/libffi.call/nested_struct2.c, + testsuite/libffi.call/cls_5_1_byte.c, + testsuite/libffi.call/nested_struct4.c, + testsuite/libffi.call/cls_24byte.c, + testsuite/libffi.call/nested_struct6.c, + testsuite/libffi.call/cls_64byte.c, + testsuite/libffi.call/nested_struct8.c, + testsuite/libffi.call/cls_uint.c, + testsuite/libffi.call/cls_multi_ushortchar.c, + testsuite/libffi.call/cls_schar.c, + testsuite/libffi.call/cls_uchar.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/cls_align_longdouble.c, + testsuite/libffi.call/cls_1_1byte.c, + testsuite/libffi.call/cls_12byte.c, + testsuite/libffi.call/cls_3_1byte.c, + testsuite/libffi.call/cls_3byte1.c, + testsuite/libffi.call/cls_4_1byte.c, + testsuite/libffi.call/cls_6_1_byte.c, + testsuite/libffi.call/cls_16byte.c, + testsuite/libffi.call/cls_18byte.c, + testsuite/libffi.call/closure_fn0.c, + testsuite/libffi.call/cls_9byte2.c, + testsuite/libffi.call/closure_fn2.c, + testsuite/libffi.call/closure_fn4.c, + testsuite/libffi.call/cls_ushort.c, + testsuite/libffi.call/closure_fn6.c, + testsuite/libffi.call/cls_5byte.c, + testsuite/libffi.call/cls_align_pointer.c, + testsuite/libffi.call/cls_7byte.c, + testsuite/libffi.call/cls_align_sint32.c, + testsuite/libffi.special/unwindtest_ffi_call.cc, + testsuite/libffi.special/unwindtest.cc: Remove xfail for mips64*-*-*. + +2007-08-10 David Daney + + PR libffi/28313 + * configure.ac: Don't treat mips64 as a special case. + * Makefile.am (nodist_libffi_la_SOURCES): Add n32.S. + * configure: Regenerate + * Makefile.in: Ditto. + * fficonfig.h.in: Ditto. + * src/mips/ffitarget.h (REG_L, REG_S, SUBU, ADDU, SRL, LI): Indent. + (LA, EH_FRAME_ALIGN, FDE_ADDR_BYTES): New preprocessor macros. + (FFI_DEFAULT_ABI): Set for n64 case. + (FFI_CLOSURES, FFI_TRAMPOLINE_SIZE): Define for n32 and n64 cases. + * src/mips/n32.S (ffi_call_N32): Add debug macros and labels for FDE. + (ffi_closure_N32): New function. + (.eh_frame): New section + * src/mips/o32.S: Clean up comments. + (ffi_closure_O32): Pass ffi_closure parameter in $12. + * src/mips/ffi.c: Use FFI_MIPS_N32 instead of + _MIPS_SIM == _ABIN32 throughout. + (FFI_MIPS_STOP_HERE): New, use in place of + ffi_stop_here. + (ffi_prep_args): Use unsigned long to hold pointer values. Rewrite + to support n32/n64 ABIs. + (calc_n32_struct_flags): Rewrite. + (calc_n32_return_struct_flags): Remove unused variable. Reverse + position of flag bits. + (ffi_prep_cif_machdep): Rewrite n32 portion. + (ffi_call): Enable for n64. Add special handling for small structure + return values. + (ffi_prep_closure_loc): Add n32 and n64 support. + (ffi_closure_mips_inner_O32): Add cast to silence warning. + (copy_struct_N32, ffi_closure_mips_inner_N32): New functions. + +2007-08-08 David Daney + + * testsuite/libffi.call/ffitest.h (ffi_type_mylong): Remove definition. + * testsuite/libffi.call/cls_align_uint16.c (main): Use correct type + specifiers. + * testsuite/libffi.call/nested_struct1.c (main): Ditto. + * testsuite/libffi.call/cls_sint.c (main): Ditto. + * testsuite/libffi.call/nested_struct9.c (main): Ditto. + * testsuite/libffi.call/cls_20byte1.c (main): Ditto. + * testsuite/libffi.call/cls_9byte1.c (main): Ditto. + * testsuite/libffi.call/closure_fn1.c (main): Ditto. + * testsuite/libffi.call/closure_fn3.c (main): Ditto. + * testsuite/libffi.call/return_dbl2.c (main): Ditto. + * testsuite/libffi.call/cls_sshort.c (main): Ditto. + * testsuite/libffi.call/return_fl3.c (main): Ditto. + * testsuite/libffi.call/closure_fn5.c (main): Ditto. + * testsuite/libffi.call/nested_struct.c (main): Ditto. + * testsuite/libffi.call/nested_struct10.c (main): Ditto. + * testsuite/libffi.call/return_ll1.c (main): Ditto. + * testsuite/libffi.call/cls_8byte.c (main): Ditto. + * testsuite/libffi.call/cls_align_uint32.c (main): Ditto. + * testsuite/libffi.call/cls_align_sint16.c (main): Ditto. + * testsuite/libffi.call/cls_20byte.c (main): Ditto. + * testsuite/libffi.call/nested_struct2.c (main): Ditto. + * testsuite/libffi.call/cls_24byte.c (main): Ditto. + * testsuite/libffi.call/nested_struct6.c (main): Ditto. + * testsuite/libffi.call/cls_uint.c (main): Ditto. + * testsuite/libffi.call/cls_12byte.c (main): Ditto. + * testsuite/libffi.call/cls_16byte.c (main): Ditto. + * testsuite/libffi.call/closure_fn0.c (main): Ditto. + * testsuite/libffi.call/cls_9byte2.c (main): Ditto. + * testsuite/libffi.call/closure_fn2.c (main): Ditto. + * testsuite/libffi.call/return_dbl1.c (main): Ditto. + * testsuite/libffi.call/closure_fn4.c (main): Ditto. + * testsuite/libffi.call/closure_fn6.c (main): Ditto. + * testsuite/libffi.call/cls_align_sint32.c (main): Ditto. + +2007-08-07 Andrew Haley + + * src/x86/sysv.S (ffi_closure_raw_SYSV): Fix typo in previous + checkin. + +2007-08-06 Andrew Haley + + PR testsuite/32843 + * src/x86/sysv.S (ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8, + FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32, + FFI_TYPE_SINT32. + +2007-08-02 David Daney + + * testsuite/libffi.call/return_ul.c (main): Define return type as + ffi_arg. Use proper printf conversion specifier. + +2007-07-30 Andrew Haley + + PR testsuite/32843 + * src/x86/ffi.c (ffi_prep_cif_machdep): in x86 case, add code for + signed/unsigned int8/16. + * src/x86/sysv.S (ffi_call_SYSV): Rewrite to: + Use a jump table. + Remove code to pop args from the stack after call. + Special-case signed/unsigned int8/16. + * testsuite/libffi.call/return_sc.c (main): Revert. + +2007-07-26 Richard Guenther + + PR testsuite/32843 + * testsuite/libffi.call/return_sc.c (main): Verify call + result as signed char, not ffi_arg. + +2007-07-16 Rainer Orth + + * configure.ac (i?86-*-solaris2.1[0-9]): Set TARGET to X86_64. + * configure: Regenerate. + +2007-07-11 David Daney + + * src/mips/ffi.c: Don't include sys/cachectl.h. + (ffi_prep_closure_loc): Use __builtin___clear_cache() instead of + cacheflush(). + +2007-05-18 Aurelien Jarno + + * src/arm/ffi.c (ffi_prep_closure_loc): Renamed and ajusted + from (ffi_prep_closure): ... this. + (FFI_INIT_TRAMPOLINE): Adjust. + +2005-12-31 Phil Blundell + + * src/arm/ffi.c (ffi_prep_incoming_args_SYSV, + ffi_closure_SYSV_inner, ffi_prep_closure): New, add closure support. + * src/arm/sysv.S(ffi_closure_SYSV): Likewise. + * src/arm/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise. + (FFI_CLOSURES): Enable closure support. + +2007-07-03 Andrew Haley + + * testsuite/libffi.call/cls_multi_ushort.c, + testsuite/libffi.call/cls_align_uint16.c, + testsuite/libffi.call/nested_struct1.c, + testsuite/libffi.call/nested_struct3.c, + testsuite/libffi.call/cls_7_1_byte.c, + testsuite/libffi.call/cls_double.c, + testsuite/libffi.call/nested_struct5.c, + testsuite/libffi.call/nested_struct7.c, + testsuite/libffi.call/cls_sint.c, + testsuite/libffi.call/nested_struct9.c, + testsuite/libffi.call/cls_20byte1.c, + testsuite/libffi.call/cls_multi_sshortchar.c, + testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_3byte2.c, + testsuite/libffi.call/cls_multi_schar.c, + testsuite/libffi.call/cls_multi_uchar.c, + testsuite/libffi.call/cls_19byte.c, + testsuite/libffi.call/cls_9byte1.c, + testsuite/libffi.call/cls_align_float.c, + testsuite/libffi.call/closure_fn1.c, + testsuite/libffi.call/problem1.c, + testsuite/libffi.call/closure_fn3.c, + testsuite/libffi.call/cls_sshort.c, + testsuite/libffi.call/closure_fn5.c, + testsuite/libffi.call/cls_align_double.c, + testsuite/libffi.call/cls_2byte.c, + testsuite/libffi.call/nested_struct.c, + testsuite/libffi.call/nested_struct10.c, + testsuite/libffi.call/cls_4byte.c, + testsuite/libffi.call/cls_6byte.c, + testsuite/libffi.call/cls_8byte.c, + testsuite/libffi.call/cls_multi_sshort.c, + testsuite/libffi.call/cls_align_uint32.c, + testsuite/libffi.call/cls_align_sint16.c, + testsuite/libffi.call/cls_float.c, + testsuite/libffi.call/cls_20byte.c, + testsuite/libffi.call/cls_5_1_byte.c, + testsuite/libffi.call/nested_struct2.c, + testsuite/libffi.call/cls_24byte.c, + testsuite/libffi.call/nested_struct4.c, + testsuite/libffi.call/nested_struct6.c, + testsuite/libffi.call/cls_64byte.c, + testsuite/libffi.call/nested_struct8.c, + testsuite/libffi.call/cls_uint.c, + testsuite/libffi.call/cls_multi_ushortchar.c, + testsuite/libffi.call/cls_schar.c, + testsuite/libffi.call/cls_uchar.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/cls_align_longdouble.c, + testsuite/libffi.call/cls_1_1byte.c, + testsuite/libffi.call/cls_12byte.c, + testsuite/libffi.call/cls_3_1byte.c, + testsuite/libffi.call/cls_3byte1.c, + testsuite/libffi.call/cls_4_1byte.c, + testsuite/libffi.call/cls_6_1_byte.c, + testsuite/libffi.call/cls_16byte.c, + testsuite/libffi.call/cls_18byte.c, + testsuite/libffi.call/closure_fn0.c, + testsuite/libffi.call/cls_9byte2.c, + testsuite/libffi.call/closure_fn2.c, + testsuite/libffi.call/closure_fn4.c, + testsuite/libffi.call/cls_ushort.c, + testsuite/libffi.call/closure_fn6.c, + testsuite/libffi.call/cls_5byte.c, + testsuite/libffi.call/cls_align_pointer.c, + testsuite/libffi.call/cls_7byte.c, + testsuite/libffi.call/cls_align_sint32.c, + testsuite/libffi.special/unwindtest_ffi_call.cc, + testsuite/libffi.special/unwindtest.cc: Enable for ARM. + +2007-07-05 H.J. Lu + + * aclocal.m4: Regenerated. + +2007-06-02 Paolo Bonzini + + * configure: Regenerate. + +2007-05-23 Steve Ellcey + + * Makefile.in: Regenerate. + * configure: Regenerate. + * aclocal.m4: Regenerate. + * include/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2007-05-10 Roman Zippel + + * src/m68k/ffi.c (ffi_prep_incoming_args_SYSV, + ffi_closure_SYSV_inner,ffi_prep_closure): New, add closure support. + * src/m68k/sysv.S(ffi_closure_SYSV,ffi_closure_struct_SYSV): Likewise. + * src/m68k/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise. + (FFI_CLOSURES): Enable closure support. + +2007-05-10 Roman Zippel + + * configure.ac (HAVE_AS_CFI_PSEUDO_OP): New test. + * configure: Regenerate. + * fficonfig.h.in: Regenerate. + * src/m68k/sysv.S (CFI_STARTPROC,CFI_ENDPROC, + CFI_OFFSET,CFI_DEF_CFA): New macros. + (ffi_call_SYSV): Add callframe annotation. + +2007-05-10 Roman Zippel + + * src/m68k/ffi.c (ffi_prep_args,ffi_prep_cif_machdep): Fix + numerous test suite failures. + * src/m68k/sysv.S (ffi_call_SYSV): Likewise. + +2007-04-11 Paolo Bonzini + + * Makefile.am (EXTRA_DIST): Bring up to date. + * Makefile.in: Regenerate. + * src/frv/eabi.S: Remove RCS keyword. + +2007-04-06 Richard Henderson + + * configure.ac: Tidy target case. + (HAVE_LONG_DOUBLE): Allow the target to override. + * configure: Regenerate. + * include/ffi.h.in: Don't define ffi_type_foo if + LIBFFI_HIDE_BASIC_TYPES is defined. + (ffi_type_longdouble): If not HAVE_LONG_DOUBLE, define + to ffi_type_double. + * types.c (LIBFFI_HIDE_BASIC_TYPES): Define. + (FFI_TYPEDEF, ffi_type_void): Mark the data const. + (ffi_type_longdouble): Special case for Alpha. Don't define + if long double == double. + + * src/alpha/ffi.c (FFI_TYPE_LONGDOUBLE): Assert unique value. + (ffi_prep_cif_machdep): Handle it as the 128-bit type. + (ffi_call, ffi_closure_osf_inner): Likewise. + (ffi_closure_osf_inner): Likewise. Mark hidden. + (ffi_call_osf, ffi_closure_osf): Mark hidden. + * src/alpha/ffitarget.h (FFI_LAST_ABI): Tidy definition. + * src/alpha/osf.S (ffi_call_osf, ffi_closure_osf): Mark hidden. + (load_table): Handle 128-bit long double. + + * testsuite/libffi.call/float4.c: Add -mieee for alpha. + +2007-04-06 Tom Tromey + + PR libffi/31491: + * README: Fixed bug in example. + +2007-04-03 Jakub Jelinek + + * src/closures.c: Include sys/statfs.h. + (_GNU_SOURCE): Define on Linux. + (FFI_MMAP_EXEC_SELINUX): Define. + (selinux_enabled): New variable. + (selinux_enabled_check): New function. + (is_selinux_enabled): Define. + (dlmmap): Use it. + +2007-03-24 Uros Bizjak + + * testsuite/libffi.call/return_fl2.c (return_fl): Mark as static. + Use 'volatile float sum' to create sum of floats to avoid false + negative due to excess precision on ix86 targets. + (main): Ditto. + +2007-03-08 Alexandre Oliva + + * src/powerpc/ffi.c (flush_icache): Fix left-over from previous + patch. + (ffi_prep_closure_loc): Remove unneeded casts. Add needed ones. + +2007-03-07 Alexandre Oliva + + * include/ffi.h.in (ffi_closure_alloc, ffi_closure_free): New. + (ffi_prep_closure_loc): New. + (ffi_prep_raw_closure_loc): New. + (ffi_prep_java_raw_closure_loc): New. + * src/closures.c: New file. + * src/dlmalloc.c [FFI_MMAP_EXEC_WRIT] (struct malloc_segment): + Replace sflags with exec_offset. + [FFI_MMAP_EXEC_WRIT] (mmap_exec_offset, add_segment_exec_offset, + sub_segment_exec_offset): New macros. + (get_segment_flags, set_segment_flags, check_segment_merge): New + macros. + (is_mmapped_segment, is_extern_segment): Use get_segment_flags. + (add_segment, sys_alloc, create_mspace, create_mspace_with_base, + destroy_mspace): Use new macros. + (sys_alloc): Silence warning. + * Makefile.am (libffi_la_SOURCES): Add src/closures.c. + * Makefile.in: Rebuilt. + * src/prep_cif [FFI_CLOSURES] (ffi_prep_closure): Implement in + terms of ffi_prep_closure_loc. + * src/raw_api.c (ffi_prep_raw_closure_loc): Renamed and adjusted + from... + (ffi_prep_raw_closure): ... this. Re-implement in terms of the + renamed version. + * src/java_raw_api (ffi_prep_java_raw_closure_loc): Renamed and + adjusted from... + (ffi_prep_java_raw_closure): ... this. Re-implement in terms of + the renamed version. + * src/alpha/ffi.c (ffi_prep_closure_loc): Renamed from + (ffi_prep_closure): ... this. + * src/pa/ffi.c: Likewise. + * src/cris/ffi.c: Likewise. Adjust. + * src/frv/ffi.c: Likewise. + * src/ia64/ffi.c: Likewise. + * src/mips/ffi.c: Likewise. + * src/powerpc/ffi_darwin.c: Likewise. + * src/s390/ffi.c: Likewise. + * src/sh/ffi.c: Likewise. + * src/sh64/ffi.c: Likewise. + * src/sparc/ffi.c: Likewise. + * src/x86/ffi64.c: Likewise. + * src/x86/ffi.c: Likewise. + (FFI_INIT_TRAMPOLINE): Adjust. + (ffi_prep_raw_closure_loc): Renamed and adjusted from... + (ffi_prep_raw_closure): ... this. + * src/powerpc/ffi.c (ffi_prep_closure_loc): Renamed from + (ffi_prep_closure): ... this. + (flush_icache): Adjust. + +2007-03-07 Alexandre Oliva + + * src/dlmalloc.c: New file, imported version 2.8.3 of Doug + Lea's malloc. + +2007-03-01 Brooks Moses + + * Makefile.am: Add dummy install-pdf target. + * Makefile.in: Regenerate + +2007-02-13 Andreas Krebbel + + * src/s390/ffi.c (ffi_prep_args, ffi_prep_cif_machdep, + ffi_closure_helper_SYSV): Add long double handling. + +2007-02-02 Jakub Jelinek + + * src/powerpc/linux64.S (ffi_call_LINUX64): Move restore of r2 + immediately after bctrl instruction. + +2007-01-18 Alexandre Oliva + + * Makefile.am (all-recursive, install-recursive, + mostlyclean-recursive, clean-recursive, distclean-recursive, + maintainer-clean-recursive): Add missing targets. + * Makefile.in: Rebuilt. + +2006-12-14 Andreas Tobler + + * configure.ac: Add TARGET for x86_64-*-darwin*. + * Makefile.am (nodist_libffi_la_SOURCES): Add rules for 64-bit sources + for X86_DARWIN. + * src/x86/ffitarget.h: Set trampoline size for x86_64-*-darwin*. + * src/x86/darwin64.S: New file for x86_64-*-darwin* support. + * configure: Regenerate. + * Makefile.in: Regenerate. + * include/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + * testsuite/libffi.special/unwindtest_ffi_call.cc: New test case for + ffi_call only. + +2006-12-13 Andreas Tobler + + * aclocal.m4: Regenerate with aclocal -I .. as written in the + Makefile.am. + +2006-10-31 Geoffrey Keating + + * src/powerpc/ffi_darwin.c (darwin_adjust_aggregate_sizes): New. + (ffi_prep_cif_machdep): Call darwin_adjust_aggregate_sizes for + Darwin. + * testsuite/libffi.call/nested_struct4.c: Remove Darwin XFAIL. + * testsuite/libffi.call/nested_struct6.c: Remove Darwin XFAIL. + +2006-10-10 Paolo Bonzini + Sandro Tolaini + + * configure.ac [i*86-*-darwin*]: Set X86_DARWIN symbol and + conditional. + * configure: Regenerated. + * Makefile.am (nodist_libffi_la_SOURCES) [X86_DARWIN]: New case. + (EXTRA_DIST): Add src/x86/darwin.S. + * Makefile.in: Regenerated. + * include/Makefile.in: Regenerated. + * testsuite/Makefile.in: Regenerated. + + * src/x86/ffi.c (ffi_prep_cif_machdep) [X86_DARWIN]: Treat like + X86_WIN32, and additionally align stack to 16 bytes. + * src/x86/darwin.S: New, based on sysv.S. + * src/prep_cif.c (ffi_prep_cif) [X86_DARWIN]: Align > 8-byte structs. + +2006-09-12 David Daney + + PR libffi/23935 + * include/Makefile.am: Install both ffi.h and ffitarget.h in + $(libdir)/gcc/$(target_alias)/$(gcc_version)/include. + * aclocal.m4: Regenerated for automake 1.9.6. + * Makefile.in: Regenerated. + * include/Makefile.in: Regenerated. + * testsuite/Makefile.in: Regenerated. + +2006-08-17 Andreas Tobler + + * include/ffi_common.h (struct): Revert accidental commit. + +2006-08-15 Andreas Tobler + + * include/ffi_common.h: Remove lint directives. + * include/ffi.h.in: Likewise. + +2006-07-25 Torsten Schoenfeld + + * include/ffi.h.in (ffi_type_ulong, ffi_type_slong): Define correctly + for 32-bit architectures. + * testsuite/libffi.call/return_ul.c: New test case. + +2006-07-19 David Daney + + * testsuite/libffi.call/closure_fn6.c: Remove xfail for mips, + xfail remains for mips64. + +2006-05-23 Carlos O'Donell + + * Makefile.am: Add install-html target. Add install-html to .PHONY + * Makefile.in: Regenerate. + * aclocal.m4: Regenerate. + * include/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2006-05-18 John David Anglin + + * pa/ffi.c (ffi_prep_args_pa32): Load floating point arguments from + stack slot. + +2006-04-22 Andreas Tobler + + * README: Remove notice about 'Crazy Comments'. + * src/debug.c: Remove lint directives. Cleanup white spaces. + * src/java_raw_api.c: Likewise. + * src/prep_cif.c: Likewise. + * src/raw_api.c: Likewise. + * src/ffitest.c: Delete. No longer needed, all test cases migrated + to the testsuite. + * src/arm/ffi.c: Remove lint directives. + * src/m32r/ffi.c: Likewise. + * src/pa/ffi.c: Likewise. + * src/powerpc/ffi.c: Likewise. + * src/powerpc/ffi_darwin.c: Likewise. + * src/sh/ffi.c: Likewise. + * src/sh64/ffi.c: Likewise. + * src/x86/ffi.c: Likewise. + * testsuite/libffi.call/float2.c: Likewise. + * testsuite/libffi.call/promotion.c: Likewise. + * testsuite/libffi.call/struct1.c: Likewise. + +2006-04-13 Andreas Tobler + + * src/pa/hpux32.S: Correct unwind offset calculation for + ffi_closure_pa32. + * src/pa/linux.S: Likewise. + +2006-04-12 James E Wilson + + PR libgcj/26483 + * src/ia64/ffi.c (stf_spill, ldf_fill): Rewrite as macros. + (hfa_type_load): Call stf_spill. + (hfa_type_store): Call ldf_fill. + (ffi_call): Adjust calls to above routines. Add local temps for + macro result. + +2006-04-10 Matthias Klose + + * testsuite/lib/libffi-dg.exp (libffi-init): Recognize multilib + directory names containing underscores. + +2006-04-07 James E Wilson + + * testsuite/libffi.call/float4.c: New testcase. + +2006-04-05 John David Anglin + Andreas Tobler + + * Makefile.am: Add PA_HPUX port. + * Makefile.in: Regenerate. + * include/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + * configure.ac: Add PA_HPUX rules. + * configure: Regenerate. + * src/pa/ffitarget.h: Rename linux target to PA_LINUX. + Add PA_HPUX and PA64_HPUX. + Rename FFI_LINUX ABI to FFI_PA32 ABI. + (FFI_TRAMPOLINE_SIZE): Define for 32-bit HP-UX targets. + (FFI_TYPE_SMALL_STRUCT2): Define. + (FFI_TYPE_SMALL_STRUCT4): Likewise. + (FFI_TYPE_SMALL_STRUCT8): Likewise. + (FFI_TYPE_SMALL_STRUCT3): Redefine. + (FFI_TYPE_SMALL_STRUCT5): Likewise. + (FFI_TYPE_SMALL_STRUCT6): Likewise. + (FFI_TYPE_SMALL_STRUCT7): Likewise. + * src/pa/ffi.c (ROUND_DOWN): Delete. + (fldw, fstw, fldd, fstd): Use '__asm__'. + (ffi_struct_type): Add support for FFI_TYPE_SMALL_STRUCT2, + FFI_TYPE_SMALL_STRUCT4 and FFI_TYPE_SMALL_STRUCT8. + (ffi_prep_args_LINUX): Rename to ffi_prep_args_pa32. Update comment. + Simplify incrementing of stack slot variable. Change type of local + 'n' to unsigned int. + (ffi_size_stack_LINUX): Rename to ffi_size_stack_pa32. Handle long + double on PA_HPUX. + (ffi_prep_cif_machdep): Likewise. + (ffi_call): Likewise. + (ffi_closure_inner_LINUX): Rename to ffi_closure_inner_pa32. Change + return type to ffi_status. Simplify incrementing of stack slot + variable. Only copy floating point argument registers when PA_LINUX + is true. Reformat debug statement. + Add support for FFI_TYPE_SMALL_STRUCT2, FFI_TYPE_SMALL_STRUCT4 and + FFI_TYPE_SMALL_STRUCT8. + (ffi_closure_LINUX): Rename to ffi_closure_pa32. Add 'extern' to + declaration. + (ffi_prep_closure): Make linux trampoline conditional on PA_LINUX. + Add nops to cache flush. Add trampoline for PA_HPUX. + * src/pa/hpux32.S: New file. + * src/pa/linux.S (ffi_call_LINUX): Rename to ffi_call_pa32. Rename + ffi_prep_args_LINUX to ffi_prep_args_pa32. + Localize labels. Add support for 2, 4 and 8-byte small structs. Handle + unaligned destinations in 3, 5, 6 and 7-byte small structs. Order + argument type checks so that common argument types appear first. + (ffi_closure_LINUX): Rename to ffi_closure_pa32. Rename + ffi_closure_inner_LINUX to ffi_closure_inner_pa32. + +2006-03-24 Alan Modra + + * src/powerpc/ffitarget.h (enum ffi_abi): Add FFI_LINUX. Default + for 32-bit using IBM extended double format. Fix FFI_LAST_ABI. + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Handle linux variant of + FFI_TYPE_LONGDOUBLE. + (ffi_prep_args64): Assert using IBM extended double. + (ffi_prep_cif_machdep): Don't munge FFI_TYPE_LONGDOUBLE type. + Handle FFI_LINUX FFI_TYPE_LONGDOUBLE return and args. + (ffi_call): Handle FFI_LINUX. + (ffi_closure_helper_SYSV): Non FFI_LINUX long double return needs + gpr3 return pointer as for struct return. Handle FFI_LINUX + FFI_TYPE_LONGDOUBLE return and args. Don't increment "nf" + unnecessarily. + * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Load both f1 and f2 + for FFI_TYPE_LONGDOUBLE. Move epilogue insns into case table. + Don't use r6 as pointer to results, instead use sp offset. Don't + make a special call to load lr with case table address, instead + use offset from previous call. + * src/powerpc/sysv.S (ffi_call_SYSV): Save long double return. + * src/powerpc/linux64.S (ffi_call_LINUX64): Simplify long double + return. + +2006-03-15 Kaz Kojima + + * src/sh64/ffi.c (ffi_prep_cif_machdep): Handle float arguments + passed with FP registers correctly. + (ffi_closure_helper_SYSV): Likewise. + * src/sh64/sysv.S: Likewise. + +2006-03-01 Andreas Tobler + + * testsuite/libffi.special/unwindtest.cc (closure_test_fn): Mark cif, + args and userdata unused. + (closure_test_fn1): Mark cif and userdata unused. + (main): Remove unused res. + +2006-02-28 Andreas Tobler + + * testsuite/libffi.call/call.exp: Adjust FSF address. Add test runs for + -O2, -O3, -Os and the warning flags -W -Wall. + * testsuite/libffi.special/special.exp: Likewise. + * testsuite/libffi.call/ffitest.h: Add an __UNUSED__ macro to mark + unused parameter unused for gcc or else do nothing. + * testsuite/libffi.special/ffitestcxx.h: Likewise. + * testsuite/libffi.call/cls_12byte.c (cls_struct_12byte_gn): Mark cif + and userdata unused. + * testsuite/libffi.call/cls_16byte.c (cls_struct_16byte_gn): Likewise. + * testsuite/libffi.call/cls_18byte.c (cls_struct_18byte_gn): Likewise. + * testsuite/libffi.call/cls_19byte.c (cls_struct_19byte_gn): Likewise. + * testsuite/libffi.call/cls_1_1byte.c (cls_struct_1_1byte_gn): Likewise. + * testsuite/libffi.call/cls_20byte.c (cls_struct_20byte_gn): Likewise. + * testsuite/libffi.call/cls_20byte1.c (cls_struct_20byte_gn): Likewise. + * testsuite/libffi.call/cls_24byte.c (cls_struct_24byte_gn): Likewise. + * testsuite/libffi.call/cls_2byte.c (cls_struct_2byte_gn): Likewise. + * testsuite/libffi.call/cls_3_1byte.c (cls_struct_3_1byte_gn): Likewise. + * testsuite/libffi.call/cls_3byte1.c (cls_struct_3byte_gn): Likewise. + * testsuite/libffi.call/cls_3byte2.c (cls_struct_3byte_gn1): Likewise. + * testsuite/libffi.call/cls_4_1byte.c (cls_struct_4_1byte_gn): Likewise. + * testsuite/libffi.call/cls_4byte.c (cls_struct_4byte_gn): Likewise. + * testsuite/libffi.call/cls_5_1_byte.c (cls_struct_5byte_gn): Likewise. + * testsuite/libffi.call/cls_5byte.c (cls_struct_5byte_gn): Likewise. + * testsuite/libffi.call/cls_64byte.c (cls_struct_64byte_gn): Likewise. + * testsuite/libffi.call/cls_6_1_byte.c (cls_struct_6byte_gn): Likewise. + * testsuite/libffi.call/cls_6byte.c (cls_struct_6byte_gn): Likewise. + * testsuite/libffi.call/cls_7_1_byte.c (cls_struct_7byte_gn): Likewise. + * testsuite/libffi.call/cls_7byte.c (cls_struct_7byte_gn): Likewise. + * testsuite/libffi.call/cls_8byte.c (cls_struct_8byte_gn): Likewise. + * testsuite/libffi.call/cls_9byte1.c (cls_struct_9byte_gn): Likewise. + * testsuite/libffi.call/cls_9byte2.c (cls_struct_9byte_gn): Likewise. + * testsuite/libffi.call/cls_align_double.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_float.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_longdouble.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_pointer.c (cls_struct_align_fn): Cast + void* to avoid compiler warning. + (main): Likewise. + (cls_struct_align_gn): Mark cif and userdata unused. + * testsuite/libffi.call/cls_align_sint16.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_sint32.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_sint64.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_uint16.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_uint32.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_double.c (cls_ret_double_fn): Likewise. + * testsuite/libffi.call/cls_float.c (cls_ret_float_fn): Likewise. + * testsuite/libffi.call/cls_multi_schar.c (test_func_gn): Mark cif and + data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_multi_sshort.c (test_func_gn): Mark cif and + data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_multi_sshortchar.c (test_func_gn): Mark cif + and data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_multi_uchar.c (test_func_gn): Mark cif and + data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_multi_ushort.c (test_func_gn): Mark cif and + data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_multi_ushortchar.c (test_func_gn): Mark cif + and data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_schar.c (cls_ret_schar_fn): Mark cif and + userdata unused. + (cls_ret_schar_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/cls_sint.c (cls_ret_sint_fn): Mark cif and + userdata unused. + (cls_ret_sint_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/cls_sshort.c (cls_ret_sshort_fn): Mark cif and + userdata unused. + (cls_ret_sshort_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/cls_uchar.c (cls_ret_uchar_fn): Mark cif and + userdata unused. + (cls_ret_uchar_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/cls_uint.c (cls_ret_uint_fn): Mark cif and + userdata unused. + (cls_ret_uint_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/cls_ulonglong.c (cls_ret_ulonglong_fn): Mark cif + and userdata unused. + * testsuite/libffi.call/cls_ushort.c (cls_ret_ushort_fn): Mark cif and + userdata unused. + (cls_ret_ushort_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/float.c (floating): Remove unused parameter e. + * testsuite/libffi.call/float1.c (main): Remove unused variable i. + Cleanup white spaces. + * testsuite/libffi.call/negint.c (checking): Remove unused variable i. + * testsuite/libffi.call/nested_struct.c (cls_struct_combined_gn): Mark + cif and userdata unused. + * testsuite/libffi.call/nested_struct1.c (cls_struct_combined_gn): + Likewise. + * testsuite/libffi.call/nested_struct10.c (B_gn): Likewise. + * testsuite/libffi.call/nested_struct2.c (B_fn): Adjust printf + formatters to silence gcc. + (B_gn): Mark cif and userdata unused. + * testsuite/libffi.call/nested_struct3.c (B_gn): Mark cif and userdata + unused. + * testsuite/libffi.call/nested_struct4.c: Mention related PR. + (B_gn): Mark cif and userdata unused. + * testsuite/libffi.call/nested_struct5.c (B_gn): Mark cif and userdata + unused. + * testsuite/libffi.call/nested_struct6.c: Mention related PR. + (B_gn): Mark cif and userdata unused. + * testsuite/libffi.call/nested_struct7.c (B_gn): Mark cif and userdata + unused. + * testsuite/libffi.call/nested_struct8.c (B_gn): Likewise. + * testsuite/libffi.call/nested_struct9.c (B_gn): Likewise. + * testsuite/libffi.call/problem1.c (stub): Likewise. + * testsuite/libffi.call/pyobjc-tc.c (main): Cast the result to silence + gcc. + * testsuite/libffi.call/return_fl2.c (return_fl): Add the note mentioned + in the last commit for this test case in the test case itself. + * testsuite/libffi.call/closure_fn0.c (closure_test_fn0): Mark cif as + unused. + * testsuite/libffi.call/closure_fn1.c (closure_test_fn1): Likewise. + * testsuite/libffi.call/closure_fn2.c (closure_test_fn2): Likewise. + * testsuite/libffi.call/closure_fn3.c (closure_test_fn3): Likewise. + * testsuite/libffi.call/closure_fn4.c (closure_test_fn0): Likewise. + * testsuite/libffi.call/closure_fn5.c (closure_test_fn5): Likewise. + * testsuite/libffi.call/closure_fn6.c (closure_test_fn0): Likewise. + +2006-02-22 Kaz Kojima + + * src/sh/sysv.S: Fix register numbers in the FDE for + ffi_closure_SYSV. + +2006-02-20 Andreas Tobler + + * testsuite/libffi.call/return_fl2.c (return_fl): Remove static + declaration to avoid a false negative on ix86. See PR323. + +2006-02-18 Kaz Kojima + + * src/sh/ffi.c (ffi_closure_helper_SYSV): Remove unused variable + and cast integer to void * if needed. Update the pointer to + the FP register saved area correctly. + +2006-02-17 Andreas Tobler + + * testsuite/libffi.call/nested_struct6.c: XFAIL this test until PR25630 + is fixed. + * testsuite/libffi.call/nested_struct4.c: Likewise. + +2006-02-16 Andreas Tobler + + * testsuite/libffi.call/return_dbl.c: New test case. + * testsuite/libffi.call/return_dbl1.c: Likewise. + * testsuite/libffi.call/return_dbl2.c: Likewise. + * testsuite/libffi.call/return_fl.c: Likewise. + * testsuite/libffi.call/return_fl1.c: Likewise. + * testsuite/libffi.call/return_fl2.c: Likewise. + * testsuite/libffi.call/return_fl3.c: Likewise. + * testsuite/libffi.call/closure_fn6.c: Likewise. + + * testsuite/libffi.call/nested_struct2.c: Remove ffi_type_mylong + definition. + * testsuite/libffi.call/ffitest.h: Add ffi_type_mylong definition + here to be used by other test cases too. + + * testsuite/libffi.call/nested_struct10.c: New test case. + * testsuite/libffi.call/nested_struct9.c: Likewise. + * testsuite/libffi.call/nested_struct8.c: Likewise. + * testsuite/libffi.call/nested_struct7.c: Likewise. + * testsuite/libffi.call/nested_struct6.c: Likewise. + * testsuite/libffi.call/nested_struct5.c: Likewise. + * testsuite/libffi.call/nested_struct4.c: Likewise. + +2006-01-21 Andreas Tobler + + * configure.ac: Enable libffi for sparc64-*-freebsd*. + * configure: Rebuilt. + +2006-01-18 Jakub Jelinek + + * src/powerpc/sysv.S (smst_two_register): Don't call __ashldi3, + instead do the shifting inline. + * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't compute %r5 + shift count unconditionally. Simplify load sequences for 1, 2, 3, 4 + and 8 byte structs, for the remaining struct sizes don't call + __lshrdi3, instead do the shifting inline. + +2005-12-07 Thiemo Seufer + + * src/mips/ffitarget.h: Remove obsolete sgidefs.h include. Add + missing parentheses. + * src/mips/o32.S (ffi_call_O32): Code formatting. Define + and use A3_OFF, FP_OFF, RA_OFF. Micro-optimizations. + (ffi_closure_O32): Likewise, but with newly defined A3_OFF2, + A2_OFF2, A1_OFF2, A0_OFF2, RA_OFF2, FP_OFF2, S0_OFF2, GP_OFF2, + V1_OFF2, V0_OFF2, FA_1_1_OFF2, FA_1_0_OFF2, FA_0_1_OFF2, + FA_0_0_OFF2. + * src/mips/ffi.c (ffi_prep_args): Code formatting. Fix + endianness bugs. + (ffi_prep_closure): Improve trampoline instruction scheduling. + (ffi_closure_mips_inner_O32): Fix endianness bugs. + +2005-12-03 Alan Modra + + * src/powerpc/ffi.c: Formatting. + (ffi_prep_args_SYSV): Avoid possible aliasing problems by using unions. + (ffi_prep_args64): Likewise. + 2005-09-30 Geoffrey Keating * testsuite/lib/libffi-dg.exp (libffi_target_compile): For diff --git a/libffi/Makefile.am b/libffi/Makefile.am index 89a2426..fb36e99 100644 --- a/libffi/Makefile.am +++ b/libffi/Makefile.am @@ -1,14 +1,15 @@ ## Process this with automake to create Makefile.in AUTOMAKE_OPTIONS = foreign subdir-objects -ACLOCAL_AMFLAGS = -I .. SUBDIRS = include testsuite -EXTRA_DIST = LICENSE ChangeLog.v1 \ +EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \ src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \ src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \ src/cris/ffi.c src/cris/sysv.S src/cris/ffitarget.h \ + src/ia64/ffi.c src/ia64/ffitarget.h src/ia64/ia64_flags.h \ + src/ia64/unix.S \ src/mips/ffi.c src/mips/n32.S src/mips/o32.S \ src/mips/ffitarget.h \ src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h \ @@ -24,9 +25,10 @@ EXTRA_DIST = LICENSE ChangeLog.v1 \ src/sh64/ffi.c src/sh64/sysv.S src/sh64/ffitarget.h \ src/sparc/v8.S src/sparc/v9.S src/sparc/ffitarget.h \ src/sparc/ffi.c \ - src/x86/ffi.c src/x86/sysv.S src/x86/win32.S \ + src/x86/ffi.c src/x86/sysv.S src/x86/win32.S src/x86/darwin.S \ src/x86/ffi64.c src/x86/unix64.S src/x86/ffitarget.h \ - src/pa/ffi.c src/pa/linux.S src/frv/eabi.S src/frv/ffitarget.h + src/pa/ffitarget.h src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S \ + src/frv/ffi.c src/frv/eabi.S src/frv/ffitarget.h ## ################################################################ @@ -77,22 +79,22 @@ toolexeclib_LTLIBRARIES = libffi.la noinst_LTLIBRARIES = libffi_convenience.la libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c \ - src/raw_api.c src/java_raw_api.c + src/raw_api.c src/java_raw_api.c src/closures.c nodist_libffi_la_SOURCES = -if MIPS_IRIX +if MIPS nodist_libffi_la_SOURCES += src/mips/ffi.c src/mips/o32.S src/mips/n32.S endif -if MIPS_LINUX -nodist_libffi_la_SOURCES += src/mips/ffi.c src/mips/o32.S -endif if X86 nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S endif if X86_WIN32 nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win32.S endif +if X86_DARWIN +nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S +endif if SPARC nodist_libffi_la_SOURCES += src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S endif @@ -141,9 +143,12 @@ endif if SH64 nodist_libffi_la_SOURCES += src/sh64/sysv.S src/sh64/ffi.c endif -if PA +if PA_LINUX nodist_libffi_la_SOURCES += src/pa/linux.S src/pa/ffi.c endif +if PA_HPUX +nodist_libffi_la_SOURCES += src/pa/hpux32.S src/pa/ffi.c +endif libffi_convenience_la_SOURCES = $(libffi_la_SOURCES) nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES) @@ -154,3 +159,9 @@ libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src AM_CCASFLAGS = $(AM_CPPFLAGS) + +# No install-html or install-pdf support in automake yet +.PHONY: install-html install-pdf +install-html: +install-pdf: + diff --git a/libffi/Makefile.in b/libffi/Makefile.in index 9af215a..2bfa906 100644 --- a/libffi/Makefile.in +++ b/libffi/Makefile.in @@ -33,10 +33,10 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -@MIPS_IRIX_TRUE@am__append_1 = src/mips/ffi.c src/mips/o32.S src/mips/n32.S -@MIPS_LINUX_TRUE@am__append_2 = src/mips/ffi.c src/mips/o32.S -@X86_TRUE@am__append_3 = src/x86/ffi.c src/x86/sysv.S -@X86_WIN32_TRUE@am__append_4 = src/x86/ffi.c src/x86/win32.S +@MIPS_TRUE@am__append_1 = src/mips/ffi.c src/mips/o32.S src/mips/n32.S +@X86_TRUE@am__append_2 = src/x86/ffi.c src/x86/sysv.S +@X86_WIN32_TRUE@am__append_3 = src/x86/ffi.c src/x86/win32.S +@X86_DARWIN_TRUE@am__append_4 = src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S @SPARC_TRUE@am__append_5 = src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S @ALPHA_TRUE@am__append_6 = src/alpha/ffi.c src/alpha/osf.S @IA64_TRUE@am__append_7 = src/ia64/ffi.c src/ia64/unix.S @@ -53,7 +53,8 @@ target_triplet = @target@ @X86_64_TRUE@am__append_18 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S @SH_TRUE@am__append_19 = src/sh/sysv.S src/sh/ffi.c @SH64_TRUE@am__append_20 = src/sh64/sysv.S src/sh64/ffi.c -@PA_TRUE@am__append_21 = src/pa/linux.S src/pa/ffi.c +@PA_LINUX_TRUE@am__append_21 = src/pa/linux.S src/pa/ffi.c +@PA_HPUX_TRUE@am__append_22 = src/pa/hpux32.S src/pa/ffi.c subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/fficonfig.h.in \ @@ -82,12 +83,13 @@ LTLIBRARIES = $(noinst_LTLIBRARIES) $(toolexeclib_LTLIBRARIES) libffi_la_LIBADD = am__dirstamp = $(am__leading_dot)dirstamp am_libffi_la_OBJECTS = src/debug.lo src/prep_cif.lo src/types.lo \ - src/raw_api.lo src/java_raw_api.lo -@MIPS_IRIX_TRUE@am__objects_1 = src/mips/ffi.lo src/mips/o32.lo \ -@MIPS_IRIX_TRUE@ src/mips/n32.lo -@MIPS_LINUX_TRUE@am__objects_2 = src/mips/ffi.lo src/mips/o32.lo -@X86_TRUE@am__objects_3 = src/x86/ffi.lo src/x86/sysv.lo -@X86_WIN32_TRUE@am__objects_4 = src/x86/ffi.lo src/x86/win32.lo + src/raw_api.lo src/java_raw_api.lo src/closures.lo +@MIPS_TRUE@am__objects_1 = src/mips/ffi.lo src/mips/o32.lo \ +@MIPS_TRUE@ src/mips/n32.lo +@X86_TRUE@am__objects_2 = src/x86/ffi.lo src/x86/sysv.lo +@X86_WIN32_TRUE@am__objects_3 = src/x86/ffi.lo src/x86/win32.lo +@X86_DARWIN_TRUE@am__objects_4 = src/x86/ffi.lo src/x86/darwin.lo \ +@X86_DARWIN_TRUE@ src/x86/ffi64.lo src/x86/darwin64.lo @SPARC_TRUE@am__objects_5 = src/sparc/ffi.lo src/sparc/v8.lo \ @SPARC_TRUE@ src/sparc/v9.lo @ALPHA_TRUE@am__objects_6 = src/alpha/ffi.lo src/alpha/osf.lo @@ -115,7 +117,8 @@ am_libffi_la_OBJECTS = src/debug.lo src/prep_cif.lo src/types.lo \ @X86_64_TRUE@ src/x86/ffi.lo src/x86/sysv.lo @SH_TRUE@am__objects_19 = src/sh/sysv.lo src/sh/ffi.lo @SH64_TRUE@am__objects_20 = src/sh64/sysv.lo src/sh64/ffi.lo -@PA_TRUE@am__objects_21 = src/pa/linux.lo src/pa/ffi.lo +@PA_LINUX_TRUE@am__objects_21 = src/pa/linux.lo src/pa/ffi.lo +@PA_HPUX_TRUE@am__objects_22 = src/pa/hpux32.lo src/pa/ffi.lo nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \ $(am__objects_3) $(am__objects_4) $(am__objects_5) \ $(am__objects_6) $(am__objects_7) $(am__objects_8) \ @@ -123,24 +126,25 @@ nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \ $(am__objects_12) $(am__objects_13) $(am__objects_14) \ $(am__objects_15) $(am__objects_16) $(am__objects_17) \ $(am__objects_18) $(am__objects_19) $(am__objects_20) \ - $(am__objects_21) + $(am__objects_21) $(am__objects_22) libffi_la_OBJECTS = $(am_libffi_la_OBJECTS) \ $(nodist_libffi_la_OBJECTS) libffi_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libffi_la_LDFLAGS) $(LDFLAGS) -o $@ libffi_convenience_la_LIBADD = -am__objects_22 = src/debug.lo src/prep_cif.lo src/types.lo \ - src/raw_api.lo src/java_raw_api.lo -am_libffi_convenience_la_OBJECTS = $(am__objects_22) -am__objects_23 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \ +am__objects_23 = src/debug.lo src/prep_cif.lo src/types.lo \ + src/raw_api.lo src/java_raw_api.lo src/closures.lo +am_libffi_convenience_la_OBJECTS = $(am__objects_23) +am__objects_24 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \ $(am__objects_4) $(am__objects_5) $(am__objects_6) \ $(am__objects_7) $(am__objects_8) $(am__objects_9) \ $(am__objects_10) $(am__objects_11) $(am__objects_12) \ $(am__objects_13) $(am__objects_14) $(am__objects_15) \ $(am__objects_16) $(am__objects_17) $(am__objects_18) \ - $(am__objects_19) $(am__objects_20) $(am__objects_21) -nodist_libffi_convenience_la_OBJECTS = $(am__objects_23) + $(am__objects_19) $(am__objects_20) $(am__objects_21) \ + $(am__objects_22) +nodist_libffi_convenience_la_OBJECTS = $(am__objects_24) libffi_convenience_la_OBJECTS = $(am_libffi_convenience_la_OBJECTS) \ $(nodist_libffi_convenience_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ @@ -309,12 +313,13 @@ toolexeclibdir = @toolexeclibdir@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign subdir-objects -ACLOCAL_AMFLAGS = -I .. SUBDIRS = include testsuite -EXTRA_DIST = LICENSE ChangeLog.v1 \ +EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \ src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \ src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \ src/cris/ffi.c src/cris/sysv.S src/cris/ffitarget.h \ + src/ia64/ffi.c src/ia64/ffitarget.h src/ia64/ia64_flags.h \ + src/ia64/unix.S \ src/mips/ffi.c src/mips/n32.S src/mips/o32.S \ src/mips/ffitarget.h \ src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h \ @@ -330,9 +335,10 @@ EXTRA_DIST = LICENSE ChangeLog.v1 \ src/sh64/ffi.c src/sh64/sysv.S src/sh64/ffitarget.h \ src/sparc/v8.S src/sparc/v9.S src/sparc/ffitarget.h \ src/sparc/ffi.c \ - src/x86/ffi.c src/x86/sysv.S src/x86/win32.S \ + src/x86/ffi.c src/x86/sysv.S src/x86/win32.S src/x86/darwin.S \ src/x86/ffi64.c src/x86/unix64.S src/x86/ffitarget.h \ - src/pa/ffi.c src/pa/linux.S src/frv/eabi.S src/frv/ffitarget.h + src/pa/ffitarget.h src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S \ + src/frv/ffi.c src/frv/eabi.S src/frv/ffitarget.h # Work around what appears to be a GNU make bug handling MAKEFLAGS @@ -376,7 +382,7 @@ MAKEOVERRIDES = toolexeclib_LTLIBRARIES = libffi.la noinst_LTLIBRARIES = libffi_convenience.la libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c \ - src/raw_api.c src/java_raw_api.c + src/raw_api.c src/java_raw_api.c src/closures.c nodist_libffi_la_SOURCES = $(am__append_1) $(am__append_2) \ $(am__append_3) $(am__append_4) $(am__append_5) \ @@ -385,7 +391,7 @@ nodist_libffi_la_SOURCES = $(am__append_1) $(am__append_2) \ $(am__append_12) $(am__append_13) $(am__append_14) \ $(am__append_15) $(am__append_16) $(am__append_17) \ $(am__append_18) $(am__append_19) $(am__append_20) \ - $(am__append_21) + $(am__append_21) $(am__append_22) libffi_convenience_la_SOURCES = $(libffi_la_SOURCES) nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES) AM_CFLAGS = -Wall -g -fexceptions @@ -494,6 +500,7 @@ src/prep_cif.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) src/types.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) src/raw_api.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) src/java_raw_api.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/closures.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) src/mips/$(am__dirstamp): @$(MKDIR_P) src/mips @: > src/mips/$(am__dirstamp) @@ -518,6 +525,12 @@ src/x86/sysv.lo: src/x86/$(am__dirstamp) \ src/x86/$(DEPDIR)/$(am__dirstamp) src/x86/win32.lo: src/x86/$(am__dirstamp) \ src/x86/$(DEPDIR)/$(am__dirstamp) +src/x86/darwin.lo: src/x86/$(am__dirstamp) \ + src/x86/$(DEPDIR)/$(am__dirstamp) +src/x86/ffi64.lo: src/x86/$(am__dirstamp) \ + src/x86/$(DEPDIR)/$(am__dirstamp) +src/x86/darwin64.lo: src/x86/$(am__dirstamp) \ + src/x86/$(DEPDIR)/$(am__dirstamp) src/sparc/$(am__dirstamp): @$(MKDIR_P) src/sparc @: > src/sparc/$(am__dirstamp) @@ -636,8 +649,6 @@ src/s390/sysv.lo: src/s390/$(am__dirstamp) \ src/s390/$(DEPDIR)/$(am__dirstamp) src/s390/ffi.lo: src/s390/$(am__dirstamp) \ src/s390/$(DEPDIR)/$(am__dirstamp) -src/x86/ffi64.lo: src/x86/$(am__dirstamp) \ - src/x86/$(DEPDIR)/$(am__dirstamp) src/x86/unix64.lo: src/x86/$(am__dirstamp) \ src/x86/$(DEPDIR)/$(am__dirstamp) src/sh/$(am__dirstamp): @@ -668,6 +679,8 @@ src/pa/$(DEPDIR)/$(am__dirstamp): src/pa/linux.lo: src/pa/$(am__dirstamp) \ src/pa/$(DEPDIR)/$(am__dirstamp) src/pa/ffi.lo: src/pa/$(am__dirstamp) src/pa/$(DEPDIR)/$(am__dirstamp) +src/pa/hpux32.lo: src/pa/$(am__dirstamp) \ + src/pa/$(DEPDIR)/$(am__dirstamp) libffi.la: $(libffi_la_OBJECTS) $(libffi_la_DEPENDENCIES) $(libffi_la_LINK) -rpath $(toolexeclibdir) $(libffi_la_OBJECTS) $(libffi_la_LIBADD) $(LIBS) libffi_convenience.la: $(libffi_convenience_la_OBJECTS) $(libffi_convenience_la_DEPENDENCIES) @@ -683,6 +696,8 @@ mostlyclean-compile: -rm -f src/arm/ffi.lo -rm -f src/arm/sysv.$(OBJEXT) -rm -f src/arm/sysv.lo + -rm -f src/closures.$(OBJEXT) + -rm -f src/closures.lo -rm -f src/cris/ffi.$(OBJEXT) -rm -f src/cris/ffi.lo -rm -f src/cris/sysv.$(OBJEXT) @@ -715,6 +730,8 @@ mostlyclean-compile: -rm -f src/mips/o32.lo -rm -f src/pa/ffi.$(OBJEXT) -rm -f src/pa/ffi.lo + -rm -f src/pa/hpux32.$(OBJEXT) + -rm -f src/pa/hpux32.lo -rm -f src/pa/linux.$(OBJEXT) -rm -f src/pa/linux.lo -rm -f src/powerpc/aix.$(OBJEXT) @@ -761,6 +778,10 @@ mostlyclean-compile: -rm -f src/sparc/v9.lo -rm -f src/types.$(OBJEXT) -rm -f src/types.lo + -rm -f src/x86/darwin.$(OBJEXT) + -rm -f src/x86/darwin.lo + -rm -f src/x86/darwin64.$(OBJEXT) + -rm -f src/x86/darwin64.lo -rm -f src/x86/ffi.$(OBJEXT) -rm -f src/x86/ffi.lo -rm -f src/x86/ffi64.$(OBJEXT) @@ -775,6 +796,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/closures.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/debug.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/java_raw_api.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/prep_cif.Plo@am__quote@ @@ -798,6 +820,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/mips/$(DEPDIR)/n32.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/mips/$(DEPDIR)/o32.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/ffi.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/hpux32.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/linux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/aix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/aix_closure.Plo@am__quote@ @@ -818,6 +841,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/sparc/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sparc/$(DEPDIR)/v8.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sparc/$(DEPDIR)/v9.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/darwin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/darwin64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/ffi64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/sysv.Plo@am__quote@ @@ -1262,14 +1287,10 @@ install-dvi: install-dvi-recursive install-exec-am: install-toolexeclibLTLIBRARIES -install-html: install-html-recursive - install-info: install-info-recursive install-man: -install-pdf: install-pdf-recursive - install-ps: install-ps-recursive installcheck-am: @@ -1318,6 +1339,11 @@ uninstall-am: uninstall-toolexeclibLTLIBRARIES pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ uninstall-toolexeclibLTLIBRARIES + +# No install-html or install-pdf support in automake yet +.PHONY: install-html install-pdf +install-html: +install-pdf: # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/libffi/README b/libffi/README index 1fc2747..f426c9d 100644 --- a/libffi/README +++ b/libffi/README @@ -212,7 +212,7 @@ Here is a trivial example that calls puts() a few times. int rc; /* Initialize the argument info vectors */ - args[0] = &ffi_type_uint; + args[0] = &ffi_type_pointer; values[0] = &s; /* Initialize the cif */ @@ -372,15 +372,6 @@ single-precision anyway. This causes one test to fail (the `many arguments' test). -What's With The Crazy Comments? -=============================== - -You might notice a number of cryptic comments in the code, delimited -by /*@ and @*/. These are annotations read by the program LCLint, a -tool for statically checking C programs. You can read all about it at -. - - History ======= diff --git a/libffi/configure b/libffi/configure index 3ad6e60..9fd638a 100755 --- a/libffi/configure +++ b/libffi/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.61 for libffi 2.1. +# Generated by GNU Autoconf 2.61 for libffi 3.0. # # Report bugs to . # @@ -728,8 +728,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='libffi' PACKAGE_TARNAME='libffi' -PACKAGE_VERSION='2.1' -PACKAGE_STRING='libffi 2.1' +PACKAGE_VERSION='3.0' +PACKAGE_STRING='libffi 3.0' PACKAGE_BUGREPORT='http://gcc.gnu.org/bugs.html' # Factoring default headers for most tests. @@ -885,16 +885,16 @@ MAINT TESTSUBDIR_TRUE TESTSUBDIR_FALSE AM_RUNTESTFLAGS -MIPS_IRIX_TRUE -MIPS_IRIX_FALSE -MIPS_LINUX_TRUE -MIPS_LINUX_FALSE +MIPS_TRUE +MIPS_FALSE SPARC_TRUE SPARC_FALSE X86_TRUE X86_FALSE X86_WIN32_TRUE X86_WIN32_FALSE +X86_DARWIN_TRUE +X86_DARWIN_FALSE ALPHA_TRUE ALPHA_FALSE IA64_TRUE @@ -925,8 +925,12 @@ SH_TRUE SH_FALSE SH64_TRUE SH64_FALSE -PA_TRUE -PA_FALSE +PA_LINUX_TRUE +PA_LINUX_FALSE +PA_HPUX_TRUE +PA_HPUX_FALSE +PA64_HPUX_TRUE +PA64_HPUX_FALSE ALLOCA HAVE_LONG_DOUBLE TARGET @@ -1453,7 +1457,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libffi 2.1 to adapt to many kinds of systems. +\`configure' configures libffi 3.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1524,7 +1528,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libffi 2.1:";; + short | recursive ) echo "Configuration of libffi 3.0:";; esac cat <<\_ACEOF @@ -1634,7 +1638,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libffi configure 2.1 +libffi configure 3.0 generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1648,7 +1652,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libffi $as_me 2.1, which was +It was created by libffi $as_me 3.0, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ @@ -2471,7 +2475,7 @@ fi # Define the identity of the package. PACKAGE='libffi' - VERSION='2.1' + VERSION='3.0' cat >>confdefs.h <<_ACEOF @@ -4684,7 +4688,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 4687 "configure"' > conftest.$ac_ext + echo '#line 4691 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -7427,11 +7431,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7430: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7434: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7434: \$? = $ac_status" >&5 + echo "$as_me:7438: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7717,11 +7721,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7720: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7724: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7724: \$? = $ac_status" >&5 + echo "$as_me:7728: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7821,11 +7825,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7824: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7828: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7828: \$? = $ac_status" >&5 + echo "$as_me:7832: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -10172,7 +10176,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:12699: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:12699: \$? = $ac_status" >&5 + echo "$as_me:12703: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -12796,11 +12800,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12799: $lt_compile\"" >&5) + (eval echo "\"\$as_me:12803: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:12803: \$? = $ac_status" >&5 + echo "$as_me:12807: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -14360,11 +14364,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14363: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14367: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14367: \$? = $ac_status" >&5 + echo "$as_me:14371: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -14464,11 +14468,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14467: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14471: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14471: \$? = $ac_status" >&5 + echo "$as_me:14475: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -16653,11 +16657,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16656: $lt_compile\"" >&5) + (eval echo "\"\$as_me:16660: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:16660: \$? = $ac_status" >&5 + echo "$as_me:16664: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -16943,11 +16947,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16946: $lt_compile\"" >&5) + (eval echo "\"\$as_me:16950: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:16950: \$? = $ac_status" >&5 + echo "$as_me:16954: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -17047,11 +17051,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:17050: $lt_compile\"" >&5) + (eval echo "\"\$as_me:17054: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:17054: \$? = $ac_status" >&5 + echo "$as_me:17058: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -20356,48 +20360,108 @@ fi TARGETDIR="unknown" case "$host" in -i*86-*-linux*) TARGET=X86; TARGETDIR=x86;; -i*86-*-gnu*) TARGET=X86; TARGETDIR=x86;; -i*86-*-solaris2.1[0-9]*) TARGET=X86_64; TARGETDIR=x86;; -i*86-*-solaris*) TARGET=X86; TARGETDIR=x86;; -i*86-*-beos*) TARGET=X86; TARGETDIR=x86;; -i*86-*-freebsd* | i*86-*-kfreebsd*-gnu) TARGET=X86; TARGETDIR=x86;; -i*86-*-netbsdelf* | i*86-*-knetbsd*-gnu) TARGET=X86; TARGETDIR=x86;; -i*86-*-rtems*) TARGET=X86; TARGETDIR=x86;; -i*86-*-win32*) TARGET=X86_WIN32; TARGETDIR=x86;; -i*86-*-cygwin*) TARGET=X86_WIN32; TARGETDIR=x86;; -i*86-*-mingw*) TARGET=X86_WIN32; TARGETDIR=x86;; -frv-*-*) TARGET=FRV; TARGETDIR=frv;; -sparc-sun-4*) TARGET=SPARC; TARGETDIR=sparc;; -sparc*-sun-*) TARGET=SPARC; TARGETDIR=sparc;; -sparc-*-linux* | sparc-*-netbsdelf* | sparc-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;; -sparc*-*-rtems*) TARGET=SPARC; TARGETDIR=sparc;; -sparc64-*-linux* | sparc64-*-netbsd* | sparc64-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;; -alpha*-*-linux* | alpha*-*-osf* | alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu | alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu) TARGET=ALPHA; TARGETDIR=alpha;; -ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;; -m32r*-*-linux* ) TARGET=M32R; TARGETDIR=m32r;; -m68k-*-linux*) TARGET=M68K; TARGETDIR=m68k;; -mips64*-*);; -mips-sgi-irix5.* | mips-sgi-irix6.*) TARGET=MIPS_IRIX; TARGETDIR=mips;; -mips*-*-linux*) TARGET=MIPS_LINUX; TARGETDIR=mips;; -powerpc*-*-linux* | powerpc-*-sysv*) TARGET=POWERPC; TARGETDIR=powerpc;; -powerpc-*-beos*) TARGET=POWERPC; TARGETDIR=powerpc;; -powerpc-*-darwin*) TARGET=POWERPC_DARWIN; TARGETDIR=powerpc;; -powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; -powerpc-*-freebsd*) TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc;; -powerpc*-*-rtems*) TARGET=POWERPC; TARGETDIR=powerpc;; -rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; -arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;; -arm*-*-netbsdelf* | arm*-*-knetbsd*-gnu) TARGET=ARM; TARGETDIR=arm;; -arm*-*-rtems*) TARGET=ARM; TARGETDIR=arm;; -cris-*-*) TARGET=LIBFFI_CRIS; TARGETDIR=cris;; -s390-*-linux-*) TARGET=S390; TARGETDIR=s390;; -s390x-*-linux-*) TARGET=S390; TARGETDIR=s390;; -x86_64-*-linux* | x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) TARGET=X86_64; TARGETDIR=x86;; -sh-*-linux* | sh[34]*-*-linux*) TARGET=SH; TARGETDIR=sh;; -sh-*-rtems*) TARGET=SH; TARGETDIR=sh;; -sh64-*-linux* | sh5*-*-linux*) TARGET=SH64; TARGETDIR=sh64;; -hppa-*-linux* | parisc-*-linux*) TARGET=PA; TARGETDIR=pa;; + alpha*-*-*) + TARGET=ALPHA; TARGETDIR=alpha; + # Support 128-bit long double, changable via command-line switch. + HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)' + ;; + + arm*-*-*) + TARGET=ARM; TARGETDIR=arm + ;; + + cris-*-*) + TARGET=LIBFFI_CRIS; TARGETDIR=cris + ;; + + frv-*-*) + TARGET=FRV; TARGETDIR=frv + ;; + + hppa*-*-linux* | parisc*-*-linux*) + TARGET=PA_LINUX; TARGETDIR=pa + ;; + hppa*64-*-hpux*) + TARGET=PA64_HPUX; TARGETDIR=pa + ;; + hppa*-*-hpux*) + TARGET=PA_HPUX; TARGETDIR=pa + ;; + + i?86-win32* | i?86-*-cygwin* | i?86-*-mingw*) + TARGET=X86_WIN32; TARGETDIR=x86 + ;; + i?86-*-darwin*) + TARGET=X86_DARWIN; TARGETDIR=x86 + ;; + i?86-*-solaris2.1[0-9]*) + TARGET=X86_64; TARGETDIR=x86 + ;; + i?86-*-*) + TARGET=X86; TARGETDIR=x86 + ;; + + ia64*-*-*) + TARGET=IA64; TARGETDIR=ia64 + ;; + + m32r*-*-*) + TARGET=M32R; TARGETDIR=m32r + ;; + + m68k-*-*) + TARGET=M68K; TARGETDIR=m68k + ;; + + mips-sgi-irix5.* | mips-sgi-irix6.*) + TARGET=MIPS; TARGETDIR=mips + ;; + mips*-*-linux*) + TARGET=MIPS; TARGETDIR=mips + ;; + + powerpc*-*-linux* | powerpc-*-sysv*) + TARGET=POWERPC; TARGETDIR=powerpc + ;; + powerpc-*-beos*) + TARGET=POWERPC; TARGETDIR=powerpc + ;; + powerpc-*-darwin*) + TARGET=POWERPC_DARWIN; TARGETDIR=powerpc + ;; + powerpc-*-aix* | rs6000-*-aix*) + TARGET=POWERPC_AIX; TARGETDIR=powerpc + ;; + powerpc-*-freebsd*) + TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc + ;; + powerpc*-*-rtems*) + TARGET=POWERPC; TARGETDIR=powerpc + ;; + + s390-*-* | s390x-*-*) + TARGET=S390; TARGETDIR=s390 + ;; + + sh-*-* | sh[34]*-*-*) + TARGET=SH; TARGETDIR=sh + ;; + sh64-*-* | sh5*-*-*) + TARGET=SH64; TARGETDIR=sh64 + ;; + + sparc*-*-*) + TARGET=SPARC; TARGETDIR=sparc + ;; + + x86_64-*-darwin*) + TARGET=X86_DARWIN; TARGETDIR=x86 + ;; + x86_64-*-cygwin* | x86_64-*-mingw*) + ;; + x86_64-*-*) + TARGET=X86_64; TARGETDIR=x86 + ;; esac @@ -20408,20 +20472,12 @@ echo "$as_me: error: \"libffi has not been ported to $host.\"" >&2;} { (exit 1); exit 1; }; } fi - if test x$TARGET = xMIPS_IRIX; then - MIPS_IRIX_TRUE= - MIPS_IRIX_FALSE='#' -else - MIPS_IRIX_TRUE='#' - MIPS_IRIX_FALSE= -fi - - if test x$TARGET = xMIPS_LINUX; then - MIPS_LINUX_TRUE= - MIPS_LINUX_FALSE='#' + if test x$TARGET = xMIPS; then + MIPS_TRUE= + MIPS_FALSE='#' else - MIPS_LINUX_TRUE='#' - MIPS_LINUX_FALSE= + MIPS_TRUE='#' + MIPS_FALSE= fi if test x$TARGET = xSPARC; then @@ -20448,6 +20504,14 @@ else X86_WIN32_FALSE= fi + if test x$TARGET = xX86_DARWIN; then + X86_DARWIN_TRUE= + X86_DARWIN_FALSE='#' +else + X86_DARWIN_TRUE='#' + X86_DARWIN_FALSE= +fi + if test x$TARGET = xALPHA; then ALPHA_TRUE= ALPHA_FALSE='#' @@ -20568,19 +20632,30 @@ else SH64_FALSE= fi - if test x$TARGET = xPA; then - PA_TRUE= - PA_FALSE='#' + if test x$TARGET = xPA_LINUX; then + PA_LINUX_TRUE= + PA_LINUX_FALSE='#' else - PA_TRUE='#' - PA_FALSE= + PA_LINUX_TRUE='#' + PA_LINUX_FALSE= fi + if test x$TARGET = xPA_HPUX; then + PA_HPUX_TRUE= + PA_HPUX_FALSE='#' +else + PA_HPUX_TRUE='#' + PA_HPUX_FALSE= +fi + + if test x$TARGET = xPA64_HPUX; then + PA64_HPUX_TRUE= + PA64_HPUX_FALSE='#' +else + PA64_HPUX_TRUE='#' + PA64_HPUX_FALSE= +fi -case x$TARGET in - xMIPS*) TARGET=MIPS ;; - *) ;; -esac { echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } @@ -22022,15 +22097,17 @@ _ACEOF # Also AC_SUBST this variable for ffi.h. -HAVE_LONG_DOUBLE=0 -if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then - if test $ac_cv_sizeof_long_double != 0; then - HAVE_LONG_DOUBLE=1 +if test -z "$HAVE_LONG_DOUBLE"; then + HAVE_LONG_DOUBLE=0 + if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then + if test $ac_cv_sizeof_long_double != 0; then + HAVE_LONG_DOUBLE=1 cat >>confdefs.h <<\_ACEOF #define HAVE_LONG_DOUBLE 1 _ACEOF + fi fi fi @@ -22272,6 +22349,66 @@ presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} esac +{ echo "$as_me:$LINENO: checking assembler .cfi pseudo-op support" >&5 +echo $ECHO_N "checking assembler .cfi pseudo-op support... $ECHO_C" >&6; } +if test "${libffi_cv_as_cfi_pseudo_op+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + libffi_cv_as_cfi_pseudo_op=unknown + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +asm (".cfi_startproc\n\t.cfi_endproc"); +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + libffi_cv_as_cfi_pseudo_op=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + libffi_cv_as_cfi_pseudo_op=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ echo "$as_me:$LINENO: result: $libffi_cv_as_cfi_pseudo_op" >&5 +echo "${ECHO_T}$libffi_cv_as_cfi_pseudo_op" >&6; } +if test "x$libffi_cv_as_cfi_pseudo_op" = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_AS_CFI_PSEUDO_OP 1 +_ACEOF + +fi + if test x$TARGET = xSPARC; then { echo "$as_me:$LINENO: checking assembler and linker support unaligned pc related relocs" >&5 echo $ECHO_N "checking assembler and linker support unaligned pc related relocs... $ECHO_C" >&6; } @@ -22699,17 +22836,10 @@ echo "$as_me: error: conditional \"TESTSUBDIR\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi -if test -z "${MIPS_IRIX_TRUE}" && test -z "${MIPS_IRIX_FALSE}"; then - { { echo "$as_me:$LINENO: error: conditional \"MIPS_IRIX\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -echo "$as_me: error: conditional \"MIPS_IRIX\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi -if test -z "${MIPS_LINUX_TRUE}" && test -z "${MIPS_LINUX_FALSE}"; then - { { echo "$as_me:$LINENO: error: conditional \"MIPS_LINUX\" was never defined. +if test -z "${MIPS_TRUE}" && test -z "${MIPS_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"MIPS\" was never defined. Usually this means the macro was only invoked conditionally." >&5 -echo "$as_me: error: conditional \"MIPS_LINUX\" was never defined. +echo "$as_me: error: conditional \"MIPS\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi @@ -22734,6 +22864,13 @@ echo "$as_me: error: conditional \"X86_WIN32\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi +if test -z "${X86_DARWIN_TRUE}" && test -z "${X86_DARWIN_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"X86_DARWIN\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"X86_DARWIN\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi if test -z "${ALPHA_TRUE}" && test -z "${ALPHA_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"ALPHA\" was never defined. Usually this means the macro was only invoked conditionally." >&5 @@ -22839,10 +22976,24 @@ echo "$as_me: error: conditional \"SH64\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi -if test -z "${PA_TRUE}" && test -z "${PA_FALSE}"; then - { { echo "$as_me:$LINENO: error: conditional \"PA\" was never defined. +if test -z "${PA_LINUX_TRUE}" && test -z "${PA_LINUX_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"PA_LINUX\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"PA_LINUX\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${PA_HPUX_TRUE}" && test -z "${PA_HPUX_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"PA_HPUX\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"PA_HPUX\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${PA64_HPUX_TRUE}" && test -z "${PA64_HPUX_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"PA64_HPUX\" was never defined. Usually this means the macro was only invoked conditionally." >&5 -echo "$as_me: error: conditional \"PA\" was never defined. +echo "$as_me: error: conditional \"PA64_HPUX\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi @@ -23146,7 +23297,7 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libffi $as_me 2.1, which was +This file was extended by libffi $as_me 3.0, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -23203,7 +23354,7 @@ Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -libffi config.status 2.1 +libffi config.status 3.0 configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" @@ -23548,16 +23699,16 @@ MAINT!$MAINT$ac_delim TESTSUBDIR_TRUE!$TESTSUBDIR_TRUE$ac_delim TESTSUBDIR_FALSE!$TESTSUBDIR_FALSE$ac_delim AM_RUNTESTFLAGS!$AM_RUNTESTFLAGS$ac_delim -MIPS_IRIX_TRUE!$MIPS_IRIX_TRUE$ac_delim -MIPS_IRIX_FALSE!$MIPS_IRIX_FALSE$ac_delim -MIPS_LINUX_TRUE!$MIPS_LINUX_TRUE$ac_delim -MIPS_LINUX_FALSE!$MIPS_LINUX_FALSE$ac_delim +MIPS_TRUE!$MIPS_TRUE$ac_delim +MIPS_FALSE!$MIPS_FALSE$ac_delim SPARC_TRUE!$SPARC_TRUE$ac_delim SPARC_FALSE!$SPARC_FALSE$ac_delim X86_TRUE!$X86_TRUE$ac_delim X86_FALSE!$X86_FALSE$ac_delim X86_WIN32_TRUE!$X86_WIN32_TRUE$ac_delim X86_WIN32_FALSE!$X86_WIN32_FALSE$ac_delim +X86_DARWIN_TRUE!$X86_DARWIN_TRUE$ac_delim +X86_DARWIN_FALSE!$X86_DARWIN_FALSE$ac_delim ALPHA_TRUE!$ALPHA_TRUE$ac_delim ALPHA_FALSE!$ALPHA_FALSE$ac_delim IA64_TRUE!$IA64_TRUE$ac_delim @@ -23588,8 +23739,12 @@ SH_TRUE!$SH_TRUE$ac_delim SH_FALSE!$SH_FALSE$ac_delim SH64_TRUE!$SH64_TRUE$ac_delim SH64_FALSE!$SH64_FALSE$ac_delim -PA_TRUE!$PA_TRUE$ac_delim -PA_FALSE!$PA_FALSE$ac_delim +PA_LINUX_TRUE!$PA_LINUX_TRUE$ac_delim +PA_LINUX_FALSE!$PA_LINUX_FALSE$ac_delim +PA_HPUX_TRUE!$PA_HPUX_TRUE$ac_delim +PA_HPUX_FALSE!$PA_HPUX_FALSE$ac_delim +PA64_HPUX_TRUE!$PA64_HPUX_TRUE$ac_delim +PA64_HPUX_FALSE!$PA64_HPUX_FALSE$ac_delim ALLOCA!$ALLOCA$ac_delim HAVE_LONG_DOUBLE!$HAVE_LONG_DOUBLE$ac_delim TARGET!$TARGET$ac_delim @@ -23600,7 +23755,7 @@ LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 70; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 74; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 diff --git a/libffi/configure.ac b/libffi/configure.ac index 86f45c7..7c9713d 100644 --- a/libffi/configure.ac +++ b/libffi/configure.ac @@ -2,7 +2,7 @@ dnl Process this with autoconf to create configure AC_PREREQ(2.59) -AC_INIT([libffi], [2.1], [http://gcc.gnu.org/bugs.html]) +AC_INIT([libffi], [3.0], [http://gcc.gnu.org/bugs.html]) AC_CONFIG_HEADERS([fficonfig.h]) AC_CANONICAL_SYSTEM @@ -39,48 +39,108 @@ AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite) TARGETDIR="unknown" case "$host" in -i*86-*-linux*) TARGET=X86; TARGETDIR=x86;; -i*86-*-gnu*) TARGET=X86; TARGETDIR=x86;; -i*86-*-solaris2.1[[0-9]]*) TARGET=X86_64; TARGETDIR=x86;; -i*86-*-solaris*) TARGET=X86; TARGETDIR=x86;; -i*86-*-beos*) TARGET=X86; TARGETDIR=x86;; -i*86-*-freebsd* | i*86-*-kfreebsd*-gnu) TARGET=X86; TARGETDIR=x86;; -i*86-*-netbsdelf* | i*86-*-knetbsd*-gnu) TARGET=X86; TARGETDIR=x86;; -i*86-*-rtems*) TARGET=X86; TARGETDIR=x86;; -i*86-*-win32*) TARGET=X86_WIN32; TARGETDIR=x86;; -i*86-*-cygwin*) TARGET=X86_WIN32; TARGETDIR=x86;; -i*86-*-mingw*) TARGET=X86_WIN32; TARGETDIR=x86;; -frv-*-*) TARGET=FRV; TARGETDIR=frv;; -sparc-sun-4*) TARGET=SPARC; TARGETDIR=sparc;; -sparc*-sun-*) TARGET=SPARC; TARGETDIR=sparc;; -sparc-*-linux* | sparc-*-netbsdelf* | sparc-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;; -sparc*-*-rtems*) TARGET=SPARC; TARGETDIR=sparc;; -sparc64-*-linux* | sparc64-*-netbsd* | sparc64-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;; -alpha*-*-linux* | alpha*-*-osf* | alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu | alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu) TARGET=ALPHA; TARGETDIR=alpha;; -ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;; -m32r*-*-linux* ) TARGET=M32R; TARGETDIR=m32r;; -m68k-*-linux*) TARGET=M68K; TARGETDIR=m68k;; -mips64*-*);; -mips-sgi-irix5.* | mips-sgi-irix6.*) TARGET=MIPS_IRIX; TARGETDIR=mips;; -mips*-*-linux*) TARGET=MIPS_LINUX; TARGETDIR=mips;; -powerpc*-*-linux* | powerpc-*-sysv*) TARGET=POWERPC; TARGETDIR=powerpc;; -powerpc-*-beos*) TARGET=POWERPC; TARGETDIR=powerpc;; -powerpc-*-darwin*) TARGET=POWERPC_DARWIN; TARGETDIR=powerpc;; -powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; -powerpc-*-freebsd*) TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc;; -powerpc*-*-rtems*) TARGET=POWERPC; TARGETDIR=powerpc;; -rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; -arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;; -arm*-*-netbsdelf* | arm*-*-knetbsd*-gnu) TARGET=ARM; TARGETDIR=arm;; -arm*-*-rtems*) TARGET=ARM; TARGETDIR=arm;; -cris-*-*) TARGET=LIBFFI_CRIS; TARGETDIR=cris;; -s390-*-linux-*) TARGET=S390; TARGETDIR=s390;; -s390x-*-linux-*) TARGET=S390; TARGETDIR=s390;; -x86_64-*-linux* | x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) TARGET=X86_64; TARGETDIR=x86;; -sh-*-linux* | sh[[34]]*-*-linux*) TARGET=SH; TARGETDIR=sh;; -sh-*-rtems*) TARGET=SH; TARGETDIR=sh;; -sh64-*-linux* | sh5*-*-linux*) TARGET=SH64; TARGETDIR=sh64;; -hppa-*-linux* | parisc-*-linux*) TARGET=PA; TARGETDIR=pa;; + alpha*-*-*) + TARGET=ALPHA; TARGETDIR=alpha; + # Support 128-bit long double, changable via command-line switch. + HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)' + ;; + + arm*-*-*) + TARGET=ARM; TARGETDIR=arm + ;; + + cris-*-*) + TARGET=LIBFFI_CRIS; TARGETDIR=cris + ;; + + frv-*-*) + TARGET=FRV; TARGETDIR=frv + ;; + + hppa*-*-linux* | parisc*-*-linux*) + TARGET=PA_LINUX; TARGETDIR=pa + ;; + hppa*64-*-hpux*) + TARGET=PA64_HPUX; TARGETDIR=pa + ;; + hppa*-*-hpux*) + TARGET=PA_HPUX; TARGETDIR=pa + ;; + + i?86-win32* | i?86-*-cygwin* | i?86-*-mingw*) + TARGET=X86_WIN32; TARGETDIR=x86 + ;; + i?86-*-darwin*) + TARGET=X86_DARWIN; TARGETDIR=x86 + ;; + i?86-*-solaris2.1[[0-9]]*) + TARGET=X86_64; TARGETDIR=x86 + ;; + i?86-*-*) + TARGET=X86; TARGETDIR=x86 + ;; + + ia64*-*-*) + TARGET=IA64; TARGETDIR=ia64 + ;; + + m32r*-*-*) + TARGET=M32R; TARGETDIR=m32r + ;; + + m68k-*-*) + TARGET=M68K; TARGETDIR=m68k + ;; + + mips-sgi-irix5.* | mips-sgi-irix6.*) + TARGET=MIPS; TARGETDIR=mips + ;; + mips*-*-linux*) + TARGET=MIPS; TARGETDIR=mips + ;; + + powerpc*-*-linux* | powerpc-*-sysv*) + TARGET=POWERPC; TARGETDIR=powerpc + ;; + powerpc-*-beos*) + TARGET=POWERPC; TARGETDIR=powerpc + ;; + powerpc-*-darwin*) + TARGET=POWERPC_DARWIN; TARGETDIR=powerpc + ;; + powerpc-*-aix* | rs6000-*-aix*) + TARGET=POWERPC_AIX; TARGETDIR=powerpc + ;; + powerpc-*-freebsd*) + TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc + ;; + powerpc*-*-rtems*) + TARGET=POWERPC; TARGETDIR=powerpc + ;; + + s390-*-* | s390x-*-*) + TARGET=S390; TARGETDIR=s390 + ;; + + sh-*-* | sh[[34]]*-*-*) + TARGET=SH; TARGETDIR=sh + ;; + sh64-*-* | sh5*-*-*) + TARGET=SH64; TARGETDIR=sh64 + ;; + + sparc*-*-*) + TARGET=SPARC; TARGETDIR=sparc + ;; + + x86_64-*-darwin*) + TARGET=X86_DARWIN; TARGETDIR=x86 + ;; + x86_64-*-cygwin* | x86_64-*-mingw*) + ;; + x86_64-*-*) + TARGET=X86_64; TARGETDIR=x86 + ;; esac AC_SUBST(AM_RUNTESTFLAGS) @@ -89,11 +149,11 @@ if test $TARGETDIR = unknown; then AC_MSG_ERROR(["libffi has not been ported to $host."]) fi -AM_CONDITIONAL(MIPS_IRIX, test x$TARGET = xMIPS_IRIX) -AM_CONDITIONAL(MIPS_LINUX, test x$TARGET = xMIPS_LINUX) +AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS) AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC) AM_CONDITIONAL(X86, test x$TARGET = xX86) AM_CONDITIONAL(X86_WIN32, test x$TARGET = xX86_WIN32) +AM_CONDITIONAL(X86_DARWIN, test x$TARGET = xX86_DARWIN) AM_CONDITIONAL(ALPHA, test x$TARGET = xALPHA) AM_CONDITIONAL(IA64, test x$TARGET = xIA64) AM_CONDITIONAL(M32R, test x$TARGET = xM32R) @@ -109,12 +169,9 @@ AM_CONDITIONAL(S390, test x$TARGET = xS390) AM_CONDITIONAL(X86_64, test x$TARGET = xX86_64) AM_CONDITIONAL(SH, test x$TARGET = xSH) AM_CONDITIONAL(SH64, test x$TARGET = xSH64) -AM_CONDITIONAL(PA, test x$TARGET = xPA) - -case x$TARGET in - xMIPS*) TARGET=MIPS ;; - *) ;; -esac +AM_CONDITIONAL(PA_LINUX, test x$TARGET = xPA_LINUX) +AM_CONDITIONAL(PA_HPUX, test x$TARGET = xPA_HPUX) +AM_CONDITIONAL(PA64_HPUX, test x$TARGET = xPA64_HPUX) AC_HEADER_STDC AC_CHECK_FUNCS(memcpy) @@ -124,17 +181,31 @@ AC_CHECK_SIZEOF(double) AC_CHECK_SIZEOF(long double) # Also AC_SUBST this variable for ffi.h. -HAVE_LONG_DOUBLE=0 -if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then - if test $ac_cv_sizeof_long_double != 0; then - HAVE_LONG_DOUBLE=1 - AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the long double type and it is bigger than a double]) +if test -z "$HAVE_LONG_DOUBLE"; then + HAVE_LONG_DOUBLE=0 + if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then + if test $ac_cv_sizeof_long_double != 0; then + HAVE_LONG_DOUBLE=1 + AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the long double type and it is bigger than a double]) + fi fi fi AC_SUBST(HAVE_LONG_DOUBLE) AC_C_BIGENDIAN +AC_CACHE_CHECK([assembler .cfi pseudo-op support], + libffi_cv_as_cfi_pseudo_op, [ + libffi_cv_as_cfi_pseudo_op=unknown + AC_TRY_COMPILE([asm (".cfi_startproc\n\t.cfi_endproc");],, + [libffi_cv_as_cfi_pseudo_op=yes], + [libffi_cv_as_cfi_pseudo_op=no]) +]) +if test "x$libffi_cv_as_cfi_pseudo_op" = xyes; then + AC_DEFINE(HAVE_AS_CFI_PSEUDO_OP, 1, + [Define if your assembler supports .cfi_* directives.]) +fi + if test x$TARGET = xSPARC; then AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs], libffi_cv_as_sparc_ua_pcrel, [ diff --git a/libffi/fficonfig.h.in b/libffi/fficonfig.h.in index bcd59db..e93cf8a 100644 --- a/libffi/fficonfig.h.in +++ b/libffi/fficonfig.h.in @@ -27,6 +27,9 @@ */ #undef HAVE_ALLOCA_H +/* Define if your assembler supports .cfi_* directives. */ +#undef HAVE_AS_CFI_PSEUDO_OP + /* Define if your assembler supports .register. */ #undef HAVE_AS_REGISTER_PSEUDO_OP @@ -91,6 +94,10 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + /* Define to 1 if your C compiler doesn't accept -c and -o together. */ #undef NO_MINUS_C_MINUS_O @@ -112,15 +119,15 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION -/* The size of `double', as computed by sizeof. */ +/* The size of a `double', as computed by sizeof. */ #undef SIZEOF_DOUBLE -/* The size of `long double', as computed by sizeof. */ +/* The size of a `long double', as computed by sizeof. */ #undef SIZEOF_LONG_DOUBLE /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be - automatically deduced at runtime. + automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ diff --git a/libffi/include/Makefile.am b/libffi/include/Makefile.am index 6ccfb13..d8c36b5 100644 --- a/libffi/include/Makefile.am +++ b/libffi/include/Makefile.am @@ -5,12 +5,4 @@ AUTOMAKE_OPTIONS=foreign DISTCLEANFILES=ffitarget.h EXTRA_DIST=ffi.h.in ffi_common.h -hackdir=$(includedir) - -hack_DATA= ffi.h ffitarget.h - -# Where generated headers like ffitarget.h get installed. -# gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER) -# Uncomment these when libffi is part of the GCC tree. -# toollibffidir := $(libdir)/gcc/$(target_alias)/$(gcc_version)/include/libffi -# toollibffi_HEADERS = ffitarget.h +HEADERS = ffi.h ffitarget.h diff --git a/libffi/include/Makefile.in b/libffi/include/Makefile.in index ddcd521..4cc1186 100644 --- a/libffi/include/Makefile.in +++ b/libffi/include/Makefile.in @@ -35,7 +35,7 @@ host_triplet = @host@ target_triplet = @target@ subdir = include DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(srcdir)/ffi.h.in + $(srcdir)/ffi.h.in $(toollibffi_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac @@ -52,9 +52,11 @@ am__vpath_adj = case $$p in \ *) f=$$p;; \ esac; am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; -am__installdirs = "$(DESTDIR)$(hackdir)" -hackDATA_INSTALL = $(INSTALL_DATA) -DATA = $(hack_DATA) +am__installdirs = "$(DESTDIR)$(toollibffidir)" +toollibffiHEADERS_INSTALL = $(INSTALL_HEADER) +HEADERS = $(toollibffi_HEADERS) +ETAGS = etags +CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ @@ -180,8 +182,11 @@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign DISTCLEANFILES = ffitarget.h EXTRA_DIST = ffi.h.in ffi_common.h -hackdir = $(includedir) -hack_DATA = ffi.h ffitarget.h + +# Where generated headers like ffitarget.h get installed. +gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER) +toollibffidir := $(libdir)/gcc/$(target_alias)/$(gcc_version)/include +toollibffi_HEADERS = ffi.h ffitarget.h all: all-am .SUFFIXES: @@ -222,29 +227,71 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs -install-hackDATA: $(hack_DATA) +install-toollibffiHEADERS: $(toollibffi_HEADERS) @$(NORMAL_INSTALL) - test -z "$(hackdir)" || $(MKDIR_P) "$(DESTDIR)$(hackdir)" - @list='$(hack_DATA)'; for p in $$list; do \ + test -z "$(toollibffidir)" || $(MKDIR_P) "$(DESTDIR)$(toollibffidir)" + @list='$(toollibffi_HEADERS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ - echo " $(hackDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(hackdir)/$$f'"; \ - $(hackDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(hackdir)/$$f"; \ + echo " $(toollibffiHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(toollibffidir)/$$f'"; \ + $(toollibffiHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(toollibffidir)/$$f"; \ done -uninstall-hackDATA: +uninstall-toollibffiHEADERS: @$(NORMAL_UNINSTALL) - @list='$(hack_DATA)'; for p in $$list; do \ + @list='$(toollibffi_HEADERS)'; for p in $$list; do \ f=$(am__strip_dir) \ - echo " rm -f '$(DESTDIR)$(hackdir)/$$f'"; \ - rm -f "$(DESTDIR)$(hackdir)/$$f"; \ + echo " rm -f '$(DESTDIR)$(toollibffidir)/$$f'"; \ + rm -f "$(DESTDIR)$(toollibffidir)/$$f"; \ done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique tags: TAGS -TAGS: +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi ctags: CTAGS -CTAGS: - +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -274,9 +321,9 @@ distdir: $(DISTFILES) done check-am: all-am check: check-am -all-am: Makefile $(DATA) +all-am: Makefile $(HEADERS) installdirs: - for dir in "$(DESTDIR)$(hackdir)"; do \ + for dir in "$(DESTDIR)$(toollibffidir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -310,7 +357,7 @@ clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile -distclean-am: clean-am distclean-generic +distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-am @@ -322,7 +369,7 @@ info: info-am info-am: -install-data-am: install-hackDATA +install-data-am: install-toollibffiHEADERS install-dvi: install-dvi-am @@ -356,28 +403,24 @@ ps: ps-am ps-am: -uninstall-am: uninstall-hackDATA +uninstall-am: uninstall-toollibffiHEADERS .MAKE: install-am install-strip -.PHONY: all all-am check check-am clean clean-generic clean-libtool \ - distclean distclean-generic distclean-libtool distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-hackDATA install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - uninstall uninstall-am uninstall-hackDATA - +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool ctags distclean distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip \ + install-toollibffiHEADERS installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags uninstall uninstall-am \ + uninstall-toollibffiHEADERS -# Where generated headers like ffitarget.h get installed. -# gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER) -# Uncomment these when libffi is part of the GCC tree. -# toollibffidir := $(libdir)/gcc/$(target_alias)/$(gcc_version)/include/libffi -# toollibffi_HEADERS = ffitarget.h # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/libffi/include/ffi.h.in b/libffi/include/ffi.h.in index 4260045..7784b2e 100644 --- a/libffi/include/ffi.h.in +++ b/libffi/include/ffi.h.in @@ -1,5 +1,5 @@ /* -----------------------------------------------------------------*-C-*- - libffi @VERSION@ - Copyright (c) 1996-2003 Red Hat, Inc. + libffi @VERSION@ - Copyright (c) 1996-2003, 2007 Red Hat, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -82,6 +82,18 @@ extern "C" { # endif #endif +/* The closure code assumes that this works on pointers, i.e. a size_t */ +/* can hold a pointer. */ + +typedef struct _ffi_type +{ + size_t size; + unsigned short alignment; + unsigned short type; + struct _ffi_type **elements; +} ffi_type; + +#ifndef LIBFFI_HIDE_BASIC_TYPES #if SCHAR_MAX == 127 # define ffi_type_uchar ffi_type_uint8 # define ffi_type_schar ffi_type_sint8 @@ -112,26 +124,23 @@ extern "C" { #error "int size not supported" #endif -#define ffi_type_ulong ffi_type_uint64 -#define ffi_type_slong ffi_type_sint64 #if LONG_MAX == 2147483647 # if FFI_LONG_LONG_MAX != 9223372036854775807 - #error "no 64-bit data type supported" + #error "no 64-bit data type supported" # endif #elif LONG_MAX != 9223372036854775807 #error "long size not supported" #endif -/* The closure code assumes that this works on pointers, i.e. a size_t */ -/* can hold a pointer. */ - -typedef struct _ffi_type -{ - size_t size; - unsigned short alignment; - unsigned short type; - /*@null@*/ struct _ffi_type **elements; -} ffi_type; +#if LONG_MAX == 2147483647 +# define ffi_type_ulong ffi_type_uint32 +# define ffi_type_slong ffi_type_sint32 +#elif LONG_MAX == 9223372036854775807 +# define ffi_type_ulong ffi_type_uint64 +# define ffi_type_slong ffi_type_sint64 +#else + #error "long size not supported" +#endif /* These are defined in types.c */ extern ffi_type ffi_type_void; @@ -145,14 +154,19 @@ extern ffi_type ffi_type_uint64; extern ffi_type ffi_type_sint64; extern ffi_type ffi_type_float; extern ffi_type ffi_type_double; -extern ffi_type ffi_type_longdouble; extern ffi_type ffi_type_pointer; +#if @HAVE_LONG_DOUBLE@ +extern ffi_type ffi_type_longdouble; +#else +#define ffi_type_longdouble ffi_type_double +#endif +#endif /* LIBFFI_HIDE_BASIC_TYPES */ typedef enum { FFI_OK = 0, FFI_BAD_TYPEDEF, - FFI_BAD_ABI + FFI_BAD_ABI } ffi_status; typedef unsigned FFI_TYPE; @@ -160,8 +174,8 @@ typedef unsigned FFI_TYPE; typedef struct { ffi_abi abi; unsigned nargs; - /*@dependent@*/ ffi_type **arg_types; - /*@dependent@*/ ffi_type *rtype; + ffi_type **arg_types; + ffi_type *rtype; unsigned bytes; unsigned flags; #ifdef FFI_EXTRA_CIF_FIELDS @@ -179,6 +193,10 @@ typedef struct { # endif #endif +#ifndef FFI_SIZEOF_JAVA_RAW +# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG +#endif + typedef union { ffi_sarg sint; ffi_arg uint; @@ -187,10 +205,25 @@ typedef union { void* ptr; } ffi_raw; -void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ ffi_raw *avalue); +#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8 +/* This is a special case for mips64/n32 ABI (and perhaps others) where + sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */ +typedef union { + signed int sint; + unsigned int uint; + float flt; + char data[FFI_SIZEOF_JAVA_RAW]; + void* ptr; +} ffi_java_raw; +#else +typedef ffi_raw ffi_java_raw; +#endif + + +void ffi_raw_call (ffi_cif *cif, + void (*fn)(), + void *rvalue, + ffi_raw *avalue); void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); @@ -200,13 +233,13 @@ size_t ffi_raw_size (ffi_cif *cif); /* packing, even on 64-bit machines. I.e. on 64-bit machines */ /* longs and doubles are followed by an empty 64-bit word. */ -void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ ffi_raw *avalue); +void ffi_java_raw_call (ffi_cif *cif, + void (*fn)(), + void *rvalue, + ffi_java_raw *avalue); -void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); -void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); +void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw); +void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args); size_t ffi_java_raw_size (ffi_cif *cif); /* ---- Definitions for closures ----------------------------------------- */ @@ -220,12 +253,22 @@ typedef struct { void *user_data; } ffi_closure __attribute__((aligned (8))); +void *ffi_closure_alloc (size_t size, void **code); +void ffi_closure_free (void *); + ffi_status ffi_prep_closure (ffi_closure*, ffi_cif *, void (*fun)(ffi_cif*,void*,void**,void*), void *user_data); +ffi_status +ffi_prep_closure_loc (ffi_closure*, + ffi_cif *, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void*codeloc); + typedef struct { char tramp[FFI_TRAMPOLINE_SIZE]; @@ -247,6 +290,27 @@ typedef struct { } ffi_raw_closure; +typedef struct { + char tramp[FFI_TRAMPOLINE_SIZE]; + + ffi_cif *cif; + +#if !FFI_NATIVE_RAW_API + + /* if this is enabled, then a raw closure has the same layout + as a regular closure. We use this to install an intermediate + handler to do the transaltion, void** -> ffi_raw*. */ + + void (*translate_args)(ffi_cif*,void*,void**,void*); + void *this_closure; + +#endif + + void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*); + void *user_data; + +} ffi_java_raw_closure; + ffi_status ffi_prep_raw_closure (ffi_raw_closure*, ffi_cif *cif, @@ -254,25 +318,39 @@ ffi_prep_raw_closure (ffi_raw_closure*, void *user_data); ffi_status -ffi_prep_java_raw_closure (ffi_raw_closure*, +ffi_prep_raw_closure_loc (ffi_raw_closure*, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void *user_data, + void *codeloc); + +ffi_status +ffi_prep_java_raw_closure (ffi_java_raw_closure*, ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), void *user_data); +ffi_status +ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), + void *user_data, + void *codeloc); + #endif /* FFI_CLOSURES */ /* ---- Public interface definition -------------------------------------- */ -ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, +ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, - unsigned int nargs, - /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, - /*@dependent@*/ ffi_type **atypes); + unsigned int nargs, + ffi_type *rtype, + ffi_type **atypes); -void ffi_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ void **avalue); +void ffi_call(ffi_cif *cif, + void (*fn)(), + void *rvalue, + void **avalue); /* Useful for eliminating compiler warnings */ #define FFI_FN(f) ((void (*)())f) @@ -310,4 +388,3 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, #endif #endif - diff --git a/libffi/include/ffi_common.h b/libffi/include/ffi_common.h index da15ab8..6af4b5f 100644 --- a/libffi/include/ffi_common.h +++ b/libffi/include/ffi_common.h @@ -1,5 +1,6 @@ /* ----------------------------------------------------------------------- ffi_common.h - Copyright (c) 1996 Red Hat, Inc. + Copyright (C) 2007 Free Software Foundation, Inc Common internal definitions and macros. Only necessary for building libffi. @@ -18,7 +19,9 @@ extern "C" { this is positioned. */ #ifdef __GNUC__ # define alloca __builtin_alloca +# define MAYBE_UNUSED __attribute__((__unused__)) #else +# define MAYBE_UNUSED # if HAVE_ALLOCA_H # include # else @@ -41,20 +44,20 @@ char *alloca (); # endif #endif -#if defined(FFI_DEBUG) +#if defined(FFI_DEBUG) #include #endif #ifdef FFI_DEBUG -/*@exits@*/ void ffi_assert(/*@temp@*/ char *expr, /*@temp@*/ char *file, int line); +void ffi_assert(char *expr, char *file, int line); void ffi_stop_here(void); -void ffi_type_test(/*@temp@*/ /*@out@*/ ffi_type *a, /*@temp@*/ char *file, int line); +void ffi_type_test(ffi_type *a, char *file, int line); #define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__)) #define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l))) #define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__) #else -#define FFI_ASSERT(x) +#define FFI_ASSERT(x) #define FFI_ASSERT_AT(x, f, l) #define FFI_ASSERT_VALID_TYPE(x) #endif @@ -68,9 +71,9 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif); /* Extended cif, used in callback from assembly routine */ typedef struct { - /*@dependent@*/ ffi_cif *cif; - /*@dependent@*/ void *rvalue; - /*@dependent@*/ void **avalue; + ffi_cif *cif; + void *rvalue; + void **avalue; } extended_cif; /* Terse sized type definitions. */ diff --git a/libffi/src/alpha/ffi.c b/libffi/src/alpha/ffi.c index 00d3379..cfa7b69 100644 --- a/libffi/src/alpha/ffi.c +++ b/libffi/src/alpha/ffi.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1998, 2001 Red Hat, Inc. + ffi.c - Copyright (c) 1998, 2001, 2007 Red Hat, Inc. Alpha Foreign Function Interface @@ -25,11 +25,22 @@ #include #include - #include -extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)()); -extern void ffi_closure_osf(void); +/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE; + all further uses in this file will refer to the 128-bit type. */ +#if defined(__LONG_DOUBLE_128__) +# if FFI_TYPE_LONGDOUBLE != 4 +# error FFI_TYPE_LONGDOUBLE out of date +# endif +#else +# undef FFI_TYPE_LONGDOUBLE +# define FFI_TYPE_LONGDOUBLE 4 +#endif + +extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)()) + FFI_HIDDEN; +extern void ffi_closure_osf(void) FFI_HIDDEN; ffi_status @@ -49,6 +60,11 @@ ffi_prep_cif_machdep(ffi_cif *cif) cif->flags = cif->rtype->type; break; + case FFI_TYPE_LONGDOUBLE: + /* 128-bit long double is returned in memory, like a struct. */ + cif->flags = FFI_TYPE_STRUCT; + break; + default: cif->flags = FFI_TYPE_INT; break; @@ -57,6 +73,7 @@ ffi_prep_cif_machdep(ffi_cif *cif) return FFI_OK; } + void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) { @@ -64,8 +81,6 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) long i, avn; ffi_type **arg_types; - FFI_ASSERT (cif->abi == FFI_OSF); - /* If the return value is a struct and we don't have a return value address then we need to make one. */ if (rvalue == NULL && cif->flags == FFI_TYPE_STRUCT) @@ -84,6 +99,8 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) while (i < avn) { + size_t size = (*arg_types)->size; + switch ((*arg_types)->type) { case FFI_TYPE_SINT8: @@ -129,6 +146,12 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) *(double *) argp = *(double *)(* avalue); break; + case FFI_TYPE_LONGDOUBLE: + /* 128-bit long double is passed by reference. */ + *(long double **) argp = (long double *)(* avalue); + size = sizeof (long double *); + break; + case FFI_TYPE_STRUCT: memcpy(argp, *avalue, (*arg_types)->size); break; @@ -137,7 +160,7 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) FFI_ASSERT(0); } - argp += ALIGN((*arg_types)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; + argp += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; i++, arg_types++, avalue++; } @@ -146,15 +169,14 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*, void*, void**, void*), - void *user_data) +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) { unsigned int *tramp; - FFI_ASSERT (cif->abi == FFI_OSF); - tramp = (unsigned int *) &closure->tramp[0]; tramp[0] = 0x47fb0401; /* mov $27,$1 */ tramp[1] = 0xa77b0010; /* ldq $27,16($27) */ @@ -177,7 +199,8 @@ ffi_prep_closure (ffi_closure* closure, return FFI_OK; } -int + +long FFI_HIDDEN ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp) { ffi_cif *cif; @@ -205,6 +228,8 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp) /* Grab the addresses of the arguments from the stack frame. */ while (i < avn) { + size_t size = arg_types[i]->size; + switch (arg_types[i]->type) { case FFI_TYPE_SINT8: @@ -236,16 +261,22 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp) avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)]; break; + case FFI_TYPE_LONGDOUBLE: + /* 128-bit long double is passed by reference. */ + avalue[i] = (long double *) argp[argn]; + size = sizeof (long double *); + break; + default: - FFI_ASSERT(0); + abort (); } - argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; + argn += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; i++; } /* Invoke the closure. */ - (closure->fun) (cif, rvalue, avalue, closure->user_data); + closure->fun (cif, rvalue, avalue, closure->user_data); /* Tell ffi_closure_osf how to perform return type promotions. */ return cif->rtype->type; diff --git a/libffi/src/alpha/ffitarget.h b/libffi/src/alpha/ffitarget.h index 00a1217..9ec82da 100644 --- a/libffi/src/alpha/ffitarget.h +++ b/libffi/src/alpha/ffitarget.h @@ -33,8 +33,8 @@ typedef signed long ffi_sarg; typedef enum ffi_abi { FFI_FIRST_ABI = 0, FFI_OSF, - FFI_DEFAULT_ABI = FFI_OSF, - FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_OSF } ffi_abi; #endif @@ -45,4 +45,3 @@ typedef enum ffi_abi { #define FFI_NATIVE_RAW_API 0 #endif - diff --git a/libffi/src/alpha/osf.S b/libffi/src/alpha/osf.S index 463aa4e..aba6782 100644 --- a/libffi/src/alpha/osf.S +++ b/libffi/src/alpha/osf.S @@ -1,10 +1,8 @@ /* ----------------------------------------------------------------------- - osf.S - Copyright (c) 1998, 2001 Red Hat + osf.S - Copyright (c) 1998, 2001, 2007 Red Hat Alpha/OSF Foreign Function Interface - $Id: osf.S,v 1.5 2008/01/29 12:28:14 green Exp $ - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including @@ -42,6 +40,8 @@ .align 3 .globl ffi_call_osf .ent ffi_call_osf + FFI_HIDDEN(ffi_call_osf) + ffi_call_osf: .frame $15, 32, $26, 0 .mask 0x4008000, -32 @@ -129,6 +129,8 @@ $LFE1: .align 3 .globl ffi_closure_osf .ent ffi_closure_osf + FFI_HIDDEN(ffi_closure_osf) + ffi_closure_osf: .frame $30, 16*8, $26, 0 .mask 0x4000000, -16*8 @@ -265,7 +267,7 @@ $load_table: .gprel32 $load_32 # FFI_TYPE_INT .gprel32 $load_float # FFI_TYPE_FLOAT .gprel32 $load_double # FFI_TYPE_DOUBLE - .gprel32 $load_double # FFI_TYPE_LONGDOUBLE + .gprel32 $load_none # FFI_TYPE_LONGDOUBLE .gprel32 $load_u8 # FFI_TYPE_UINT8 .gprel32 $load_s8 # FFI_TYPE_SINT8 .gprel32 $load_u16 # FFI_TYPE_UINT16 diff --git a/libffi/src/arm/ffi.c b/libffi/src/arm/ffi.c index 1f58d93..35b2c34 100644 --- a/libffi/src/arm/ffi.c +++ b/libffi/src/arm/ffi.c @@ -31,9 +31,7 @@ /* ffi_prep_args is called by the assembly routine once stack space has been allocated for the function's arguments */ -/*@-exportheader@*/ void ffi_prep_args(char *stack, extended_cif *ecif) -/*@=exportheader@*/ { register unsigned int i; register void **p_argv; @@ -42,7 +40,7 @@ void ffi_prep_args(char *stack, extended_cif *ecif) argp = stack; - if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) { + if ( ecif->cif->flags == FFI_TYPE_STRUCT ) { *(void **) argp = ecif->rvalue; argp += 4; } @@ -60,6 +58,9 @@ void ffi_prep_args(char *stack, extended_cif *ecif) argp = (char *) ALIGN(argp, (*p_arg)->alignment); } + if ((*p_arg)->type == FFI_TYPE_STRUCT) + argp = (char *) ALIGN(argp, 4); + z = (*p_arg)->size; if (z < sizeof(int)) { @@ -83,7 +84,7 @@ void ffi_prep_args(char *stack, extended_cif *ecif) break; case FFI_TYPE_STRUCT: - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + memcpy(argp, *p_argv, (*p_arg)->size); break; default: @@ -117,7 +118,6 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) switch (cif->rtype->type) { case FFI_TYPE_VOID: - case FFI_TYPE_STRUCT: case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: cif->flags = (unsigned) cif->rtype->type; @@ -128,6 +128,17 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) cif->flags = (unsigned) FFI_TYPE_SINT64; break; + case FFI_TYPE_STRUCT: + if (cif->rtype->size <= 4) + /* A Composite Type not larger than 4 bytes is returned in r0. */ + cif->flags = (unsigned)FFI_TYPE_INT; + else + /* A Composite Type larger than 4 bytes, or whose size cannot + be determined statically ... is stored in memory at an + address passed [in r0]. */ + cif->flags = (unsigned)FFI_TYPE_STRUCT; + break; + default: cif->flags = FFI_TYPE_INT; break; @@ -136,50 +147,162 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) return FFI_OK; } -/*@-declundef@*/ -/*@-exportheader@*/ -extern void ffi_call_SYSV(void (*)(char *, extended_cif *), - /*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, - void (*fn)()); -/*@=declundef@*/ -/*@=exportheader@*/ +extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, + unsigned, unsigned, unsigned *, void (*fn)()); -void ffi_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ void **avalue) +void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) { extended_cif ecif; + int small_struct = (cif->flags == FFI_TYPE_INT + && cif->rtype->type == FFI_TYPE_STRUCT); + ecif.cif = cif; ecif.avalue = avalue; + + unsigned int temp; /* If the return value is a struct and we don't have a return */ /* value address then we need to make one */ if ((rvalue == NULL) && - (cif->rtype->type == FFI_TYPE_STRUCT)) + (cif->flags == FFI_TYPE_STRUCT)) { - /*@-sysunrecog@*/ ecif.rvalue = alloca(cif->rtype->size); - /*@=sysunrecog@*/ } + else if (small_struct) + ecif.rvalue = &temp; else ecif.rvalue = rvalue; - - + switch (cif->abi) { case FFI_SYSV: - /*@-usedef@*/ - ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ + ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, + fn); + break; default: FFI_ASSERT(0); break; } + if (small_struct) + memcpy (rvalue, &temp, cif->rtype->size); +} + +/** private members **/ + +static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, + void** args, ffi_cif* cif); + +void ffi_closure_SYSV (ffi_closure *); + +/* This function is jumped to by the trampoline */ + +unsigned int +ffi_closure_SYSV_inner (closure, respp, args) + ffi_closure *closure; + void **respp; + void *args; +{ + // our various things... + ffi_cif *cif; + void **arg_area; + + cif = closure->cif; + arg_area = (void**) alloca (cif->nargs * sizeof (void*)); + + /* this call will initialize ARG_AREA, such that each + * element in that array points to the corresponding + * value on the stack; and if the function returns + * a structure, it will re-set RESP to point to the + * structure return address. */ + + ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif); + + (closure->fun) (cif, *respp, arg_area, closure->user_data); + + return cif->flags; +} + +/*@-exportheader@*/ +static void +ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, + void **avalue, ffi_cif *cif) +/*@=exportheader@*/ +{ + register unsigned int i; + register void **p_argv; + register char *argp; + register ffi_type **p_arg; + + argp = stack; + + if ( cif->flags == FFI_TYPE_STRUCT ) { + *rvalue = *(void **) argp; + argp += 4; + } + + p_argv = avalue; + + for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) + { + size_t z; + + size_t alignment = (*p_arg)->alignment; + if (alignment < 4) + alignment = 4; + /* Align if necessary */ + if ((alignment - 1) & (unsigned) argp) { + argp = (char *) ALIGN(argp, alignment); + } + + z = (*p_arg)->size; + + /* because we're little endian, this is what it turns into. */ + + *p_argv = (void*) argp; + + p_argv++; + argp += z; + } + + return; +} + +/* How to make a trampoline. */ + +#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \ +({ unsigned char *__tramp = (unsigned char*)(TRAMP); \ + unsigned int __fun = (unsigned int)(FUN); \ + unsigned int __ctx = (unsigned int)(CTX); \ + *(unsigned int*) &__tramp[0] = 0xe92d000f; /* stmfd sp!, {r0-r3} */ \ + *(unsigned int*) &__tramp[4] = 0xe59f0000; /* ldr r0, [pc] */ \ + *(unsigned int*) &__tramp[8] = 0xe59ff000; /* ldr pc, [pc] */ \ + *(unsigned int*) &__tramp[12] = __ctx; \ + *(unsigned int*) &__tramp[16] = __fun; \ + __clear_cache((&__tramp[0]), (&__tramp[19])); \ + }) + + +/* the cif must already be prep'ed */ + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void *codeloc) +{ + FFI_ASSERT (cif->abi == FFI_SYSV); + + FFI_INIT_TRAMPOLINE (&closure->tramp[0], \ + &ffi_closure_SYSV, \ + codeloc); + + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + return FFI_OK; } diff --git a/libffi/src/arm/ffitarget.h b/libffi/src/arm/ffitarget.h index 96f4bb2..7ba0446 100644 --- a/libffi/src/arm/ffitarget.h +++ b/libffi/src/arm/ffitarget.h @@ -40,7 +40,8 @@ typedef enum ffi_abi { /* ---- Definitions for closures ----------------------------------------- */ -#define FFI_CLOSURES 0 +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 20 #define FFI_NATIVE_RAW_API 0 #endif diff --git a/libffi/src/arm/sysv.S b/libffi/src/arm/sysv.S index c3471a8..12876d1 100644 --- a/libffi/src/arm/sysv.S +++ b/libffi/src/arm/sysv.S @@ -82,6 +82,14 @@ # define call_reg(x) mov lr, pc ; mov pc, x #endif +/* Conditionally compile unwinder directives. */ +#ifdef __ARM_EABI__ +#define UNWIND +#else +#define UNWIND @ +#endif + + #if defined(__thumb__) && !defined(__THUMB_INTERWORK__) .macro ARM_FUNC_START name .text @@ -92,6 +100,7 @@ bx pc nop .arm + UNWIND .fnstart /* A hook to tell gdb that we've switched to ARM mode. Also used to call directly from other local arm routines. */ _L__\name: @@ -102,6 +111,7 @@ _L__\name: .align 0 .arm ENTRY(\name) + UNWIND .fnstart .endm #endif @@ -134,8 +144,11 @@ _L__\name: ARM_FUNC_START ffi_call_SYSV @ Save registers stmfd sp!, {r0-r3, fp, lr} + UNWIND .save {r0-r3, fp, lr} mov fp, sp + UNWIND .setfp fp, sp + @ Make room for all of the new args. sub sp, fp, r2 @@ -205,5 +218,78 @@ LSYM(Lepilogue): RETLDM "r0-r3,fp" .ffi_call_SYSV_end: + UNWIND .fnend .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV) +/* + unsigned int FFI_HIDDEN + ffi_closure_SYSV_inner (closure, respp, args) + ffi_closure *closure; + void **respp; + void *args; +*/ + +ARM_FUNC_START ffi_closure_SYSV + UNWIND .pad #16 + add ip, sp, #16 + stmfd sp!, {ip, lr} + UNWIND .save {r0, lr} + add r2, sp, #8 + .pad #16 + sub sp, sp, #16 + str sp, [sp, #8] + add r1, sp, #8 + bl ffi_closure_SYSV_inner + cmp r0, #FFI_TYPE_INT + beq .Lretint + + cmp r0, #FFI_TYPE_FLOAT +#ifdef __SOFTFP__ + beq .Lretint +#else + beq .Lretfloat +#endif + + cmp r0, #FFI_TYPE_DOUBLE +#ifdef __SOFTFP__ + beq .Lretlonglong +#else + beq .Lretdouble +#endif + + cmp r0, #FFI_TYPE_LONGDOUBLE +#ifdef __SOFTFP__ + beq .Lretlonglong +#else + beq .Lretlongdouble +#endif + + cmp r0, #FFI_TYPE_SINT64 + beq .Lretlonglong +.Lclosure_epilogue: + add sp, sp, #16 + ldmfd sp, {sp, pc} +.Lretint: + ldr r0, [sp] + b .Lclosure_epilogue +.Lretlonglong: + ldr r0, [sp] + ldr r1, [sp, #4] + b .Lclosure_epilogue + +#ifndef __SOFTFP__ +.Lretfloat: + ldfs f0, [sp] + b .Lclosure_epilogue +.Lretdouble: + ldfd f0, [sp] + b .Lclosure_epilogue +.Lretlongdouble: + ldfd f0, [sp] + b .Lclosure_epilogue +#endif + +.ffi_closure_SYSV_end: + UNWIND .fnend + .size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV) + diff --git a/libffi/src/cris/ffi.c b/libffi/src/cris/ffi.c index 364c990..e9c3953 100644 --- a/libffi/src/cris/ffi.c +++ b/libffi/src/cris/ffi.c @@ -2,6 +2,7 @@ ffi.c - Copyright (c) 1998 Cygnus Solutions Copyright (c) 2004 Simon Posnjak Copyright (c) 2005 Axis Communications AB + Copyright (C) 2007 Free Software Foundation, Inc. CRIS Foreign Function Interface @@ -360,10 +361,11 @@ ffi_prep_closure_inner (void **params, ffi_closure* closure) /* API function: Prepare the trampoline. */ ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif *, void *, void **, void*), - void *user_data) +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif *, void *, void **, void*), + void *user_data, + void *codeloc) { void *innerfn = ffi_prep_closure_inner; FFI_ASSERT (cif->abi == FFI_SYSV); @@ -375,7 +377,7 @@ ffi_prep_closure (ffi_closure* closure, memcpy (closure->tramp + ffi_cris_trampoline_fn_offset, &innerfn, sizeof (void *)); memcpy (closure->tramp + ffi_cris_trampoline_closure_offset, - &closure, sizeof (void *)); + &codeloc, sizeof (void *)); return FFI_OK; } diff --git a/libffi/src/debug.c b/libffi/src/debug.c index 98f1f9f..f15eb91 100644 --- a/libffi/src/debug.c +++ b/libffi/src/debug.c @@ -31,7 +31,7 @@ void ffi_stop_here(void) { /* This function is only useful for debugging purposes. - Place a breakpoint on ffi_stop_here to be notified of + Place a breakpoint on ffi_stop_here to be notified of significant events. */ } @@ -50,10 +50,9 @@ void ffi_type_test(ffi_type *a, char *file, int line) { FFI_ASSERT_AT(a != NULL, file, line); - /*@-usedef@*/ FFI_ASSERT_AT(a->type <= FFI_TYPE_LAST, file, line); FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->size > 0, file, line); FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->alignment > 0, file, line); FFI_ASSERT_AT(a->type != FFI_TYPE_STRUCT || a->elements != NULL, file, line); - /*@=usedef@*/ + } diff --git a/libffi/src/frv/eabi.S b/libffi/src/frv/eabi.S index 5846949..379ea4b 100644 --- a/libffi/src/frv/eabi.S +++ b/libffi/src/frv/eabi.S @@ -3,8 +3,6 @@ FR-V Assembly glue. - $Id: eabi.S,v 1.2 2008/01/29 12:28:14 green Exp $ - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including diff --git a/libffi/src/frv/ffi.c b/libffi/src/frv/ffi.c index 6e2ac68..e9dc676 100644 --- a/libffi/src/frv/ffi.c +++ b/libffi/src/frv/ffi.c @@ -1,5 +1,6 @@ /* ----------------------------------------------------------------------- ffi.c - Copyright (c) 2004 Anthony Green + Copyright (C) 2007 Free Software Foundation, Inc. FR-V Foreign Function Interface @@ -243,14 +244,15 @@ void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3, } ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*, void*, void**, void*), - void *user_data) +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) { unsigned int *tramp = (unsigned int *) &closure->tramp[0]; unsigned long fn = (long) ffi_closure_eabi; - unsigned long cls = (long) closure; + unsigned long cls = (long) codeloc; #ifdef __FRV_FDPIC__ register void *got __asm__("gr15"); #endif @@ -259,7 +261,7 @@ ffi_prep_closure (ffi_closure* closure, fn = (unsigned long) ffi_closure_eabi; #ifdef __FRV_FDPIC__ - tramp[0] = &tramp[2]; + tramp[0] = &((unsigned int *)codeloc)[2]; tramp[1] = got; tramp[2] = 0x8cfc0000 + (fn & 0xffff); /* setlos lo(fn), gr6 */ tramp[3] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7 */ @@ -281,7 +283,8 @@ ffi_prep_closure (ffi_closure* closure, /* Cache flushing. */ for (i = 0; i < FFI_TRAMPOLINE_SIZE; i++) - __asm__ volatile ("dcf @(%0,%1)\n\tici @(%0,%1)" :: "r" (tramp), "r" (i)); + __asm__ volatile ("dcf @(%0,%1)\n\tici @(%2,%1)" :: "r" (tramp), "r" (i), + "r" (codeloc)); return FFI_OK; } diff --git a/libffi/src/ia64/ffi.c b/libffi/src/ia64/ffi.c index e810827..09021de 100644 --- a/libffi/src/ia64/ffi.c +++ b/libffi/src/ia64/ffi.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1998 Red Hat, Inc. + ffi.c - Copyright (c) 1998, 2007 Red Hat, Inc. Copyright (c) 2000 Hewlett Packard Company IA64 Foreign Function Interface @@ -69,24 +69,19 @@ endian_adjust (void *addr, size_t len) #endif } -/* Store VALUE to ADDR in the current cpu implementation's fp spill format. */ +/* Store VALUE to ADDR in the current cpu implementation's fp spill format. + This is a macro instead of a function, so that it works for all 3 floating + point types without type conversions. Type conversion to long double breaks + the denorm support. */ -static inline void -stf_spill(fpreg *addr, __float80 value) -{ +#define stf_spill(addr, value) \ asm ("stf.spill %0 = %1%P0" : "=m" (*addr) : "f"(value)); -} /* Load a value from ADDR, which is in the current cpu implementation's - fp spill format. */ + fp spill format. As above, this must also be a macro. */ -static inline __float80 -ldf_fill(fpreg *addr) -{ - __float80 ret; - asm ("ldf.fill %0 = %1%P1" : "=f"(ret) : "m"(*addr)); - return ret; -} +#define ldf_fill(result, addr) \ + asm ("ldf.fill %0 = %1%P1" : "=f"(result) : "m"(*addr)); /* Return the size of the C type associated with with TYPE. Which will be one of the FFI_IA64_TYPE_HFA_* values. */ @@ -110,17 +105,20 @@ hfa_type_size (int type) /* Load from ADDR a value indicated by TYPE. Which will be one of the FFI_IA64_TYPE_HFA_* values. */ -static __float80 -hfa_type_load (int type, void *addr) +static void +hfa_type_load (fpreg *fpaddr, int type, void *addr) { switch (type) { case FFI_IA64_TYPE_HFA_FLOAT: - return *(float *) addr; + stf_spill (fpaddr, *(float *) addr); + return; case FFI_IA64_TYPE_HFA_DOUBLE: - return *(double *) addr; + stf_spill (fpaddr, *(double *) addr); + return; case FFI_IA64_TYPE_HFA_LDOUBLE: - return *(__float80 *) addr; + stf_spill (fpaddr, *(__float80 *) addr); + return; default: abort (); } @@ -130,19 +128,31 @@ hfa_type_load (int type, void *addr) the FFI_IA64_TYPE_HFA_* values. */ static void -hfa_type_store (int type, void *addr, __float80 value) +hfa_type_store (int type, void *addr, fpreg *fpaddr) { switch (type) { case FFI_IA64_TYPE_HFA_FLOAT: - *(float *) addr = value; - break; + { + float result; + ldf_fill (result, fpaddr); + *(float *) addr = result; + break; + } case FFI_IA64_TYPE_HFA_DOUBLE: - *(double *) addr = value; - break; + { + double result; + ldf_fill (result, fpaddr); + *(double *) addr = result; + break; + } case FFI_IA64_TYPE_HFA_LDOUBLE: - *(__float80 *) addr = value; - break; + { + __float80 result; + ldf_fill (result, fpaddr); + *(__float80 *) addr = result; + break; + } default: abort (); } @@ -351,8 +361,8 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) && offset < size && gp_offset < 8 * 8) { - stf_spill (&stack->fp_regs[fpcount], - hfa_type_load (hfa_type, avalue[i] + offset)); + hfa_type_load (&stack->fp_regs[fpcount], hfa_type, + avalue[i] + offset); offset += hfa_size; gp_offset += hfa_size; fpcount += 1; @@ -390,10 +400,11 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) extern void ffi_closure_unix (); ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data) +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void *codeloc) { /* The layout of a function descriptor. A C function pointer really points to one of these. */ @@ -420,7 +431,7 @@ ffi_prep_closure (ffi_closure* closure, tramp->code_pointer = fd->code_pointer; tramp->real_gp = fd->gp; - tramp->fake_gp = (UINT64)(PTR64)closure; + tramp->fake_gp = (UINT64)(PTR64)codeloc; closure->cif = cif; closure->user_data = user_data; closure->fun = fun; @@ -475,9 +486,11 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack, case FFI_TYPE_FLOAT: if (gpcount < 8 && fpcount < 8) { - void *addr = &stack->fp_regs[fpcount++]; + fpreg *addr = &stack->fp_regs[fpcount++]; + float result; avalue[i] = addr; - *(float *)addr = ldf_fill (addr); + ldf_fill (result, addr); + *(float *)addr = result; } else avalue[i] = endian_adjust(&stack->gp_regs[gpcount], 4); @@ -487,9 +500,11 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack, case FFI_TYPE_DOUBLE: if (gpcount < 8 && fpcount < 8) { - void *addr = &stack->fp_regs[fpcount++]; + fpreg *addr = &stack->fp_regs[fpcount++]; + double result; avalue[i] = addr; - *(double *)addr = ldf_fill (addr); + ldf_fill (result, addr); + *(double *)addr = result; } else avalue[i] = &stack->gp_regs[gpcount]; @@ -501,9 +516,11 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack, gpcount++; if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8) { - void *addr = &stack->fp_regs[fpcount++]; + fpreg *addr = &stack->fp_regs[fpcount++]; + __float80 result; avalue[i] = addr; - *(__float80 *)addr = ldf_fill (addr); + ldf_fill (result, addr); + *(__float80 *)addr = result; } else avalue[i] = &stack->gp_regs[gpcount]; @@ -533,8 +550,8 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack, && offset < size && gp_offset < 8 * 8) { - hfa_type_store (hfa_type, addr + offset, - ldf_fill (&stack->fp_regs[fpcount])); + hfa_type_store (hfa_type, addr + offset, + &stack->fp_regs[fpcount]); offset += hfa_size; gp_offset += hfa_size; fpcount += 1; diff --git a/libffi/src/java_raw_api.c b/libffi/src/java_raw_api.c index 5b0e347..4fef115 100644 --- a/libffi/src/java_raw_api.c +++ b/libffi/src/java_raw_api.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - java_raw_api.c - Copyright (c) 1999 Red Hat, Inc. + java_raw_api.c - Copyright (c) 1999, 2007 Red Hat, Inc. Cloned from raw_api.c @@ -29,10 +29,10 @@ ----------------------------------------------------------------------- */ /* This defines a Java- and 64-bit specific variant of the raw API. */ -/* It assumes that "raw" argument blocks look like Java stacks on a */ +/* It assumes that "raw" argument blocks look like Java stacks on a */ /* 64-bit machine. Arguments that can be stored in a single stack */ /* stack slots (longs, doubles) occupy 128 bits, but only the first */ -/* 64 bits are actually used. */ +/* 64 bits are actually used. */ #include #include @@ -54,13 +54,13 @@ ffi_java_raw_size (ffi_cif *cif) case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: case FFI_TYPE_DOUBLE: - result += 2 * FFI_SIZEOF_ARG; + result += 2 * FFI_SIZEOF_JAVA_RAW; break; case FFI_TYPE_STRUCT: /* No structure parameters in Java. */ abort(); default: - result += FFI_SIZEOF_ARG; + result += FFI_SIZEOF_JAVA_RAW; } } @@ -69,7 +69,7 @@ ffi_java_raw_size (ffi_cif *cif) void -ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args) +ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args) { unsigned i; ffi_type **tp = cif->arg_types; @@ -77,20 +77,20 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args) #if WORDS_BIGENDIAN for (i = 0; i < cif->nargs; i++, tp++, args++) - { + { switch ((*tp)->type) { case FFI_TYPE_UINT8: case FFI_TYPE_SINT8: *args = (void*) ((char*)(raw++) + 3); break; - + case FFI_TYPE_UINT16: case FFI_TYPE_SINT16: *args = (void*) ((char*)(raw++) + 2); break; -#if FFI_SIZEOF_ARG == 8 +#if FFI_SIZEOF_JAVA_RAW == 8 case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: case FFI_TYPE_DOUBLE: @@ -102,10 +102,11 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args) case FFI_TYPE_POINTER: *args = (void*) &(raw++)->ptr; break; - + default: *args = raw; - raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; + raw += + ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw); } } @@ -116,7 +117,7 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args) /* then assume little endian */ for (i = 0; i < cif->nargs; i++, tp++, args++) { -#if FFI_SIZEOF_ARG == 8 +#if FFI_SIZEOF_JAVA_RAW == 8 switch((*tp)->type) { case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: @@ -127,10 +128,11 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args) default: *args = (void*) raw++; } -#else /* FFI_SIZEOF_ARG != 8 */ +#else /* FFI_SIZEOF_JAVA_RAW != 8 */ *args = (void*) raw; - raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*); -#endif /* FFI_SIZEOF_ARG == 8 */ + raw += + ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw); +#endif /* FFI_SIZEOF_JAVA_RAW == 8 */ } #else @@ -141,13 +143,13 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args) } void -ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw) +ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw) { unsigned i; ffi_type **tp = cif->arg_types; for (i = 0; i < cif->nargs; i++, tp++, args++) - { + { switch ((*tp)->type) { case FFI_TYPE_UINT8: @@ -202,7 +204,7 @@ ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw) (raw++)->flt = *(FLOAT32*) (*args); break; -#if FFI_SIZEOF_ARG == 8 +#if FFI_SIZEOF_JAVA_RAW == 8 case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: case FFI_TYPE_DOUBLE: @@ -216,11 +218,12 @@ ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw) break; default: -#if FFI_SIZEOF_ARG == 8 +#if FFI_SIZEOF_JAVA_RAW == 8 FFI_ASSERT(0); /* Should have covered all cases */ -#else +#else memcpy ((void*) raw->data, (void*)*args, (*tp)->size); - raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; + raw += + ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw); #endif } } @@ -244,6 +247,9 @@ ffi_java_rvalue_to_raw (ffi_cif *cif, void *rvalue) case FFI_TYPE_SINT16: case FFI_TYPE_SINT32: case FFI_TYPE_INT: +#if FFI_SIZEOF_JAVA_RAW == 4 + case FFI_TYPE_POINTER: +#endif *(SINT64 *)rvalue <<= 32; break; @@ -269,6 +275,9 @@ ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue) case FFI_TYPE_SINT16: case FFI_TYPE_SINT32: case FFI_TYPE_INT: +#if FFI_SIZEOF_JAVA_RAW == 4 + case FFI_TYPE_POINTER: +#endif *(SINT64 *)rvalue >>= 32; break; @@ -285,10 +294,8 @@ ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue) * these following couple of functions will handle the translation forth * and back automatically. */ -void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ ffi_raw *raw) +void ffi_java_raw_call (ffi_cif *cif, void (*fn)(), void *rvalue, + ffi_java_raw *raw) { void **avalue = (void**) alloca (cif->nargs * sizeof (void*)); ffi_java_raw_to_ptrarray (cif, raw, avalue); @@ -298,11 +305,11 @@ void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif, #if FFI_CLOSURES /* base system provides closures */ -static void +static void ffi_java_translate_args (ffi_cif *cif, void *rvalue, void **avalue, void *user_data) { - ffi_raw *raw = (ffi_raw*)alloca (ffi_java_raw_size (cif)); + ffi_java_raw *raw = (ffi_java_raw*)alloca (ffi_java_raw_size (cif)); ffi_raw_closure *cl = (ffi_raw_closure*)user_data; ffi_java_ptrarray_to_raw (cif, avalue, raw); @@ -310,22 +317,20 @@ ffi_java_translate_args (ffi_cif *cif, void *rvalue, ffi_java_raw_to_rvalue (cif, rvalue); } -/* Again, here is the generic version of ffi_prep_raw_closure, which - * will install an intermediate "hub" for translation of arguments from - * the pointer-array format, to the raw format */ - ffi_status -ffi_prep_java_raw_closure (ffi_raw_closure* cl, - ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void *user_data) +ffi_prep_java_raw_closure_loc (ffi_java_raw_closure* cl, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), + void *user_data, + void *codeloc) { ffi_status status; - status = ffi_prep_closure ((ffi_closure*) cl, - cif, - &ffi_java_translate_args, - (void*)cl); + status = ffi_prep_closure_loc ((ffi_closure*) cl, + cif, + &ffi_java_translate_args, + codeloc, + codeloc); if (status == FFI_OK) { cl->fun = fun; @@ -335,6 +340,19 @@ ffi_prep_java_raw_closure (ffi_raw_closure* cl, return status; } +/* Again, here is the generic version of ffi_prep_raw_closure, which + * will install an intermediate "hub" for translation of arguments from + * the pointer-array format, to the raw format */ + +ffi_status +ffi_prep_java_raw_closure (ffi_java_raw_closure* cl, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), + void *user_data) +{ + return ffi_prep_java_raw_closure_loc (cl, cif, fun, user_data, cl); +} + #endif /* FFI_CLOSURES */ #endif /* !FFI_NATIVE_RAW_API */ #endif /* !FFI_NO_RAW_API */ diff --git a/libffi/src/m32r/ffi.c b/libffi/src/m32r/ffi.c index 9a3b550..c3e8204 100644 --- a/libffi/src/m32r/ffi.c +++ b/libffi/src/m32r/ffi.c @@ -31,9 +31,7 @@ /* ffi_prep_args is called by the assembly routine once stack space has been allocated for the function's arguments. */ -/*@-exportheader@*/ void ffi_prep_args(char *stack, extended_cif *ecif) -/*@=exportheader@*/ { unsigned int i; int tmp; @@ -173,20 +171,10 @@ ffi_prep_cif_machdep(ffi_cif *cif) return FFI_OK; } -/*@-declundef@*/ -/*@-exportheader@*/ -extern void ffi_call_SYSV(void (*)(char *, extended_cif *), - /*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, - void (*fn)()); -/*@=declundef@*/ -/*@=exportheader@*/ - -void ffi_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ void **avalue) +extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, + unsigned, unsigned, unsigned *, void (*fn)()); + +void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) { extended_cif ecif; @@ -198,9 +186,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { - /*@-sysunrecog@*/ ecif.rvalue = alloca (cif->rtype->size); - /*@=sysunrecog@*/ } else ecif.rvalue = rvalue; @@ -208,7 +194,6 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, switch (cif->abi) { case FFI_SYSV: - /*@-usedef@*/ ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); if (cif->rtype->type == FFI_TYPE_STRUCT) @@ -237,7 +222,6 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, } } } - /*@=usedef@*/ break; default: diff --git a/libffi/src/m68k/ffi.c b/libffi/src/m68k/ffi.c index 55f3a98..600cf20 100644 --- a/libffi/src/m68k/ffi.c +++ b/libffi/src/m68k/ffi.c @@ -8,11 +8,23 @@ #include #include +#include +#include +#include + +void ffi_call_SYSV (extended_cif *, + unsigned, unsigned, + void *, void (*fn) ()); +void *ffi_prep_args (void *stack, extended_cif *ecif); +void ffi_closure_SYSV (ffi_closure *); +void ffi_closure_struct_SYSV (ffi_closure *); +unsigned int ffi_closure_SYSV_inner (ffi_closure *closure, + void *resp, void *args); /* ffi_prep_args is called by the assembly routine once stack space has been allocated for the function's arguments. */ -static void * +void * ffi_prep_args (void *stack, extended_cif *ecif) { unsigned int i; @@ -24,7 +36,7 @@ ffi_prep_args (void *stack, extended_cif *ecif) argp = stack; if (ecif->cif->rtype->type == FFI_TYPE_STRUCT - && ecif->cif->rtype->size > 8) + && !ecif->cif->flags) struct_value_ptr = ecif->rvalue; else struct_value_ptr = NULL; @@ -37,44 +49,47 @@ ffi_prep_args (void *stack, extended_cif *ecif) { size_t z; - /* Align if necessary. */ - if (((*p_arg)->alignment - 1) & (unsigned) argp) - argp = (char *) ALIGN (argp, (*p_arg)->alignment); - - z = (*p_arg)->size; - if (z < sizeof (int)) + z = (*p_arg)->size; + if (z < sizeof (int)) + { + switch ((*p_arg)->type) { - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - *(signed int *) argp = (signed int) *(SINT8 *) *p_argv; - break; - - case FFI_TYPE_UINT8: - *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv; - break; - - case FFI_TYPE_SINT16: - *(signed int *) argp = (signed int) *(SINT16 *) *p_argv; - break; - - case FFI_TYPE_UINT16: - *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv; - break; - - case FFI_TYPE_STRUCT: - memcpy (argp + sizeof (int) - z, *p_argv, z); - break; - - default: - FFI_ASSERT (0); - } - z = sizeof (int); + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int) *(SINT8 *) *p_argv; + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv; + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int) *(SINT16 *) *p_argv; + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv; + break; + + case FFI_TYPE_STRUCT: + memcpy (argp + sizeof (int) - z, *p_argv, z); + break; + + default: + FFI_ASSERT (0); } - else - memcpy (argp, *p_argv, z); - p_argv++; - argp += z; + z = sizeof (int); + } + else + { + memcpy (argp, *p_argv, z); + + /* Align if necessary. */ + if ((sizeof(int) - 1) & z) + z = ALIGN(z, sizeof(int)); + } + + p_argv++; + argp += z; } return struct_value_ptr; @@ -86,7 +101,8 @@ ffi_prep_args (void *stack, extended_cif *ecif) #define CIF_FLAGS_DOUBLE 8 #define CIF_FLAGS_LDOUBLE 16 #define CIF_FLAGS_POINTER 32 -#define CIF_FLAGS_STRUCT 64 +#define CIF_FLAGS_STRUCT1 64 +#define CIF_FLAGS_STRUCT2 128 /* Perform machine dependent cif processing */ ffi_status @@ -100,12 +116,24 @@ ffi_prep_cif_machdep (ffi_cif *cif) break; case FFI_TYPE_STRUCT: - if (cif->rtype->size > 4 && cif->rtype->size <= 8) - cif->flags = CIF_FLAGS_DINT; - else if (cif->rtype->size <= 4) - cif->flags = CIF_FLAGS_STRUCT; - else - cif->flags = 0; + switch (cif->rtype->size) + { + case 1: + cif->flags = CIF_FLAGS_STRUCT1; + break; + case 2: + cif->flags = CIF_FLAGS_STRUCT2; + break; + case 4: + cif->flags = CIF_FLAGS_INT; + break; + case 8: + cif->flags = CIF_FLAGS_DINT; + break; + default: + cif->flags = 0; + break; + } break; case FFI_TYPE_FLOAT: @@ -137,11 +165,6 @@ ffi_prep_cif_machdep (ffi_cif *cif) return FFI_OK; } -extern void ffi_call_SYSV (void *(*) (void *, extended_cif *), - extended_cif *, - unsigned, unsigned, unsigned, - void *, void (*fn) ()); - void ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue) { @@ -149,7 +172,7 @@ ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue) ecif.cif = cif; ecif.avalue = avalue; - + /* If the return value is a struct and we don't have a return value address then we need to make one. */ @@ -159,13 +182,11 @@ ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue) ecif.rvalue = alloca (cif->rtype->size); else ecif.rvalue = rvalue; - - - switch (cif->abi) + + switch (cif->abi) { case FFI_SYSV: - ffi_call_SYSV (ffi_prep_args, &ecif, cif->bytes, - cif->flags, cif->rtype->size * 8, + ffi_call_SYSV (&ecif, cif->bytes, cif->flags, ecif.rvalue, fn); break; @@ -174,3 +195,84 @@ ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue) break; } } + +static void +ffi_prep_incoming_args_SYSV (char *stack, void **avalue, ffi_cif *cif) +{ + unsigned int i; + void **p_argv; + char *argp; + ffi_type **p_arg; + + argp = stack; + p_argv = avalue; + + for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) + { + size_t z; + + z = (*p_arg)->size; + if (z <= 4) + { + *p_argv = (void *) (argp + 4 - z); + + z = 4; + } + else + { + *p_argv = (void *) argp; + + /* Align if necessary */ + if ((sizeof(int) - 1) & z) + z = ALIGN(z, sizeof(int)); + } + + p_argv++; + argp += z; + } +} + +unsigned int +ffi_closure_SYSV_inner (ffi_closure *closure, void *resp, void *args) +{ + ffi_cif *cif; + void **arg_area; + + cif = closure->cif; + arg_area = (void**) alloca (cif->nargs * sizeof (void *)); + + ffi_prep_incoming_args_SYSV(args, arg_area, cif); + + (closure->fun) (cif, resp, arg_area, closure->user_data); + + return cif->flags; +} + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void *codeloc) +{ + FFI_ASSERT (cif->abi == FFI_SYSV); + + *(unsigned short *)closure->tramp = 0x207c; + *(void **)(closure->tramp + 2) = codeloc; + *(unsigned short *)(closure->tramp + 6) = 0x4ef9; + if (cif->rtype->type == FFI_TYPE_STRUCT + && !cif->flags) + *(void **)(closure->tramp + 8) = ffi_closure_struct_SYSV; + else + *(void **)(closure->tramp + 8) = ffi_closure_SYSV; + + syscall(SYS_cacheflush, codeloc, FLUSH_SCOPE_LINE, + FLUSH_CACHE_BOTH, FFI_TRAMPOLINE_SIZE); + + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + return FFI_OK; +} + diff --git a/libffi/src/m68k/ffitarget.h b/libffi/src/m68k/ffitarget.h index aca7fac..9a072db 100644 --- a/libffi/src/m68k/ffitarget.h +++ b/libffi/src/m68k/ffitarget.h @@ -40,7 +40,8 @@ typedef enum ffi_abi { /* ---- Definitions for closures ----------------------------------------- */ -#define FFI_CLOSURES 0 +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 16 #define FFI_NATIVE_RAW_API 0 #endif diff --git a/libffi/src/m68k/sysv.S b/libffi/src/m68k/sysv.S index d019a37..d2a4ff1 100644 --- a/libffi/src/m68k/sysv.S +++ b/libffi/src/m68k/sysv.S @@ -8,40 +8,60 @@ #include #include +#ifdef HAVE_AS_CFI_PSEUDO_OP +#define CFI_STARTPROC() .cfi_startproc +#define CFI_OFFSET(reg,off) .cfi_offset reg,off +#define CFI_DEF_CFA(reg,off) .cfi_def_cfa reg,off +#define CFI_ENDPROC() .cfi_endproc +#else +#define CFI_STARTPROC() +#define CFI_OFFSET(reg,off) +#define CFI_DEF_CFA(reg,off) +#define CFI_ENDPROC() +#endif + .text .globl ffi_call_SYSV .type ffi_call_SYSV,@function + .align 4 ffi_call_SYSV: + CFI_STARTPROC() link %fp,#0 + CFI_OFFSET(14,-8) + CFI_DEF_CFA(14,8) move.l %d2,-(%sp) + CFI_OFFSET(2,-12) | Make room for all of the new args. - sub.l 16(%fp),%sp + sub.l 12(%fp),%sp | Call ffi_prep_args - move.l 12(%fp),-(%sp) + move.l 8(%fp),-(%sp) pea 4(%sp) - move.l 8(%fp),%a0 - jsr (%a0) +#if !defined __PIC__ + jsr ffi_prep_args +#else + bsr.l ffi_prep_args@PLTPC +#endif addq.l #8,%sp | Pass pointer to struct value, if any move.l %a0,%a1 | Call the function - move.l 32(%fp),%a0 + move.l 24(%fp),%a0 jsr (%a0) | Remove the space we pushed for the args - add.l 16(%fp),%sp + add.l 12(%fp),%sp | Load the pointer to storage for the return value - move.l 28(%fp),%a1 + move.l 20(%fp),%a1 | Load the return type code - move.l 20(%fp),%d2 + move.l 16(%fp),%d2 | If the return value pointer is NULL, assume no return value. tst.l %a1 @@ -79,19 +99,111 @@ retlongdouble: retpointer: btst #5,%d2 - jbeq retstruct + jbeq retstruct1 move.l %a0,(%a1) jbra epilogue -retstruct: +retstruct1: btst #6,%d2 + jbeq retstruct2 + move.b %d0,(%a1) + jbra epilogue + +retstruct2: + btst #7,%d2 jbeq noretval - move.l 24(%fp),%d2 - bfins %d0,(%a1){#0,%d2} + move.w %d0,(%a1) noretval: epilogue: move.l (%sp)+,%d2 - unlk %a6 + unlk %fp rts + CFI_ENDPROC() .size ffi_call_SYSV,.-ffi_call_SYSV + + .globl ffi_closure_SYSV + .type ffi_closure_SYSV, @function + .align 4 + +ffi_closure_SYSV: + CFI_STARTPROC() + link %fp,#-12 + CFI_OFFSET(14,-8) + CFI_DEF_CFA(14,8) + move.l %sp,-12(%fp) + pea 8(%fp) + pea -12(%fp) + move.l %a0,-(%sp) +#if !defined __PIC__ + jsr ffi_closure_SYSV_inner +#else + bsr.l ffi_closure_SYSV_inner@PLTPC +#endif + + lsr.l #1,%d0 + jne 1f + jcc .Lcls_epilogue + move.l -12(%fp),%d0 +.Lcls_epilogue: + unlk %fp + rts +1: + lea -12(%fp),%a0 + lsr.l #2,%d0 + jne 1f + jcs .Lcls_ret_float + move.l (%a0)+,%d0 + move.l (%a0),%d1 + jra .Lcls_epilogue +.Lcls_ret_float: + fmove.s (%a0),%fp0 + jra .Lcls_epilogue +1: + lsr.l #2,%d0 + jne 1f + jcs .Lcls_ret_ldouble + fmove.d (%a0),%fp0 + jra .Lcls_epilogue +.Lcls_ret_ldouble: + fmove.x (%a0),%fp0 + jra .Lcls_epilogue +1: + lsr.l #2,%d0 + jne .Lcls_ret_struct2 + jcs .Lcls_ret_struct1 + move.l (%a0),%a0 + move.l %a0,%d0 + jra .Lcls_epilogue +.Lcls_ret_struct1: + move.b (%a0),%d0 + jra .Lcls_epilogue +.Lcls_ret_struct2: + move.w (%a0),%d0 + jra .Lcls_epilogue + CFI_ENDPROC() + + .size ffi_closure_SYSV,.-ffi_closure_SYSV + + .globl ffi_closure_struct_SYSV + .type ffi_closure_struct_SYSV, @function + .align 4 + +ffi_closure_struct_SYSV: + CFI_STARTPROC() + link %fp,#0 + CFI_OFFSET(14,-8) + CFI_DEF_CFA(14,8) + move.l %sp,-12(%fp) + pea 8(%fp) + move.l %a1,-(%sp) + move.l %a0,-(%sp) +#if !defined __PIC__ + jsr ffi_closure_SYSV_inner +#else + bsr.l ffi_closure_SYSV_inner@PLTPC +#endif + unlk %fp + rts + CFI_ENDPROC() + .size ffi_closure_struct_SYSV,.-ffi_closure_struct_SYSV diff --git a/libffi/src/mips/ffi.c b/libffi/src/mips/ffi.c index 352226c..d0ce201 100644 --- a/libffi/src/mips/ffi.c +++ b/libffi/src/mips/ffi.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1996 Red Hat, Inc. + ffi.c - Copyright (c) 1996, 2007 Red Hat, Inc. MIPS Foreign Function Interface @@ -27,15 +27,20 @@ #include #include -#include -#if _MIPS_SIM == _ABIN32 +#ifdef FFI_DEBUG +# define FFI_MIPS_STOP_HERE() ffi_stop_here() +#else +# define FFI_MIPS_STOP_HERE() do {} while(0) +#endif + +#ifdef FFI_MIPS_N32 #define FIX_ARGP \ FFI_ASSERT(argp <= &stack[bytes]); \ if (argp == &stack[bytes]) \ { \ argp = stack; \ - ffi_stop_here(); \ + FFI_MIPS_STOP_HERE(); \ } #else #define FIX_ARGP @@ -50,17 +55,17 @@ static void ffi_prep_args(char *stack, int bytes, int flags) { - register int i; - register void **p_argv; - register char *argp; - register ffi_type **p_arg; + int i; + void **p_argv; + char *argp; + ffi_type **p_arg; -#if _MIPS_SIM == _ABIN32 +#ifdef FFI_MIPS_N32 /* If more than 8 double words are used, the remainder go on the stack. We reorder stuff on the stack here to support this easily. */ - if (bytes > 8 * FFI_SIZEOF_ARG) - argp = &stack[bytes - (8 * FFI_SIZEOF_ARG)]; + if (bytes > 8 * sizeof(ffi_arg)) + argp = &stack[bytes - (8 * sizeof(ffi_arg))]; else argp = stack; #else @@ -69,7 +74,7 @@ static void ffi_prep_args(char *stack, memset(stack, 0, bytes); -#if _MIPS_SIM == _ABIN32 +#ifdef FFI_MIPS_N32 if ( ecif->cif->rstruct_flag != 0 ) #else if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) @@ -85,105 +90,101 @@ static void ffi_prep_args(char *stack, for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++) { size_t z; - unsigned short a; + unsigned int a; - /* Align if necessary */ + /* Align if necessary. */ a = (*p_arg)->alignment; - if (a < FFI_SIZEOF_ARG) - a = FFI_SIZEOF_ARG; + if (a < sizeof(ffi_arg)) + a = sizeof(ffi_arg); - if ((a - 1) & (unsigned) argp) { - argp = (char *) ALIGN(argp, a); - FIX_ARGP; - } + if ((a - 1) & (unsigned long) argp) + { + argp = (char *) ALIGN(argp, a); + FIX_ARGP; + } -#if _MIPS_SIM == _ABIO32 -#define OFFSET 0 -#else -#define OFFSET sizeof(int) -#endif + z = (*p_arg)->size; + if (z <= sizeof(ffi_arg)) + { + int type = (*p_arg)->type; + z = sizeof(ffi_arg); + + /* The size of a pointer depends on the ABI */ + if (type == FFI_TYPE_POINTER) + type = + (ecif->cif->abi == FFI_N64) ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32; - z = (*p_arg)->size; - if (z < sizeof(ffi_arg)) + switch (type) { - z = sizeof(ffi_arg); + case FFI_TYPE_SINT8: + *(ffi_arg *)argp = *(SINT8 *)(* p_argv); + break; - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT8 *)(* p_argv); - break; - - case FFI_TYPE_UINT8: - *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT8 *)(* p_argv); - break; + case FFI_TYPE_UINT8: + *(ffi_arg *)argp = *(UINT8 *)(* p_argv); + break; - case FFI_TYPE_SINT16: - *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT16 *)(* p_argv); - break; + case FFI_TYPE_SINT16: + *(ffi_arg *)argp = *(SINT16 *)(* p_argv); + break; - case FFI_TYPE_UINT16: - *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT16 *)(* p_argv); - break; + case FFI_TYPE_UINT16: + *(ffi_arg *)argp = *(UINT16 *)(* p_argv); + break; - case FFI_TYPE_SINT32: - *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT32 *)(* p_argv); - break; + case FFI_TYPE_SINT32: + *(ffi_arg *)argp = *(SINT32 *)(* p_argv); + break; - case FFI_TYPE_UINT32: - case FFI_TYPE_POINTER: - *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT32 *)(* p_argv); - break; - - /* This can only happen with 64bit slots */ - case FFI_TYPE_FLOAT: - *(float *) argp = *(float *)(* p_argv); - break; - - /* Handle small structures */ - case FFI_TYPE_STRUCT: - memcpy(argp, *p_argv, (*p_arg)->size); - break; - - default: - FFI_ASSERT(0); - } + case FFI_TYPE_UINT32: + *(ffi_arg *)argp = *(UINT32 *)(* p_argv); + break; + + /* This can only happen with 64bit slots. */ + case FFI_TYPE_FLOAT: + *(float *) argp = *(float *)(* p_argv); + break; + + /* Handle structures. */ + default: + memcpy(argp, *p_argv, (*p_arg)->size); + break; } - else - { -#if _MIPS_SIM == _ABIO32 - memcpy(argp, *p_argv, z); + } + else + { +#ifdef FFI_MIPS_O32 + memcpy(argp, *p_argv, z); #else + { + unsigned long end = (unsigned long) argp + z; + unsigned long cap = (unsigned long) stack + bytes; + + /* Check if the data will fit within the register space. + Handle it if it doesn't. */ + + if (end <= cap) + memcpy(argp, *p_argv, z); + else { - unsigned end = (unsigned) argp+z; - unsigned cap = (unsigned) stack+bytes; - - /* Check if the data will fit within the register - space. Handle it if it doesn't. */ - - if (end <= cap) - memcpy(argp, *p_argv, z); - else - { - unsigned portion = end - cap; - - memcpy(argp, *p_argv, portion); - argp = stack; - memcpy(argp, - (void*)((unsigned)(*p_argv)+portion), z - portion); - } + unsigned long portion = cap - (unsigned long)argp; + + memcpy(argp, *p_argv, portion); + argp = stack; + z -= portion; + memcpy(argp, (void*)((unsigned long)(*p_argv) + portion), + z); } + } #endif - } - p_argv++; - argp += z; - FIX_ARGP; + } + p_argv++; + argp += z; + FIX_ARGP; } - - return; } -#if _MIPS_SIM == _ABIN32 +#ifdef FFI_MIPS_N32 /* The n32 spec says that if "a chunk consists solely of a double float field (but not a double, which is part of a union), it @@ -191,35 +192,41 @@ static void ffi_prep_args(char *stack, passed in an integer register". This code traverses structure definitions and generates the appropriate flags. */ -unsigned calc_n32_struct_flags(ffi_type *arg, unsigned *shift) +static unsigned +calc_n32_struct_flags(ffi_type *arg, unsigned *loc, unsigned *arg_reg) { unsigned flags = 0; unsigned index = 0; ffi_type *e; - while (e = arg->elements[index]) + while ((e = arg->elements[index])) { + /* Align this object. */ + *loc = ALIGN(*loc, e->alignment); if (e->type == FFI_TYPE_DOUBLE) { - flags += (FFI_TYPE_DOUBLE << *shift); - *shift += FFI_FLAG_BITS; + /* Already aligned to FFI_SIZEOF_ARG. */ + *arg_reg = *loc / FFI_SIZEOF_ARG; + if (*arg_reg > 7) + break; + flags += (FFI_TYPE_DOUBLE << (*arg_reg * FFI_FLAG_BITS)); + *loc += e->size; } - else if (e->type == FFI_TYPE_STRUCT) - flags += calc_n32_struct_flags(e, shift); else - *shift += FFI_FLAG_BITS; - + *loc += e->size; index++; } + /* Next Argument register at alignment of FFI_SIZEOF_ARG. */ + *arg_reg = ALIGN(*loc, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; return flags; } -unsigned calc_n32_return_struct_flags(ffi_type *arg) +static unsigned +calc_n32_return_struct_flags(ffi_type *arg) { unsigned flags = 0; - unsigned index = 0; unsigned small = FFI_TYPE_SMALLSTRUCT; ffi_type *e; @@ -238,16 +245,16 @@ unsigned calc_n32_return_struct_flags(ffi_type *arg) e = arg->elements[0]; if (e->type == FFI_TYPE_DOUBLE) - flags = FFI_TYPE_DOUBLE << FFI_FLAG_BITS; + flags = FFI_TYPE_DOUBLE; else if (e->type == FFI_TYPE_FLOAT) - flags = FFI_TYPE_FLOAT << FFI_FLAG_BITS; + flags = FFI_TYPE_FLOAT; if (flags && (e = arg->elements[1])) { if (e->type == FFI_TYPE_DOUBLE) - flags += FFI_TYPE_DOUBLE; + flags += FFI_TYPE_DOUBLE << FFI_FLAG_BITS; else if (e->type == FFI_TYPE_FLOAT) - flags += FFI_TYPE_FLOAT; + flags += FFI_TYPE_FLOAT << FFI_FLAG_BITS; else return small; @@ -272,7 +279,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) { cif->flags = 0; -#if _MIPS_SIM == _ABIO32 +#ifdef FFI_MIPS_O32 /* Set the flags necessary for O32 processing. FFI_O32_SOFT_FLOAT * does not have special handling for floating point args. */ @@ -360,10 +367,11 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) } #endif -#if _MIPS_SIM == _ABIN32 +#ifdef FFI_MIPS_N32 /* Set the flags necessary for N32 processing */ { - unsigned shift = 0; + unsigned arg_reg = 0; + unsigned loc = 0; unsigned count = (cif->nargs < 8) ? cif->nargs : 8; unsigned index = 0; @@ -378,7 +386,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) /* This means that the structure is being passed as a hidden argument */ - shift = FFI_FLAG_BITS; + arg_reg = 1; count = (cif->nargs < 7) ? cif->nargs : 7; cif->rstruct_flag = !0; @@ -389,23 +397,37 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) else cif->rstruct_flag = 0; - while (count-- > 0) + while (count-- > 0 && arg_reg < 8) { switch ((cif->arg_types)[index]->type) { case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: - cif->flags += ((cif->arg_types)[index]->type << shift); - shift += FFI_FLAG_BITS; + cif->flags += + ((cif->arg_types)[index]->type << (arg_reg * FFI_FLAG_BITS)); + arg_reg++; break; + case FFI_TYPE_LONGDOUBLE: + /* Align it. */ + arg_reg = ALIGN(arg_reg, 2); + /* Treat it as two adjacent doubles. */ + cif->flags += + (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS)); + arg_reg++; + cif->flags += + (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS)); + arg_reg++; + break; case FFI_TYPE_STRUCT: + loc = arg_reg * FFI_SIZEOF_ARG; cif->flags += calc_n32_struct_flags((cif->arg_types)[index], - &shift); + &loc, &arg_reg); break; default: - shift += FFI_FLAG_BITS; + arg_reg++; + break; } index++; @@ -440,7 +462,13 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) case FFI_TYPE_DOUBLE: cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8); break; - + case FFI_TYPE_LONGDOUBLE: + /* Long double is returned as if it were a struct containing + two doubles. */ + cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8); + cif->flags += (FFI_TYPE_DOUBLE + (FFI_TYPE_DOUBLE << FFI_FLAG_BITS)) + << (4 + (FFI_FLAG_BITS * 8)); + break; default: cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8); break; @@ -479,7 +507,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) switch (cif->abi) { -#if _MIPS_SIM == _ABIO32 +#ifdef FFI_MIPS_O32 case FFI_O32: case FFI_O32_SOFT_FLOAT: ffi_call_O32(ffi_prep_args, &ecif, cif->bytes, @@ -487,10 +515,25 @@ void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) break; #endif -#if _MIPS_SIM == _ABIN32 +#ifdef FFI_MIPS_N32 case FFI_N32: - ffi_call_N32(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); + case FFI_N64: + { + int copy_rvalue = 0; + void *rvalue_copy = ecif.rvalue; + if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16) + { + /* For structures smaller than 16 bytes we clobber memory + in 8 byte increments. Make a copy so we don't clobber + the callers memory outside of the struct bounds. */ + rvalue_copy = alloca(16); + copy_rvalue = 1; + } + ffi_call_N32(ffi_prep_args, &ecif, cif->bytes, + cif->flags, rvalue_copy, fn); + if (copy_rvalue) + memcpy(ecif.rvalue, rvalue_copy, cif->rtype->size); + } break; #endif @@ -500,41 +543,79 @@ void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) } } -#if FFI_CLOSURES /* N32 not implemented yet, FFI_CLOSURES not defined */ +#if FFI_CLOSURES #if defined(FFI_MIPS_O32) extern void ffi_closure_O32(void); +#else +extern void ffi_closure_N32(void); #endif /* FFI_MIPS_O32 */ ffi_status -ffi_prep_closure (ffi_closure *closure, - ffi_cif *cif, - void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data) +ffi_prep_closure_loc (ffi_closure *closure, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void *codeloc) { unsigned int *tramp = (unsigned int *) &closure->tramp[0]; - unsigned int fn; - unsigned int ctx = (unsigned int) closure; + void * fn; + char *clear_location = (char *) codeloc; #if defined(FFI_MIPS_O32) FFI_ASSERT(cif->abi == FFI_O32 || cif->abi == FFI_O32_SOFT_FLOAT); - fn = (unsigned int) ffi_closure_O32; + fn = ffi_closure_O32; #else /* FFI_MIPS_N32 */ - FFI_ASSERT(cif->abi == FFI_N32); - FFI_ASSERT(!"not implemented"); + FFI_ASSERT(cif->abi == FFI_N32 || cif->abi == FFI_N64); + fn = ffi_closure_N32; #endif /* FFI_MIPS_O32 */ - tramp[0] = 0x3c190000 | (fn >> 16); /* lui $25,high(fn) */ - tramp[1] = 0x3c080000 | (ctx >> 16); /* lui $8,high(ctx) */ - tramp[2] = 0x37390000 | (fn & 0xffff); /* ori $25,low(fn) */ - tramp[3] = 0x03200008; /* jr $25 */ - tramp[4] = 0x35080000 | (ctx & 0xffff); /* ori $8,low(ctx) */ +#if defined(FFI_MIPS_O32) || (_MIPS_SIM ==_ABIN32) + /* lui $25,high(fn) */ + tramp[0] = 0x3c190000 | ((unsigned)fn >> 16); + /* ori $25,low(fn) */ + tramp[1] = 0x37390000 | ((unsigned)fn & 0xffff); + /* lui $12,high(codeloc) */ + tramp[2] = 0x3c0c0000 | ((unsigned)codeloc >> 16); + /* jr $25 */ + tramp[3] = 0x03200008; + /* ori $12,low(codeloc) */ + tramp[4] = 0x358c0000 | ((unsigned)codeloc & 0xffff); +#else + /* N64 has a somewhat larger trampoline. */ + /* lui $25,high(fn) */ + tramp[0] = 0x3c190000 | ((unsigned long)fn >> 48); + /* lui $12,high(codeloc) */ + tramp[1] = 0x3c0c0000 | ((unsigned long)codeloc >> 48); + /* ori $25,mid-high(fn) */ + tramp[2] = 0x37390000 | (((unsigned long)fn >> 32 ) & 0xffff); + /* ori $12,mid-high(codeloc) */ + tramp[3] = 0x358c0000 | (((unsigned long)codeloc >> 32) & 0xffff); + /* dsll $25,$25,16 */ + tramp[4] = 0x0019cc38; + /* dsll $12,$12,16 */ + tramp[5] = 0x000c6438; + /* ori $25,mid-low(fn) */ + tramp[6] = 0x37390000 | (((unsigned long)fn >> 16 ) & 0xffff); + /* ori $12,mid-low(codeloc) */ + tramp[7] = 0x358c0000 | (((unsigned long)codeloc >> 16) & 0xffff); + /* dsll $25,$25,16 */ + tramp[8] = 0x0019cc38; + /* dsll $12,$12,16 */ + tramp[9] = 0x000c6438; + /* ori $25,low(fn) */ + tramp[10] = 0x37390000 | ((unsigned long)fn & 0xffff); + /* jr $25 */ + tramp[11] = 0x03200008; + /* ori $12,low(codeloc) */ + tramp[12] = 0x358c0000 | ((unsigned long)codeloc & 0xffff); + +#endif closure->cif = cif; closure->fun = fun; closure->user_data = user_data; - /* XXX this is available on Linux, but anything else? */ - cacheflush (tramp, FFI_TRAMPOLINE_SIZE, ICACHE); + __builtin___clear_cache(clear_location, clear_location + FFI_TRAMPOLINE_SIZE); return FFI_OK; } @@ -558,23 +639,25 @@ ffi_prep_closure (ffi_closure *closure, */ int ffi_closure_mips_inner_O32 (ffi_closure *closure, - void *rvalue, unsigned long *ar, + void *rvalue, ffi_arg *ar, double *fpr) { ffi_cif *cif; - void **avalue; + void **avaluep; + ffi_arg *avalue; ffi_type **arg_types; int i, avn, argn, seen_int; cif = closure->cif; - avalue = alloca (cif->nargs * sizeof (void *)); + avalue = alloca (cif->nargs * sizeof (ffi_arg)); + avaluep = alloca (cif->nargs * sizeof (ffi_arg)); seen_int = (cif->abi == FFI_O32_SOFT_FLOAT); argn = 0; if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT) { - rvalue = (void *) ar[0]; + rvalue = (void *)(UINT32)ar[0]; argn = 1; } @@ -588,13 +671,43 @@ ffi_closure_mips_inner_O32 (ffi_closure *closure, (arg_types[i]->type == FFI_TYPE_FLOAT || arg_types[i]->type == FFI_TYPE_DOUBLE)) { - avalue[i] = ((char *) &fpr[i]); +#ifdef __MIPSEB__ + if (arg_types[i]->type == FFI_TYPE_FLOAT) + avaluep[i] = ((char *) &fpr[i]) + sizeof (float); + else +#endif + avaluep[i] = (char *) &fpr[i]; } else { if (arg_types[i]->alignment == 8 && (argn & 0x1)) argn++; - avalue[i] = ((char *) &ar[argn]); + switch (arg_types[i]->type) + { + case FFI_TYPE_SINT8: + avaluep[i] = &avalue[i]; + *(SINT8 *) &avalue[i] = (SINT8) ar[argn]; + break; + + case FFI_TYPE_UINT8: + avaluep[i] = &avalue[i]; + *(UINT8 *) &avalue[i] = (UINT8) ar[argn]; + break; + + case FFI_TYPE_SINT16: + avaluep[i] = &avalue[i]; + *(SINT16 *) &avalue[i] = (SINT16) ar[argn]; + break; + + case FFI_TYPE_UINT16: + avaluep[i] = &avalue[i]; + *(UINT16 *) &avalue[i] = (UINT16) ar[argn]; + break; + + default: + avaluep[i] = (char *) &ar[argn]; + break; + } seen_int = 1; } argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; @@ -602,7 +715,7 @@ ffi_closure_mips_inner_O32 (ffi_closure *closure, } /* Invoke the closure. */ - (closure->fun) (cif, rvalue, avalue, closure->user_data); + (closure->fun) (cif, rvalue, avaluep, closure->user_data); if (cif->abi == FFI_O32_SOFT_FLOAT) { @@ -622,4 +735,177 @@ ffi_closure_mips_inner_O32 (ffi_closure *closure, } } +#if defined(FFI_MIPS_N32) + +static void +copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type, + int argn, unsigned arg_offset, ffi_arg *ar, + ffi_arg *fpr) +{ + ffi_type **elt_typep = type->elements; + while(*elt_typep) + { + ffi_type *elt_type = *elt_typep; + unsigned o; + char *tp; + char *argp; + char *fpp; + + o = ALIGN(offset, elt_type->alignment); + arg_offset += o - offset; + offset = o; + argn += arg_offset / sizeof(ffi_arg); + arg_offset = arg_offset % sizeof(ffi_arg); + + argp = (char *)(ar + argn); + fpp = (char *)(argn >= 8 ? ar + argn : fpr + argn); + + tp = target + offset; + + if (elt_type->type == FFI_TYPE_DOUBLE) + *(double *)tp = *(double *)fpp; + else + memcpy(tp, argp + arg_offset, elt_type->size); + + offset += elt_type->size; + arg_offset += elt_type->size; + elt_typep++; + argn += arg_offset / sizeof(ffi_arg); + arg_offset = arg_offset % sizeof(ffi_arg); + } +} + +/* + * Decodes the arguments to a function, which will be stored on the + * stack. AR is the pointer to the beginning of the integer + * arguments. FPR is a pointer to the area where floating point + * registers have been saved. + * + * RVALUE is the location where the function return value will be + * stored. CLOSURE is the prepared closure to invoke. + * + * This function should only be called from assembly, which is in + * turn called from a trampoline. + * + * Returns the function return flags. + * + */ +int +ffi_closure_mips_inner_N32 (ffi_closure *closure, + void *rvalue, ffi_arg *ar, + ffi_arg *fpr) +{ + ffi_cif *cif; + void **avaluep; + ffi_arg *avalue; + ffi_type **arg_types; + int i, avn, argn; + + cif = closure->cif; + avalue = alloca (cif->nargs * sizeof (ffi_arg)); + avaluep = alloca (cif->nargs * sizeof (ffi_arg)); + + argn = 0; + + if (cif->rstruct_flag) + { +#if _MIPS_SIM==_ABIN32 + rvalue = (void *)(UINT32)ar[0]; +#else /* N64 */ + rvalue = (void *)ar[0]; +#endif + argn = 1; + } + + i = 0; + avn = cif->nargs; + arg_types = cif->arg_types; + + while (i < avn) + { + if (arg_types[i]->type == FFI_TYPE_FLOAT + || arg_types[i]->type == FFI_TYPE_DOUBLE) + { + ffi_arg *argp = argn >= 8 ? ar + argn : fpr + argn; +#ifdef __MIPSEB__ + if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8) + avaluep[i] = ((char *) argp) + sizeof (float); + else +#endif + avaluep[i] = (char *) argp; + } + else + { + unsigned type = arg_types[i]->type; + + if (arg_types[i]->alignment > sizeof(ffi_arg)) + argn = ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg)); + + ffi_arg *argp = ar + argn; + + /* The size of a pointer depends on the ABI */ + if (type == FFI_TYPE_POINTER) + type = (cif->abi == FFI_N64) ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32; + + switch (type) + { + case FFI_TYPE_SINT8: + avaluep[i] = &avalue[i]; + *(SINT8 *) &avalue[i] = (SINT8) *argp; + break; + + case FFI_TYPE_UINT8: + avaluep[i] = &avalue[i]; + *(UINT8 *) &avalue[i] = (UINT8) *argp; + break; + + case FFI_TYPE_SINT16: + avaluep[i] = &avalue[i]; + *(SINT16 *) &avalue[i] = (SINT16) *argp; + break; + + case FFI_TYPE_UINT16: + avaluep[i] = &avalue[i]; + *(UINT16 *) &avalue[i] = (UINT16) *argp; + break; + + case FFI_TYPE_SINT32: + avaluep[i] = &avalue[i]; + *(SINT32 *) &avalue[i] = (SINT32) *argp; + break; + + case FFI_TYPE_UINT32: + avaluep[i] = &avalue[i]; + *(UINT32 *) &avalue[i] = (UINT32) *argp; + break; + + case FFI_TYPE_STRUCT: + if (argn < 8) + { + /* Allocate space for the struct as at least part of + it was passed in registers. */ + avaluep[i] = alloca(arg_types[i]->size); + copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i], + argn, 0, ar, fpr); + + break; + } + /* Else fall through. */ + default: + avaluep[i] = (char *) argp; + break; + } + } + argn += ALIGN(arg_types[i]->size, sizeof(ffi_arg)) / sizeof(ffi_arg); + i++; + } + + /* Invoke the closure. */ + (closure->fun) (cif, rvalue, avaluep, closure->user_data); + + return cif->flags >> (FFI_FLAG_BITS * 8); +} + +#endif /* FFI_MIPS_N32 */ + #endif /* FFI_CLOSURES */ diff --git a/libffi/src/mips/ffitarget.h b/libffi/src/mips/ffitarget.h index 6f28e70..ccfc82b 100644 --- a/libffi/src/mips/ffitarget.h +++ b/libffi/src/mips/ffitarget.h @@ -26,17 +26,13 @@ #ifndef LIBFFI_TARGET_H #define LIBFFI_TARGET_H -#ifndef LIBFFI_ASM -#include -#endif - #if !defined(_MIPS_SIM) -- something is very wrong -- #else # if (_MIPS_SIM==_ABIN32 && defined(_ABIN32)) || (_MIPS_SIM==_ABI64 && defined(_ABI64)) # define FFI_MIPS_N32 # else -# if _MIPS_SIM==_ABIO32 && defined(_ABIO32) +# if (_MIPS_SIM==_ABIO32 && defined(_ABIO32)) # define FFI_MIPS_O32 # else -- this is an unsupported platform -- @@ -46,10 +42,13 @@ #ifdef FFI_MIPS_O32 /* O32 stack frames have 32bit integer args */ -#define FFI_SIZEOF_ARG 4 +# define FFI_SIZEOF_ARG 4 #else /* N32 and N64 frames have 64bit integer args */ -#define FFI_SIZEOF_ARG 8 +# define FFI_SIZEOF_ARG 8 +# if _MIPS_SIM == _ABIN32 +# define FFI_SIZEOF_JAVA_RAW 4 +# endif #endif #define FFI_FLAG_BITS 2 @@ -108,19 +107,28 @@ #define ra $31 #ifdef FFI_MIPS_O32 -#define REG_L lw -#define REG_S sw -#define SUBU subu -#define ADDU addu -#define SRL srl -#define LI li +# define REG_L lw +# define REG_S sw +# define SUBU subu +# define ADDU addu +# define SRL srl +# define LI li #else /* !FFI_MIPS_O32 */ -#define REG_L ld -#define REG_S sd -#define SUBU dsubu -#define ADDU daddu -#define SRL dsrl -#define LI dli +# define REG_L ld +# define REG_S sd +# define SUBU dsubu +# define ADDU daddu +# define SRL dsrl +# define LI dli +# if (_MIPS_SIM==_ABI64) +# define LA dla +# define EH_FRAME_ALIGN 3 +# define FDE_ADDR_BYTES .8byte +# else +# define LA la +# define EH_FRAME_ALIGN 2 +# define FDE_ADDR_BYTES .4byte +# endif /* _MIPS_SIM==_ABI64 */ #endif /* !FFI_MIPS_O32 */ #else /* !LIBFFI_ASM */ #ifdef FFI_MIPS_O32 @@ -147,7 +155,11 @@ typedef enum ffi_abi { FFI_DEFAULT_ABI = FFI_O32, #endif #else +# if _MIPS_SIM==_ABI64 + FFI_DEFAULT_ABI = FFI_N64, +# else FFI_DEFAULT_ABI = FFI_N32, +# endif #endif FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 @@ -162,8 +174,13 @@ typedef enum ffi_abi { #define FFI_CLOSURES 1 #define FFI_TRAMPOLINE_SIZE 20 #else -/* N32/N64 not implemented yet. */ -#define FFI_CLOSURES 0 +/* N32/N64. */ +# define FFI_CLOSURES 1 +#if _MIPS_SIM==_ABI64 +#define FFI_TRAMPOLINE_SIZE 52 +#else +#define FFI_TRAMPOLINE_SIZE 20 +#endif #endif /* FFI_MIPS_O32 */ #define FFI_NATIVE_RAW_API 0 diff --git a/libffi/src/mips/n32.S b/libffi/src/mips/n32.S index 358cfd7..2f9edb4 100644 --- a/libffi/src/mips/n32.S +++ b/libffi/src/mips/n32.S @@ -45,13 +45,19 @@ .globl ffi_call_N32 .ent ffi_call_N32 ffi_call_N32: +.LFB3: + .frame $fp, SIZEOF_FRAME, ra + .mask 0xc0000000,-FFI_SIZEOF_ARG + .fmask 0x00000000,0 # Prologue SUBU $sp, SIZEOF_FRAME # Frame size +.LCFI0: REG_S $fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Save frame pointer REG_S ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp) # Save return address +.LCFI1: move $fp, $sp - +.LCFI3: move t9, callback # callback function pointer REG_S bytes, 2*FFI_SIZEOF_ARG($fp) # bytes REG_S flags, 3*FFI_SIZEOF_ARG($fp) # flags @@ -72,14 +78,12 @@ sixteen: SUBU $sp, $sp, v0 # move the stack pointer to reflect the # arg space - ADDU a0, $sp, 0 # 4 * FFI_SIZEOF_ARG + move a0, $sp # 4 * FFI_SIZEOF_ARG ADDU a3, $fp, 3 * FFI_SIZEOF_ARG # Call ffi_prep_args jal t9 - # ADDU $sp, $sp, 4 * FFI_SIZEOF_ARG # adjust $sp to new args - # Copy the stack pointer to t9 move t9, $sp @@ -90,18 +94,16 @@ sixteen: REG_L t6, 2*FFI_SIZEOF_ARG($fp) # Is it bigger than 8 * FFI_SIZEOF_ARG? - dadd t7, $0, 8 * FFI_SIZEOF_ARG - dsub t8, t6, t7 + daddiu t8, t6, -(8 * FFI_SIZEOF_ARG) bltz t8, loadregs - add t9, t9, t8 + ADDU t9, t9, t8 loadregs: - REG_L t4, 3*FFI_SIZEOF_ARG($fp) # load the flags word - add t6, t4, 0 # and copy it into t6 + REG_L t6, 3*FFI_SIZEOF_ARG($fp) # load the flags word into t6. - and t4, ((1< HPPA Foreign Function Interface + HP-UX PA ABI support (c) 2006 Free Software Foundation, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -30,15 +31,19 @@ #include #define ROUND_UP(v, a) (((size_t)(v) + (a) - 1) & ~((a) - 1)) -#define ROUND_DOWN(v, a) (((size_t)(v) - (a) + 1) & ~((a) - 1)) + #define MIN_STACK_SIZE 64 #define FIRST_ARG_SLOT 9 #define DEBUG_LEVEL 0 -#define fldw(addr, fpreg) asm volatile ("fldw 0(%0), %%" #fpreg "L" : : "r"(addr) : #fpreg) -#define fstw(fpreg, addr) asm volatile ("fstw %%" #fpreg "L, 0(%0)" : : "r"(addr)) -#define fldd(addr, fpreg) asm volatile ("fldd 0(%0), %%" #fpreg : : "r"(addr) : #fpreg) -#define fstd(fpreg, addr) asm volatile ("fstd %%" #fpreg "L, 0(%0)" : : "r"(addr)) +#define fldw(addr, fpreg) \ + __asm__ volatile ("fldw 0(%0), %%" #fpreg "L" : : "r"(addr) : #fpreg) +#define fstw(fpreg, addr) \ + __asm__ volatile ("fstw %%" #fpreg "L, 0(%0)" : : "r"(addr)) +#define fldd(addr, fpreg) \ + __asm__ volatile ("fldd 0(%0), %%" #fpreg : : "r"(addr) : #fpreg) +#define fstd(fpreg, addr) \ + __asm__ volatile ("fstd %%" #fpreg "L, 0(%0)" : : "r"(addr)) #define debug(lvl, x...) do { if (lvl <= DEBUG_LEVEL) { printf(x); } } while (0) @@ -47,16 +52,19 @@ static inline int ffi_struct_type(ffi_type *t) size_t sz = t->size; /* Small structure results are passed in registers, - larger ones are passed by pointer. */ + larger ones are passed by pointer. Note that + small structures of size 2, 4 and 8 differ from + the corresponding integer types in that they have + different alignment requirements. */ if (sz <= 1) return FFI_TYPE_UINT8; else if (sz == 2) - return FFI_TYPE_UINT16; + return FFI_TYPE_SMALL_STRUCT2; else if (sz == 3) return FFI_TYPE_SMALL_STRUCT3; else if (sz == 4) - return FFI_TYPE_UINT32; + return FFI_TYPE_SMALL_STRUCT4; else if (sz == 5) return FFI_TYPE_SMALL_STRUCT5; else if (sz == 6) @@ -64,61 +72,80 @@ static inline int ffi_struct_type(ffi_type *t) else if (sz == 7) return FFI_TYPE_SMALL_STRUCT7; else if (sz <= 8) - return FFI_TYPE_UINT64; + return FFI_TYPE_SMALL_STRUCT8; else return FFI_TYPE_STRUCT; /* else, we pass it by pointer. */ } /* PA has a downward growing stack, which looks like this: - + Offset - [ Variable args ] + [ Variable args ] SP = (4*(n+9)) arg word N ... SP-52 arg word 4 - [ Fixed args ] + [ Fixed args ] SP-48 arg word 3 SP-44 arg word 2 SP-40 arg word 1 SP-36 arg word 0 - [ Frame marker ] + [ Frame marker ] ... SP-20 RP SP-4 previous SP - - First 4 non-FP 32-bit args are passed in gr26, gr25, gr24 and gr23 - First 2 non-FP 64-bit args are passed in register pairs, starting - on an even numbered register (i.e. r26/r25 and r24+r23) - First 4 FP 32-bit arguments are passed in fr4L, fr5L, fr6L and fr7L - First 2 FP 64-bit arguments are passed in fr5 and fr7 - The rest are passed on the stack starting at SP-52, but 64-bit - arguments need to be aligned to an 8-byte boundary - + + The first four argument words on the stack are reserved for use by + the callee. Instead, the general and floating registers replace + the first four argument slots. Non FP arguments are passed solely + in the general registers. FP arguments are passed in both general + and floating registers when using libffi. + + Non-FP 32-bit args are passed in gr26, gr25, gr24 and gr23. + Non-FP 64-bit args are passed in register pairs, starting + on an odd numbered register (i.e. r25+r26 and r23+r24). + FP 32-bit arguments are passed in fr4L, fr5L, fr6L and fr7L. + FP 64-bit arguments are passed in fr5 and fr7. + + The registers are allocated in the same manner as stack slots. + This allows the callee to save its arguments on the stack if + necessary: + + arg word 3 -> gr23 or fr7L + arg word 2 -> gr24 or fr6L or fr7R + arg word 1 -> gr25 or fr5L + arg word 0 -> gr26 or fr4L or fr5R + + Note that fr4R and fr6R are never used for arguments (i.e., + doubles are not passed in fr4 or fr6). + + The rest of the arguments are passed on the stack starting at SP-52, + but 64-bit arguments need to be aligned to an 8-byte boundary + This means we can have holes either in the register allocation, or in the stack. */ /* ffi_prep_args is called by the assembly routine once stack space has been allocated for the function's arguments - + The following code will put everything into the stack frame (which was allocated by the asm routine), and on return the asm routine will load the arguments that should be passed by register into the appropriate registers - + NOTE: We load floating point args in this function... that means we assume gcc will not mess with fp regs in here. */ -/*@-exportheader@*/ -void ffi_prep_args_LINUX(UINT32 *stack, extended_cif *ecif, unsigned bytes) -/*@=exportheader@*/ +void ffi_prep_args_pa32(UINT32 *stack, extended_cif *ecif, unsigned bytes) { register unsigned int i; register ffi_type **p_arg; register void **p_argv; - unsigned int slot = FIRST_ARG_SLOT - 1; + unsigned int slot = FIRST_ARG_SLOT; char *dest_cpy; + size_t len; - debug(1, "%s: stack = %p, ecif = %p, bytes = %u\n", __FUNCTION__, stack, ecif, bytes); + debug(1, "%s: stack = %p, ecif = %p, bytes = %u\n", __FUNCTION__, stack, + ecif, bytes); p_arg = ecif->cif->arg_types; p_argv = ecif->avalue; @@ -130,116 +157,105 @@ void ffi_prep_args_LINUX(UINT32 *stack, extended_cif *ecif, unsigned bytes) switch (type) { case FFI_TYPE_SINT8: - slot++; *(SINT32 *)(stack - slot) = *(SINT8 *)(*p_argv); break; case FFI_TYPE_UINT8: - slot++; *(UINT32 *)(stack - slot) = *(UINT8 *)(*p_argv); break; case FFI_TYPE_SINT16: - slot++; *(SINT32 *)(stack - slot) = *(SINT16 *)(*p_argv); break; case FFI_TYPE_UINT16: - slot++; *(UINT32 *)(stack - slot) = *(UINT16 *)(*p_argv); break; case FFI_TYPE_UINT32: case FFI_TYPE_SINT32: case FFI_TYPE_POINTER: - slot++; - debug(3, "Storing UINT32 %u in slot %u\n", *(UINT32 *)(*p_argv), slot); + debug(3, "Storing UINT32 %u in slot %u\n", *(UINT32 *)(*p_argv), + slot); *(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv); break; case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: - slot += 2; - if (slot & 1) - slot++; - - *(UINT32 *)(stack - slot) = (*(UINT64 *)(*p_argv)) >> 32; - *(UINT32 *)(stack - slot + 1) = (*(UINT64 *)(*p_argv)) & 0xffffffffUL; + /* Align slot for 64-bit type. */ + slot += (slot & 1) ? 1 : 2; + *(UINT64 *)(stack - slot) = *(UINT64 *)(*p_argv); break; case FFI_TYPE_FLOAT: - /* First 4 args go in fr4L - fr7L */ - slot++; + /* First 4 args go in fr4L - fr7L. */ + debug(3, "Storing UINT32(float) in slot %u\n", slot); + *(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv); switch (slot - FIRST_ARG_SLOT) { - case 0: fldw(*p_argv, fr4); break; - case 1: fldw(*p_argv, fr5); break; - case 2: fldw(*p_argv, fr6); break; - case 3: fldw(*p_argv, fr7); break; - default: - /* Other ones are just passed on the stack. */ - debug(3, "Storing UINT32(float) in slot %u\n", slot); - *(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv); - break; + /* First 4 args go in fr4L - fr7L. */ + case 0: fldw(stack - slot, fr4); break; + case 1: fldw(stack - slot, fr5); break; + case 2: fldw(stack - slot, fr6); break; + case 3: fldw(stack - slot, fr7); break; } - break; + break; case FFI_TYPE_DOUBLE: - slot += 2; - if (slot & 1) - slot++; - switch (slot - FIRST_ARG_SLOT + 1) + /* Align slot for 64-bit type. */ + slot += (slot & 1) ? 1 : 2; + debug(3, "Storing UINT64(double) at slot %u\n", slot); + *(UINT64 *)(stack - slot) = *(UINT64 *)(*p_argv); + switch (slot - FIRST_ARG_SLOT) { - /* First 2 args go in fr5, fr7 */ - case 2: fldd(*p_argv, fr5); break; - case 4: fldd(*p_argv, fr7); break; - default: - debug(3, "Storing UINT64(double) at slot %u\n", slot); - *(UINT64 *)(stack - slot) = *(UINT64 *)(*p_argv); - break; + /* First 2 args go in fr5, fr7. */ + case 1: fldd(stack - slot, fr5); break; + case 3: fldd(stack - slot, fr7); break; } break; +#ifdef PA_HPUX + case FFI_TYPE_LONGDOUBLE: + /* Long doubles are passed in the same manner as structures + larger than 8 bytes. */ + *(UINT32 *)(stack - slot) = (UINT32)(*p_argv); + break; +#endif + case FFI_TYPE_STRUCT: /* Structs smaller or equal than 4 bytes are passed in one register. Structs smaller or equal 8 bytes are passed in two registers. Larger structures are passed by pointer. */ - if((*p_arg)->size <= 4) + len = (*p_arg)->size; + if (len <= 4) { - slot++; - dest_cpy = (char *)(stack - slot); - dest_cpy += 4 - (*p_arg)->size; - memcpy((char *)dest_cpy, (char *)*p_argv, (*p_arg)->size); + dest_cpy = (char *)(stack - slot) + 4 - len; + memcpy(dest_cpy, (char *)*p_argv, len); } - else if ((*p_arg)->size <= 8) - { - slot += 2; - if (slot & 1) - slot++; - dest_cpy = (char *)(stack - slot); - dest_cpy += 8 - (*p_arg)->size; - memcpy((char *)dest_cpy, (char *)*p_argv, (*p_arg)->size); - } - else + else if (len <= 8) { - slot++; - *(UINT32 *)(stack - slot) = (UINT32)(*p_argv); + slot += (slot & 1) ? 1 : 2; + dest_cpy = (char *)(stack - slot) + 8 - len; + memcpy(dest_cpy, (char *)*p_argv, len); } + else + *(UINT32 *)(stack - slot) = (UINT32)(*p_argv); break; default: FFI_ASSERT(0); } + slot++; p_arg++; p_argv++; } /* Make sure we didn't mess up and scribble on the stack. */ { - int n; + unsigned int n; debug(5, "Stack setup:\n"); for (n = 0; n < (bytes + 3) / 4; n++) @@ -255,7 +271,7 @@ void ffi_prep_args_LINUX(UINT32 *stack, extended_cif *ecif, unsigned bytes) return; } -static void ffi_size_stack_LINUX(ffi_cif *cif) +static void ffi_size_stack_pa32(ffi_cif *cif) { ffi_type **ptr; int i; @@ -273,6 +289,9 @@ static void ffi_size_stack_LINUX(ffi_cif *cif) z += 2 + (z & 1); /* must start on even regs, so we may waste one */ break; +#ifdef PA_HPUX + case FFI_TYPE_LONGDOUBLE: +#endif case FFI_TYPE_STRUCT: z += 1; /* pass by ptr, callee will copy */ break; @@ -304,6 +323,13 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) cif->flags = (unsigned) cif->rtype->type; break; +#ifdef PA_HPUX + case FFI_TYPE_LONGDOUBLE: + /* Long doubles are treated like a structure. */ + cif->flags = FFI_TYPE_STRUCT; + break; +#endif + case FFI_TYPE_STRUCT: /* For the return type we have to check the size of the structures. If the size is smaller or equal 4 bytes, the result is given back @@ -327,8 +353,8 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) own stack sizing. */ switch (cif->abi) { - case FFI_LINUX: - ffi_size_stack_LINUX(cif); + case FFI_PA32: + ffi_size_stack_pa32(cif); break; default: @@ -339,20 +365,11 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) return FFI_OK; } -/*@-declundef@*/ -/*@-exportheader@*/ -extern void ffi_call_LINUX(void (*)(UINT32 *, extended_cif *, unsigned), - /*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, - void (*fn)()); -/*@=declundef@*/ -/*@=exportheader@*/ - -void ffi_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ void **avalue) +extern void ffi_call_pa32(void (*)(UINT32 *, extended_cif *, unsigned), + extended_cif *, unsigned, unsigned, unsigned *, + void (*fn)()); + +void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) { extended_cif ecif; @@ -362,12 +379,15 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, /* If the return value is a struct and we don't have a return value address then we need to make one. */ - if ((rvalue == NULL) && - (cif->rtype->type == FFI_TYPE_STRUCT)) + if (rvalue == NULL +#ifdef PA_HPUX + && (cif->rtype->type == FFI_TYPE_STRUCT + || cif->rtype->type == FFI_TYPE_LONGDOUBLE)) +#else + && cif->rtype->type == FFI_TYPE_STRUCT) +#endif { - /*@-sysunrecog@*/ ecif.rvalue = alloca(cif->rtype->size); - /*@=sysunrecog@*/ } else ecif.rvalue = rvalue; @@ -375,12 +395,10 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, switch (cif->abi) { - case FFI_LINUX: - /*@-usedef@*/ - debug(2, "Calling ffi_call_LINUX: ecif=%p, bytes=%u, flags=%u, rvalue=%p, fn=%p\n", &ecif, cif->bytes, cif->flags, ecif.rvalue, (void *)fn); - ffi_call_LINUX(ffi_prep_args_LINUX, &ecif, cif->bytes, + case FFI_PA32: + debug(3, "Calling ffi_call_pa32: ecif=%p, bytes=%u, flags=%u, rvalue=%p, fn=%p\n", &ecif, cif->bytes, cif->flags, ecif.rvalue, (void *)fn); + ffi_call_pa32(ffi_prep_args_pa32, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ break; default: @@ -394,7 +412,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, the stack, and we need to fill them into a cif structure and invoke the user function. This really ought to be in asm to make sure the compiler doesn't do things we don't expect. */ -UINT32 ffi_closure_inner_LINUX(ffi_closure *closure, UINT32 *stack) +ffi_status ffi_closure_inner_pa32(ffi_closure *closure, UINT32 *stack) { ffi_cif *cif; void **avalue; @@ -402,7 +420,8 @@ UINT32 ffi_closure_inner_LINUX(ffi_closure *closure, UINT32 *stack) UINT32 ret[2]; /* function can return up to 64-bits in registers */ ffi_type **p_arg; char *tmp; - int i, avn, slot = FIRST_ARG_SLOT - 1; + int i, avn; + unsigned int slot = FIRST_ARG_SLOT; register UINT32 r28 asm("r28"); cif = closure->cif; @@ -430,20 +449,23 @@ UINT32 ffi_closure_inner_LINUX(ffi_closure *closure, UINT32 *stack) case FFI_TYPE_SINT32: case FFI_TYPE_UINT32: case FFI_TYPE_POINTER: - slot++; avalue[i] = (char *)(stack - slot) + sizeof(UINT32) - (*p_arg)->size; break; case FFI_TYPE_SINT64: case FFI_TYPE_UINT64: - slot += 2; - if (slot & 1) - slot++; + slot += (slot & 1) ? 1 : 2; avalue[i] = (void *)(stack - slot); break; case FFI_TYPE_FLOAT: - slot++; +#ifdef PA_LINUX + /* The closure call is indirect. In Linux, floating point + arguments in indirect calls with a prototype are passed + in the floating point registers instead of the general + registers. So, we need to replace what was previously + stored in the current slot with the value in the + corresponding floating point register. */ switch (slot - FIRST_ARG_SLOT) { case 0: fstw(fr4, (void *)(stack - slot)); break; @@ -451,18 +473,20 @@ UINT32 ffi_closure_inner_LINUX(ffi_closure *closure, UINT32 *stack) case 2: fstw(fr6, (void *)(stack - slot)); break; case 3: fstw(fr7, (void *)(stack - slot)); break; } +#endif avalue[i] = (void *)(stack - slot); break; case FFI_TYPE_DOUBLE: - slot += 2; - if (slot & 1) - slot++; - switch (slot - FIRST_ARG_SLOT + 1) + slot += (slot & 1) ? 1 : 2; +#ifdef PA_LINUX + /* See previous comment for FFI_TYPE_FLOAT. */ + switch (slot - FIRST_ARG_SLOT) { - case 2: fstd(fr5, (void *)(stack - slot)); break; - case 4: fstd(fr7, (void *)(stack - slot)); break; + case 1: fstd(fr5, (void *)(stack - slot)); break; + case 3: fstd(fr7, (void *)(stack - slot)); break; } +#endif avalue[i] = (void *)(stack - slot); break; @@ -470,35 +494,36 @@ UINT32 ffi_closure_inner_LINUX(ffi_closure *closure, UINT32 *stack) /* Structs smaller or equal than 4 bytes are passed in one register. Structs smaller or equal 8 bytes are passed in two registers. Larger structures are passed by pointer. */ - if((*p_arg)->size <= 4) { - slot++; - avalue[i] = (void *)(stack - slot) + sizeof(UINT32) - - (*p_arg)->size; - } else if ((*p_arg)->size <= 8) { - slot += 2; - if (slot & 1) - slot++; - avalue[i] = (void *)(stack - slot) + sizeof(UINT64) - - (*p_arg)->size; - } else { - slot++; + if((*p_arg)->size <= 4) + { + avalue[i] = (void *)(stack - slot) + sizeof(UINT32) - + (*p_arg)->size; + } + else if ((*p_arg)->size <= 8) + { + slot += (slot & 1) ? 1 : 2; + avalue[i] = (void *)(stack - slot) + sizeof(UINT64) - + (*p_arg)->size; + } + else avalue[i] = (void *) *(stack - slot); - } break; default: FFI_ASSERT(0); } + slot++; p_arg++; } /* Invoke the closure. */ (closure->fun) (cif, rvalue, avalue, closure->user_data); - debug(3, "after calling function, ret[0] = %08x, ret[1] = %08x\n", ret[0], ret[1]); + debug(3, "after calling function, ret[0] = %08x, ret[1] = %08x\n", ret[0], + ret[1]); - /* Store the result */ + /* Store the result using the lower 2 bytes of the flags. */ switch (cif->flags) { case FFI_TYPE_UINT8: @@ -536,7 +561,9 @@ UINT32 ffi_closure_inner_LINUX(ffi_closure *closure, UINT32 *stack) /* Don't need a return value, done by caller. */ break; + case FFI_TYPE_SMALL_STRUCT2: case FFI_TYPE_SMALL_STRUCT3: + case FFI_TYPE_SMALL_STRUCT4: tmp = (void*)(stack - FIRST_ARG_SLOT); tmp += 4 - cif->rtype->size; memcpy((void*)tmp, &ret[0], cif->rtype->size); @@ -545,6 +572,7 @@ UINT32 ffi_closure_inner_LINUX(ffi_closure *closure, UINT32 *stack) case FFI_TYPE_SMALL_STRUCT5: case FFI_TYPE_SMALL_STRUCT6: case FFI_TYPE_SMALL_STRUCT7: + case FFI_TYPE_SMALL_STRUCT8: { unsigned int ret2[2]; int off; @@ -582,39 +610,93 @@ UINT32 ffi_closure_inner_LINUX(ffi_closure *closure, UINT32 *stack) cif specifies the argument and result types for fun. The cif must already be prep'ed. */ -void ffi_closure_LINUX(void); +extern void ffi_closure_pa32(void); ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data) +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void *codeloc) { UINT32 *tramp = (UINT32 *)(closure->tramp); +#ifdef PA_HPUX + UINT32 *tmp; +#endif - FFI_ASSERT (cif->abi == FFI_LINUX); + FFI_ASSERT (cif->abi == FFI_PA32); /* Make a small trampoline that will branch to our handler function. Use PC-relative addressing. */ - tramp[0] = 0xeaa00000; /* b,l .+8, %r21 ; %r21 <- pc+8 */ - tramp[1] = 0xd6a01c1e; /* depi 0,31,2, %r21 ; mask priv bits */ - tramp[2] = 0x4aa10028; /* ldw 20(%r21), %r1 ; load plabel */ - tramp[3] = 0x36b53ff1; /* ldo -8(%r21), %r21 ; get closure addr */ - tramp[4] = 0x0c201096; /* ldw 0(%r1), %r22 ; address of handler */ - tramp[5] = 0xeac0c000; /* bv %r0(%r22) ; branch to handler */ - tramp[6] = 0x0c281093; /* ldw 4(%r1), %r19 ; GP of handler */ - tramp[7] = ((UINT32)(ffi_closure_LINUX) & ~2); +#ifdef PA_LINUX + tramp[0] = 0xeaa00000; /* b,l .+8,%r21 ; %r21 <- pc+8 */ + tramp[1] = 0xd6a01c1e; /* depi 0,31,2,%r21 ; mask priv bits */ + tramp[2] = 0x4aa10028; /* ldw 20(%r21),%r1 ; load plabel */ + tramp[3] = 0x36b53ff1; /* ldo -8(%r21),%r21 ; get closure addr */ + tramp[4] = 0x0c201096; /* ldw 0(%r1),%r22 ; address of handler */ + tramp[5] = 0xeac0c000; /* bv%r0(%r22) ; branch to handler */ + tramp[6] = 0x0c281093; /* ldw 4(%r1),%r19 ; GP of handler */ + tramp[7] = ((UINT32)(ffi_closure_pa32) & ~2); /* Flush d/icache -- have to flush up 2 two lines because of alignment. */ - asm volatile ( - "fdc 0(%0)\n" - "fdc %1(%0)\n" - "fic 0(%%sr4, %0)\n" - "fic %1(%%sr4, %0)\n" - "sync\n" - : : "r"((unsigned long)tramp & ~31), "r"(32 /* stride */)); + __asm__ volatile( + "fdc 0(%0)\n\t" + "fdc %1(%0)\n\t" + "fic 0(%%sr4, %0)\n\t" + "fic %1(%%sr4, %0)\n\t" + "sync\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n" + : + : "r"((unsigned long)tramp & ~31), + "r"(32 /* stride */) + : "memory"); +#endif + +#ifdef PA_HPUX + tramp[0] = 0xeaa00000; /* b,l .+8,%r21 ; %r21 <- pc+8 */ + tramp[1] = 0xd6a01c1e; /* depi 0,31,2,%r21 ; mask priv bits */ + tramp[2] = 0x4aa10038; /* ldw 28(%r21),%r1 ; load plabel */ + tramp[3] = 0x36b53ff1; /* ldo -8(%r21),%r21 ; get closure addr */ + tramp[4] = 0x0c201096; /* ldw 0(%r1),%r22 ; address of handler */ + tramp[5] = 0x02c010b4; /* ldsid (%r22),%r20 ; load space id */ + tramp[6] = 0x00141820; /* mtsp %r20,%sr0 ; into %sr0 */ + tramp[7] = 0xe2c00000; /* be 0(%sr0,%r22) ; branch to handler */ + tramp[8] = 0x0c281093; /* ldw 4(%r1),%r19 ; GP of handler */ + tramp[9] = ((UINT32)(ffi_closure_pa32) & ~2); + + /* Flush d/icache -- have to flush three lines because of alignment. */ + __asm__ volatile( + "copy %1,%0\n\t" + "fdc,m %2(%0)\n\t" + "fdc,m %2(%0)\n\t" + "fdc,m %2(%0)\n\t" + "ldsid (%1),%0\n\t" + "mtsp %0,%%sr0\n\t" + "copy %1,%0\n\t" + "fic,m %2(%%sr0,%0)\n\t" + "fic,m %2(%%sr0,%0)\n\t" + "fic,m %2(%%sr0,%0)\n\t" + "sync\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n" + : "=&r" ((unsigned long)tmp) + : "r" ((unsigned long)tramp & ~31), + "r" (32/* stride */) + : "memory"); +#endif closure->cif = cif; closure->user_data = user_data; diff --git a/libffi/src/pa/ffitarget.h b/libffi/src/pa/ffitarget.h index 5620696..95ac480 100644 --- a/libffi/src/pa/ffitarget.h +++ b/libffi/src/pa/ffitarget.h @@ -35,9 +35,20 @@ typedef signed long ffi_sarg; typedef enum ffi_abi { FFI_FIRST_ABI = 0, -#ifdef PA - FFI_LINUX, - FFI_DEFAULT_ABI = FFI_LINUX, +#ifdef PA_LINUX + FFI_PA32, + FFI_DEFAULT_ABI = FFI_PA32, +#endif + +#ifdef PA_HPUX + FFI_PA32, + FFI_DEFAULT_ABI = FFI_PA32, +#endif + +#ifdef PA64_HPUX +#error "PA64_HPUX FFI is not yet implemented" + FFI_PA64, + FFI_DEFAULT_ABI = FFI_PA64, #endif FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 @@ -49,11 +60,17 @@ typedef enum ffi_abi { #define FFI_CLOSURES 1 #define FFI_NATIVE_RAW_API 0 +#ifdef PA_LINUX #define FFI_TRAMPOLINE_SIZE 32 - -#define FFI_TYPE_SMALL_STRUCT3 -1 -#define FFI_TYPE_SMALL_STRUCT5 -2 -#define FFI_TYPE_SMALL_STRUCT6 -3 -#define FFI_TYPE_SMALL_STRUCT7 -4 +#else +#define FFI_TRAMPOLINE_SIZE 40 #endif +#define FFI_TYPE_SMALL_STRUCT2 -1 +#define FFI_TYPE_SMALL_STRUCT3 -2 +#define FFI_TYPE_SMALL_STRUCT4 -3 +#define FFI_TYPE_SMALL_STRUCT5 -4 +#define FFI_TYPE_SMALL_STRUCT6 -5 +#define FFI_TYPE_SMALL_STRUCT7 -6 +#define FFI_TYPE_SMALL_STRUCT8 -7 +#endif diff --git a/libffi/src/pa/linux.S b/libffi/src/pa/linux.S index 267cff7..20be177 100644 --- a/libffi/src/pa/linux.S +++ b/libffi/src/pa/linux.S @@ -31,7 +31,7 @@ .level 1.1 .align 4 - /* void ffi_call_LINUX(void (*)(char *, extended_cif *), + /* void ffi_call_pa32(void (*)(char *, extended_cif *), extended_cif *ecif, unsigned bytes, unsigned flags, @@ -39,12 +39,12 @@ void (*fn)()); */ - .export ffi_call_LINUX,code - .import ffi_prep_args_LINUX,code + .export ffi_call_pa32,code + .import ffi_prep_args_pa32,code - .type ffi_call_LINUX, @function + .type ffi_call_pa32, @function .LFB1: -ffi_call_LINUX: +ffi_call_pa32: .proc .callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=4 .entry @@ -63,7 +63,7 @@ ffi_call_LINUX: [ 64-bytes register save area ] <- %r4 [ Stack space for actual call, passed as ] <- %arg0 - [ arg0 to ffi_prep_args_LINUX ] + [ arg0 to ffi_prep_args_pa32 ] [ Stack for calling prep_args ] <- %sp */ @@ -73,14 +73,14 @@ ffi_call_LINUX: .LCFI13: copy %sp, %r4 - addl %arg2, %r4, %arg0 /* arg stack */ - stw %arg3, -48(%r3) /* save flags; we need it later */ + addl %arg2, %r4, %arg0 /* arg stack */ + stw %arg3, -48(%r3) /* save flags; we need it later */ /* Call prep_args: %arg0(stack) -- set up above %arg1(ecif) -- same as incoming param %arg2(bytes) -- same as incoming param */ - bl ffi_prep_args_LINUX,%r2 + bl ffi_prep_args_pa32,%r2 ldo 64(%arg0), %sp ldo -64(%sp), %sp @@ -106,90 +106,139 @@ ffi_call_LINUX: /* Store the result according to the return type. */ -checksmst3: - comib,<>,n FFI_TYPE_SMALL_STRUCT3, %r21, checksmst567 - /* 3-byte structs are returned in ret0 as ??xxyyzz. Shift - left 8 bits to write to the result structure. */ - zdep %ret0, 23, 24, %r22 - b done - stw %r22, 0(%r20) - -checksmst567: - /* 5-7 byte values are returned right justified: +.Lcheckint: + comib,<>,n FFI_TYPE_INT, %r21, .Lcheckint8 + b .Ldone + stw %ret0, 0(%r20) + +.Lcheckint8: + comib,<>,n FFI_TYPE_UINT8, %r21, .Lcheckint16 + b .Ldone + stb %ret0, 0(%r20) + +.Lcheckint16: + comib,<>,n FFI_TYPE_UINT16, %r21, .Lcheckdbl + b .Ldone + sth %ret0, 0(%r20) + +.Lcheckdbl: + comib,<>,n FFI_TYPE_DOUBLE, %r21, .Lcheckfloat + b .Ldone + fstd %fr4,0(%r20) + +.Lcheckfloat: + comib,<>,n FFI_TYPE_FLOAT, %r21, .Lcheckll + b .Ldone + fstw %fr4L,0(%r20) + +.Lcheckll: + comib,<>,n FFI_TYPE_UINT64, %r21, .Lchecksmst2 + stw %ret0, 0(%r20) + b .Ldone + stw %ret1, 4(%r20) + +.Lchecksmst2: + comib,<>,n FFI_TYPE_SMALL_STRUCT2, %r21, .Lchecksmst3 + /* 2-byte structs are returned in ret0 as ????xxyy. */ + extru %ret0, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + b .Ldone + stb %ret0, 0(%r20) + +.Lchecksmst3: + comib,<>,n FFI_TYPE_SMALL_STRUCT3, %r21, .Lchecksmst4 + /* 3-byte structs are returned in ret0 as ??xxyyzz. */ + extru %ret0, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret0, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + b .Ldone + stb %ret0, 0(%r20) + +.Lchecksmst4: + comib,<>,n FFI_TYPE_SMALL_STRUCT4, %r21, .Lchecksmst5 + /* 4-byte structs are returned in ret0 as wwxxyyzz. */ + extru %ret0, 7, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret0, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret0, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + b .Ldone + stb %ret0, 0(%r20) + +.Lchecksmst5: + comib,<>,n FFI_TYPE_SMALL_STRUCT5, %r21, .Lchecksmst6 + /* 5 byte values are returned right justified: + ret0 ret1 + 5: ??????aa bbccddee */ + stbs,ma %ret0, 1(%r20) + extru %ret1, 7, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + b .Ldone + stb %ret1, 0(%r20) + +.Lchecksmst6: + comib,<>,n FFI_TYPE_SMALL_STRUCT6, %r21, .Lchecksmst7 + /* 6 byte values are returned right justified: + ret0 ret1 + 6: ????aabb ccddeeff */ + extru %ret0, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + stbs,ma %ret0, 1(%r20) + extru %ret1, 7, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + b .Ldone + stb %ret1, 0(%r20) + +.Lchecksmst7: + comib,<>,n FFI_TYPE_SMALL_STRUCT7, %r21, .Lchecksmst8 + /* 7 byte values are returned right justified: ret0 ret1 - 5: ??????aa bbccddee - 6: ????aabb ccddeeff - 7: ??aabbcc ddeeffgg - - To store this in the result, write the first 4 bytes into a temp - register using shrpw (t1 = aabbccdd), followed by a rotation of - ret1: - - ret0 ret1 ret1 - 5: ??????aa bbccddee -> eebbccdd (rotate 8) - 6: ????aabb ccddeeff -> eeffccdd (rotate 16) - 7: ??aabbcc ddeeffgg -> eeffggdd (rotate 24) - - then we write (t1, ret1) into the result. */ - - addi,<> -FFI_TYPE_SMALL_STRUCT5,%r21,%r0 - ldi 8, %r22 - addi,<> -FFI_TYPE_SMALL_STRUCT6,%r21,%r0 - ldi 16, %r22 - addi,<> -FFI_TYPE_SMALL_STRUCT7,%r21,%r0 - ldi 24, %r22 - - /* This relies on all the FFI_TYPE_*_STRUCT* defines being <0 */ - cmpib,<=,n 0, %r21, checkint8 - mtsar %r22 - - shrpw %ret0, %ret1, %sar, %ret0 /* ret0 = aabbccdd */ - shrpw %ret1, %ret1, %sar, %ret1 /* rotate ret1 */ - - stw %ret0, 0(%r20) - b done - stw %ret1, 4(%r20) - -checkint8: - comib,<>,n FFI_TYPE_UINT8, %r21, checkint16 - b done - stb %ret0, 0(%r20) - -checkint16: - comib,<>,n FFI_TYPE_UINT16, %r21, checkint32 - b done - sth %ret0, 0(%r20) - -checkint32: - comib,<>,n FFI_TYPE_UINT32, %r21, checkint - b done - stw %ret0, 0(%r20) - -checkint: - comib,<>,n FFI_TYPE_INT, %r21, checkll - b done - stw %ret0, 0(%r20) - -checkll: - comib,<>,n FFI_TYPE_UINT64, %r21, checkdbl - stw %ret0, 0(%r20) - b done - stw %ret1, 4(%r20) - -checkdbl: - comib,<>,n FFI_TYPE_DOUBLE, %r21, checkfloat - b done - fstd %fr4,0(%r20) - -checkfloat: - comib,<>,n FFI_TYPE_FLOAT, %r21, done - fstw %fr4L,0(%r20) - - /* structure returns are either handled by one of the - INT/UINT64 cases above, or, if passed by pointer, - is handled by the callee. */ - -done: + 7: ??aabbcc ddeeffgg */ + extru %ret0, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret0, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + stbs,ma %ret0, 1(%r20) + extru %ret1, 7, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + b .Ldone + stb %ret1, 0(%r20) + +.Lchecksmst8: + comib,<>,n FFI_TYPE_SMALL_STRUCT8, %r21, .Ldone + /* 8 byte values are returned right justified: + ret0 ret1 + 8: aabbccdd eeffgghh */ + extru %ret0, 7, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret0, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret0, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + stbs,ma %ret0, 1(%r20) + extru %ret1, 7, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 15, 8, %r22 + stbs,ma %r22, 1(%r20) + extru %ret1, 23, 8, %r22 + stbs,ma %r22, 1(%r20) + stb %ret1, 0(%r20) + +.Ldone: /* all done, return */ copy %r4, %sp /* pop arg stack */ ldw 12(%r3), %r4 @@ -201,14 +250,14 @@ done: .procend .LFE1: - /* void ffi_closure_LINUX(void); + /* void ffi_closure_pa32(void); Called with closure argument in %r21 */ - .export ffi_closure_LINUX,code - .import ffi_closure_inner_LINUX,code + .export ffi_closure_pa32,code + .import ffi_closure_inner_pa32,code - .type ffi_closure_LINUX, @function + .type ffi_closure_pa32, @function .LFB2: -ffi_closure_LINUX: +ffi_closure_pa32: .proc .callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3 .entry @@ -228,7 +277,7 @@ ffi_closure_LINUX: stw %arg3, -48(%r3) copy %r21, %arg0 - bl ffi_closure_inner_LINUX, %r2 + bl ffi_closure_inner_pa32, %r2 copy %r3, %arg1 ldwm -64(%sp), %r3 @@ -299,7 +348,7 @@ ffi_closure_LINUX: .sleb128 -5 .byte 0x4 ;# DW_CFA_advance_loc4 - .word .LCFI12-.LCFI11 + .word .LCFI22-.LCFI21 .byte 0xd ;# DW_CFA_def_cfa_register = r3 .uleb128 0x3 diff --git a/libffi/src/powerpc/ffi.c b/libffi/src/powerpc/ffi.c index 7d8bf3a..e6b869f 100644 --- a/libffi/src/powerpc/ffi.c +++ b/libffi/src/powerpc/ffi.c @@ -1,5 +1,6 @@ /* ----------------------------------------------------------------------- ffi.c - Copyright (c) 1998 Geoffrey Keating + Copyright (C) 2007 Free Software Foundation, Inc PowerPC Foreign Function Interface @@ -30,8 +31,8 @@ #include -extern void ffi_closure_SYSV(void); -extern void FFI_HIDDEN ffi_closure_LINUX64(void); +extern void ffi_closure_SYSV (void); +extern void FFI_HIDDEN ffi_closure_LINUX64 (void); enum { /* The assembly depends on these exact flags. */ @@ -39,7 +40,8 @@ enum { FLAG_RETURNS_NOTHING = 1 << (31-30), /* These go in cr7 */ FLAG_RETURNS_FP = 1 << (31-29), FLAG_RETURNS_64BITS = 1 << (31-28), - FLAG_RETURNS_128BITS = 1 << (31-27), + + FLAG_RETURNS_128BITS = 1 << (31-27), /* cr6 */ FLAG_ARG_NEEDS_COPY = 1 << (31- 7), FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */ @@ -48,10 +50,13 @@ enum { }; /* About the SYSV ABI. */ -enum { - NUM_GPR_ARG_REGISTERS = 8, - NUM_FPR_ARG_REGISTERS = 8 -}; +unsigned int NUM_GPR_ARG_REGISTERS = 8; +#ifndef __NO_FPRS__ +unsigned int NUM_FPR_ARG_REGISTERS = 8; +#else +unsigned int NUM_FPR_ARG_REGISTERS = 0; +#endif + enum { ASM_NEEDS_REGISTERS = 4 }; /* ffi_prep_args_SYSV is called by the assembly routine once stack space @@ -80,79 +85,112 @@ enum { ASM_NEEDS_REGISTERS = 4 }; */ -/*@-exportheader@*/ -void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack) -/*@=exportheader@*/ +void +ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack) { const unsigned bytes = ecif->cif->bytes; const unsigned flags = ecif->cif->flags; + typedef union { + char *c; + unsigned *u; + long long *ll; + float *f; + double *d; + } valp; + /* 'stacktop' points at the previous backchain pointer. */ - unsigned *const stacktop = stack + (bytes / sizeof(unsigned)); + valp stacktop; /* 'gpr_base' points at the space for gpr3, and grows upwards as we use GPR registers. */ - unsigned *gpr_base = stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS; - int intarg_count = 0; + valp gpr_base; + int intarg_count; /* 'fpr_base' points at the space for fpr1, and grows upwards as we use FPR registers. */ - double *fpr_base = (double *)gpr_base - NUM_FPR_ARG_REGISTERS; - int fparg_count = 0; + valp fpr_base; + int fparg_count; /* 'copy_space' grows down as we put structures in it. It should stay 16-byte aligned. */ - char *copy_space = ((flags & FLAG_FP_ARGUMENTS) - ? (char *)fpr_base - : (char *)gpr_base); + valp copy_space; /* 'next_arg' grows up as we put parameters in it. */ - unsigned *next_arg = stack + 2; + valp next_arg; - int i; + int i, ii MAYBE_UNUSED; ffi_type **ptr; double double_tmp; - void **p_argv; + union { + void **v; + char **c; + signed char **sc; + unsigned char **uc; + signed short **ss; + unsigned short **us; + unsigned int **ui; + long long **ll; + float **f; + double **d; + } p_argv; size_t struct_copy_size; unsigned gprvalue; + if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT) + NUM_FPR_ARG_REGISTERS = 0; + + stacktop.c = (char *) stack + bytes; + gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS; + intarg_count = 0; + fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS; + fparg_count = 0; + copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c); + next_arg.u = stack + 2; + /* Check that everything starts aligned properly. */ - FFI_ASSERT(((unsigned)(char *)stack & 0xF) == 0); - FFI_ASSERT(((unsigned)(char *)copy_space & 0xF) == 0); - FFI_ASSERT(((unsigned)(char *)stacktop & 0xF) == 0); - FFI_ASSERT((bytes & 0xF) == 0); - FFI_ASSERT(copy_space >= (char *)next_arg); + FFI_ASSERT (((unsigned) (char *) stack & 0xF) == 0); + FFI_ASSERT (((unsigned) copy_space.c & 0xF) == 0); + FFI_ASSERT (((unsigned) stacktop.c & 0xF) == 0); + FFI_ASSERT ((bytes & 0xF) == 0); + FFI_ASSERT (copy_space.c >= next_arg.c); /* Deal with return values that are actually pass-by-reference. */ if (flags & FLAG_RETVAL_REFERENCE) { - *gpr_base++ = (unsigned long)(char *)ecif->rvalue; + *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue; intarg_count++; } /* Now for the arguments. */ - p_argv = ecif->avalue; + p_argv.v = ecif->avalue; for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs; i > 0; - i--, ptr++, p_argv++) + i--, ptr++, p_argv.v++) { switch ((*ptr)->type) { case FFI_TYPE_FLOAT: - double_tmp = *(float *)*p_argv; + /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32. */ + if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT) + goto soft_float_prep; + double_tmp = **p_argv.f; if (fparg_count >= NUM_FPR_ARG_REGISTERS) { - *(float *)next_arg = (float)double_tmp; - next_arg += 1; + *next_arg.f = (float) double_tmp; + next_arg.u += 1; } else - *fpr_base++ = double_tmp; + *fpr_base.d++ = double_tmp; fparg_count++; - FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); break; case FFI_TYPE_DOUBLE: - double_tmp = *(double *)*p_argv; + /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64. */ + if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT) + goto soft_double_prep; + double_tmp = **p_argv.d; if (fparg_count >= NUM_FPR_ARG_REGISTERS) { @@ -160,30 +198,99 @@ void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack) && intarg_count % 2 != 0) { intarg_count++; - next_arg++; + next_arg.u++; } - *(double *)next_arg = double_tmp; - next_arg += 2; + *next_arg.d = double_tmp; + next_arg.u += 2; } else - *fpr_base++ = double_tmp; + *fpr_base.d++ = double_tmp; fparg_count++; - FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + break; + +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + if ((ecif->cif->abi != FFI_LINUX) + && (ecif->cif->abi != FFI_LINUX_SOFT_FLOAT)) + goto do_struct; + /* The soft float ABI for long doubles works like this, + a long double is passed in four consecutive gprs if available. + A maximum of 2 long doubles can be passed in gprs. + If we do not have 4 gprs left, the long double is passed on the + stack, 4-byte aligned. */ + if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT) + { + unsigned int int_tmp = (*p_argv.ui)[0]; + if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3) + { + if (intarg_count < NUM_GPR_ARG_REGISTERS) + intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count; + *next_arg.u = int_tmp; + next_arg.u++; + for (ii = 1; ii < 4; ii++) + { + int_tmp = (*p_argv.ui)[ii]; + *next_arg.u = int_tmp; + next_arg.u++; + } + } + else + { + *gpr_base.u++ = int_tmp; + for (ii = 1; ii < 4; ii++) + { + int_tmp = (*p_argv.ui)[ii]; + *gpr_base.u++ = int_tmp; + } + } + intarg_count +=4; + } + else + { + double_tmp = (*p_argv.d)[0]; + + if (fparg_count >= NUM_FPR_ARG_REGISTERS - 1) + { + if (intarg_count >= NUM_GPR_ARG_REGISTERS + && intarg_count % 2 != 0) + { + intarg_count++; + next_arg.u++; + } + *next_arg.d = double_tmp; + next_arg.u += 2; + double_tmp = (*p_argv.d)[1]; + *next_arg.d = double_tmp; + next_arg.u += 2; + } + else + { + *fpr_base.d++ = double_tmp; + double_tmp = (*p_argv.d)[1]; + *fpr_base.d++ = double_tmp; + } + + fparg_count += 2; + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + } break; +#endif case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: + soft_double_prep: if (intarg_count == NUM_GPR_ARG_REGISTERS-1) intarg_count++; if (intarg_count >= NUM_GPR_ARG_REGISTERS) { - if (intarg_count%2 != 0) + if (intarg_count % 2 != 0) { intarg_count++; - next_arg++; + next_arg.u++; } - *(long long *)next_arg = *(long long *)*p_argv; - next_arg += 2; + *next_arg.ll = **p_argv.ll; + next_arg.u += 2; } else { @@ -194,65 +301,67 @@ void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack) * not correct starting register of pair then skip * until the proper starting register */ - if (intarg_count%2 != 0) + if (intarg_count % 2 != 0) { intarg_count ++; - gpr_base++; + gpr_base.u++; } - *(long long *)gpr_base = *(long long *)*p_argv; - gpr_base += 2; + *gpr_base.ll++ = **p_argv.ll; } intarg_count += 2; break; case FFI_TYPE_STRUCT: #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: + do_struct: #endif struct_copy_size = ((*ptr)->size + 15) & ~0xF; - copy_space -= struct_copy_size; - memcpy(copy_space, (char *)*p_argv, (*ptr)->size); + copy_space.c -= struct_copy_size; + memcpy (copy_space.c, *p_argv.c, (*ptr)->size); - gprvalue = (unsigned long)copy_space; + gprvalue = (unsigned long) copy_space.c; - FFI_ASSERT(copy_space > (char *)next_arg); - FFI_ASSERT(flags & FLAG_ARG_NEEDS_COPY); + FFI_ASSERT (copy_space.c > next_arg.c); + FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY); goto putgpr; case FFI_TYPE_UINT8: - gprvalue = *(unsigned char *)*p_argv; + gprvalue = **p_argv.uc; goto putgpr; case FFI_TYPE_SINT8: - gprvalue = *(signed char *)*p_argv; + gprvalue = **p_argv.sc; goto putgpr; case FFI_TYPE_UINT16: - gprvalue = *(unsigned short *)*p_argv; + gprvalue = **p_argv.us; goto putgpr; case FFI_TYPE_SINT16: - gprvalue = *(signed short *)*p_argv; + gprvalue = **p_argv.ss; goto putgpr; case FFI_TYPE_INT: case FFI_TYPE_UINT32: case FFI_TYPE_SINT32: case FFI_TYPE_POINTER: - gprvalue = *(unsigned *)*p_argv; + soft_float_prep: + + gprvalue = **p_argv.ui; + putgpr: if (intarg_count >= NUM_GPR_ARG_REGISTERS) - *next_arg++ = gprvalue; + *next_arg.u++ = gprvalue; else - *gpr_base++ = gprvalue; + *gpr_base.u++ = gprvalue; intarg_count++; break; } } /* Check that we didn't overrun the stack... */ - FFI_ASSERT(copy_space >= (char *)next_arg); - FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS); - FFI_ASSERT((unsigned *)fpr_base - <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS); - FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4); + FFI_ASSERT (copy_space.c >= next_arg.c); + FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS); + FFI_ASSERT (fpr_base.u + <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS); + FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4); } /* About the LINUX64 ABI. */ @@ -296,160 +405,187 @@ enum { ASM_NEEDS_REGISTERS64 = 4 }; */ -/*@-exportheader@*/ -void FFI_HIDDEN ffi_prep_args64(extended_cif *ecif, unsigned long *const stack) -/*@=exportheader@*/ +void FFI_HIDDEN +ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack) { const unsigned long bytes = ecif->cif->bytes; const unsigned long flags = ecif->cif->flags; + typedef union { + char *c; + unsigned long *ul; + float *f; + double *d; + } valp; + /* 'stacktop' points at the previous backchain pointer. */ - unsigned long *const stacktop = stack + (bytes / sizeof(unsigned long)); + valp stacktop; /* 'next_arg' points at the space for gpr3, and grows upwards as we use GPR registers, then continues at rest. */ - unsigned long *const gpr_base = stacktop - ASM_NEEDS_REGISTERS64 - - NUM_GPR_ARG_REGISTERS64; - unsigned long *const gpr_end = gpr_base + NUM_GPR_ARG_REGISTERS64; - unsigned long *const rest = stack + 6 + NUM_GPR_ARG_REGISTERS64; - unsigned long *next_arg = gpr_base; + valp gpr_base; + valp gpr_end; + valp rest; + valp next_arg; /* 'fpr_base' points at the space for fpr3, and grows upwards as we use FPR registers. */ - double *fpr_base = (double *)gpr_base - NUM_FPR_ARG_REGISTERS64; - int fparg_count = 0; + valp fpr_base; + int fparg_count; int i, words; ffi_type **ptr; double double_tmp; - void **p_argv; + union { + void **v; + char **c; + signed char **sc; + unsigned char **uc; + signed short **ss; + unsigned short **us; + signed int **si; + unsigned int **ui; + unsigned long **ul; + float **f; + double **d; + } p_argv; unsigned long gprvalue; + stacktop.c = (char *) stack + bytes; + gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64; + gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64; + rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64; + fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64; + fparg_count = 0; + next_arg.ul = gpr_base.ul; + /* Check that everything starts aligned properly. */ - FFI_ASSERT(((unsigned long)(char *)stack & 0xF) == 0); - FFI_ASSERT(((unsigned long)(char *)stacktop & 0xF) == 0); - FFI_ASSERT((bytes & 0xF) == 0); + FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0); + FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0); + FFI_ASSERT ((bytes & 0xF) == 0); /* Deal with return values that are actually pass-by-reference. */ if (flags & FLAG_RETVAL_REFERENCE) - *next_arg++ = (unsigned long)(char *)ecif->rvalue; + *next_arg.ul++ = (unsigned long) (char *) ecif->rvalue; /* Now for the arguments. */ - p_argv = ecif->avalue; + p_argv.v = ecif->avalue; for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs; i > 0; - i--, ptr++, p_argv++) + i--, ptr++, p_argv.v++) { switch ((*ptr)->type) { case FFI_TYPE_FLOAT: - double_tmp = *(float *)*p_argv; - *(float *)next_arg = (float)double_tmp; - if (++next_arg == gpr_end) - next_arg = rest; + double_tmp = **p_argv.f; + *next_arg.f = (float) double_tmp; + if (++next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; if (fparg_count < NUM_FPR_ARG_REGISTERS64) - *fpr_base++ = double_tmp; + *fpr_base.d++ = double_tmp; fparg_count++; - FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); break; case FFI_TYPE_DOUBLE: - double_tmp = *(double *)*p_argv; - *(double *)next_arg = double_tmp; - if (++next_arg == gpr_end) - next_arg = rest; + double_tmp = **p_argv.d; + *next_arg.d = double_tmp; + if (++next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; if (fparg_count < NUM_FPR_ARG_REGISTERS64) - *fpr_base++ = double_tmp; + *fpr_base.d++ = double_tmp; fparg_count++; - FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); break; #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE case FFI_TYPE_LONGDOUBLE: - double_tmp = ((double *) *p_argv)[0]; - *(double *) next_arg = double_tmp; - if (++next_arg == gpr_end) - next_arg = rest; + double_tmp = (*p_argv.d)[0]; + *next_arg.d = double_tmp; + if (++next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; if (fparg_count < NUM_FPR_ARG_REGISTERS64) - *fpr_base++ = double_tmp; + *fpr_base.d++ = double_tmp; fparg_count++; - double_tmp = ((double *) *p_argv)[1]; - *(double *) next_arg = double_tmp; - if (++next_arg == gpr_end) - next_arg = rest; + double_tmp = (*p_argv.d)[1]; + *next_arg.d = double_tmp; + if (++next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; if (fparg_count < NUM_FPR_ARG_REGISTERS64) - *fpr_base++ = double_tmp; + *fpr_base.d++ = double_tmp; fparg_count++; - FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); + FFI_ASSERT (__LDBL_MANT_DIG__ == 106); + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); break; #endif case FFI_TYPE_STRUCT: words = ((*ptr)->size + 7) / 8; - if (next_arg >= gpr_base && next_arg + words > gpr_end) + if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul) { - size_t first = (char *) gpr_end - (char *) next_arg; - memcpy((char *) next_arg, (char *) *p_argv, first); - memcpy((char *) rest, (char *) *p_argv + first, - (*ptr)->size - first); - next_arg = (unsigned long *) ((char *) rest + words * 8 - first); + size_t first = gpr_end.c - next_arg.c; + memcpy (next_arg.c, *p_argv.c, first); + memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first); + next_arg.c = rest.c + words * 8 - first; } else { - char *where = (char *) next_arg; + char *where = next_arg.c; /* Structures with size less than eight bytes are passed left-padded. */ if ((*ptr)->size < 8) where += 8 - (*ptr)->size; - memcpy (where, (char *) *p_argv, (*ptr)->size); - next_arg += words; - if (next_arg == gpr_end) - next_arg = rest; + memcpy (where, *p_argv.c, (*ptr)->size); + next_arg.ul += words; + if (next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; } break; case FFI_TYPE_UINT8: - gprvalue = *(unsigned char *)*p_argv; + gprvalue = **p_argv.uc; goto putgpr; case FFI_TYPE_SINT8: - gprvalue = *(signed char *)*p_argv; + gprvalue = **p_argv.sc; goto putgpr; case FFI_TYPE_UINT16: - gprvalue = *(unsigned short *)*p_argv; + gprvalue = **p_argv.us; goto putgpr; case FFI_TYPE_SINT16: - gprvalue = *(signed short *)*p_argv; + gprvalue = **p_argv.ss; goto putgpr; case FFI_TYPE_UINT32: - gprvalue = *(unsigned int *)*p_argv; + gprvalue = **p_argv.ui; goto putgpr; case FFI_TYPE_INT: case FFI_TYPE_SINT32: - gprvalue = *(signed int *)*p_argv; + gprvalue = **p_argv.si; goto putgpr; case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: case FFI_TYPE_POINTER: - gprvalue = *(unsigned long *)*p_argv; + gprvalue = **p_argv.ul; putgpr: - *next_arg++ = gprvalue; - if (next_arg == gpr_end) - next_arg = rest; + *next_arg.ul++ = gprvalue; + if (next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; break; } } - FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS - || (next_arg >= gpr_base && next_arg <= gpr_base + 4)); + FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS + || (next_arg.ul >= gpr_base.ul + && next_arg.ul <= gpr_base.ul + 4)); } /* Perform machine dependent cif processing */ -ffi_status ffi_prep_cif_machdep(ffi_cif *cif) +ffi_status +ffi_prep_cif_machdep (ffi_cif *cif) { /* All this is for the SYSV and LINUX64 ABI. */ int i; @@ -461,16 +597,19 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) unsigned type = cif->rtype->type; unsigned size = cif->rtype->size; + if (cif->abi == FFI_LINUX_SOFT_FLOAT) + NUM_FPR_ARG_REGISTERS = 0; + if (cif->abi != FFI_LINUX64) { /* All the machine-independent calculation of cif->bytes will be wrong. Redo the calculation for SYSV. */ /* Space for the frame pointer, callee's LR, and the asm's temp regs. */ - bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof(int); + bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int); /* Space for the GPR registers. */ - bytes += NUM_GPR_ARG_REGISTERS * sizeof(int); + bytes += NUM_GPR_ARG_REGISTERS * sizeof (int); } else { @@ -478,15 +617,10 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp regs. */ - bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof(long); + bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long); /* Space for the mandatory parm save area and general registers. */ - bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof(long); - -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - if (type == FFI_TYPE_LONGDOUBLE) - type = FFI_TYPE_DOUBLE; -#endif + bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long); } /* Return value handling. The rules for SYSV are as follows: @@ -495,19 +629,33 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) - 64-bit integer values and structures between 5 and 8 bytes are returned in gpr3 and gpr4; - Single/double FP values are returned in fpr1; - - Larger structures and long double (if not equivalent to double) values - are allocated space and a pointer is passed as the first argument. + - Larger structures are allocated space and a pointer is passed as + the first argument. + - long doubles (if not equivalent to double) are returned in + fpr1,fpr2 for Linux and as for large structs for SysV. For LINUX64: - integer values in gpr3; - Structures/Unions by reference; - - Single/double FP values in fpr1, long double in fpr1,fpr2. */ + - Single/double FP values in fpr1, long double in fpr1,fpr2. + - soft-float float/doubles are treated as UINT32/UINT64 respectivley. + - soft-float long doubles are returned in gpr3-gpr6. */ switch (type) { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64 + && cif->abi != FFI_LINUX_SOFT_FLOAT) + goto byref; + flags |= FLAG_RETURNS_128BITS; + /* Fall through. */ +#endif case FFI_TYPE_DOUBLE: flags |= FLAG_RETURNS_64BITS; /* Fall through. */ case FFI_TYPE_FLOAT: - flags |= FLAG_RETURNS_FP; + /* With FFI_LINUX_SOFT_FLOAT no fp registers are used. */ + if (cif->abi != FFI_LINUX_SOFT_FLOAT) + flags |= FLAG_RETURNS_FP; break; case FFI_TYPE_UINT64: @@ -523,33 +671,29 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) in memory. */ /* Treat structs with size <= 8 bytes. */ - if (size <= 8) { - flags |= FLAG_RETURNS_SMST; - /* These structs are returned in r3. We pack the type and the - precalculated shift value (needed in the sysv.S) into flags. - The same applies for the structs returned in r3/r4. */ - if (size <= 4) { - flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 1 ) - | (8 * (4 - size) << 4); - break; - } - /* These structs are returned in r3 and r4. See above. */ - if (size <= 8) { - flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 2 ) - | (8 * (8 - size) << 4); - break; + if (size <= 8) + { + flags |= FLAG_RETURNS_SMST; + /* These structs are returned in r3. We pack the type and the + precalculated shift value (needed in the sysv.S) into flags. + The same applies for the structs returned in r3/r4. */ + if (size <= 4) + { + flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 1); + flags |= 8 * (4 - size) << 4; + break; + } + /* These structs are returned in r3 and r4. See above. */ + if (size <= 8) + { + flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 2); + flags |= 8 * (8 - size) << 4; + break; + } } - } } - /* else fall through. */ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - if (type == FFI_TYPE_LONGDOUBLE && cif->abi == FFI_LINUX64) - { - flags |= FLAG_RETURNS_128BITS; - flags |= FLAG_RETURNS_FP; - break; - } + byref: #endif intarg_count++; flags |= FLAG_RETVAL_REFERENCE; @@ -574,11 +718,36 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) switch ((*ptr)->type) { case FFI_TYPE_FLOAT: + /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32. */ + if (cif->abi == FFI_LINUX_SOFT_FLOAT) + goto soft_float_cif; fparg_count++; /* floating singles are not 8-aligned on stack */ break; +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT) + goto do_struct; + if (cif->abi == FFI_LINUX_SOFT_FLOAT) + { + if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3 + || intarg_count < NUM_GPR_ARG_REGISTERS) + /* A long double in FFI_LINUX_SOFT_FLOAT can use only + a set of four consecutive gprs. If we have not enough, + we have to adjust the intarg_count value. */ + intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count; + intarg_count += 4; + break; + } + else + fparg_count++; + /* Fall thru */ +#endif case FFI_TYPE_DOUBLE: + /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64. */ + if (cif->abi == FFI_LINUX_SOFT_FLOAT) + goto soft_double_cif; fparg_count++; /* If this FP arg is going on the stack, it must be 8-byte-aligned. */ @@ -590,6 +759,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: + soft_double_cif: /* 'long long' arguments are passed as two words, but either both words must fit in registers or both go on the stack. If they go on the stack, they must @@ -600,14 +770,14 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) (r7,r8), (r9,r10). */ if (intarg_count == NUM_GPR_ARG_REGISTERS-1 - || intarg_count%2 != 0) + || intarg_count % 2 != 0) intarg_count++; intarg_count += 2; break; case FFI_TYPE_STRUCT: #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: + do_struct: #endif /* We must allocate space for a copy of these to enforce pass-by-value. Pad the space up to a multiple of 16 @@ -617,6 +787,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) /* Fall through (allocate space for the pointer). */ default: + soft_float_cif: /* Everything else is passed as a 4-byte word in a GPR, either the object itself or a pointer to it. */ intarg_count++; @@ -630,8 +801,13 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) { #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE case FFI_TYPE_LONGDOUBLE: - fparg_count += 2; - intarg_count += 2; + if (cif->abi == FFI_LINUX_SOFT_FLOAT) + intarg_count += 4; + else + { + fparg_count += 2; + intarg_count += 2; + } break; #endif case FFI_TYPE_FLOAT: @@ -663,23 +839,23 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) { /* Space for the FPR registers, if needed. */ if (fparg_count != 0) - bytes += NUM_FPR_ARG_REGISTERS * sizeof(double); + bytes += NUM_FPR_ARG_REGISTERS * sizeof (double); /* Stack space. */ if (intarg_count > NUM_GPR_ARG_REGISTERS) - bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof(int); + bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int); if (fparg_count > NUM_FPR_ARG_REGISTERS) - bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof(double); + bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double); } else { /* Space for the FPR registers, if needed. */ if (fparg_count != 0) - bytes += NUM_FPR_ARG_REGISTERS64 * sizeof(double); + bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double); /* Stack space. */ if (intarg_count > NUM_GPR_ARG_REGISTERS64) - bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof(long); + bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long); } /* The stack space allocated needs to be a multiple of 16 bytes. */ @@ -694,23 +870,14 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) return FFI_OK; } -/*@-declundef@*/ -/*@-exportheader@*/ -extern void ffi_call_SYSV(/*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, +extern void ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *, void (*fn)()); -extern void FFI_HIDDEN ffi_call_LINUX64(/*@out@*/ extended_cif *, - unsigned long, unsigned long, - /*@out@*/ unsigned long *, +extern void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long, + unsigned long, unsigned long *, void (*fn)()); -/*@=declundef@*/ -/*@=exportheader@*/ -void ffi_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ void **avalue) +void +ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) { extended_cif ecif; @@ -720,12 +887,9 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, /* If the return value is a struct and we don't have a return */ /* value address then we need to make one */ - if ((rvalue == NULL) && - (cif->rtype->type == FFI_TYPE_STRUCT)) + if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { - /*@-sysunrecog@*/ ecif.rvalue = alloca(cif->rtype->size); - /*@=sysunrecog@*/ } else ecif.rvalue = rvalue; @@ -736,49 +900,44 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, #ifndef POWERPC64 case FFI_SYSV: case FFI_GCC_SYSV: - /*@-usedef@*/ - ffi_call_SYSV(&ecif, -cif->bytes, - cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ + case FFI_LINUX: + case FFI_LINUX_SOFT_FLOAT: + ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn); break; #else case FFI_LINUX64: - /*@-usedef@*/ - ffi_call_LINUX64(&ecif, -(long) cif->bytes, - cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ + ffi_call_LINUX64 (&ecif, -(long) cif->bytes, cif->flags, ecif.rvalue, fn); break; #endif default: - FFI_ASSERT(0); + FFI_ASSERT (0); break; } } #ifndef POWERPC64 -static void flush_icache(char *, int); - #define MIN_CACHE_LINE_SIZE 8 -static void flush_icache(char * addr1, int size) +static void +flush_icache (char *wraddr, char *xaddr, int size) { int i; - char * addr; - for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) { - addr = addr1 + i; - __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" : : "r"(addr) : "memory"); - } - addr = addr1 + size - 1; - __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" "sync;" "isync;" : : "r"(addr) : "memory"); + for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) + __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" + : : "r" (xaddr + i), "r" (wraddr + i) : "memory"); + __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;" + : : "r"(xaddr + size - 1), "r"(wraddr + size - 1) + : "memory"); } #endif ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*, void*, void**, void*), - void *user_data) +ffi_prep_closure_loc (ffi_closure *closure, + ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, + void *codeloc) { #ifdef POWERPC64 void **tramp = (void **) &closure->tramp[0]; @@ -786,7 +945,7 @@ ffi_prep_closure (ffi_closure* closure, FFI_ASSERT (cif->abi == FFI_LINUX64); /* Copy function address and TOC from ffi_closure_LINUX64. */ memcpy (tramp, (char *) ffi_closure_LINUX64, 16); - tramp[2] = (void *) closure; + tramp[2] = codeloc; #else unsigned int *tramp; @@ -801,11 +960,11 @@ ffi_prep_closure (ffi_closure* closure, tramp[7] = 0x816b0004; /* lwz r11,4(r11) */ tramp[8] = 0x7c0903a6; /* mtctr r0 */ tramp[9] = 0x4e800420; /* bctr */ - *(void **) &tramp[2] = (void *)ffi_closure_SYSV; /* function */ - *(void **) &tramp[3] = (void *)closure; /* context */ + *(void **) &tramp[2] = (void *) ffi_closure_SYSV; /* function */ + *(void **) &tramp[3] = codeloc; /* context */ /* Flush the icache. */ - flush_icache(&closure->tramp[0],FFI_TRAMPOLINE_SIZE); + flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE); #endif closure->cif = cif; @@ -821,8 +980,8 @@ typedef union double d; } ffi_dblfl; -int ffi_closure_helper_SYSV (ffi_closure*, void*, unsigned long*, - ffi_dblfl*, unsigned long*); +int ffi_closure_helper_SYSV (ffi_closure *, void *, unsigned long *, + ffi_dblfl *, unsigned long *); /* Basically the trampoline invokes ffi_closure_SYSV, and on * entry, r11 holds the address of the closure. @@ -833,9 +992,9 @@ int ffi_closure_helper_SYSV (ffi_closure*, void*, unsigned long*, */ int -ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, - unsigned long * pgr, ffi_dblfl * pfr, - unsigned long * pst) +ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, + unsigned long *pgr, ffi_dblfl *pfr, + unsigned long *pst) { /* rvalue is the pointer to space for return value in closure assembly */ /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */ @@ -852,7 +1011,7 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, unsigned size; cif = closure->cif; - avalue = alloca(cif->nargs * sizeof(void *)); + avalue = alloca (cif->nargs * sizeof (void *)); size = cif->rtype->size; nf = 0; @@ -863,13 +1022,17 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, For FFI_SYSV the result is passed in r3/r4 if the struct size is less or equal 8 bytes. */ - if (cif->rtype->type == FFI_TYPE_STRUCT) + if ((cif->rtype->type == FFI_TYPE_STRUCT + && !((cif->abi == FFI_SYSV) && (size <= 8))) +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + || (cif->rtype->type == FFI_TYPE_LONGDOUBLE + && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT) +#endif + ) { - if (!((cif->abi == FFI_SYSV) && (size <= 8))) { - rvalue = (void *) *pgr; - ng++; - pgr++; - } + rvalue = (void *) *pgr; + ng++; + pgr++; } i = 0; @@ -884,58 +1047,75 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, case FFI_TYPE_SINT8: case FFI_TYPE_UINT8: /* there are 8 gpr registers used to pass values */ - if (ng < 8) { - avalue[i] = (((char *)pgr)+3); - ng++; - pgr++; - } else { - avalue[i] = (((char *)pst)+3); - pst++; - } + if (ng < 8) + { + avalue[i] = (char *) pgr + 3; + ng++; + pgr++; + } + else + { + avalue[i] = (char *) pst + 3; + pst++; + } break; case FFI_TYPE_SINT16: case FFI_TYPE_UINT16: /* there are 8 gpr registers used to pass values */ - if (ng < 8) { - avalue[i] = (((char *)pgr)+2); - ng++; - pgr++; - } else { - avalue[i] = (((char *)pst)+2); - pst++; - } + if (ng < 8) + { + avalue[i] = (char *) pgr + 2; + ng++; + pgr++; + } + else + { + avalue[i] = (char *) pst + 2; + pst++; + } break; case FFI_TYPE_SINT32: case FFI_TYPE_UINT32: case FFI_TYPE_POINTER: + soft_float_closure: /* there are 8 gpr registers used to pass values */ - if (ng < 8) { - avalue[i] = pgr; - ng++; - pgr++; - } else { - avalue[i] = pst; - pst++; - } + if (ng < 8) + { + avalue[i] = pgr; + ng++; + pgr++; + } + else + { + avalue[i] = pst; + pst++; + } break; case FFI_TYPE_STRUCT: +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + do_struct: +#endif /* Structs are passed by reference. The address will appear in a gpr if it is one of the first 8 arguments. */ - if (ng < 8) { - avalue[i] = (void *) *pgr; - ng++; - pgr++; - } else { - avalue[i] = (void *) *pst; - pst++; - } + if (ng < 8) + { + avalue[i] = (void *) *pgr; + ng++; + pgr++; + } + else + { + avalue[i] = (void *) *pst; + pst++; + } break; case FFI_TYPE_SINT64: case FFI_TYPE_UINT64: + soft_double_closure: /* passing long long ints are complex, they must * be passed in suitable register pairs such as * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10) @@ -945,23 +1125,31 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, * or pst to find the correct address for this type * of parameter. */ - if (ng < 7) { - if (ng & 0x01) { - /* skip r4, r6, r8 as starting points */ - ng++; - pgr++; + if (ng < 7) + { + if (ng & 0x01) + { + /* skip r4, r6, r8 as starting points */ + ng++; + pgr++; + } + avalue[i] = pgr; + ng += 2; + pgr += 2; + } + else + { + if (((long) pst) & 4) + pst++; + avalue[i] = pst; + pst += 2; } - avalue[i] = pgr; - ng+=2; - pgr+=2; - } else { - if (((long)pst) & 4) pst++; - avalue[i] = pst; - pst+=2; - } break; case FFI_TYPE_FLOAT: + /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32. */ + if (cif->abi == FFI_LINUX_SOFT_FLOAT) + goto soft_float_closure; /* unfortunately float values are stored as doubles * in the ffi_closure_SYSV code (since we don't check * the type in that routine). @@ -969,42 +1157,87 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, /* there are 8 64bit floating point registers */ - if (nf < 8) { - temp = pfr->d; - pfr->f = (float)temp; - avalue[i] = pfr; - nf++; - pfr++; - } else { - /* FIXME? here we are really changing the values - * stored in the original calling routines outgoing - * parameter stack. This is probably a really - * naughty thing to do but... - */ - avalue[i] = pst; - nf++; - pst+=1; - } + if (nf < 8) + { + temp = pfr->d; + pfr->f = (float) temp; + avalue[i] = pfr; + nf++; + pfr++; + } + else + { + /* FIXME? here we are really changing the values + * stored in the original calling routines outgoing + * parameter stack. This is probably a really + * naughty thing to do but... + */ + avalue[i] = pst; + pst += 1; + } break; case FFI_TYPE_DOUBLE: + /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64. */ + if (cif->abi == FFI_LINUX_SOFT_FLOAT) + goto soft_double_closure; /* On the outgoing stack all values are aligned to 8 */ /* there are 8 64bit floating point registers */ - if (nf < 8) { - avalue[i] = pfr; - nf++; - pfr++; - } else { - if (((long)pst) & 4) pst++; - avalue[i] = pst; - nf++; - pst+=2; - } + if (nf < 8) + { + avalue[i] = pfr; + nf++; + pfr++; + } + else + { + if (((long) pst) & 4) + pst++; + avalue[i] = pst; + pst += 2; + } + break; + +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT) + goto do_struct; + if (cif->abi == FFI_LINUX_SOFT_FLOAT) + { /* Test if for the whole long double, 4 gprs are available. + otherwise the stuff ends up on the stack. */ + if (ng < 5) + { + avalue[i] = pgr; + pgr += 4; + ng += 4; + } + else + { + avalue[i] = pst; + pst += 4; + } + break; + } + if (nf < 7) + { + avalue[i] = pfr; + pfr += 2; + nf += 2; + } + else + { + if (((long) pst) & 4) + pst++; + avalue[i] = pst; + pst += 4; + nf = 8; + } break; +#endif default: - FFI_ASSERT(0); + FFI_ASSERT (0); } i++; @@ -1019,12 +1252,40 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, if (cif->abi == FFI_SYSV && cif->rtype->type == FFI_TYPE_STRUCT && size <= 8) return FFI_SYSV_TYPE_SMALL_STRUCT + size; - return cif->rtype->type; - +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + else if (cif->rtype->type == FFI_TYPE_LONGDOUBLE + && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT) + return FFI_TYPE_STRUCT; +#endif + /* With FFI_LINUX_SOFT_FLOAT floats and doubles are handled like UINT32 + respectivley UINT64. */ + if (cif->abi == FFI_LINUX_SOFT_FLOAT) + { + switch (cif->rtype->type) + { + case FFI_TYPE_FLOAT: + return FFI_TYPE_UINT32; + break; + case FFI_TYPE_DOUBLE: + return FFI_TYPE_UINT64; + break; +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + return FFI_TYPE_UINT128; + break; +#endif + default: + return cif->rtype->type; + } + } + else + { + return cif->rtype->type; + } } -int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure*, void*, unsigned long*, - ffi_dblfl*); +int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *, + unsigned long *, ffi_dblfl *); int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue, @@ -1153,7 +1414,7 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue, #endif default: - FFI_ASSERT(0); + FFI_ASSERT (0); } i++; diff --git a/libffi/src/powerpc/ffi_darwin.c b/libffi/src/powerpc/ffi_darwin.c index d758f8f..6d1b73e 100644 --- a/libffi/src/powerpc/ffi_darwin.c +++ b/libffi/src/powerpc/ffi_darwin.c @@ -1,11 +1,12 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1998 Geoffrey Keating + ffi_darwin.c - PowerPC Foreign Function Interface - - Darwin ABI support (c) 2001 John Hornkvist - AIX ABI support (c) 2002 Free Software Foundation, Inc. + Copyright (C) 1998 Geoffrey Keating + Copyright (C) 2001 John Hornkvist + Copyright (C) 2002, 2006, 2007 Free Software Foundation, Inc. + FFI support for Darwin and AIX. + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including @@ -79,9 +80,7 @@ enum { ASM_NEEDS_REGISTERS = 4 }; */ -/*@-exportheader@*/ void ffi_prep_args(extended_cif *ecif, unsigned *const stack) -/*@=exportheader@*/ { const unsigned bytes = ecif->cif->bytes; const unsigned flags = ecif->cif->flags; @@ -227,6 +226,48 @@ void ffi_prep_args(extended_cif *ecif, unsigned *const stack) //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4); } +/* Adjust the size of S to be correct for Darwin. + On Darwin, the first field of a structure has natural alignment. */ + +static void +darwin_adjust_aggregate_sizes (ffi_type *s) +{ + int i; + + if (s->type != FFI_TYPE_STRUCT) + return; + + s->size = 0; + for (i = 0; s->elements[i] != NULL; i++) + { + ffi_type *p; + int align; + + p = s->elements[i]; + darwin_adjust_aggregate_sizes (p); + if (i == 0 + && (p->type == FFI_TYPE_UINT64 + || p->type == FFI_TYPE_SINT64 + || p->type == FFI_TYPE_DOUBLE + || p->alignment == 8)) + align = 8; + else if (p->alignment == 16 || p->alignment < 4) + align = p->alignment; + else + align = 4; + s->size = ALIGN(s->size, align) + p->size; + } + + s->size = ALIGN(s->size, s->alignment); + + if (s->elements[0]->type == FFI_TYPE_UINT64 + || s->elements[0]->type == FFI_TYPE_SINT64 + || s->elements[0]->type == FFI_TYPE_DOUBLE + || s->elements[0]->alignment == 8) + s->alignment = s->alignment > 8 ? s->alignment : 8; + /* Do not add additional tail padding. */ +} + /* Perform machine dependent cif processing. */ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) { @@ -239,8 +280,16 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) unsigned size_al = 0; /* All the machine-independent calculation of cif->bytes will be wrong. + All the calculation of structure sizes will also be wrong. Redo the calculation for DARWIN. */ + if (cif->abi == FFI_DARWIN) + { + darwin_adjust_aggregate_sizes (cif->rtype); + for (i = 0; i < cif->nargs; i++) + darwin_adjust_aggregate_sizes (cif->arg_types[i]); + } + /* Space for the frame pointer, callee's LR, CR, etc, and for the asm's temp regs. */ @@ -375,25 +424,12 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) return FFI_OK; } -/*@-declundef@*/ -/*@-exportheader@*/ -extern void ffi_call_AIX(/*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, - void (*fn)(), - void (*fn2)()); -extern void ffi_call_DARWIN(/*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, - void (*fn)(), - void (*fn2)()); -/*@=declundef@*/ -/*@=exportheader@*/ - -void ffi_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ void **avalue) +extern void ffi_call_AIX(extended_cif *, unsigned, unsigned, unsigned *, + void (*fn)(), void (*fn2)()); +extern void ffi_call_DARWIN(extended_cif *, unsigned, unsigned, unsigned *, + void (*fn)(), void (*fn2)()); + +void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) { extended_cif ecif; @@ -406,9 +442,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { - /*@-sysunrecog@*/ ecif.rvalue = alloca(cif->rtype->size); - /*@=sysunrecog@*/ } else ecif.rvalue = rvalue; @@ -416,16 +450,12 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, switch (cif->abi) { case FFI_AIX: - /*@-usedef@*/ - ffi_call_AIX(&ecif, -cif->bytes, - cif->flags, ecif.rvalue, fn, ffi_prep_args); - /*@=usedef@*/ + ffi_call_AIX(&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn, + ffi_prep_args); break; case FFI_DARWIN: - /*@-usedef@*/ - ffi_call_DARWIN(&ecif, -cif->bytes, - cif->flags, ecif.rvalue, fn, ffi_prep_args); - /*@=usedef@*/ + ffi_call_DARWIN(&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn, + ffi_prep_args); break; default: FFI_ASSERT(0); @@ -498,10 +528,11 @@ SP current --> +---------------------------------------+ 176 <- parent frame */ ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*, void*, void**, void*), - void *user_data) +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) { unsigned int *tramp; struct ffi_aix_trampoline_struct *tramp_aix; @@ -523,14 +554,14 @@ ffi_prep_closure (ffi_closure* closure, tramp[8] = 0x816b0004; /* lwz r11,4(r11) static chain */ tramp[9] = 0x4e800420; /* bctr */ tramp[2] = (unsigned long) ffi_closure_ASM; /* function */ - tramp[3] = (unsigned long) closure; /* context */ + tramp[3] = (unsigned long) codeloc; /* context */ closure->cif = cif; closure->fun = fun; closure->user_data = user_data; /* Flush the icache. Only necessary on Darwin. */ - flush_range(&closure->tramp[0],FFI_TRAMPOLINE_SIZE); + flush_range(codeloc, FFI_TRAMPOLINE_SIZE); break; @@ -543,7 +574,7 @@ ffi_prep_closure (ffi_closure* closure, tramp_aix->code_pointer = fd->code_pointer; tramp_aix->toc = fd->toc; - tramp_aix->static_chain = closure; + tramp_aix->static_chain = codeloc; closure->cif = cif; closure->fun = fun; closure->user_data = user_data; diff --git a/libffi/src/powerpc/ffitarget.h b/libffi/src/powerpc/ffitarget.h index af63796..e3fa30b 100644 --- a/libffi/src/powerpc/ffitarget.h +++ b/libffi/src/powerpc/ffitarget.h @@ -1,5 +1,6 @@ /* -----------------------------------------------------------------*-C-*- ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. + Copyright (C) 2007 Free Software Foundation, Inc Target configuration macros for PowerPC. Permission is hereby granted, free of charge, to any person obtaining @@ -43,10 +44,20 @@ typedef enum ffi_abi { FFI_SYSV, FFI_GCC_SYSV, FFI_LINUX64, + FFI_LINUX, + FFI_LINUX_SOFT_FLOAT, # ifdef POWERPC64 FFI_DEFAULT_ABI = FFI_LINUX64, # else +# if (!defined(__NO_FPRS__) && (__LDBL_MANT_DIG__ == 106)) + FFI_DEFAULT_ABI = FFI_LINUX, +# else +# ifdef __NO_FPRS__ + FFI_DEFAULT_ABI = FFI_LINUX_SOFT_FLOAT, +# else FFI_DEFAULT_ABI = FFI_GCC_SYSV, +# endif +# endif # endif #endif @@ -69,7 +80,7 @@ typedef enum ffi_abi { FFI_DEFAULT_ABI = FFI_SYSV, #endif - FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 + FFI_LAST_ABI } ffi_abi; #endif @@ -78,8 +89,14 @@ typedef enum ffi_abi { #define FFI_CLOSURES 1 #define FFI_NATIVE_RAW_API 0 +/* For additional types like the below, take care about the order in + ppc_closures.S. They must follow after the FFI_TYPE_LAST. */ + +/* Needed for soft-float long-double-128 support. */ +#define FFI_TYPE_UINT128 (FFI_TYPE_LAST + 1) + /* Needed for FFI_SYSV small structure returns. */ -#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST) +#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 2) #if defined(POWERPC64) || defined(POWERPC_AIX) #define FFI_TRAMPOLINE_SIZE 24 diff --git a/libffi/src/powerpc/linux64.S b/libffi/src/powerpc/linux64.S index 25b2c4f..2cfebbf 100644 --- a/libffi/src/powerpc/linux64.S +++ b/libffi/src/powerpc/linux64.S @@ -47,8 +47,8 @@ ffi_call_LINUX64: std %r0, 16(%r1) mr %r28, %r1 /* our AP. */ - stdux %r1, %r1, %r4 .LCFI0: + stdux %r1, %r1, %r4 mr %r31, %r5 /* flags, */ mr %r30, %r6 /* rvalue, */ mr %r29, %r7 /* function address. */ @@ -100,6 +100,10 @@ ffi_call_LINUX64: /* Make the call. */ bctrl + /* This must follow the call immediately, the unwinder + uses this to find out if r2 has been saved or not. */ + ld %r2, 40(%r1) + /* Now, deal with the return value. */ mtcrf 0x01, %r31 bt- 30, .Ldone_return_value @@ -109,7 +113,6 @@ ffi_call_LINUX64: .Ldone_return_value: /* Restore the registers we used and return. */ - ld %r2, 40(%r1) mr %r1, %r28 ld %r0, 16(%r28) ld %r28, -32(%r1) @@ -120,12 +123,10 @@ ffi_call_LINUX64: blr .Lfp_return_value: - bt 27, .Lfd_return_value bf 28, .Lfloat_return_value stfd %f1, 0(%r30) - b .Ldone_return_value -.Lfd_return_value: - stfd %f1, 0(%r30) + mtcrf 0x02, %r31 /* cr6 */ + bf 27, .Ldone_return_value stfd %f2, 8(%r30) b .Ldone_return_value .Lfloat_return_value: diff --git a/libffi/src/powerpc/ppc_closure.S b/libffi/src/powerpc/ppc_closure.S index 36f8ac0..c9f5742 100644 --- a/libffi/src/powerpc/ppc_closure.S +++ b/libffi/src/powerpc/ppc_closure.S @@ -28,6 +28,7 @@ ENTRY(ffi_closure_SYSV) stw %r9, 40(%r1) stw %r10,44(%r1) +#ifndef __NO_FPRS__ # next save fpr 1 to fpr 8 (aligned to 8) stfd %f1, 48(%r1) stfd %f2, 56(%r1) @@ -37,6 +38,7 @@ ENTRY(ffi_closure_SYSV) stfd %f6, 88(%r1) stfd %f7, 96(%r1) stfd %f8, 104(%r1) +#endif # set up registers for the routine that actually does the work # get the context pointer from the trampoline @@ -58,223 +60,190 @@ ENTRY(ffi_closure_SYSV) # make the call bl ffi_closure_helper_SYSV@local - +.Lret: # now r3 contains the return type # so use it to look up in a table # so we know how to deal with each type - # Extract the size of the return type for small structures. - # Then calculate (4 - size) and multiply the result by 8. - # This gives the value needed for the shift operation below. - # This part is only needed for FFI_SYSV and small structures. - addi %r5,%r3,-(FFI_SYSV_TYPE_SMALL_STRUCT) - cmpwi cr0,%r5,4 - ble cr0,.Lnext - addi %r5,%r5,-4 -.Lnext: - addi %r5,%r5,-4 - neg %r5,%r5 - slwi %r5,%r5,3 - # look up the proper starting point in table # by using return type as offset - addi %r6,%r1,112 # get pointer to results area - bl .Lget_ret_type0_addr # get pointer to .Lret_type0 into LR - mflr %r4 # move to r4 - slwi %r3,%r3,4 # now multiply return type by 16 - add %r3,%r3,%r4 # add contents of table to table address + + mflr %r4 # move address of .Lret to r4 + slwi %r3,%r3,4 # now multiply return type by 16 + addi %r4, %r4, .Lret_type0 - .Lret + lwz %r0,148(%r1) + add %r3,%r3,%r4 # add contents of table to table address mtctr %r3 - bctr # jump to it + bctr # jump to it .LFE1: # Each of the ret_typeX code fragments has to be exactly 16 bytes long # (4 instructions). For cache effectiveness we align to a 16 byte boundary # first. .align 4 - - nop - nop - nop -.Lget_ret_type0_addr: - blrl - # case FFI_TYPE_VOID .Lret_type0: - b .Lfinish - nop - nop + mtlr %r0 + addi %r1,%r1,144 + blr nop # case FFI_TYPE_INT -.Lret_type1: - lwz %r3,0(%r6) - b .Lfinish - nop - nop + lwz %r3,112+0(%r1) + mtlr %r0 +.Lfinish: + addi %r1,%r1,144 + blr # case FFI_TYPE_FLOAT -.Lret_type2: - lfs %f1,0(%r6) - b .Lfinish - nop - nop + lfs %f1,112+0(%r1) + mtlr %r0 + addi %r1,%r1,144 + blr # case FFI_TYPE_DOUBLE -.Lret_type3: - lfd %f1,0(%r6) - b .Lfinish - nop - nop + lfd %f1,112+0(%r1) + mtlr %r0 + addi %r1,%r1,144 + blr # case FFI_TYPE_LONGDOUBLE -.Lret_type4: - lfd %f1,0(%r6) + lfd %f1,112+0(%r1) + lfd %f2,112+8(%r1) + mtlr %r0 b .Lfinish - nop - nop # case FFI_TYPE_UINT8 -.Lret_type5: - lbz %r3,3(%r6) - b .Lfinish - nop - nop + lbz %r3,112+3(%r1) + mtlr %r0 + addi %r1,%r1,144 + blr # case FFI_TYPE_SINT8 -.Lret_type6: - lbz %r3,3(%r6) + lbz %r3,112+3(%r1) extsb %r3,%r3 + mtlr %r0 b .Lfinish - nop # case FFI_TYPE_UINT16 -.Lret_type7: - lhz %r3,2(%r6) - b .Lfinish - nop - nop + lhz %r3,112+2(%r1) + mtlr %r0 + addi %r1,%r1,144 + blr # case FFI_TYPE_SINT16 -.Lret_type8: - lha %r3,2(%r6) - b .Lfinish - nop - nop + lha %r3,112+2(%r1) + mtlr %r0 + addi %r1,%r1,144 + blr # case FFI_TYPE_UINT32 -.Lret_type9: - lwz %r3,0(%r6) - b .Lfinish - nop - nop + lwz %r3,112+0(%r1) + mtlr %r0 + addi %r1,%r1,144 + blr # case FFI_TYPE_SINT32 -.Lret_type10: - lwz %r3,0(%r6) - b .Lfinish - nop - nop + lwz %r3,112+0(%r1) + mtlr %r0 + addi %r1,%r1,144 + blr # case FFI_TYPE_UINT64 -.Lret_type11: - lwz %r3,0(%r6) - lwz %r4,4(%r6) + lwz %r3,112+0(%r1) + lwz %r4,112+4(%r1) + mtlr %r0 b .Lfinish - nop # case FFI_TYPE_SINT64 -.Lret_type12: - lwz %r3,0(%r6) - lwz %r4,4(%r6) + lwz %r3,112+0(%r1) + lwz %r4,112+4(%r1) + mtlr %r0 b .Lfinish - nop # case FFI_TYPE_STRUCT -.Lret_type13: - b .Lfinish - nop - nop + mtlr %r0 + addi %r1,%r1,144 + blr nop # case FFI_TYPE_POINTER -.Lret_type14: - lwz %r3,0(%r6) - b .Lfinish - nop - nop + lwz %r3,112+0(%r1) + mtlr %r0 + addi %r1,%r1,144 + blr + +# case FFI_TYPE_UINT128 + lwz %r3,112+0(%r1) + lwz %r4,112+4(%r1) + lwz %r5,112+8(%r1) + bl .Luint128 # The return types below are only used when the ABI type is FFI_SYSV. # case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct. -.Lret_type15: -# fall through. - nop - nop - nop - nop + lbz %r3,112+0(%r1) + mtlr %r0 + addi %r1,%r1,144 + blr # case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct. -.Lret_type16: -# fall through. - nop - nop - nop - nop + lhz %r3,112+0(%r1) + mtlr %r0 + addi %r1,%r1,144 + blr # case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct. -.Lret_type17: -# fall through. - nop - nop - nop - nop + lwz %r3,112+0(%r1) + srwi %r3,%r3,8 + mtlr %r0 + b .Lfinish # case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct. -.Lret_type18: -# this one handles the structs from above too. - lwz %r3,0(%r6) - srw %r3,%r3,%r5 - b .Lfinish - nop + lwz %r3,112+0(%r1) + mtlr %r0 + addi %r1,%r1,144 + blr # case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct. -.Lret_type19: -# fall through. - nop - nop - nop - nop + lwz %r3,112+0(%r1) + lwz %r4,112+4(%r1) + li %r5,24 + b .Lstruct567 # case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct. -.Lret_type20: -# fall through. - nop - nop - nop - nop + lwz %r3,112+0(%r1) + lwz %r4,112+4(%r1) + li %r5,16 + b .Lstruct567 # case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct. -.Lret_type21: -# fall through. - nop - nop - nop - nop + lwz %r3,112+0(%r1) + lwz %r4,112+4(%r1) + li %r5,8 + b .Lstruct567 # case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct. -.Lret_type22: -# this one handles the above unhandled structs. - lwz %r3,0(%r6) - lwz %r4,4(%r6) - bl __lshrdi3 # libgcc function to shift r3/r4, shift value in r5. + lwz %r3,112+0(%r1) + lwz %r4,112+4(%r1) + mtlr %r0 b .Lfinish -# case done -.Lfinish: +.Lstruct567: + subfic %r6,%r5,32 + srw %r4,%r4,%r5 + slw %r6,%r3,%r6 + srw %r3,%r3,%r5 + or %r4,%r6,%r4 + mtlr %r0 + addi %r1,%r1,144 + blr - lwz %r0,148(%r1) +.Luint128: + lwz %r6,112+12(%r1) mtlr %r0 addi %r1,%r1,144 blr + END(ffi_closure_SYSV) .section ".eh_frame",EH_FRAME_FLAGS,@progbits diff --git a/libffi/src/powerpc/sysv.S b/libffi/src/powerpc/sysv.S index 235acfa..2136714 100644 --- a/libffi/src/powerpc/sysv.S +++ b/libffi/src/powerpc/sysv.S @@ -1,5 +1,6 @@ /* ----------------------------------------------------------------------- - sysv.h - Copyright (c) 1998 Geoffrey Keating + sysv.S - Copyright (c) 1998 Geoffrey Keating + Copyright (C) 2007 Free Software Foundation, Inc PowerPC Assembly glue. @@ -98,13 +99,17 @@ ENTRY(ffi_call_SYSV) bctrl /* Now, deal with the return value. */ - mtcrf 0x01,%r31 + mtcrf 0x01,%r31 /* cr7 */ bt- 31,L(small_struct_return_value) bt- 30,L(done_return_value) bt- 29,L(fp_return_value) stw %r3,0(%r30) bf+ 28,L(done_return_value) stw %r4,4(%r30) + mtcrf 0x02,%r31 /* cr6 */ + bf 27,L(done_return_value) + stw %r5,8(%r30) + stw %r6,12(%r30) /* Fall through... */ L(done_return_value): @@ -121,6 +126,9 @@ L(done_return_value): L(fp_return_value): bf 28,L(float_return_value) stfd %f1,0(%r30) + mtcrf 0x02,%r31 /* cr6 */ + bf 27,L(done_return_value) + stfd %f2,8(%r30) b L(done_return_value) L(float_return_value): stfs %f1,0(%r30) @@ -140,8 +148,14 @@ L(smst_one_register): b L(done_return_value) L(smst_two_register): rlwinm %r5,%r31,5+23,32-5,31 /* Extract the value to shift. */ - bl __ashldi3 /* libgcc function to shift r3/r4, - shift value in r5. */ + cmpwi %r5,0 + subfic %r9,%r5,32 + slw %r29,%r3,%r5 + srw %r9,%r4,%r9 + beq- L(smst_8byte) + or %r3,%r9,%r29 + slw %r4,%r4,%r5 +L(smst_8byte): stw %r3,0(%r30) stw %r4,4(%r30) b L(done_return_value) diff --git a/libffi/src/prep_cif.c b/libffi/src/prep_cif.c index 0faa5dd..b6bc52a 100644 --- a/libffi/src/prep_cif.c +++ b/libffi/src/prep_cif.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - prep_cif.c - Copyright (c) 1996, 1998 Red Hat, Inc. + prep_cif.c - Copyright (c) 1996, 1998, 2007 Red Hat, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -25,7 +25,6 @@ #include #include - /* Round up to FFI_SIZEOF_ARG. */ #define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG) @@ -33,14 +32,12 @@ /* Perform machine independent initialization of aggregate type specifications. */ -static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg) +static ffi_status initialize_aggregate(ffi_type *arg) { - ffi_type **ptr; + ffi_type **ptr; FFI_ASSERT(arg != NULL); - /*@-usedef@*/ - FFI_ASSERT(arg->elements != NULL); FFI_ASSERT(arg->size == 0); FFI_ASSERT(arg->alignment == 0); @@ -51,14 +48,14 @@ static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg) { if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) return FFI_BAD_TYPEDEF; - + /* Perform a sanity check on the argument type */ FFI_ASSERT_VALID_TYPE(*ptr); arg->size = ALIGN(arg->size, (*ptr)->alignment); arg->size += (*ptr)->size; - arg->alignment = (arg->alignment > (*ptr)->alignment) ? + arg->alignment = (arg->alignment > (*ptr)->alignment) ? arg->alignment : (*ptr)->alignment; ptr++; @@ -77,8 +74,6 @@ static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg) return FFI_BAD_TYPEDEF; else return FFI_OK; - - /*@=usedef@*/ } #ifndef __CRIS__ @@ -89,10 +84,8 @@ static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg) /* Perform machine independent ffi_cif preparation, then call machine dependent routine. */ -ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, - ffi_abi abi, unsigned int nargs, - /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, - /*@dependent@*/ ffi_type **atypes) +ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs, + ffi_type *rtype, ffi_type **atypes) { unsigned bytes = 0; unsigned int i; @@ -109,10 +102,8 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, cif->flags = 0; /* Initialize the return type if necessary */ - /*@-usedef@*/ if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK)) return FFI_BAD_TYPEDEF; - /*@=usedef@*/ /* Perform a sanity check on the return type */ FFI_ASSERT_VALID_TYPE(cif->rtype); @@ -124,7 +115,10 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, #ifdef SPARC && (cif->abi != FFI_V9 || cif->rtype->size > 32) #endif - ) +#ifdef X86_DARWIN + && (cif->rtype->size > 8) +#endif + ) bytes = STACK_ARG_SIZE(sizeof(void*)); #endif @@ -135,7 +129,7 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) return FFI_BAD_TYPEDEF; - /* Perform a sanity check on the argument type, do this + /* Perform a sanity check on the argument type, do this check after the initialization. */ FFI_ASSERT_VALID_TYPE(*ptr); @@ -152,7 +146,7 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, /* Add any padding if necessary */ if (((*ptr)->alignment - 1) & bytes) bytes = ALIGN(bytes, (*ptr)->alignment); - + bytes += STACK_ARG_SIZE((*ptr)->size); } #endif @@ -164,3 +158,16 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, return ffi_prep_cif_machdep(cif); } #endif /* not __CRIS__ */ + +#if FFI_CLOSURES + +ffi_status +ffi_prep_closure (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data) +{ + return ffi_prep_closure_loc (closure, cif, fun, user_data, closure); +} + +#endif diff --git a/libffi/src/raw_api.c b/libffi/src/raw_api.c index f4f4d80..b3ca511 100644 --- a/libffi/src/raw_api.c +++ b/libffi/src/raw_api.c @@ -189,10 +189,7 @@ ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw) * these following couple of functions will handle the translation forth * and back automatically. */ -void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ ffi_raw *raw) +void ffi_raw_call (ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *raw) { void **avalue = (void**) alloca (cif->nargs * sizeof (void*)); ffi_raw_to_ptrarray (cif, raw, avalue); @@ -201,7 +198,7 @@ void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, #if FFI_CLOSURES /* base system provides closures */ -static void +static void ffi_translate_args (ffi_cif *cif, void *rvalue, void **avalue, void *user_data) { @@ -212,22 +209,20 @@ ffi_translate_args (ffi_cif *cif, void *rvalue, (*cl->fun) (cif, rvalue, raw, cl->user_data); } -/* Again, here is the generic version of ffi_prep_raw_closure, which - * will install an intermediate "hub" for translation of arguments from - * the pointer-array format, to the raw format */ - ffi_status -ffi_prep_raw_closure (ffi_raw_closure* cl, - ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void *user_data) +ffi_prep_raw_closure_loc (ffi_raw_closure* cl, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void *user_data, + void *codeloc) { ffi_status status; - status = ffi_prep_closure ((ffi_closure*) cl, - cif, - &ffi_translate_args, - (void*)cl); + status = ffi_prep_closure_loc ((ffi_closure*) cl, + cif, + &ffi_translate_args, + codeloc, + codeloc); if (status == FFI_OK) { cl->fun = fun; @@ -239,4 +234,22 @@ ffi_prep_raw_closure (ffi_raw_closure* cl, #endif /* FFI_CLOSURES */ #endif /* !FFI_NATIVE_RAW_API */ + +#if FFI_CLOSURES + +/* Again, here is the generic version of ffi_prep_raw_closure, which + * will install an intermediate "hub" for translation of arguments from + * the pointer-array format, to the raw format */ + +ffi_status +ffi_prep_raw_closure (ffi_raw_closure* cl, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void *user_data) +{ + return ffi_prep_raw_closure_loc (cl, cif, fun, user_data, cl); +} + +#endif /* FFI_CLOSURES */ + #endif /* !FFI_NO_RAW_API */ diff --git a/libffi/src/s390/ffi.c b/libffi/src/s390/ffi.c index 399fa2a..d17f790 100644 --- a/libffi/src/s390/ffi.c +++ b/libffi/src/s390/ffi.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 2000 Software AG + ffi.c - Copyright (c) 2000, 2007 Software AG S390 Foreign Function Interface @@ -207,6 +207,12 @@ ffi_prep_args (unsigned char *stack, extended_cif *ecif) void *arg = *p_argv; int type = (*ptr)->type; +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + /* 16-byte long double is passed like a struct. */ + if (type == FFI_TYPE_LONGDOUBLE) + type = FFI_TYPE_STRUCT; +#endif + /* Check how a structure type is passed. */ if (type == FFI_TYPE_STRUCT) { @@ -364,6 +370,12 @@ ffi_prep_cif_machdep(ffi_cif *cif) cif->flags = FFI390_RET_DOUBLE; break; +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + cif->flags = FFI390_RET_STRUCT; + n_gpr++; + break; +#endif /* Integer values are returned in gpr 2 (and gpr 3 for 64-bit values on 31-bit machines). */ case FFI_TYPE_UINT64: @@ -400,6 +412,12 @@ ffi_prep_cif_machdep(ffi_cif *cif) { int type = (*ptr)->type; +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + /* 16-byte long double is passed like a struct. */ + if (type == FFI_TYPE_LONGDOUBLE) + type = FFI_TYPE_STRUCT; +#endif + /* Check how a structure type is passed. */ if (type == FFI_TYPE_STRUCT) { @@ -562,6 +580,12 @@ ffi_closure_helper_SYSV (ffi_closure *closure, int deref_struct_pointer = 0; int type = (*ptr)->type; +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + /* 16-byte long double is passed like a struct. */ + if (type == FFI_TYPE_LONGDOUBLE) + type = FFI_TYPE_STRUCT; +#endif + /* Check how a structure type is passed. */ if (type == FFI_TYPE_STRUCT) { @@ -662,6 +686,9 @@ ffi_closure_helper_SYSV (ffi_closure *closure, /* Void is easy, and so is struct. */ case FFI_TYPE_VOID: case FFI_TYPE_STRUCT: +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: +#endif break; /* Floating point values are returned in fpr 0. */ @@ -709,17 +736,18 @@ ffi_closure_helper_SYSV (ffi_closure *closure, /*====================================================================*/ /* */ -/* Name - ffi_prep_closure. */ +/* Name - ffi_prep_closure_loc. */ /* */ /* Function - Prepare a FFI closure. */ /* */ /*====================================================================*/ ffi_status -ffi_prep_closure (ffi_closure *closure, - ffi_cif *cif, - void (*fun) (ffi_cif *, void *, void **, void *), - void *user_data) +ffi_prep_closure_loc (ffi_closure *closure, + ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, + void *codeloc) { FFI_ASSERT (cif->abi == FFI_SYSV); @@ -728,7 +756,7 @@ ffi_prep_closure (ffi_closure *closure, *(short *)&closure->tramp [2] = 0x9801; /* lm %r0,%r1,6(%r1) */ *(short *)&closure->tramp [4] = 0x1006; *(short *)&closure->tramp [6] = 0x07f1; /* br %r1 */ - *(long *)&closure->tramp [8] = (long)closure; + *(long *)&closure->tramp [8] = (long)codeloc; *(long *)&closure->tramp[12] = (long)&ffi_closure_SYSV; #else *(short *)&closure->tramp [0] = 0x0d10; /* basr %r1,0 */ @@ -736,7 +764,7 @@ ffi_prep_closure (ffi_closure *closure, *(short *)&closure->tramp [4] = 0x100e; *(short *)&closure->tramp [6] = 0x0004; *(short *)&closure->tramp [8] = 0x07f1; /* br %r1 */ - *(long *)&closure->tramp[16] = (long)closure; + *(long *)&closure->tramp[16] = (long)codeloc; *(long *)&closure->tramp[24] = (long)&ffi_closure_SYSV; #endif diff --git a/libffi/src/sh/ffi.c b/libffi/src/sh/ffi.c index 38449e9..0cb8c72 100644 --- a/libffi/src/sh/ffi.c +++ b/libffi/src/sh/ffi.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 2002, 2003, 2004, 2005 Kaz Kojima + ffi.c - Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 Kaz Kojima SuperH Foreign Function Interface @@ -106,9 +106,7 @@ return_type (ffi_type *arg) /* ffi_prep_args is called by the assembly routine once stack space has been allocated for the function's arguments */ -/*@-exportheader@*/ void ffi_prep_args(char *stack, extended_cif *ecif) -/*@=exportheader@*/ { register unsigned int i; register int tmp; @@ -406,20 +404,10 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) return FFI_OK; } -/*@-declundef@*/ -/*@-exportheader@*/ -extern void ffi_call_SYSV(void (*)(char *, extended_cif *), - /*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, - void (*fn)()); -/*@=declundef@*/ -/*@=exportheader@*/ - -void ffi_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ void **avalue) +extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, + unsigned, unsigned, unsigned *, void (*fn)()); + +void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) { extended_cif ecif; UINT64 trvalue; @@ -436,9 +424,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, else if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { - /*@-sysunrecog@*/ ecif.rvalue = alloca(cif->rtype->size); - /*@=sysunrecog@*/ } else ecif.rvalue = rvalue; @@ -446,10 +432,8 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, switch (cif->abi) { case FFI_SYSV: - /*@-usedef@*/ - ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ + ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, + fn); break; default: FFI_ASSERT(0); @@ -468,10 +452,11 @@ extern void __ic_invalidate (void *line); #endif ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*, void*, void**, void*), - void *user_data) +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) { unsigned int *tramp; unsigned short insn; @@ -491,7 +476,7 @@ ffi_prep_closure (ffi_closure* closure, tramp[0] = 0xd102d301; tramp[1] = 0x412b0000 | insn; #endif - *(void **) &tramp[2] = (void *)closure; /* ctx */ + *(void **) &tramp[2] = (void *)codeloc; /* ctx */ *(void **) &tramp[3] = (void *)ffi_closure_SYSV; /* funaddr */ closure->cif = cif; @@ -500,7 +485,7 @@ ffi_prep_closure (ffi_closure* closure, #if defined(__SH4__) /* Flush the icache. */ - __ic_invalidate(&closure->tramp[0]); + __ic_invalidate(codeloc); #endif return FFI_OK; @@ -535,7 +520,6 @@ ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, int freg = 0; #endif ffi_cif *cif; - double temp; cif = closure->cif; avalue = alloca(cif->nargs * sizeof(void *)); @@ -544,7 +528,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, returns the data directly to the caller. */ if (cif->rtype->type == FFI_TYPE_STRUCT && STRUCT_VALUE_ADDRESS_WITH_ARG) { - rvalue = *pgr++; + rvalue = (void *) *pgr++; ireg = 1; } else @@ -611,6 +595,8 @@ ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, { if (freg + 1 >= NFREGARG) continue; + if (freg & 1) + pfr++; freg = (freg + 1) & ~1; freg += 2; avalue[i] = pfr; diff --git a/libffi/src/sh/sysv.S b/libffi/src/sh/sysv.S index c9002a7..6628f2d 100644 --- a/libffi/src/sh/sysv.S +++ b/libffi/src/sh/sysv.S @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - sysv.S - Copyright (c) 2002, 2003, 2004 Kaz Kojima + sysv.S - Copyright (c) 2002, 2003, 2004, 2006 Kaz Kojima SuperH Foreign Function Interface @@ -829,13 +829,13 @@ __FRAME_BEGIN__: .byte 0x6 /* uleb128 0x6 */ .byte 0x8e /* DW_CFA_offset, column 0xe */ .byte 0x5 /* uleb128 0x5 */ - .byte 0x8b /* DW_CFA_offset, column 0xb */ + .byte 0x84 /* DW_CFA_offset, column 0x4 */ .byte 0x4 /* uleb128 0x4 */ - .byte 0x8a /* DW_CFA_offset, column 0xa */ + .byte 0x85 /* DW_CFA_offset, column 0x5 */ .byte 0x3 /* uleb128 0x3 */ - .byte 0x89 /* DW_CFA_offset, column 0x9 */ + .byte 0x86 /* DW_CFA_offset, column 0x6 */ .byte 0x2 /* uleb128 0x2 */ - .byte 0x88 /* DW_CFA_offset, column 0x8 */ + .byte 0x87 /* DW_CFA_offset, column 0x7 */ .byte 0x1 /* uleb128 0x1 */ .byte 0x4 /* DW_CFA_advance_loc4 */ .4byte .LCFIE-.LCFID diff --git a/libffi/src/sparc/ffi.c b/libffi/src/sparc/ffi.c index b83d63d..a10fe81 100644 --- a/libffi/src/sparc/ffi.c +++ b/libffi/src/sparc/ffi.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1996, 2003, 2004 Red Hat, Inc. + ffi.c - Copyright (c) 1996, 2003, 2004, 2007 Red Hat, Inc. SPARC Foreign Function Interface @@ -425,10 +425,11 @@ extern void ffi_closure_v8(void); #endif ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*, void*, void**, void*), - void *user_data) +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) { unsigned int *tramp = (unsigned int *) &closure->tramp[0]; unsigned long fn; @@ -443,7 +444,7 @@ ffi_prep_closure (ffi_closure* closure, tramp[3] = 0x01000000; /* nop */ *((unsigned long *) &tramp[4]) = fn; #else - unsigned long ctx = (unsigned long) closure; + unsigned long ctx = (unsigned long) codeloc; FFI_ASSERT (cif->abi == FFI_V8); fn = (unsigned long) ffi_closure_v8; tramp[0] = 0x03000000 | fn >> 10; /* sethi %hi(fn), %g1 */ diff --git a/libffi/src/types.c b/libffi/src/types.c index b657873..6d30488 100644 --- a/libffi/src/types.c +++ b/libffi/src/types.c @@ -23,6 +23,10 @@ OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ +/* Hide the basic type definitions from the header file, so that we + can redefine them here as "const". */ +#define LIBFFI_HIDE_BASIC_TYPES + #include #include @@ -33,14 +37,14 @@ struct struct_align_##name { \ char c; \ type x; \ }; \ -ffi_type ffi_type_##name = { \ +const ffi_type ffi_type_##name = { \ sizeof(type), \ offsetof(struct struct_align_##name, x), \ id, NULL \ } /* Size and alignment are fake here. They must not be 0. */ -ffi_type ffi_type_void = { +const ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID, NULL }; @@ -57,4 +61,16 @@ FFI_TYPEDEF(pointer, void*, FFI_TYPE_POINTER); FFI_TYPEDEF(float, float, FFI_TYPE_FLOAT); FFI_TYPEDEF(double, double, FFI_TYPE_DOUBLE); + +#ifdef __alpha__ +/* Even if we're not configured to default to 128-bit long double, + maintain binary compatibility, as -mlong-double-128 can be used + at any time. */ +/* Validate the hard-coded number below. */ +# if defined(__LONG_DOUBLE_128__) && FFI_TYPE_LONGDOUBLE != 4 +# error FFI_TYPE_LONGDOUBLE out of date +# endif +const ffi_type ffi_type_longdouble = { 16, 16, 4, NULL }; +#elif FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE FFI_TYPEDEF(longdouble, long double, FFI_TYPE_LONGDOUBLE); +#endif diff --git a/libffi/src/x86/darwin.S b/libffi/src/x86/darwin.S index aec9b82..eeee802 100644 --- a/libffi/src/x86/darwin.S +++ b/libffi/src/x86/darwin.S @@ -1,7 +1,8 @@ /* ----------------------------------------------------------------------- - sysv.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005 Red Hat, Inc. - - X86 Foreign Function Interface + darwin.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005 Red Hat, Inc. + Copyright (C) 2008 Free Software Foundation, Inc. + + X86 Foreign Function Interface Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -60,16 +61,15 @@ _ffi_call_SYSV: call *28(%ebp) - /* Remove the space we pushed for the args */ - movl 16(%ebp),%ecx - addl %ecx,%esp - /* Load %ecx with the return type code */ movl 20(%ebp),%ecx + /* Protect %esi. We're going to pop it in the epilogue. */ + pushl %esi + /* If the return value pointer is NULL, assume no return value. */ cmpl $0,24(%ebp) - jne retint + jne 0f /* Even if there is no space for the return value, we are obliged to handle floating-point values. */ @@ -77,79 +77,102 @@ _ffi_call_SYSV: jne noretval fstp %st(0) - jmp epilogue - -retint: - cmpl $FFI_TYPE_INT,%ecx - jne retfloat - /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx - movl %eax,0(%ecx) jmp epilogue +0: + .align 4 + call 1f +.Lstore_table: + .long noretval-.Lstore_table /* FFI_TYPE_VOID */ + .long retint-.Lstore_table /* FFI_TYPE_INT */ + .long retfloat-.Lstore_table /* FFI_TYPE_FLOAT */ + .long retdouble-.Lstore_table /* FFI_TYPE_DOUBLE */ + .long retlongdouble-.Lstore_table /* FFI_TYPE_LONGDOUBLE */ + .long retuint8-.Lstore_table /* FFI_TYPE_UINT8 */ + .long retsint8-.Lstore_table /* FFI_TYPE_SINT8 */ + .long retuint16-.Lstore_table /* FFI_TYPE_UINT16 */ + .long retsint16-.Lstore_table /* FFI_TYPE_SINT16 */ + .long retint-.Lstore_table /* FFI_TYPE_UINT32 */ + .long retint-.Lstore_table /* FFI_TYPE_SINT32 */ + .long retint64-.Lstore_table /* FFI_TYPE_UINT64 */ + .long retint64-.Lstore_table /* FFI_TYPE_SINT64 */ + .long retstruct-.Lstore_table /* FFI_TYPE_STRUCT */ + .long retint-.Lstore_table /* FFI_TYPE_POINTER */ + .long retstruct1b-.Lstore_table /* FFI_TYPE_SMALL_STRUCT_1B */ + .long retstruct2b-.Lstore_table /* FFI_TYPE_SMALL_STRUCT_2B */ +1: + pop %esi + add (%esi, %ecx, 4), %esi + jmp *%esi + + /* Sign/zero extend as appropriate. */ +retsint8: + movsbl %al, %eax + jmp retint + +retsint16: + movswl %ax, %eax + jmp retint + +retuint8: + movzbl %al, %eax + jmp retint + +retuint16: + movzwl %ax, %eax + jmp retint retfloat: - cmpl $FFI_TYPE_FLOAT,%ecx - jne retdouble /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx + movl 24(%ebp),%ecx fstps (%ecx) jmp epilogue retdouble: - cmpl $FFI_TYPE_DOUBLE,%ecx - jne retlongdouble /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx + movl 24(%ebp),%ecx fstpl (%ecx) jmp epilogue retlongdouble: - cmpl $FFI_TYPE_LONGDOUBLE,%ecx - jne retint64 /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx + movl 24(%ebp),%ecx fstpt (%ecx) jmp epilogue - -retint64: - cmpl $FFI_TYPE_SINT64,%ecx - jne retstruct1b + +retint64: /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx + movl 24(%ebp),%ecx movl %eax,0(%ecx) movl %edx,4(%ecx) jmp epilogue - -retstruct1b: - cmpl $FFI_TYPE_SINT8,%ecx - jne retstruct2b + +retstruct1b: /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx + movl 24(%ebp),%ecx movb %al,0(%ecx) jmp epilogue -retstruct2b: - cmpl $FFI_TYPE_SINT16,%ecx - jne retstruct +retstruct2b: /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx + movl 24(%ebp),%ecx movw %ax,0(%ecx) jmp epilogue +retint: + /* Load %ecx with the pointer to storage for the return value */ + movl 24(%ebp),%ecx + movl %eax,0(%ecx) + retstruct: - cmpl $FFI_TYPE_STRUCT,%ecx - jne noretval /* Nothing to do! */ - addl $4,%esp - popl %ebp - ret noretval: epilogue: - addl $8,%esp - movl %ebp,%esp - popl %ebp - ret + popl %esi + movl %ebp,%esp + popl %ebp + ret + .LFE1: .ffi_call_SYSV_end: @@ -177,7 +200,15 @@ _ffi_closure_SYSV: movl -12(%ebp), %ecx cmpl $FFI_TYPE_INT, %eax je .Lcls_retint - cmpl $FFI_TYPE_FLOAT, %eax + + /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16, + FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32. */ + cmpl $FFI_TYPE_UINT64, %eax + jge 0f + cmpl $FFI_TYPE_UINT8, %eax + jge .Lcls_retint + +0: cmpl $FFI_TYPE_FLOAT, %eax je .Lcls_retfloat cmpl $FFI_TYPE_DOUBLE, %eax je .Lcls_retdouble @@ -185,10 +216,10 @@ _ffi_closure_SYSV: je .Lcls_retldouble cmpl $FFI_TYPE_SINT64, %eax je .Lcls_retllong - cmpl $FFI_TYPE_SINT8, %eax - je .Lcls_retstruct1 - cmpl $FFI_TYPE_SINT16, %eax - je .Lcls_retstruct2 + cmpl $FFI_TYPE_SMALL_STRUCT_1B, %eax + je .Lcls_retstruct1b + cmpl $FFI_TYPE_SMALL_STRUCT_2B, %eax + je .Lcls_retstruct2b cmpl $FFI_TYPE_STRUCT, %eax je .Lcls_retstruct .Lcls_epilogue: @@ -211,10 +242,10 @@ _ffi_closure_SYSV: movl (%ecx), %eax movl 4(%ecx), %edx jmp .Lcls_epilogue -.Lcls_retstruct1: +.Lcls_retstruct1b: movsbl (%ecx), %eax jmp .Lcls_epilogue -.Lcls_retstruct2: +.Lcls_retstruct2b: movswl (%ecx), %eax jmp .Lcls_epilogue .Lcls_retstruct: @@ -256,6 +287,14 @@ _ffi_closure_raw_SYSV: movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */ cmpl $FFI_TYPE_INT, %eax je .Lrcls_retint + + /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16, + FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32. */ + cmpl $FFI_TYPE_UINT64, %eax + jge 0f + cmpl $FFI_TYPE_UINT8, %eax + jge .Lrcls_retint +0: cmpl $FFI_TYPE_FLOAT, %eax je .Lrcls_retfloat cmpl $FFI_TYPE_DOUBLE, %eax diff --git a/libffi/src/x86/ffi.c b/libffi/src/x86/ffi.c index e4d5fc3..a4d4798 100644 --- a/libffi/src/x86/ffi.c +++ b/libffi/src/x86/ffi.c @@ -1,10 +1,11 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1996, 1998, 1999, 2001 Red Hat, Inc. + ffi.c - Copyright (c) 1996, 1998, 1999, 2001, 2007 Red Hat, Inc. Copyright (c) 2002 Ranjit Mathew Copyright (c) 2002 Bo Thorsen Copyright (c) 2002 Roger Sayle - - x86 Foreign Function Interface + Copyright (C) 2008 Free Software Foundation, Inc. + + x86 Foreign Function Interface Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -36,9 +37,7 @@ /* ffi_prep_args is called by the assembly routine once stack space has been allocated for the function's arguments */ -/*@-exportheader@*/ void ffi_prep_args(char *stack, extended_cif *ecif) -/*@=exportheader@*/ { register unsigned int i; register void **p_argv; @@ -121,9 +120,16 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) switch (cif->rtype->type) { case FFI_TYPE_VOID: -#ifndef X86_WIN32 +#ifdef X86 case FFI_TYPE_STRUCT: #endif +#if defined(X86) || defined(X86_DARWIN) + case FFI_TYPE_UINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT8: + case FFI_TYPE_SINT16: +#endif + case FFI_TYPE_SINT64: case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: @@ -135,15 +141,15 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) cif->flags = FFI_TYPE_SINT64; break; -#ifdef X86_WIN32 +#ifndef X86 case FFI_TYPE_STRUCT: if (cif->rtype->size == 1) { - cif->flags = FFI_TYPE_SINT8; /* same as char size */ + cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */ } else if (cif->rtype->size == 2) { - cif->flags = FFI_TYPE_SINT16; /* same as short size */ + cif->flags = FFI_TYPE_SMALL_STRUCT_2B; /* same as short size */ } else if (cif->rtype->size == 4) { @@ -165,35 +171,23 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) break; } +#ifdef X86_DARWIN + cif->bytes = (cif->bytes + 15) & ~0xF; +#endif + return FFI_OK; } -/*@-declundef@*/ -/*@-exportheader@*/ -extern void ffi_call_SYSV(void (*)(char *, extended_cif *), - /*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, - void (*fn)()); -/*@=declundef@*/ -/*@=exportheader@*/ +extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, + unsigned, unsigned, unsigned *, void (*fn)()); #ifdef X86_WIN32 -/*@-declundef@*/ -/*@-exportheader@*/ -extern void ffi_call_STDCALL(void (*)(char *, extended_cif *), - /*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, - void (*fn)()); -/*@=declundef@*/ -/*@=exportheader@*/ +extern void ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, + unsigned, unsigned, unsigned *, void (*fn)()); + #endif /* X86_WIN32 */ -void ffi_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ void **avalue) +void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) { extended_cif ecif; @@ -206,9 +200,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, if ((rvalue == NULL) && (cif->flags == FFI_TYPE_STRUCT)) { - /*@-sysunrecog@*/ ecif.rvalue = alloca(cif->rtype->size); - /*@=sysunrecog@*/ } else ecif.rvalue = rvalue; @@ -217,17 +209,13 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, switch (cif->abi) { case FFI_SYSV: - /*@-usedef@*/ - ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ + ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, + fn); break; #ifdef X86_WIN32 case FFI_STDCALL: - /*@-usedef@*/ - ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ + ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, cif->flags, + ecif.rvalue, fn); break; #endif /* X86_WIN32 */ default: @@ -276,11 +264,9 @@ ffi_closure_SYSV_inner (closure, respp, args) return cif->flags; } -/*@-exportheader@*/ -static void -ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, - void **avalue, ffi_cif *cif) -/*@=exportheader@*/ +static void +ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, + ffi_cif *cif) { register unsigned int i; register void **p_argv; @@ -324,7 +310,7 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, ({ unsigned char *__tramp = (unsigned char*)(TRAMP); \ unsigned int __fun = (unsigned int)(FUN); \ unsigned int __ctx = (unsigned int)(CTX); \ - unsigned int __dis = __fun - ((unsigned int) __tramp + FFI_TRAMPOLINE_SIZE); \ + unsigned int __dis = __fun - (__ctx + FFI_TRAMPOLINE_SIZE); \ *(unsigned char*) &__tramp[0] = 0xb8; \ *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \ *(unsigned char *) &__tramp[5] = 0xe9; \ @@ -335,16 +321,17 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, /* the cif must already be prep'ed */ ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data) +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void *codeloc) { FFI_ASSERT (cif->abi == FFI_SYSV); FFI_INIT_TRAMPOLINE (&closure->tramp[0], \ &ffi_closure_SYSV, \ - (void*)closure); + codeloc); closure->cif = cif; closure->user_data = user_data; @@ -358,10 +345,11 @@ ffi_prep_closure (ffi_closure* closure, #if !FFI_NO_RAW_API ffi_status -ffi_prep_raw_closure (ffi_raw_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void *user_data) +ffi_prep_raw_closure_loc (ffi_raw_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void *user_data, + void *codeloc) { int i; @@ -380,7 +368,7 @@ ffi_prep_raw_closure (ffi_raw_closure* closure, FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV, - (void*)closure); + codeloc); closure->cif = cif; closure->user_data = user_data; @@ -400,27 +388,18 @@ ffi_prep_args_raw(char *stack, extended_cif *ecif) * libffi-1.20, this is not the case.) */ -extern void -ffi_call_SYSV(void (*)(char *, extended_cif *), - /*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, - void (*fn)()); +extern void +ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, unsigned, + unsigned, unsigned *, void (*fn)()); #ifdef X86_WIN32 extern void -ffi_call_STDCALL(void (*)(char *, extended_cif *), - /*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, - void (*fn)()); +ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, unsigned, + unsigned, unsigned *, void (*fn)()); #endif /* X86_WIN32 */ void -ffi_raw_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ ffi_raw *fake_avalue) +ffi_raw_call(ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *fake_avalue) { extended_cif ecif; void **avalue = (void **)fake_avalue; @@ -434,9 +413,7 @@ ffi_raw_call(/*@dependent@*/ ffi_cif *cif, if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { - /*@-sysunrecog@*/ ecif.rvalue = alloca(cif->rtype->size); - /*@=sysunrecog@*/ } else ecif.rvalue = rvalue; @@ -445,17 +422,13 @@ ffi_raw_call(/*@dependent@*/ ffi_cif *cif, switch (cif->abi) { case FFI_SYSV: - /*@-usedef@*/ - ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ + ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, + ecif.rvalue, fn); break; #ifdef X86_WIN32 case FFI_STDCALL: - /*@-usedef@*/ - ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ + ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, + ecif.rvalue, fn); break; #endif /* X86_WIN32 */ default: diff --git a/libffi/src/x86/ffi64.c b/libffi/src/x86/ffi64.c index c6cf330..0bb18c6 100644 --- a/libffi/src/x86/ffi64.c +++ b/libffi/src/x86/ffi64.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 2002 Bo Thorsen + ffi.c - Copyright (c) 2002, 2007 Bo Thorsen x86-64 Foreign Function Interface @@ -433,10 +433,11 @@ ffi_call (ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) extern void ffi_closure_unix64(void); ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*, void*, void**, void*), - void *user_data) +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) { volatile unsigned short *tramp; @@ -445,7 +446,7 @@ ffi_prep_closure (ffi_closure* closure, tramp[0] = 0xbb49; /* mov , %r11 */ *(void * volatile *) &tramp[1] = ffi_closure_unix64; tramp[5] = 0xba49; /* mov , %r10 */ - *(void * volatile *) &tramp[6] = closure; + *(void * volatile *) &tramp[6] = codeloc; /* Set the carry bit iff the function uses any sse registers. This is clc or stc, together with the first byte of the jmp. */ diff --git a/libffi/src/x86/ffitarget.h b/libffi/src/x86/ffitarget.h index 9500f40..3a1427c 100644 --- a/libffi/src/x86/ffitarget.h +++ b/libffi/src/x86/ffitarget.h @@ -1,5 +1,7 @@ /* -----------------------------------------------------------------*-C-*- ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. + Copyright (C) 2008 Free Software Foundation, Inc. + Target configuration macros for x86 and x86-64. Permission is hereby granted, free of charge, to any person obtaining @@ -68,8 +70,10 @@ typedef enum ffi_abi { /* ---- Definitions for closures ----------------------------------------- */ #define FFI_CLOSURES 1 +#define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1) +#define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2) -#ifdef X86_64 +#if defined (X86_64) || (defined (__x86_64__) && defined (X86_DARWIN)) #define FFI_TRAMPOLINE_SIZE 24 #define FFI_NATIVE_RAW_API 0 #else diff --git a/libffi/src/x86/sysv.S b/libffi/src/x86/sysv.S index 46759f4..f22c939 100644 --- a/libffi/src/x86/sysv.S +++ b/libffi/src/x86/sysv.S @@ -59,16 +59,15 @@ ffi_call_SYSV: call *28(%ebp) - /* Remove the space we pushed for the args */ - movl 16(%ebp),%ecx - addl %ecx,%esp - /* Load %ecx with the return type code */ movl 20(%ebp),%ecx + /* Protect %esi. We're going to pop it in the epilogue. */ + pushl %esi + /* If the return value pointer is NULL, assume no return value. */ cmpl $0,24(%ebp) - jne retint + jne 0f /* Even if there is no space for the return value, we are obliged to handle floating-point values. */ @@ -78,51 +77,84 @@ ffi_call_SYSV: jmp epilogue -retint: - cmpl $FFI_TYPE_INT,%ecx - jne retfloat - /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx - movl %eax,0(%ecx) - jmp epilogue +0: + call 1f + +.Lstore_table: + .long noretval-.Lstore_table /* FFI_TYPE_VOID */ + .long retint-.Lstore_table /* FFI_TYPE_INT */ + .long retfloat-.Lstore_table /* FFI_TYPE_FLOAT */ + .long retdouble-.Lstore_table /* FFI_TYPE_DOUBLE */ + .long retlongdouble-.Lstore_table /* FFI_TYPE_LONGDOUBLE */ + .long retuint8-.Lstore_table /* FFI_TYPE_UINT8 */ + .long retsint8-.Lstore_table /* FFI_TYPE_SINT8 */ + .long retuint16-.Lstore_table /* FFI_TYPE_UINT16 */ + .long retsint16-.Lstore_table /* FFI_TYPE_SINT16 */ + .long retint-.Lstore_table /* FFI_TYPE_UINT32 */ + .long retint-.Lstore_table /* FFI_TYPE_SINT32 */ + .long retint64-.Lstore_table /* FFI_TYPE_UINT64 */ + .long retint64-.Lstore_table /* FFI_TYPE_SINT64 */ + .long retstruct-.Lstore_table /* FFI_TYPE_STRUCT */ + .long retint-.Lstore_table /* FFI_TYPE_POINTER */ + +1: + pop %esi + add (%esi, %ecx, 4), %esi + jmp *%esi + + /* Sign/zero extend as appropriate. */ +retsint8: + movsbl %al, %eax + jmp retint + +retsint16: + movswl %ax, %eax + jmp retint + +retuint8: + movzbl %al, %eax + jmp retint + +retuint16: + movzwl %ax, %eax + jmp retint retfloat: - cmpl $FFI_TYPE_FLOAT,%ecx - jne retdouble /* Load %ecx with the pointer to storage for the return value */ movl 24(%ebp),%ecx fstps (%ecx) jmp epilogue retdouble: - cmpl $FFI_TYPE_DOUBLE,%ecx - jne retlongdouble /* Load %ecx with the pointer to storage for the return value */ movl 24(%ebp),%ecx fstpl (%ecx) jmp epilogue retlongdouble: - cmpl $FFI_TYPE_LONGDOUBLE,%ecx - jne retint64 /* Load %ecx with the pointer to storage for the return value */ movl 24(%ebp),%ecx fstpt (%ecx) jmp epilogue retint64: - cmpl $FFI_TYPE_SINT64,%ecx - jne retstruct /* Load %ecx with the pointer to storage for the return value */ movl 24(%ebp),%ecx movl %eax,0(%ecx) movl %edx,4(%ecx) + jmp epilogue +retint: + /* Load %ecx with the pointer to storage for the return value */ + movl 24(%ebp),%ecx + movl %eax,0(%ecx) + retstruct: /* Nothing to do! */ noretval: epilogue: + popl %esi movl %ebp,%esp popl %ebp ret @@ -162,7 +194,15 @@ ffi_closure_SYSV: movl -12(%ebp), %ecx cmpl $FFI_TYPE_INT, %eax je .Lcls_retint - cmpl $FFI_TYPE_FLOAT, %eax + + /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16, + FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32. */ + cmpl $FFI_TYPE_UINT64, %eax + jge 0f + cmpl $FFI_TYPE_UINT8, %eax + jge .Lcls_retint + +0: cmpl $FFI_TYPE_FLOAT, %eax je .Lcls_retfloat cmpl $FFI_TYPE_DOUBLE, %eax je .Lcls_retdouble @@ -226,6 +266,14 @@ ffi_closure_raw_SYSV: movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */ cmpl $FFI_TYPE_INT, %eax je .Lrcls_retint + + /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16, + FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32. */ + cmpl $FFI_TYPE_UINT64, %eax + jge 0f + cmpl $FFI_TYPE_UINT8, %eax + jge .Lrcls_retint +0: cmpl $FFI_TYPE_FLOAT, %eax je .Lrcls_retfloat cmpl $FFI_TYPE_DOUBLE, %eax diff --git a/libffi/testsuite/lib/libffi-dg.exp b/libffi/testsuite/lib/libffi-dg.exp index c3eecff..11dd39c 100644 --- a/libffi/testsuite/lib/libffi-dg.exp +++ b/libffi/testsuite/lib/libffi-dg.exp @@ -120,7 +120,7 @@ proc libffi-init { args } { if { [is_remote host] == 0 && [which $compiler] != 0 } { foreach i "[exec $compiler --print-multi-lib]" { set mldir "" - regexp -- "\[a-z0-9=/\.-\]*;" $i mldir + regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir set mldir [string trimright $mldir "\;@"] if { "$mldir" == "." } { continue diff --git a/libffi/testsuite/libffi.call/call.exp b/libffi/testsuite/libffi.call/call.exp index 3b0bd32..bd4d2e8 100644 --- a/libffi/testsuite/libffi.call/call.exp +++ b/libffi/testsuite/libffi.call/call.exp @@ -1,18 +1,18 @@ -# Copyright (C) 2003 Free Software Foundation, Inc. +# Copyright (C) 2003, 2006 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # libffi testsuite that uses the 'dg.exp' driver. @@ -23,7 +23,10 @@ libffi-init global srcdir subdir -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "" "" +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-finish diff --git a/libffi/testsuite/libffi.call/closure_fn0.c b/libffi/testsuite/libffi.call/closure_fn0.c index 13209c2..e487527 100644 --- a/libffi/testsuite/libffi.call/closure_fn0.c +++ b/libffi/testsuite/libffi.call/closure_fn0.c @@ -6,11 +6,15 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ + + + +/* { dg-do run } */ #include "ffitest.h" static void -closure_test_fn0(ffi_cif* cif,void* resp,void** args, void* userdata) +closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata) { *(ffi_arg*)resp = (int)*(unsigned long long *)args[0] + (int)(*(int *)args[1]) + @@ -59,21 +63,21 @@ int main (void) #endif cl_arg_types[0] = &ffi_type_uint64; - cl_arg_types[1] = &ffi_type_uint; + cl_arg_types[1] = &ffi_type_sint; cl_arg_types[2] = &ffi_type_uint64; - cl_arg_types[3] = &ffi_type_uint; + cl_arg_types[3] = &ffi_type_sint; cl_arg_types[4] = &ffi_type_sshort; cl_arg_types[5] = &ffi_type_uint64; - cl_arg_types[6] = &ffi_type_uint; - cl_arg_types[7] = &ffi_type_uint; + cl_arg_types[6] = &ffi_type_sint; + cl_arg_types[7] = &ffi_type_sint; cl_arg_types[8] = &ffi_type_double; - cl_arg_types[9] = &ffi_type_uint; - cl_arg_types[10] = &ffi_type_uint; + cl_arg_types[9] = &ffi_type_sint; + cl_arg_types[10] = &ffi_type_sint; cl_arg_types[11] = &ffi_type_float; - cl_arg_types[12] = &ffi_type_uint; - cl_arg_types[13] = &ffi_type_uint; - cl_arg_types[14] = &ffi_type_uint; - cl_arg_types[15] = &ffi_type_uint; + cl_arg_types[12] = &ffi_type_sint; + cl_arg_types[13] = &ffi_type_sint; + cl_arg_types[14] = &ffi_type_sint; + cl_arg_types[15] = &ffi_type_sint; cl_arg_types[16] = NULL; /* Initialize the cif */ diff --git a/libffi/testsuite/libffi.call/closure_fn1.c b/libffi/testsuite/libffi.call/closure_fn1.c index ab3b165..db26c42 100644 --- a/libffi/testsuite/libffi.call/closure_fn1.c +++ b/libffi/testsuite/libffi.call/closure_fn1.c @@ -6,11 +6,11 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" -static void closure_test_fn1(ffi_cif* cif,void* resp,void** args, +static void closure_test_fn1(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata) { *(ffi_arg*)resp = @@ -61,15 +61,15 @@ int main (void) cl_arg_types[4] = &ffi_type_sshort; cl_arg_types[5] = &ffi_type_float; cl_arg_types[6] = &ffi_type_float; - cl_arg_types[7] = &ffi_type_uint; + cl_arg_types[7] = &ffi_type_sint; cl_arg_types[8] = &ffi_type_double; - cl_arg_types[9] = &ffi_type_uint; - cl_arg_types[10] = &ffi_type_uint; + cl_arg_types[9] = &ffi_type_sint; + cl_arg_types[10] = &ffi_type_sint; cl_arg_types[11] = &ffi_type_float; - cl_arg_types[12] = &ffi_type_uint; - cl_arg_types[13] = &ffi_type_uint; - cl_arg_types[14] = &ffi_type_uint; - cl_arg_types[15] = &ffi_type_uint; + cl_arg_types[12] = &ffi_type_sint; + cl_arg_types[13] = &ffi_type_sint; + cl_arg_types[14] = &ffi_type_sint; + cl_arg_types[15] = &ffi_type_sint; cl_arg_types[16] = NULL; /* Initialize the cif */ diff --git a/libffi/testsuite/libffi.call/closure_fn2.c b/libffi/testsuite/libffi.call/closure_fn2.c index 5a61099..cbf7385 100644 --- a/libffi/testsuite/libffi.call/closure_fn2.c +++ b/libffi/testsuite/libffi.call/closure_fn2.c @@ -6,10 +6,10 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" -static void closure_test_fn2(ffi_cif* cif,void* resp,void** args, +static void closure_test_fn2(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata) { *(ffi_arg*)resp = @@ -61,15 +61,15 @@ int main (void) cl_arg_types[4] = &ffi_type_sshort; cl_arg_types[5] = &ffi_type_double; cl_arg_types[6] = &ffi_type_double; - cl_arg_types[7] = &ffi_type_uint; + cl_arg_types[7] = &ffi_type_sint; cl_arg_types[8] = &ffi_type_double; - cl_arg_types[9] = &ffi_type_uint; - cl_arg_types[10] = &ffi_type_uint; + cl_arg_types[9] = &ffi_type_sint; + cl_arg_types[10] = &ffi_type_sint; cl_arg_types[11] = &ffi_type_float; - cl_arg_types[12] = &ffi_type_uint; + cl_arg_types[12] = &ffi_type_sint; cl_arg_types[13] = &ffi_type_float; - cl_arg_types[14] = &ffi_type_uint; - cl_arg_types[15] = &ffi_type_uint; + cl_arg_types[14] = &ffi_type_sint; + cl_arg_types[15] = &ffi_type_sint; cl_arg_types[16] = NULL; /* Initialize the cif */ diff --git a/libffi/testsuite/libffi.call/closure_fn3.c b/libffi/testsuite/libffi.call/closure_fn3.c index 42bd44c..1fb32a8 100644 --- a/libffi/testsuite/libffi.call/closure_fn3.c +++ b/libffi/testsuite/libffi.call/closure_fn3.c @@ -6,10 +6,10 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" -static void closure_test_fn3(ffi_cif* cif,void* resp,void** args, +static void closure_test_fn3(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata) { *(ffi_arg*)resp = @@ -64,13 +64,13 @@ int main (void) cl_arg_types[6] = &ffi_type_float; cl_arg_types[7] = &ffi_type_float; cl_arg_types[8] = &ffi_type_double; - cl_arg_types[9] = &ffi_type_uint; + cl_arg_types[9] = &ffi_type_sint; cl_arg_types[10] = &ffi_type_float; cl_arg_types[11] = &ffi_type_float; - cl_arg_types[12] = &ffi_type_uint; + cl_arg_types[12] = &ffi_type_sint; cl_arg_types[13] = &ffi_type_float; cl_arg_types[14] = &ffi_type_float; - cl_arg_types[15] = &ffi_type_uint; + cl_arg_types[15] = &ffi_type_sint; cl_arg_types[16] = NULL; /* Initialize the cif */ diff --git a/libffi/testsuite/libffi.call/closure_fn4.c b/libffi/testsuite/libffi.call/closure_fn4.c index 2eec222..74506f3 100644 --- a/libffi/testsuite/libffi.call/closure_fn4.c +++ b/libffi/testsuite/libffi.call/closure_fn4.c @@ -6,12 +6,13 @@ PR: none. Originator: 20031026 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" static void -closure_test_fn0(ffi_cif* cif,void* resp,void** args, void* userdata) +closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata) { *(ffi_arg*)resp = (int)*(unsigned long long *)args[0] + (int)*(unsigned long long *)args[1] + @@ -75,7 +76,7 @@ int main (void) for (i = 0; i < 15; i++) { cl_arg_types[i] = &ffi_type_uint64; } - cl_arg_types[15] = &ffi_type_uint; + cl_arg_types[15] = &ffi_type_sint; cl_arg_types[16] = NULL; /* Initialize the cif */ diff --git a/libffi/testsuite/libffi.call/closure_fn5.c b/libffi/testsuite/libffi.call/closure_fn5.c index 1151393..c64ee8d 100644 --- a/libffi/testsuite/libffi.call/closure_fn5.c +++ b/libffi/testsuite/libffi.call/closure_fn5.c @@ -6,12 +6,12 @@ PR: none. Originator: 20031026 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ - +/* { dg-do run } */ #include "ffitest.h" static void -closure_test_fn5(ffi_cif* cif,void* resp,void** args, void* userdata) +closure_test_fn5(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata) { *(ffi_arg*)resp = (int)*(unsigned long long *)args[0] + (int)*(unsigned long long *)args[1] + @@ -74,11 +74,11 @@ int main (void) for (i = 0; i < 10; i++) { cl_arg_types[i] = &ffi_type_uint64; } - cl_arg_types[10] = &ffi_type_uint; + cl_arg_types[10] = &ffi_type_sint; for (i = 11; i < 15; i++) { cl_arg_types[i] = &ffi_type_uint64; } - cl_arg_types[15] = &ffi_type_uint; + cl_arg_types[15] = &ffi_type_sint; cl_arg_types[16] = NULL; /* Initialize the cif */ diff --git a/libffi/testsuite/libffi.call/closure_fn6.c b/libffi/testsuite/libffi.call/closure_fn6.c index eb64773..16c52fd 100644 --- a/libffi/testsuite/libffi.call/closure_fn6.c +++ b/libffi/testsuite/libffi.call/closure_fn6.c @@ -5,7 +5,7 @@ PR: PR23404 Originator: 20050830 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" static void @@ -67,16 +67,16 @@ int main (void) cl_arg_types[1] = &ffi_type_uint64; cl_arg_types[2] = &ffi_type_uint64; cl_arg_types[3] = &ffi_type_uint64; - cl_arg_types[4] = &ffi_type_uint; + cl_arg_types[4] = &ffi_type_sint; cl_arg_types[5] = &ffi_type_double; cl_arg_types[6] = &ffi_type_double; cl_arg_types[7] = &ffi_type_float; cl_arg_types[8] = &ffi_type_double; cl_arg_types[9] = &ffi_type_double; - cl_arg_types[10] = &ffi_type_uint; + cl_arg_types[10] = &ffi_type_sint; cl_arg_types[11] = &ffi_type_float; - cl_arg_types[12] = &ffi_type_uint; - cl_arg_types[13] = &ffi_type_uint; + cl_arg_types[12] = &ffi_type_sint; + cl_arg_types[13] = &ffi_type_sint; cl_arg_types[14] = &ffi_type_double; cl_arg_types[15] = &ffi_type_double; cl_arg_types[16] = NULL; diff --git a/libffi/testsuite/libffi.call/cls_12byte.c b/libffi/testsuite/libffi.call/cls_12byte.c index a0b4c75..92530d5 100644 --- a/libffi/testsuite/libffi.call/cls_12byte.c +++ b/libffi/testsuite/libffi.call/cls_12byte.c @@ -4,7 +4,7 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_12byte { @@ -28,7 +28,8 @@ cls_struct_12byte cls_struct_12byte_fn(struct cls_struct_12byte b1, return result; } -static void cls_struct_12byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +static void cls_struct_12byte_gn(ffi_cif* cif __UNUSED__, void* resp, + void** args , void* userdata __UNUSED__) { struct cls_struct_12byte b1, b2; @@ -65,9 +66,9 @@ int main (void) struct cls_struct_12byte j_dbl = { 1, 5, 3 }; struct cls_struct_12byte res_dbl; - cls_struct_fields[0] = &ffi_type_uint32; - cls_struct_fields[1] = &ffi_type_uint32; - cls_struct_fields[2] = &ffi_type_uint32; + cls_struct_fields[0] = &ffi_type_sint; + cls_struct_fields[1] = &ffi_type_sint; + cls_struct_fields[2] = &ffi_type_sint; cls_struct_fields[3] = NULL; dbl_arg_types[0] = &cls_struct_type; diff --git a/libffi/testsuite/libffi.call/cls_16byte.c b/libffi/testsuite/libffi.call/cls_16byte.c index b40018a..f3c314a 100644 --- a/libffi/testsuite/libffi.call/cls_16byte.c +++ b/libffi/testsuite/libffi.call/cls_16byte.c @@ -5,7 +5,7 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_16byte { @@ -29,7 +29,8 @@ cls_struct_16byte cls_struct_16byte_fn(struct cls_struct_16byte b1, return result; } -static void cls_struct_16byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +static void cls_struct_16byte_gn(ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) { struct cls_struct_16byte b1, b2; @@ -66,9 +67,9 @@ int main (void) struct cls_struct_16byte j_dbl = { 1, 9.0, 3 }; struct cls_struct_16byte res_dbl; - cls_struct_fields[0] = &ffi_type_uint32; + cls_struct_fields[0] = &ffi_type_sint; cls_struct_fields[1] = &ffi_type_double; - cls_struct_fields[2] = &ffi_type_uint32; + cls_struct_fields[2] = &ffi_type_sint; cls_struct_fields[3] = NULL; dbl_arg_types[0] = &cls_struct_type; diff --git a/libffi/testsuite/libffi.call/cls_18byte.c b/libffi/testsuite/libffi.call/cls_18byte.c index d04d8b3..9016580 100644 --- a/libffi/testsuite/libffi.call/cls_18byte.c +++ b/libffi/testsuite/libffi.call/cls_18byte.c @@ -5,7 +5,7 @@ PR: none. Originator: 20030915 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_18byte { @@ -33,7 +33,8 @@ cls_struct_18byte cls_struct_18byte_fn(struct cls_struct_18byte a1, } static void -cls_struct_18byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_18byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_18byte a1, a2; diff --git a/libffi/testsuite/libffi.call/cls_19byte.c b/libffi/testsuite/libffi.call/cls_19byte.c index 1f08da1..8af5834 100644 --- a/libffi/testsuite/libffi.call/cls_19byte.c +++ b/libffi/testsuite/libffi.call/cls_19byte.c @@ -5,7 +5,7 @@ PR: none. Originator: 20030915 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_19byte { @@ -36,7 +36,8 @@ cls_struct_19byte cls_struct_19byte_fn(struct cls_struct_19byte a1, } static void -cls_struct_19byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_19byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_19byte a1, a2; diff --git a/libffi/testsuite/libffi.call/cls_1_1byte.c b/libffi/testsuite/libffi.call/cls_1_1byte.c index 4b64d92..0fcc8c6 100644 --- a/libffi/testsuite/libffi.call/cls_1_1byte.c +++ b/libffi/testsuite/libffi.call/cls_1_1byte.c @@ -6,7 +6,9 @@ PR: none. Originator: 20030902 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ + + +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_1_1byte { @@ -26,7 +28,8 @@ cls_struct_1_1byte cls_struct_1_1byte_fn(struct cls_struct_1_1byte a1, } static void -cls_struct_1_1byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_1_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_1_1byte a1, a2; diff --git a/libffi/testsuite/libffi.call/cls_20byte.c b/libffi/testsuite/libffi.call/cls_20byte.c index 0a33b11..fa5f81a 100644 --- a/libffi/testsuite/libffi.call/cls_20byte.c +++ b/libffi/testsuite/libffi.call/cls_20byte.c @@ -5,7 +5,7 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_20byte { @@ -29,7 +29,8 @@ cls_struct_20byte cls_struct_20byte_fn(struct cls_struct_20byte a1, } static void -cls_struct_20byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_20byte a1, a2; @@ -68,7 +69,7 @@ int main (void) cls_struct_fields[0] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_double; - cls_struct_fields[2] = &ffi_type_uint32; + cls_struct_fields[2] = &ffi_type_sint; cls_struct_fields[3] = NULL; dbl_arg_types[0] = &cls_struct_type; diff --git a/libffi/testsuite/libffi.call/cls_20byte1.c b/libffi/testsuite/libffi.call/cls_20byte1.c index c10a85c..072bafc 100644 --- a/libffi/testsuite/libffi.call/cls_20byte1.c +++ b/libffi/testsuite/libffi.call/cls_20byte1.c @@ -5,7 +5,9 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ + + +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_20byte { @@ -29,7 +31,8 @@ cls_struct_20byte cls_struct_20byte_fn(struct cls_struct_20byte a1, } static void -cls_struct_20byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_20byte a1, a2; @@ -66,7 +69,7 @@ int main (void) struct cls_struct_20byte f_dbl = { 4, 5.0, 7.0 }; struct cls_struct_20byte res_dbl; - cls_struct_fields[0] = &ffi_type_uint32; + cls_struct_fields[0] = &ffi_type_sint; cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[2] = &ffi_type_double; cls_struct_fields[3] = NULL; diff --git a/libffi/testsuite/libffi.call/cls_24byte.c b/libffi/testsuite/libffi.call/cls_24byte.c index 6a0a530..22e1690 100644 --- a/libffi/testsuite/libffi.call/cls_24byte.c +++ b/libffi/testsuite/libffi.call/cls_24byte.c @@ -5,7 +5,7 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_24byte { @@ -38,7 +38,8 @@ cls_struct_24byte cls_struct_24byte_fn(struct cls_struct_24byte b0, } static void -cls_struct_24byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_24byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_24byte b0, b1, b2, b3; @@ -81,7 +82,7 @@ int main (void) cls_struct_fields[0] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_double; - cls_struct_fields[2] = &ffi_type_uint32; + cls_struct_fields[2] = &ffi_type_sint; cls_struct_fields[3] = &ffi_type_float; cls_struct_fields[4] = NULL; diff --git a/libffi/testsuite/libffi.call/cls_2byte.c b/libffi/testsuite/libffi.call/cls_2byte.c index 267dbc1..5b91a09 100644 --- a/libffi/testsuite/libffi.call/cls_2byte.c +++ b/libffi/testsuite/libffi.call/cls_2byte.c @@ -6,7 +6,7 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_2byte { @@ -28,7 +28,8 @@ cls_struct_2byte cls_struct_2byte_fn(struct cls_struct_2byte a1, } static void -cls_struct_2byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_2byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_2byte a1, a2; diff --git a/libffi/testsuite/libffi.call/cls_3_1byte.c b/libffi/testsuite/libffi.call/cls_3_1byte.c index b8a475b..93fe911 100644 --- a/libffi/testsuite/libffi.call/cls_3_1byte.c +++ b/libffi/testsuite/libffi.call/cls_3_1byte.c @@ -6,7 +6,7 @@ PR: none. Originator: 20030902 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_3_1byte { @@ -32,7 +32,8 @@ cls_struct_3_1byte cls_struct_3_1byte_fn(struct cls_struct_3_1byte a1, } static void -cls_struct_3_1byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_3_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_3_1byte a1, a2; diff --git a/libffi/testsuite/libffi.call/cls_3byte1.c b/libffi/testsuite/libffi.call/cls_3byte1.c index e5a2820..b772691 100644 --- a/libffi/testsuite/libffi.call/cls_3byte1.c +++ b/libffi/testsuite/libffi.call/cls_3byte1.c @@ -6,7 +6,7 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_3byte { @@ -28,7 +28,8 @@ cls_struct_3byte cls_struct_3byte_fn(struct cls_struct_3byte a1, } static void -cls_struct_3byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_3byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_3byte a1, a2; diff --git a/libffi/testsuite/libffi.call/cls_3byte2.c b/libffi/testsuite/libffi.call/cls_3byte2.c index 356def9..51128cc 100644 --- a/libffi/testsuite/libffi.call/cls_3byte2.c +++ b/libffi/testsuite/libffi.call/cls_3byte2.c @@ -6,7 +6,7 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_3byte_1 { @@ -28,7 +28,8 @@ cls_struct_3byte_1 cls_struct_3byte_fn1(struct cls_struct_3byte_1 a1, } static void -cls_struct_3byte_gn1(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_3byte_gn1(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_3byte_1 a1, a2; diff --git a/libffi/testsuite/libffi.call/cls_4_1byte.c b/libffi/testsuite/libffi.call/cls_4_1byte.c index c4970ce..a378d19 100644 --- a/libffi/testsuite/libffi.call/cls_4_1byte.c +++ b/libffi/testsuite/libffi.call/cls_4_1byte.c @@ -6,7 +6,7 @@ PR: none. Originator: 20030902 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_4_1byte { @@ -34,7 +34,8 @@ cls_struct_4_1byte cls_struct_4_1byte_fn(struct cls_struct_4_1byte a1, } static void -cls_struct_4_1byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_4_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_4_1byte a1, a2; diff --git a/libffi/testsuite/libffi.call/cls_4byte.c b/libffi/testsuite/libffi.call/cls_4byte.c index d4f2198..b2c951d 100644 --- a/libffi/testsuite/libffi.call/cls_4byte.c +++ b/libffi/testsuite/libffi.call/cls_4byte.c @@ -5,7 +5,7 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" @@ -28,7 +28,8 @@ cls_struct_4byte cls_struct_4byte_fn(struct cls_struct_4byte a1, } static void -cls_struct_4byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_4byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_4byte a1, a2; diff --git a/libffi/testsuite/libffi.call/cls_5_1_byte.c b/libffi/testsuite/libffi.call/cls_5_1_byte.c index e047168..40d2e64 100644 --- a/libffi/testsuite/libffi.call/cls_5_1_byte.c +++ b/libffi/testsuite/libffi.call/cls_5_1_byte.c @@ -5,7 +5,7 @@ PR: none. Originator: 20050708 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_5byte { @@ -36,7 +36,8 @@ cls_struct_5byte cls_struct_5byte_fn(struct cls_struct_5byte a1, } static void -cls_struct_5byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_5byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_5byte a1, a2; diff --git a/libffi/testsuite/libffi.call/cls_5byte.c b/libffi/testsuite/libffi.call/cls_5byte.c index 14e3c83..0307e51 100644 --- a/libffi/testsuite/libffi.call/cls_5byte.c +++ b/libffi/testsuite/libffi.call/cls_5byte.c @@ -5,7 +5,7 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_5byte { @@ -31,7 +31,8 @@ cls_struct_5byte cls_struct_5byte_fn(struct cls_struct_5byte a1, } static void -cls_struct_5byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_5byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_5byte a1, a2; diff --git a/libffi/testsuite/libffi.call/cls_64byte.c b/libffi/testsuite/libffi.call/cls_64byte.c index fed6412..1329c6f 100644 --- a/libffi/testsuite/libffi.call/cls_64byte.c +++ b/libffi/testsuite/libffi.call/cls_64byte.c @@ -6,7 +6,7 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_64byte { @@ -43,7 +43,8 @@ cls_struct_64byte cls_struct_64byte_fn(struct cls_struct_64byte b0, } static void -cls_struct_64byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_64byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_64byte b0, b1, b2, b3; diff --git a/libffi/testsuite/libffi.call/cls_6_1_byte.c b/libffi/testsuite/libffi.call/cls_6_1_byte.c index 22c575d..7ddb586 100644 --- a/libffi/testsuite/libffi.call/cls_6_1_byte.c +++ b/libffi/testsuite/libffi.call/cls_6_1_byte.c @@ -5,7 +5,7 @@ PR: none. Originator: 20050708 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_6byte { @@ -38,7 +38,8 @@ cls_struct_6byte cls_struct_6byte_fn(struct cls_struct_6byte a1, } static void -cls_struct_6byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_6byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_6byte a1, a2; diff --git a/libffi/testsuite/libffi.call/cls_6byte.c b/libffi/testsuite/libffi.call/cls_6byte.c index 149eddd..24fd63b 100644 --- a/libffi/testsuite/libffi.call/cls_6byte.c +++ b/libffi/testsuite/libffi.call/cls_6byte.c @@ -5,7 +5,8 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ + +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_6byte { @@ -33,7 +34,8 @@ cls_struct_6byte cls_struct_6byte_fn(struct cls_struct_6byte a1, } static void -cls_struct_6byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_6byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_6byte a1, a2; diff --git a/libffi/testsuite/libffi.call/cls_7_1_byte.c b/libffi/testsuite/libffi.call/cls_7_1_byte.c index 43df487..0cf1371 100644 --- a/libffi/testsuite/libffi.call/cls_7_1_byte.c +++ b/libffi/testsuite/libffi.call/cls_7_1_byte.c @@ -5,7 +5,7 @@ PR: none. Originator: 20050708 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_7byte { @@ -40,7 +40,8 @@ cls_struct_7byte cls_struct_7byte_fn(struct cls_struct_7byte a1, } static void -cls_struct_7byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_7byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_7byte a1, a2; diff --git a/libffi/testsuite/libffi.call/cls_7byte.c b/libffi/testsuite/libffi.call/cls_7byte.c index fff800e..7785862 100644 --- a/libffi/testsuite/libffi.call/cls_7byte.c +++ b/libffi/testsuite/libffi.call/cls_7byte.c @@ -5,7 +5,7 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_7byte { @@ -33,7 +33,8 @@ cls_struct_7byte cls_struct_7byte_fn(struct cls_struct_7byte a1, } static void -cls_struct_7byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_7byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_7byte a1, a2; diff --git a/libffi/testsuite/libffi.call/cls_8byte.c b/libffi/testsuite/libffi.call/cls_8byte.c index 8992687..75326b8 100644 --- a/libffi/testsuite/libffi.call/cls_8byte.c +++ b/libffi/testsuite/libffi.call/cls_8byte.c @@ -5,7 +5,7 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_8byte { @@ -27,7 +27,8 @@ cls_struct_8byte cls_struct_8byte_fn(struct cls_struct_8byte a1, } static void -cls_struct_8byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_8byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_8byte a1, a2; @@ -65,7 +66,7 @@ int main (void) struct cls_struct_8byte f_dbl = { 4, 5.0 }; struct cls_struct_8byte res_dbl; - cls_struct_fields[0] = &ffi_type_uint32; + cls_struct_fields[0] = &ffi_type_sint; cls_struct_fields[1] = &ffi_type_float; cls_struct_fields[2] = NULL; diff --git a/libffi/testsuite/libffi.call/cls_9byte1.c b/libffi/testsuite/libffi.call/cls_9byte1.c index daff5d0..0b3de9d 100644 --- a/libffi/testsuite/libffi.call/cls_9byte1.c +++ b/libffi/testsuite/libffi.call/cls_9byte1.c @@ -7,7 +7,7 @@ PR: none. Originator: 20030914 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_9byte { @@ -29,8 +29,8 @@ cls_struct_9byte cls_struct_9byte_fn(struct cls_struct_9byte b1, return result; } -static void cls_struct_9byte_gn(ffi_cif* cif, void* resp, void** args, - void* userdata) +static void cls_struct_9byte_gn(ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) { struct cls_struct_9byte b1, b2; @@ -67,7 +67,7 @@ int main (void) struct cls_struct_9byte j_dbl = { 1, 9.0}; struct cls_struct_9byte res_dbl; - cls_struct_fields[0] = &ffi_type_uint32; + cls_struct_fields[0] = &ffi_type_sint; cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[2] = NULL; diff --git a/libffi/testsuite/libffi.call/cls_9byte2.c b/libffi/testsuite/libffi.call/cls_9byte2.c index de4c674..8cafc8a 100644 --- a/libffi/testsuite/libffi.call/cls_9byte2.c +++ b/libffi/testsuite/libffi.call/cls_9byte2.c @@ -7,7 +7,7 @@ PR: none. Originator: 20030914 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_9byte { @@ -29,8 +29,8 @@ cls_struct_9byte cls_struct_9byte_fn(struct cls_struct_9byte b1, return result; } -static void cls_struct_9byte_gn(ffi_cif* cif, void* resp, void** args, - void* userdata) +static void cls_struct_9byte_gn(ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) { struct cls_struct_9byte b1, b2; @@ -68,7 +68,7 @@ int main (void) struct cls_struct_9byte res_dbl; cls_struct_fields[0] = &ffi_type_double; - cls_struct_fields[1] = &ffi_type_uint32; + cls_struct_fields[1] = &ffi_type_sint; cls_struct_fields[2] = NULL; dbl_arg_types[0] = &cls_struct_type; diff --git a/libffi/testsuite/libffi.call/cls_align_double.c b/libffi/testsuite/libffi.call/cls_align_double.c index 35a0a76..5ba2301 100644 --- a/libffi/testsuite/libffi.call/cls_align_double.c +++ b/libffi/testsuite/libffi.call/cls_align_double.c @@ -4,7 +4,9 @@ PR: none. Originator: 20031203 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ + + +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_align { @@ -28,7 +30,8 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1, } static void -cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_align a1, a2; diff --git a/libffi/testsuite/libffi.call/cls_align_float.c b/libffi/testsuite/libffi.call/cls_align_float.c index d97863e..996e1ab 100644 --- a/libffi/testsuite/libffi.call/cls_align_float.c +++ b/libffi/testsuite/libffi.call/cls_align_float.c @@ -4,7 +4,7 @@ PR: none. Originator: 20031203 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_align { @@ -28,7 +28,8 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1, } static void -cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_align a1, a2; diff --git a/libffi/testsuite/libffi.call/cls_align_longdouble.c b/libffi/testsuite/libffi.call/cls_align_longdouble.c index bcfddf5..cb60395 100644 --- a/libffi/testsuite/libffi.call/cls_align_longdouble.c +++ b/libffi/testsuite/libffi.call/cls_align_longdouble.c @@ -4,7 +4,7 @@ PR: none. Originator: 20031203 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" @@ -29,7 +29,8 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1, } static void -cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_align a1, a2; diff --git a/libffi/testsuite/libffi.call/cls_align_pointer.c b/libffi/testsuite/libffi.call/cls_align_pointer.c index 0041fcc..441edcb 100644 --- a/libffi/testsuite/libffi.call/cls_align_pointer.c +++ b/libffi/testsuite/libffi.call/cls_align_pointer.c @@ -4,7 +4,7 @@ PR: none. Originator: 20031203 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_align { @@ -19,16 +19,19 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1, struct cls_struct_align result; result.a = a1.a + a2.a; - result.b = (void *)((size_t)a1.b + (size_t)a2.b); + result.b = (void *)((unsigned long)a1.b + (unsigned long)a2.b); result.c = a1.c + a2.c; - printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, (size_t)a1.b, a1.c, a2.a, (size_t)a2.b, a2.c, result.a, (size_t)result.b, result.c); + printf("%d %lu %d %d %lu %d: %d %lu %d\n", a1.a, (unsigned long)a1.b, a1.c, + a2.a, (unsigned long)a2.b, a2.c, result.a, (unsigned long)result.b, + result.c); - return result; + return result; } static void -cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_align a1, a2; @@ -84,14 +87,14 @@ int main (void) ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl); /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */ - printf("res: %d %d %d\n", res_dbl.a, (size_t)res_dbl.b, res_dbl.c); + printf("res: %d %lu %d\n", res_dbl.a, (unsigned long)res_dbl.b, res_dbl.c); /* { dg-output "\nres: 13 14271 140" } */ CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK); res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl); /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */ - printf("res: %d %d %d\n", res_dbl.a, (size_t)res_dbl.b, res_dbl.c); + printf("res: %d %lu %d\n", res_dbl.a, (unsigned long)res_dbl.b, res_dbl.c); /* { dg-output "\nres: 13 14271 140" } */ exit(0); diff --git a/libffi/testsuite/libffi.call/cls_align_sint16.c b/libffi/testsuite/libffi.call/cls_align_sint16.c index 144c891..fe4fe09 100644 --- a/libffi/testsuite/libffi.call/cls_align_sint16.c +++ b/libffi/testsuite/libffi.call/cls_align_sint16.c @@ -4,7 +4,7 @@ PR: none. Originator: 20031203 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_align { @@ -28,7 +28,8 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1, } static void -cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_align a1, a2; @@ -67,7 +68,7 @@ int main (void) struct cls_struct_align res_dbl; cls_struct_fields[0] = &ffi_type_uchar; - cls_struct_fields[1] = &ffi_type_sint16; + cls_struct_fields[1] = &ffi_type_sshort; cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[3] = NULL; diff --git a/libffi/testsuite/libffi.call/cls_align_sint32.c b/libffi/testsuite/libffi.call/cls_align_sint32.c index c16654e..c059da8 100644 --- a/libffi/testsuite/libffi.call/cls_align_sint32.c +++ b/libffi/testsuite/libffi.call/cls_align_sint32.c @@ -4,7 +4,7 @@ PR: none. Originator: 20031203 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_align { @@ -28,7 +28,8 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1, } static void -cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_align a1, a2; @@ -67,7 +68,7 @@ int main (void) struct cls_struct_align res_dbl; cls_struct_fields[0] = &ffi_type_uchar; - cls_struct_fields[1] = &ffi_type_sint32; + cls_struct_fields[1] = &ffi_type_sint; cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[3] = NULL; diff --git a/libffi/testsuite/libffi.call/cls_align_sint64.c b/libffi/testsuite/libffi.call/cls_align_sint64.c index 40ef6c4..f5e9746 100644 --- a/libffi/testsuite/libffi.call/cls_align_sint64.c +++ b/libffi/testsuite/libffi.call/cls_align_sint64.c @@ -4,7 +4,7 @@ PR: none. Originator: 20031203 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_align { @@ -28,7 +28,8 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1, } static void -cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_align a1, a2; diff --git a/libffi/testsuite/libffi.call/cls_align_uint16.c b/libffi/testsuite/libffi.call/cls_align_uint16.c index 6df9625..c861bee 100644 --- a/libffi/testsuite/libffi.call/cls_align_uint16.c +++ b/libffi/testsuite/libffi.call/cls_align_uint16.c @@ -4,7 +4,7 @@ PR: none. Originator: 20031203 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_align { @@ -28,7 +28,8 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1, } static void -cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_align a1, a2; @@ -67,7 +68,7 @@ int main (void) struct cls_struct_align res_dbl; cls_struct_fields[0] = &ffi_type_uchar; - cls_struct_fields[1] = &ffi_type_uint16; + cls_struct_fields[1] = &ffi_type_ushort; cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[3] = NULL; diff --git a/libffi/testsuite/libffi.call/cls_align_uint32.c b/libffi/testsuite/libffi.call/cls_align_uint32.c index 15b7558..d680d8a 100644 --- a/libffi/testsuite/libffi.call/cls_align_uint32.c +++ b/libffi/testsuite/libffi.call/cls_align_uint32.c @@ -4,7 +4,7 @@ PR: none. Originator: 20031203 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_align { @@ -28,7 +28,8 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1, } static void -cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_align a1, a2; @@ -67,7 +68,7 @@ int main (void) struct cls_struct_align res_dbl; cls_struct_fields[0] = &ffi_type_uchar; - cls_struct_fields[1] = &ffi_type_uint32; + cls_struct_fields[1] = &ffi_type_uint; cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[3] = NULL; diff --git a/libffi/testsuite/libffi.call/cls_align_uint64.c b/libffi/testsuite/libffi.call/cls_align_uint64.c index 8b7ac6b..0737ba2 100644 --- a/libffi/testsuite/libffi.call/cls_align_uint64.c +++ b/libffi/testsuite/libffi.call/cls_align_uint64.c @@ -4,7 +4,8 @@ PR: none. Originator: 20031203 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ + +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_align { @@ -28,7 +29,8 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1, } static void -cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_align a1, a2; diff --git a/libffi/testsuite/libffi.call/cls_double.c b/libffi/testsuite/libffi.call/cls_double.c index be320d2..ee77add 100644 --- a/libffi/testsuite/libffi.call/cls_double.c +++ b/libffi/testsuite/libffi.call/cls_double.c @@ -4,11 +4,11 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" -static void cls_ret_double_fn(ffi_cif* cif,void* resp,void** args, - void* userdata) +static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { *(double *)resp = *(double *)args[0]; diff --git a/libffi/testsuite/libffi.call/cls_float.c b/libffi/testsuite/libffi.call/cls_float.c index 41ce4ba..8bed628 100644 --- a/libffi/testsuite/libffi.call/cls_float.c +++ b/libffi/testsuite/libffi.call/cls_float.c @@ -4,11 +4,11 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" -static void cls_ret_float_fn(ffi_cif* cif,void* resp,void** args, - void* userdata) +static void cls_ret_float_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { *(float *)resp = *(float *)args[0]; diff --git a/libffi/testsuite/libffi.call/cls_multi_schar.c b/libffi/testsuite/libffi.call/cls_multi_schar.c index 31a66fb..713c318 100644 --- a/libffi/testsuite/libffi.call/cls_multi_schar.c +++ b/libffi/testsuite/libffi.call/cls_multi_schar.c @@ -4,7 +4,7 @@ PR: PR13221. Originator: 20031129 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" signed char test_func_fn(signed char a1, signed char a2) @@ -19,7 +19,8 @@ signed char test_func_fn(signed char a1, signed char a2) } -static void test_func_gn(ffi_cif *cif, void *rval, void **avals, void *data) +static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals, + void *data __UNUSED__) { signed char a1, a2; @@ -67,7 +68,7 @@ int main (void) ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl); /* { dg-output "2 125: 127" } */ - printf("res: %d\n", res_call); + printf("res: %d\n", (signed char)res_call); /* { dg-output "\nres: 127" } */ CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK); diff --git a/libffi/testsuite/libffi.call/cls_multi_sshort.c b/libffi/testsuite/libffi.call/cls_multi_sshort.c index 8b4b554..852fdf7 100644 --- a/libffi/testsuite/libffi.call/cls_multi_sshort.c +++ b/libffi/testsuite/libffi.call/cls_multi_sshort.c @@ -4,7 +4,7 @@ PR: PR13221. Originator: 20031129 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" signed short test_func_fn(signed short a1, signed short a2) @@ -19,7 +19,8 @@ signed short test_func_fn(signed short a1, signed short a2) } -static void test_func_gn(ffi_cif *cif, void *rval, void **avals, void *data) +static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals, + void *data __UNUSED__) { signed short a1, a2; @@ -67,7 +68,7 @@ int main (void) ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl); /* { dg-output "2 32765: 32767" } */ - printf("res: %d\n", res_call); + printf("res: %d\n", (unsigned short)res_call); /* { dg-output "\nres: 32767" } */ CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK); diff --git a/libffi/testsuite/libffi.call/cls_multi_sshortchar.c b/libffi/testsuite/libffi.call/cls_multi_sshortchar.c index 223b10f..e4e92ef 100644 --- a/libffi/testsuite/libffi.call/cls_multi_sshortchar.c +++ b/libffi/testsuite/libffi.call/cls_multi_sshortchar.c @@ -4,7 +4,7 @@ PR: PR13221. Originator: 20031129 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" signed short test_func_fn(signed char a1, signed short a2, @@ -20,7 +20,8 @@ signed short test_func_fn(signed char a1, signed short a2, } -static void test_func_gn(ffi_cif *cif, void *rval, void **avals, void *data) +static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals, + void *data __UNUSED__) { signed char a1, a3; signed short a2, a4; @@ -79,7 +80,7 @@ int main (void) ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl); /* { dg-output "1 32765 127 -128: 32765" } */ - printf("res: %d\n", res_call); + printf("res: %d\n", (signed short)res_call); /* { dg-output "\nres: 32765" } */ CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK); diff --git a/libffi/testsuite/libffi.call/cls_multi_uchar.c b/libffi/testsuite/libffi.call/cls_multi_uchar.c index 8cf574b..2c84aef 100644 --- a/libffi/testsuite/libffi.call/cls_multi_uchar.c +++ b/libffi/testsuite/libffi.call/cls_multi_uchar.c @@ -4,7 +4,7 @@ PR: PR13221. Originator: 20031129 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" unsigned char test_func_fn(unsigned char a1, unsigned char a2, @@ -20,7 +20,8 @@ unsigned char test_func_fn(unsigned char a1, unsigned char a2, } -static void test_func_gn(ffi_cif *cif, void *rval, void **avals, void *data) +static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals, + void *data __UNUSED__) { unsigned char a1, a2, a3, a4; @@ -35,7 +36,9 @@ static void test_func_gn(ffi_cif *cif, void *rval, void **avals, void *data) typedef unsigned char (*test_type)(unsigned char, unsigned char, unsigned char, unsigned char); -void test_func(ffi_cif *cif, void *rval, void **avals, void *data) + +void test_func(ffi_cif *cif __UNUSED__, void *rval __UNUSED__, void **avals, + void *data __UNUSED__) { printf("%d %d %d %d\n", *(unsigned char *)avals[0], *(unsigned char *)avals[1], *(unsigned char *)avals[2], @@ -82,7 +85,7 @@ int main (void) ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl); /* { dg-output "1 2 127 125: 255" } */ - printf("res: %d\n", res_call); + printf("res: %d\n", (unsigned char)res_call); /* { dg-output "\nres: 255" } */ CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK); diff --git a/libffi/testsuite/libffi.call/cls_multi_ushort.c b/libffi/testsuite/libffi.call/cls_multi_ushort.c index 6549884..215fef8 100644 --- a/libffi/testsuite/libffi.call/cls_multi_ushort.c +++ b/libffi/testsuite/libffi.call/cls_multi_ushort.c @@ -4,7 +4,7 @@ PR: PR13221. Originator: 20031129 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" unsigned short test_func_fn(unsigned short a1, unsigned short a2) @@ -19,7 +19,8 @@ unsigned short test_func_fn(unsigned short a1, unsigned short a2) } -static void test_func_gn(ffi_cif *cif, void *rval, void **avals, void *data) +static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals, + void *data __UNUSED__) { unsigned short a1, a2; @@ -67,7 +68,7 @@ int main (void) ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl); /* { dg-output "2 32765: 32767" } */ - printf("res: %d\n", res_call); + printf("res: %d\n", (unsigned short)res_call); /* { dg-output "\nres: 32767" } */ CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK); diff --git a/libffi/testsuite/libffi.call/cls_multi_ushortchar.c b/libffi/testsuite/libffi.call/cls_multi_ushortchar.c index 3379eed..1cde84a 100644 --- a/libffi/testsuite/libffi.call/cls_multi_ushortchar.c +++ b/libffi/testsuite/libffi.call/cls_multi_ushortchar.c @@ -4,7 +4,7 @@ PR: PR13221. Originator: 20031129 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" unsigned short test_func_fn(unsigned char a1, unsigned short a2, @@ -20,7 +20,8 @@ unsigned short test_func_fn(unsigned char a1, unsigned short a2, } -static void test_func_gn(ffi_cif *cif, void *rval, void **avals, void *data) +static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals, + void *data __UNUSED__) { unsigned char a1, a3; unsigned short a2, a4; @@ -79,7 +80,7 @@ int main (void) ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl); /* { dg-output "1 2 127 128: 258" } */ - printf("res: %d\n", res_call); + printf("res: %d\n", (unsigned short)res_call); /* { dg-output "\nres: 258" } */ CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK); diff --git a/libffi/testsuite/libffi.call/cls_schar.c b/libffi/testsuite/libffi.call/cls_schar.c index 30292ea..bb1f2c6 100644 --- a/libffi/testsuite/libffi.call/cls_schar.c +++ b/libffi/testsuite/libffi.call/cls_schar.c @@ -4,15 +4,17 @@ PR: none. Originator: 20031108 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ + + +/* { dg-do run } */ #include "ffitest.h" -static void cls_ret_schar_fn(ffi_cif* cif,void* resp,void** args, - void* userdata) +static void cls_ret_schar_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { *(ffi_arg*)resp = *(signed char *)args[0]; printf("%d: %d\n",*(signed char *)args[0], - *(ffi_arg*)resp); + (int)*(ffi_arg *)(resp)); } typedef signed char (*cls_ret_schar)(signed char); diff --git a/libffi/testsuite/libffi.call/cls_sint.c b/libffi/testsuite/libffi.call/cls_sint.c index 9998137..cf21bf8 100644 --- a/libffi/testsuite/libffi.call/cls_sint.c +++ b/libffi/testsuite/libffi.call/cls_sint.c @@ -4,15 +4,15 @@ PR: none. Originator: 20031108 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" -static void cls_ret_sint_fn(ffi_cif* cif,void* resp,void** args, - void* userdata) +static void cls_ret_sint_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { *(ffi_arg*)resp = *(signed int *)args[0]; printf("%d: %d\n",*(signed int *)args[0], - *(ffi_arg*)resp); + (int)*(ffi_arg *)(resp)); } typedef signed int (*cls_ret_sint)(signed int); @@ -32,12 +32,12 @@ int main (void) pcl = &cl; #endif - cl_arg_types[0] = &ffi_type_sint32; + cl_arg_types[0] = &ffi_type_sint; cl_arg_types[1] = NULL; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_sint32, cl_arg_types) == FFI_OK); + &ffi_type_sint, cl_arg_types) == FFI_OK); CHECK(ffi_prep_closure(pcl, &cif, cls_ret_sint_fn, NULL) == FFI_OK); diff --git a/libffi/testsuite/libffi.call/cls_sshort.c b/libffi/testsuite/libffi.call/cls_sshort.c index 319c67b..8d63413 100644 --- a/libffi/testsuite/libffi.call/cls_sshort.c +++ b/libffi/testsuite/libffi.call/cls_sshort.c @@ -4,15 +4,15 @@ PR: none. Originator: 20031108 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" -static void cls_ret_sshort_fn(ffi_cif* cif,void* resp,void** args, - void* userdata) +static void cls_ret_sshort_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { *(ffi_arg*)resp = *(signed short *)args[0]; printf("%d: %d\n",*(signed short *)args[0], - *(ffi_arg*)resp); + (int)*(ffi_arg *)(resp)); } typedef signed short (*cls_ret_sshort)(signed short); @@ -32,12 +32,12 @@ int main (void) pcl = &cl; #endif - cl_arg_types[0] = &ffi_type_sint16; + cl_arg_types[0] = &ffi_type_sshort; cl_arg_types[1] = NULL; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_sint16, cl_arg_types) == FFI_OK); + &ffi_type_sshort, cl_arg_types) == FFI_OK); CHECK(ffi_prep_closure(pcl, &cif, cls_ret_sshort_fn, NULL) == FFI_OK); diff --git a/libffi/testsuite/libffi.call/cls_uchar.c b/libffi/testsuite/libffi.call/cls_uchar.c index 1ea4665..ea78ce5 100644 --- a/libffi/testsuite/libffi.call/cls_uchar.c +++ b/libffi/testsuite/libffi.call/cls_uchar.c @@ -4,15 +4,15 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" -static void cls_ret_uchar_fn(ffi_cif* cif,void* resp,void** args, - void* userdata) +static void cls_ret_uchar_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { *(ffi_arg*)resp = *(unsigned char *)args[0]; printf("%d: %d\n",*(unsigned char *)args[0], - *(ffi_arg*)resp); + (int)*(ffi_arg *)(resp)); } typedef unsigned char (*cls_ret_uchar)(unsigned char); diff --git a/libffi/testsuite/libffi.call/cls_uint.c b/libffi/testsuite/libffi.call/cls_uint.c index 5344175..e31e41a 100644 --- a/libffi/testsuite/libffi.call/cls_uint.c +++ b/libffi/testsuite/libffi.call/cls_uint.c @@ -4,17 +4,17 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" -static void cls_ret_uint_fn(ffi_cif* cif,void* resp,void** args, - void* userdata) - { - *(ffi_arg *)resp = *(unsigned int *)args[0]; +static void cls_ret_uint_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + *(ffi_arg *)resp = *(unsigned int *)args[0]; - printf("%d: %d\n",*(unsigned int *)args[0], - *(ffi_arg *)resp); - } + printf("%d: %d\n",*(unsigned int *)args[0], + (int)*(ffi_arg *)(resp)); +} typedef unsigned int (*cls_ret_uint)(unsigned int); int main (void) @@ -33,12 +33,12 @@ int main (void) pcl = &cl; #endif - cl_arg_types[0] = &ffi_type_uint32; + cl_arg_types[0] = &ffi_type_uint; cl_arg_types[1] = NULL; /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_uint32, cl_arg_types) == FFI_OK); + &ffi_type_uint, cl_arg_types) == FFI_OK); CHECK(ffi_prep_closure(pcl, &cif, cls_ret_uint_fn, NULL) == FFI_OK); diff --git a/libffi/testsuite/libffi.call/cls_ulonglong.c b/libffi/testsuite/libffi.call/cls_ulonglong.c index bf866b8..1cc0a38 100644 --- a/libffi/testsuite/libffi.call/cls_ulonglong.c +++ b/libffi/testsuite/libffi.call/cls_ulonglong.c @@ -4,17 +4,17 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" -static void cls_ret_ulonglong_fn(ffi_cif* cif,void* resp,void** args, - void* userdata) - { - *(unsigned long long *)resp= *(unsigned long long *)args[0]; +static void cls_ret_ulonglong_fn(ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) +{ + *(unsigned long long *)resp= *(unsigned long long *)args[0]; - printf("%llu: %llu\n",*(unsigned long long *)args[0], - *(unsigned long long *)resp); - } + printf("%llu: %llu\n",*(unsigned long long *)args[0], + *(unsigned long long *)(resp)); +} typedef unsigned long long (*cls_ret_ulonglong)(unsigned long long); int main (void) diff --git a/libffi/testsuite/libffi.call/cls_ushort.c b/libffi/testsuite/libffi.call/cls_ushort.c index dfc0fac..81f9848 100644 --- a/libffi/testsuite/libffi.call/cls_ushort.c +++ b/libffi/testsuite/libffi.call/cls_ushort.c @@ -4,17 +4,17 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" -static void cls_ret_ushort_fn(ffi_cif* cif,void* resp,void** args, - void* userdata) - { - *(ffi_arg*)resp = *(unsigned short *)args[0]; +static void cls_ret_ushort_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) +{ + *(ffi_arg*)resp = *(unsigned short *)args[0]; - printf("%d: %d\n",*(unsigned short *)args[0], - *(ffi_arg*)resp); - } + printf("%d: %d\n",*(unsigned short *)args[0], + (int)*(ffi_arg *)(resp)); +} typedef unsigned short (*cls_ret_ushort)(unsigned short); int main (void) diff --git a/libffi/testsuite/libffi.call/ffitest.h b/libffi/testsuite/libffi.call/ffitest.h index b41e14b..e73f758 100644 --- a/libffi/testsuite/libffi.call/ffitest.h +++ b/libffi/testsuite/libffi.call/ffitest.h @@ -9,6 +9,13 @@ #define CHECK(x) !(x) ? abort() : 0 +/* Define __UNUSED__ that also other compilers than gcc can run the tests. */ +#undef __UNUSED__ +#if defined(__GNUC__) +#define __UNUSED__ __attribute__((__unused__)) +#else +#define __UNUSED__ +#endif /* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a file open. */ diff --git a/libffi/testsuite/libffi.call/float.c b/libffi/testsuite/libffi.call/float.c index 51cb2fa..fbc272d 100644 --- a/libffi/testsuite/libffi.call/float.c +++ b/libffi/testsuite/libffi.call/float.c @@ -8,7 +8,7 @@ #include "ffitest.h" -static int floating(int a, float b, double c, long double d, int e) +static int floating(int a, float b, double c, long double d) { int i; @@ -28,7 +28,6 @@ int main (void) signed int si1; double d; long double ld; - signed int si2; args[0] = &ffi_type_sint; values[0] = &si1; @@ -38,26 +37,23 @@ int main (void) values[2] = &d; args[3] = &ffi_type_longdouble; values[3] = &ld; - args[4] = &ffi_type_sint; - values[4] = &si2; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 5, + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &ffi_type_sint, args) == FFI_OK); si1 = 6; f = 3.14159; d = (double)1.0/(double)3.0; ld = 2.71828182846L; - si2 = 10; - floating (si1, f, d, ld, si2); + floating (si1, f, d, ld); ffi_call(&cif, FFI_FN(floating), &rint, values); - printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld, si2)); + printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld)); - CHECK(rint == floating(si1, f, d, ld, si2)); + CHECK((int)rint == floating(si1, f, d, ld)); exit (0); } diff --git a/libffi/testsuite/libffi.call/float1.c b/libffi/testsuite/libffi.call/float1.c index fb81d7d..991d059 100644 --- a/libffi/testsuite/libffi.call/float1.c +++ b/libffi/testsuite/libffi.call/float1.c @@ -28,25 +28,25 @@ int main (void) void *values[MAX_ARGS]; float f; value_type result[2]; - int i; + unsigned int i; args[0] = &ffi_type_float; values[0] = &f; - + /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_double, args) == FFI_OK); - + f = 3.14159; - + /* Put a canary in the return array. This is a regression test for a buffer overrun. */ memset(result[1].c, CANARY, sizeof (double)); ffi_call(&cif, FFI_FN(dblit), &result[0].d, values); - + /* These are not always the same!! Check for a reasonable delta */ - + CHECK(result[0].d - dblit(f) < DBL_EPSILON); /* Check the canary. */ diff --git a/libffi/testsuite/libffi.call/float2.c b/libffi/testsuite/libffi.call/float2.c index 2039724..fa9dd31 100644 --- a/libffi/testsuite/libffi.call/float2.c +++ b/libffi/testsuite/libffi.call/float2.c @@ -48,9 +48,7 @@ int main (void) #endif /* These are not always the same!! Check for a reasonable delta */ - /*@-realcompare@*/ if (ld - ldblit(f) < LDBL_EPSILON) - /*@=realcompare@*/ puts("long double return value tests ok!"); else CHECK(0); diff --git a/libffi/testsuite/libffi.call/float4.c b/libffi/testsuite/libffi.call/float4.c index febad5e..0dd6d85 100644 --- a/libffi/testsuite/libffi.call/float4.c +++ b/libffi/testsuite/libffi.call/float4.c @@ -5,6 +5,8 @@ Originator: From the original ffitest.c */ /* { dg-do run } */ +/* { dg-options "-mieee" { target alpha*-*-* } } */ + #include "ffitest.h" #include "float.h" diff --git a/libffi/testsuite/libffi.call/negint.c b/libffi/testsuite/libffi.call/negint.c index 1c8ed61..3168113 100644 --- a/libffi/testsuite/libffi.call/negint.c +++ b/libffi/testsuite/libffi.call/negint.c @@ -11,7 +11,6 @@ static int checking(int a, short b, signed char c) { - int i; return (a < 0 && b < 0 && c < 0); } diff --git a/libffi/testsuite/libffi.call/nested_struct.c b/libffi/testsuite/libffi.call/nested_struct.c index 0b9da70..adce7ba 100644 --- a/libffi/testsuite/libffi.call/nested_struct.c +++ b/libffi/testsuite/libffi.call/nested_struct.c @@ -5,7 +5,7 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_16byte1 { @@ -50,7 +50,8 @@ cls_struct_combined cls_struct_combined_fn(struct cls_struct_16byte1 b0, } static void -cls_struct_combined_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_16byte1 b0; struct cls_struct_16byte2 b1; @@ -107,10 +108,10 @@ int main (void) cls_struct_fields[0] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_float; - cls_struct_fields[2] = &ffi_type_uint32; + cls_struct_fields[2] = &ffi_type_sint; cls_struct_fields[3] = NULL; - cls_struct_fields1[0] = &ffi_type_uint32; + cls_struct_fields1[0] = &ffi_type_sint; cls_struct_fields1[1] = &ffi_type_double; cls_struct_fields1[2] = &ffi_type_float; cls_struct_fields1[3] = NULL; diff --git a/libffi/testsuite/libffi.call/nested_struct1.c b/libffi/testsuite/libffi.call/nested_struct1.c index f6aefcb..f7fe72e 100644 --- a/libffi/testsuite/libffi.call/nested_struct1.c +++ b/libffi/testsuite/libffi.call/nested_struct1.c @@ -5,7 +5,7 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct cls_struct_16byte1 { @@ -52,7 +52,8 @@ cls_struct_combined cls_struct_combined_fn(struct cls_struct_16byte1 b0, } static void -cls_struct_combined_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct cls_struct_16byte1 b0; struct cls_struct_16byte2 b1; @@ -112,10 +113,10 @@ int main (void) cls_struct_fields[0] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_float; - cls_struct_fields[2] = &ffi_type_uint32; + cls_struct_fields[2] = &ffi_type_sint; cls_struct_fields[3] = NULL; - cls_struct_fields1[0] = &ffi_type_uint32; + cls_struct_fields1[0] = &ffi_type_sint; cls_struct_fields1[1] = &ffi_type_double; cls_struct_fields1[2] = &ffi_type_float; cls_struct_fields1[3] = NULL; diff --git a/libffi/testsuite/libffi.call/nested_struct10.c b/libffi/testsuite/libffi.call/nested_struct10.c index a9f5974..8d9aba2 100644 --- a/libffi/testsuite/libffi.call/nested_struct10.c +++ b/libffi/testsuite/libffi.call/nested_struct10.c @@ -6,7 +6,7 @@ PR: none. Originator: 20051010 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct A { @@ -102,7 +102,7 @@ int main (void) cls_struct_fields1[0] = &ffi_type_uchar; cls_struct_fields1[1] = &cls_struct_type; - cls_struct_fields1[2] = &ffi_type_uint32; + cls_struct_fields1[2] = &ffi_type_uint; cls_struct_fields1[3] = NULL; cls_struct_fields2[0] = &ffi_type_uint64; diff --git a/libffi/testsuite/libffi.call/nested_struct2.c b/libffi/testsuite/libffi.call/nested_struct2.c index 907fe89..821fcc4 100644 --- a/libffi/testsuite/libffi.call/nested_struct2.c +++ b/libffi/testsuite/libffi.call/nested_struct2.c @@ -6,19 +6,9 @@ PR: none. Originator: 20030911 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" -#if LONG_MAX == 2147483647 -#define ffi_type_mylong ffi_type_uint32 -#else -#if LONG_MAX == 9223372036854775807 -#define ffi_type_mylong ffi_type_uint64 -#else -#error "Error, size LONG not defined as expected" -#endif -#endif - typedef struct A { unsigned long a; unsigned char b; @@ -37,14 +27,15 @@ B B_fn(struct A b0, struct B b1) result.x.b = b0.b + b1.x.b + b1.y; result.y = b0.b + b1.x.b; - printf("%d %d %d %d %d: %d %d %d\n", b0.a, b0.b, b1.x.a, b1.x.b, b1.y, + printf("%lu %d %lu %d %d: %lu %d %d\n", b0.a, b0.b, b1.x.a, b1.x.b, b1.y, result.x.a, result.x.b, result.y); return result; } static void -B_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct A b0; struct B b1; @@ -89,7 +80,7 @@ int main (void) struct B res_dbl; - cls_struct_fields[0] = &ffi_type_mylong; + cls_struct_fields[0] = &ffi_type_ulong; cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[2] = NULL; @@ -115,7 +106,6 @@ int main (void) CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); - CHECK(ffi_prep_closure(pcl, &cif, B_gn, NULL) == FFI_OK); res_dbl = ((B(*)(A, B))(pcl))(e_dbl, f_dbl); @@ -123,5 +113,6 @@ int main (void) CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); + exit(0); } diff --git a/libffi/testsuite/libffi.call/nested_struct3.c b/libffi/testsuite/libffi.call/nested_struct3.c index bb6b9d3..f11aff4 100644 --- a/libffi/testsuite/libffi.call/nested_struct3.c +++ b/libffi/testsuite/libffi.call/nested_struct3.c @@ -6,7 +6,7 @@ PR: none. Originator: 20030911 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct A { @@ -35,7 +35,8 @@ B B_fn(struct A b0, struct B b1) } static void -B_gn(ffi_cif* cif, void* resp, void** args, void* userdata) +B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct A b0; struct B b1; diff --git a/libffi/testsuite/libffi.call/nested_struct4.c b/libffi/testsuite/libffi.call/nested_struct4.c index f67b6a9..0553ce8 100644 --- a/libffi/testsuite/libffi.call/nested_struct4.c +++ b/libffi/testsuite/libffi.call/nested_struct4.c @@ -6,7 +6,7 @@ PR: PR 25630. Originator: 20051010 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct A { diff --git a/libffi/testsuite/libffi.call/nested_struct5.c b/libffi/testsuite/libffi.call/nested_struct5.c index 07821b4..a77931b 100644 --- a/libffi/testsuite/libffi.call/nested_struct5.c +++ b/libffi/testsuite/libffi.call/nested_struct5.c @@ -6,7 +6,7 @@ PR: none. Originator: 20051010 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct A { diff --git a/libffi/testsuite/libffi.call/nested_struct6.c b/libffi/testsuite/libffi.call/nested_struct6.c index 8bf737b..af2821c 100644 --- a/libffi/testsuite/libffi.call/nested_struct6.c +++ b/libffi/testsuite/libffi.call/nested_struct6.c @@ -6,7 +6,7 @@ PR: PR 25630. Originator: 20051010 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct A { @@ -103,7 +103,7 @@ int main (void) cls_struct_fields1[1] = &ffi_type_uchar; cls_struct_fields1[2] = NULL; - cls_struct_fields2[0] = &ffi_type_mylong; + cls_struct_fields2[0] = &ffi_type_slong; cls_struct_fields2[1] = &ffi_type_uchar; cls_struct_fields2[2] = NULL; diff --git a/libffi/testsuite/libffi.call/nested_struct7.c b/libffi/testsuite/libffi.call/nested_struct7.c index 6e7de9e..c7dd4f7 100644 --- a/libffi/testsuite/libffi.call/nested_struct7.c +++ b/libffi/testsuite/libffi.call/nested_struct7.c @@ -6,7 +6,7 @@ PR: none. Originator: 20051010 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct A { diff --git a/libffi/testsuite/libffi.call/nested_struct8.c b/libffi/testsuite/libffi.call/nested_struct8.c index 1f745a0..775ff70 100644 --- a/libffi/testsuite/libffi.call/nested_struct8.c +++ b/libffi/testsuite/libffi.call/nested_struct8.c @@ -6,7 +6,7 @@ PR: none. Originator: 20051010 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct A { diff --git a/libffi/testsuite/libffi.call/nested_struct9.c b/libffi/testsuite/libffi.call/nested_struct9.c index 94636b5..70332de 100644 --- a/libffi/testsuite/libffi.call/nested_struct9.c +++ b/libffi/testsuite/libffi.call/nested_struct9.c @@ -6,7 +6,7 @@ PR: none. Originator: 20051010 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct A { @@ -103,7 +103,7 @@ int main (void) cls_struct_fields1[1] = &ffi_type_uchar; cls_struct_fields1[2] = NULL; - cls_struct_fields2[0] = &ffi_type_mylong; + cls_struct_fields2[0] = &ffi_type_ulong; cls_struct_fields2[1] = &ffi_type_uchar; cls_struct_fields2[2] = NULL; diff --git a/libffi/testsuite/libffi.call/problem1.c b/libffi/testsuite/libffi.call/problem1.c index 46c88db..ca70cc8 100644 --- a/libffi/testsuite/libffi.call/problem1.c +++ b/libffi/testsuite/libffi.call/problem1.c @@ -4,7 +4,7 @@ PR: none. Originator: 20030828 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitest.h" typedef struct my_ffi_struct { @@ -27,7 +27,8 @@ my_ffi_struct callee(struct my_ffi_struct a1, struct my_ffi_struct a2) return result; } -void stub(ffi_cif* cif, void* resp, void** args, void* userdata) +void stub(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) { struct my_ffi_struct a1; struct my_ffi_struct a2; diff --git a/libffi/testsuite/libffi.call/promotion.c b/libffi/testsuite/libffi.call/promotion.c index 3fb0fe2..4456161 100644 --- a/libffi/testsuite/libffi.call/promotion.c +++ b/libffi/testsuite/libffi.call/promotion.c @@ -43,10 +43,10 @@ int main (void) ul = 0; for (sc = (signed char) -127; - sc <= (signed char) 120; /*@-type@*/ sc += 1 /*@=type@*/) + sc <= (signed char) 120; sc += 1) for (ss = -30000; ss <= 30000; ss += 10000) for (uc = (unsigned char) 0; - uc <= (unsigned char) 200; /*@-type@*/ uc += 20 /*@=type@*/) + uc <= (unsigned char) 200; uc += 20) for (us = 0; us <= 60000; us += 10000) { ul++; diff --git a/libffi/testsuite/libffi.call/pyobjc-tc.c b/libffi/testsuite/libffi.call/pyobjc-tc.c index 017323c..e29bd6c 100644 --- a/libffi/testsuite/libffi.call/pyobjc-tc.c +++ b/libffi/testsuite/libffi.call/pyobjc-tc.c @@ -107,7 +107,7 @@ int main(void) ffi_call(&cif, FFI_FN(doit), &result, values); - printf ("The result is %d\n", result); + printf ("The result is %d\n", (int)result); } exit(0); diff --git a/libffi/testsuite/libffi.call/return_dbl1.c b/libffi/testsuite/libffi.call/return_dbl1.c index a6c1cfc..0ea5d50 100644 --- a/libffi/testsuite/libffi.call/return_dbl1.c +++ b/libffi/testsuite/libffi.call/return_dbl1.c @@ -21,7 +21,7 @@ int main (void) unsigned int in3; args[0] = &ffi_type_double; args[1] = &ffi_type_float; - args[2] = &ffi_type_uint32; + args[2] = &ffi_type_uint; args[3] = &ffi_type_double; values[0] = &dbl1; values[1] = &fl2; diff --git a/libffi/testsuite/libffi.call/return_dbl2.c b/libffi/testsuite/libffi.call/return_dbl2.c index 51af3ba..b3818f8 100644 --- a/libffi/testsuite/libffi.call/return_dbl2.c +++ b/libffi/testsuite/libffi.call/return_dbl2.c @@ -20,7 +20,7 @@ int main (void) unsigned int in3; args[0] = &ffi_type_double; args[1] = &ffi_type_double; - args[2] = &ffi_type_uint32; + args[2] = &ffi_type_uint; args[3] = &ffi_type_double; values[0] = &dbl1; values[1] = &dbl2; diff --git a/libffi/testsuite/libffi.call/return_fl2.c b/libffi/testsuite/libffi.call/return_fl2.c index 6df5b54..ddb976c 100644 --- a/libffi/testsuite/libffi.call/return_fl2.c +++ b/libffi/testsuite/libffi.call/return_fl2.c @@ -7,12 +7,13 @@ /* { dg-do run } */ #include "ffitest.h" -/* To avoid a false negative on ix86 do not declare the return_fl static. - See PR323. -*/ -float return_fl(float fl1, float fl2, float fl3, float fl4) +/* Use volatile float to avoid false negative on ix86. See PR target/323. */ +static float return_fl(float fl1, float fl2, float fl3, float fl4) { - return fl1 + fl2 + fl3 + fl4; + volatile float sum; + + sum = fl1 + fl2 + fl3 + fl4; + return sum; } int main (void) { @@ -20,6 +21,7 @@ int main (void) ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; float fl1, fl2, fl3, fl4, rfl; + volatile float sum; args[0] = &ffi_type_float; args[1] = &ffi_type_float; @@ -40,6 +42,8 @@ int main (void) ffi_call(&cif, FFI_FN(return_fl), &rfl, values); printf ("%f vs %f\n", rfl, return_fl(fl1, fl2, fl3, fl4)); - CHECK(rfl == fl1 + fl2 + fl3 + fl4); + + sum = fl1 + fl2 + fl3 + fl4; + CHECK(rfl == sum); exit(0); } diff --git a/libffi/testsuite/libffi.call/return_fl3.c b/libffi/testsuite/libffi.call/return_fl3.c index c3d2f12..c37877b 100644 --- a/libffi/testsuite/libffi.call/return_fl3.c +++ b/libffi/testsuite/libffi.call/return_fl3.c @@ -20,7 +20,7 @@ int main (void) unsigned int in3; args[0] = &ffi_type_float; args[1] = &ffi_type_float; - args[2] = &ffi_type_uint32; + args[2] = &ffi_type_uint; args[3] = &ffi_type_float; values[0] = &fl1; values[1] = &fl2; diff --git a/libffi/testsuite/libffi.call/return_ll1.c b/libffi/testsuite/libffi.call/return_ll1.c index 32fdfa1..5681d84 100644 --- a/libffi/testsuite/libffi.call/return_ll1.c +++ b/libffi/testsuite/libffi.call/return_ll1.c @@ -20,9 +20,9 @@ int main (void) long long ll1; unsigned ll0, ll2; - args[0] = &ffi_type_uint32; + args[0] = &ffi_type_sint; args[1] = &ffi_type_sint64; - args[2] = &ffi_type_uint32; + args[2] = &ffi_type_sint; values[0] = &ll0; values[1] = &ll1; values[2] = &ll2; diff --git a/libffi/testsuite/libffi.call/return_ul.c b/libffi/testsuite/libffi.call/return_ul.c index 2510224..12b266f 100644 --- a/libffi/testsuite/libffi.call/return_ul.c +++ b/libffi/testsuite/libffi.call/return_ul.c @@ -16,7 +16,7 @@ int main (void) ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; - unsigned long res; + ffi_arg res; unsigned long ul1, ul2; args[0] = &ffi_type_ulong; @@ -31,7 +31,7 @@ int main (void) ul2 = 1073741824L; ffi_call(&cif, FFI_FN(return_ul), &res, values); - printf("res: %ld, %ld\n", res, ul1 + ul2); + printf("res: %lu, %lu\n", (unsigned long)res, ul1 + ul2); /* { dg-output "res: 2147483647, 2147483647" } */ exit(0); diff --git a/libffi/testsuite/libffi.call/struct1.c b/libffi/testsuite/libffi.call/struct1.c index 99c5d3b..ea76c85 100644 --- a/libffi/testsuite/libffi.call/struct1.c +++ b/libffi/testsuite/libffi.call/struct1.c @@ -16,9 +16,7 @@ typedef struct static test_structure_1 struct1(test_structure_1 ts) { - /*@-type@*/ ts.uc++; - /*@=type@*/ ts.d--; ts.ui++; diff --git a/libffi/testsuite/libffi.special/ffitestcxx.h b/libffi/testsuite/libffi.special/ffitestcxx.h index 01414cc..b9f0d48 100644 --- a/libffi/testsuite/libffi.special/ffitestcxx.h +++ b/libffi/testsuite/libffi.special/ffitestcxx.h @@ -6,6 +6,15 @@ #define MAX_ARGS 256 + +/* Define __UNUSED__ that also other compilers than gcc can run the tests. */ +#undef __UNUSED__ +#if defined(__GNUC__) +#define __UNUSED__ __attribute__((__unused__)) +#else +#define __UNUSED__ +#endif + #define CHECK(x) (!(x) ? abort() : (void)0) /* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a diff --git a/libffi/testsuite/libffi.special/special.exp b/libffi/testsuite/libffi.special/special.exp index 5a1c081..b7d31da 100644 --- a/libffi/testsuite/libffi.special/special.exp +++ b/libffi/testsuite/libffi.special/special.exp @@ -1,19 +1,18 @@ -# Copyright (C) 2003 Free Software Foundation, Inc. +# Copyright (C) 2003, 2006 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - +# Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # libffi testsuite that uses the 'dg.exp' driver. load_lib libffi-dg.exp @@ -27,7 +26,10 @@ global cxx_options set cxx_options " -shared-libgcc -lstdc++" -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "-O0 -W -Wall" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "-O2" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "-O3" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "-Os" dg-finish diff --git a/libffi/testsuite/libffi.special/unwindtest.cc b/libffi/testsuite/libffi.special/unwindtest.cc index bb733c2..a3d8037 100644 --- a/libffi/testsuite/libffi.special/unwindtest.cc +++ b/libffi/testsuite/libffi.special/unwindtest.cc @@ -4,19 +4,20 @@ PR: none. Originator: Jeff Sturm */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitestcxx.h" void -closure_test_fn(ffi_cif* cif, void* resp, void** args, void* userdata) +closure_test_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, + void** args __UNUSED__, void* userdata __UNUSED__) { throw 9; } typedef void (*closure_test_type)(); -void closure_test_fn1(ffi_cif* cif,void* resp,void** args, - void* userdata) +void closure_test_fn1(ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) { *(ffi_arg*)resp = (int)*(float *)args[0] +(int)(*(float *)args[1]) + @@ -54,7 +55,6 @@ int main (void) #endif ffi_closure *pcl; ffi_type * cl_arg_types[17]; - int res; #ifdef USING_MMAP pcl = (ffi_closure *) allocate_mmap (sizeof(ffi_closure)); #else diff --git a/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc b/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc index 0911e0e..29739cd 100644 --- a/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc +++ b/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc @@ -4,7 +4,7 @@ PR: none. Originator: Andreas Tobler 20061213 */ -/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run } */ #include "ffitestcxx.h" static int checking(int a __UNUSED__, short b __UNUSED__, -- 2.7.4