libffi merge
authorAnthony Green <green@gcc.gnu.org>
Wed, 26 Dec 2012 16:28:02 +0000 (16:28 +0000)
committerAnthony Green <green@gcc.gnu.org>
Wed, 26 Dec 2012 16:28:02 +0000 (16:28 +0000)
From-SVN: r194722

123 files changed:
libffi/ChangeLog
libffi/ChangeLog.libffi [new file with mode: 0644]
libffi/Makefile.am
libffi/README
libffi/configure
libffi/configure.ac
libffi/generate-ios-source-and-headers.py [new file with mode: 0644]
libffi/generate-osx-source-and-headers.py [new file with mode: 0644]
libffi/libffi.xcodeproj/project.pbxproj [new file with mode: 0644]
libffi/man/Makefile.am
libffi/man/Makefile.in
libffi/src/aarch64/ffi.c [new file with mode: 0644]
libffi/src/aarch64/ffitarget.h [new file with mode: 0644]
libffi/src/aarch64/sysv.S [new file with mode: 0644]
libffi/src/arm/ffi.c
libffi/src/arm/sysv.S
libffi/src/arm/trampoline.S
libffi/src/bfin/ffi.c [new file with mode: 0644]
libffi/src/bfin/ffitarget.h [new file with mode: 0644]
libffi/src/bfin/sysv.S [new file with mode: 0644]
libffi/src/closures.c
libffi/src/m68k/ffi.c
libffi/src/m68k/sysv.S
libffi/src/powerpc/ffi_darwin.c
libffi/src/prep_cif.c
libffi/src/tile/ffi.c [new file with mode: 0644]
libffi/src/tile/ffitarget.h [new file with mode: 0644]
libffi/src/tile/tile.S [new file with mode: 0644]
libffi/src/x86/ffi.c
libffi/src/x86/ffi64.c
libffi/src/x86/ffitarget.h
libffi/src/x86/win32.S
libffi/testsuite/Makefile.am
libffi/testsuite/Makefile.in
libffi/testsuite/lib/libffi.exp
libffi/testsuite/libffi.call/closure_stdcall.c
libffi/testsuite/libffi.call/closure_thiscall.c
libffi/testsuite/libffi.call/cls_12byte.c
libffi/testsuite/libffi.call/cls_16byte.c
libffi/testsuite/libffi.call/cls_18byte.c
libffi/testsuite/libffi.call/cls_19byte.c
libffi/testsuite/libffi.call/cls_1_1byte.c
libffi/testsuite/libffi.call/cls_20byte.c
libffi/testsuite/libffi.call/cls_20byte1.c
libffi/testsuite/libffi.call/cls_24byte.c
libffi/testsuite/libffi.call/cls_2byte.c
libffi/testsuite/libffi.call/cls_3_1byte.c
libffi/testsuite/libffi.call/cls_3byte1.c
libffi/testsuite/libffi.call/cls_3byte2.c
libffi/testsuite/libffi.call/cls_4_1byte.c
libffi/testsuite/libffi.call/cls_4byte.c
libffi/testsuite/libffi.call/cls_5_1_byte.c
libffi/testsuite/libffi.call/cls_5byte.c
libffi/testsuite/libffi.call/cls_64byte.c
libffi/testsuite/libffi.call/cls_6_1_byte.c
libffi/testsuite/libffi.call/cls_6byte.c
libffi/testsuite/libffi.call/cls_7_1_byte.c
libffi/testsuite/libffi.call/cls_7byte.c
libffi/testsuite/libffi.call/cls_8byte.c
libffi/testsuite/libffi.call/cls_9byte1.c
libffi/testsuite/libffi.call/cls_9byte2.c
libffi/testsuite/libffi.call/cls_align_double.c
libffi/testsuite/libffi.call/cls_align_float.c
libffi/testsuite/libffi.call/cls_align_longdouble.c
libffi/testsuite/libffi.call/cls_align_longdouble_split.c
libffi/testsuite/libffi.call/cls_align_longdouble_split2.c
libffi/testsuite/libffi.call/cls_align_pointer.c
libffi/testsuite/libffi.call/cls_align_sint16.c
libffi/testsuite/libffi.call/cls_align_sint32.c
libffi/testsuite/libffi.call/cls_align_sint64.c
libffi/testsuite/libffi.call/cls_align_uint16.c
libffi/testsuite/libffi.call/cls_align_uint32.c
libffi/testsuite/libffi.call/cls_align_uint64.c
libffi/testsuite/libffi.call/cls_dbls_struct.c
libffi/testsuite/libffi.call/cls_double_va.c
libffi/testsuite/libffi.call/cls_longdouble_va.c
libffi/testsuite/libffi.call/cls_pointer_stack.c
libffi/testsuite/libffi.call/cls_struct_va1.c [new file with mode: 0644]
libffi/testsuite/libffi.call/cls_uchar_va.c [new file with mode: 0644]
libffi/testsuite/libffi.call/cls_uint_va.c [new file with mode: 0644]
libffi/testsuite/libffi.call/cls_ulong_va.c [new file with mode: 0644]
libffi/testsuite/libffi.call/cls_ushort_va.c [new file with mode: 0644]
libffi/testsuite/libffi.call/err_bad_typedef.c
libffi/testsuite/libffi.call/fastthis1_win32.c
libffi/testsuite/libffi.call/fastthis2_win32.c
libffi/testsuite/libffi.call/fastthis3_win32.c
libffi/testsuite/libffi.call/ffitest.h
libffi/testsuite/libffi.call/float_va.c
libffi/testsuite/libffi.call/huge_struct.c
libffi/testsuite/libffi.call/nested_struct.c
libffi/testsuite/libffi.call/nested_struct1.c
libffi/testsuite/libffi.call/nested_struct10.c
libffi/testsuite/libffi.call/nested_struct11.c [new file with mode: 0644]
libffi/testsuite/libffi.call/nested_struct2.c
libffi/testsuite/libffi.call/nested_struct3.c
libffi/testsuite/libffi.call/nested_struct4.c
libffi/testsuite/libffi.call/nested_struct5.c
libffi/testsuite/libffi.call/nested_struct6.c
libffi/testsuite/libffi.call/nested_struct7.c
libffi/testsuite/libffi.call/nested_struct8.c
libffi/testsuite/libffi.call/nested_struct9.c
libffi/testsuite/libffi.call/stret_large.c
libffi/testsuite/libffi.call/stret_large2.c
libffi/testsuite/libffi.call/stret_medium.c
libffi/testsuite/libffi.call/stret_medium2.c
libffi/testsuite/libffi.call/strlen2_win32.c
libffi/testsuite/libffi.call/struct1.c
libffi/testsuite/libffi.call/struct1_win32.c
libffi/testsuite/libffi.call/struct2.c
libffi/testsuite/libffi.call/struct2_win32.c
libffi/testsuite/libffi.call/struct3.c
libffi/testsuite/libffi.call/struct4.c
libffi/testsuite/libffi.call/struct5.c
libffi/testsuite/libffi.call/struct6.c
libffi/testsuite/libffi.call/struct7.c
libffi/testsuite/libffi.call/struct8.c
libffi/testsuite/libffi.call/struct9.c
libffi/testsuite/libffi.call/testclosure.c
libffi/testsuite/libffi.call/uninitialized.c [new file with mode: 0644]
libffi/testsuite/libffi.call/va_1.c [new file with mode: 0644]
libffi/testsuite/libffi.call/va_struct1.c [new file with mode: 0644]
libffi/testsuite/libffi.call/va_struct2.c [new file with mode: 0644]
libffi/testsuite/libffi.call/va_struct3.c [new file with mode: 0644]

index 56d772542996e15d513b8e75d41986f63338249f..62332c6939a3c29116bbc2db8d732a840668d631 100644 (file)
@@ -3,6 +3,63 @@
        * src/powerpc/linux64_closure.S: Add new ABI support.
        * src/powerpc/linux64.S: Likewise.
 
+2012-10-30  Magnus Granberg  <zorry@gentoo.org>
+           Pavel Labushev  <pavel.labushev@runbox.ru>
+
+       * configure.ac: New options pax_emutramp
+       * configure, fficonfig.h.in: Regenerated
+       * src/closures.c: New function emutramp_enabled_check() and
+       checks.
+
+2012-10-30  Frederick Cheung  <frederick.cheung@gmail.com>
+
+       * configure.ac: Enable FFI_MAP_EXEC_WRIT for Darwin 12 (mountain
+       lion) and future version.
+       * configure: Rebuild.
+
+2012-10-30  James Greenhalgh  <james.greenhalgh at arm.com>
+            Marcus Shawcroft  <marcus.shawcroft at arm.com>
+
+        * README: Add details of aarch64 port.
+        * src/aarch64/ffi.c: New.
+        * src/aarch64/ffitarget.h: Likewise.
+        * src/aarch64/sysv.S: Likewise.
+       * Makefile.am: Support aarch64.
+       * configure.ac: Support aarch64.
+       * Makefile.in, configure: Rebuilt.
+
+2012-10-30  James Greenhalgh  <james.greenhalgh at arm.com>
+            Marcus Shawcroft  <marcus.shawcroft at arm.com>
+
+        * testsuite/lib/libffi.exp: Add support for aarch64.
+        * testsuite/libffi.call/cls_struct_va1.c: New.
+        * testsuite/libffi.call/cls_uchar_va.c: Likewise.
+        * testsuite/libffi.call/cls_uint_va.c: Likewise.
+        * testsuite/libffi.call/cls_ulong_va.c: Likewise.
+        * testsuite/libffi.call/cls_ushort_va.c: Likewise.
+        * testsuite/libffi.call/nested_struct11.c: Likewise.
+        * testsuite/libffi.call/uninitialized.c: Likewise.
+        * testsuite/libffi.call/va_1.c: Likewise.
+        * testsuite/libffi.call/va_struct1.c: Likewise.
+        * testsuite/libffi.call/va_struct2.c: Likewise.
+        * testsuite/libffi.call/va_struct3.c: Likewise.
+
+2012-10-12  Walter Lee  <walt@tilera.com>
+
+        * Makefile.am: Add TILE-Gx/TILEPro support.
+        * configure.ac: Likewise.
+        * Makefile.in: Regenerate.
+        * configure: Likewise.
+        * src/prep_cif.c (ffi_prep_cif_core): Handle TILE-Gx/TILEPro.
+        * src/tile: New directory.
+        * src/tile/ffi.c: New file.
+        * src/tile/ffitarget.h: Ditto.
+        * src/tile/tile.S: Ditto.
+
+2012-10-12  Matthias Klose  <doko@ubuntu.com>
+
+       * generate-osx-source-and-headers.py: Normalize whitespace.
+
 2012-09-14  David Edelsohn  <dje.gcc@gmail.com>
 
        * configure: Regenerated.
 
        * configure: Regenerated.
 
+2012-05-05  Nicolas Lelong
+
+       * libffi.xcodeproj/project.pbxproj: Fixes.
+       * README: Update for iOS builds.
+
+2012-04-23  Alexandre Keunecke I. de Mendonca <alexandre.keunecke@gmail.com>
+
+       * configure.ac: Add Blackfin/sysv support
+       * Makefile.am: Add Blackfin/sysv support
+       * src/bfin/ffi.c:  Add Blackfin/sysv support
+       * src/bfin/ffitarget.h: Add Blackfin/sysv support
+
+2012-04-11  Anthony Green  <green@moxielogic.com>
+
+       * Makefile.am (EXTRA_DIST): Add new script.
+       * Makefile.in: Rebuilt.
+
+2012-04-11  Zachary Waldowski  <zwaldowski@gmail.com>
+
+       * generate-ios-source-and-headers.py,
+       libffi.xcodeproj/project.pbxproj: Support a Mac static library via
+       Xcode. Set iOS compatibility to 4.0.  Move iOS trampoline
+       generation into an Xcode "run script" phase.  Include both as
+       Xcode build scripts. Don't always regenerate config files.
+
+2012-04-10  Anthony Green  <green@moxielogic.com>
+
+       * src/powerpc/ffi_darwin.c (ffi_prep_args): Add missing semicolon.
+
+2012-04-06  Anthony Green  <green@moxielogic.com>
+
+       * Makefile.am (EXTRA_DIST): Add new iOS/xcode files.
+       * Makefile.in: Rebuilt.
+
+2012-04-06  Mike Lewis  <mikelikespie@gmail.com>
+
+       * generate-ios-source-and-headers.py: New file.
+       * libffi.xcodeproj/project.pbxproj: New file.
+       * README: Update instructions on building iOS binary.
+       * build-ios.sh: Delete.
+
+2012-04-06  Anthony Green  <green@moxielogic.com>
+
+       * src/x86/ffi64.c (UINT128): Define differently for Intel and GNU
+       compilers, then use it.
+
+2012-04-06  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * m4/libtool.m4 (_LT_ENABLE_LOCK): Support x32.
+
+2012-04-06  Anthony Green  <green@moxielogic.com>
+
+       * testsuite/Makefile.am (EXTRA_DIST): Add missing test cases.
+       * testsuite/Makefile.in: Rebuilt.
+
+2012-04-05  Zachary Waldowski  <zwaldowski@gmail.com>
+
+       * include/ffi.h.in: Add missing trampoline table fields.
+       * src/arm/sysv.S: Fix ENTRY definition, and wrap symbol references
+       in CNAME.
+       * src/x86/ffi.c: Wrap Windows specific code in ifdefs.
+
+2012-03-29  Peter Rosin  <peda@lysator.liu.se>
+
+       * src/x86/win32.S (ffi_closure_raw_THISCALL): Unify the frame
+       generation, fix the ENDP label and remove the surplus third arg
+       from the 'lea' insn.
+
+2012-03-29  Peter Rosin  <peda@lysator.liu.se>
+
+       * src/x86/win32.S (ffi_closure_raw_SYSV): Make the 'stubraw' label
+       visible outside the PROC, so that ffi_closure_raw_THISCALL can see
+       it.  Also instruct the assembler to add a frame to the function.
+
+2012-03-23  Peter Rosin  <peda@lysator.liu.se>
+
+       * Makefile.am (AM_CPPFLAGS): Add -DFFI_BUILDING.
+       * Makefile.in: Rebuilt.
+       * include/ffi.h.in [MSVC]: Add __declspec(dllimport) decorations
+       to all data exports, when compiling libffi clients using MSVC.
+
+2012-03-29  Peter Rosin  <peda@lysator.liu.se>
+
+       * src/x86/ffitarget.h (ffi_abi): Add new ABI FFI_MS_CDECL and
+       make it the default for MSVC.
+       (FFI_TYPE_MS_STRUCT): New structure return convention.
+       * src/x86/ffi.c (ffi_prep_cif_machdep): Tweak the structure
+       return convention for FFI_MS_CDECL to be FFI_TYPE_MS_STRUCT
+       instead of an ordinary FFI_TYPE_STRUCT.
+       (ffi_prep_args): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT.
+       (ffi_call): Likewise.
+       (ffi_prep_incoming_args_SYSV): Likewise.
+       (ffi_raw_call): Likewise.
+       (ffi_prep_closure_loc): Treat FFI_MS_CDECL as FFI_SYSV.
+       * src/x86/win32.S (ffi_closure_SYSV): For FFI_TYPE_MS_STRUCT,
+       return a pointer to the result structure in eax and don't pop
+       that pointer from the stack, the caller takes care of it.
+       (ffi_call_win32): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT.
+       (ffi_closure_raw_SYSV): Likewise.
+
+2012-03-22  Peter Rosin  <peda@lysator.liu.se>
+
+       * testsuite/libffi.call/closure_stdcall.c [MSVC]: Add inline
+       assembly version with Intel syntax.
+       * testsuite/libffi.call/closure_thiscall.c [MSVC]: Likewise.
+
+2012-03-23  Peter Rosin  <peda@lysator.liu.se>
+
+       * testsuite/libffi.call/ffitest.h: Provide abstration of
+       __attribute__((fastcall)) in the form of a __FASTCALL__
+       define.  Define it to __fastcall for MSVC.
+       * testsuite/libffi.call/fastthis1_win32.c: Use the above.
+       * testsuite/libffi.call/fastthis2_win32.c: Likewise.
+       * testsuite/libffi.call/fastthis3_win32.c: Likewise.
+       * testsuite/libffi.call/strlen2_win32.c: Likewise.
+       * testsuite/libffi.call/struct1_win32.c: Likewise.
+       * testsuite/libffi.call/struct2_win32.c: Likewise.
+
+2012-03-22  Peter Rosin  <peda@lysator.liu.se>
+
+       * src/x86/win32.S [MSVC] (ffi_closure_THISCALL): Remove the manual
+       frame on function entry, MASM adds one automatically.
+
+2012-03-22  Peter Rosin  <peda@lysator.liu.se>
+
+       * testsuite/libffi.call/ffitest.h [MSVC]: Add kludge for missing
+       bits in the MSVC headers.
+
+2012-03-22  Peter Rosin  <peda@lysator.liu.se>
+
+       * testsuite/libffi.call/cls_12byte.c: Adjust to the C89 style
+       with no declarations after statements.
+       * testsuite/libffi.call/cls_16byte.c: Likewise.
+       * testsuite/libffi.call/cls_18byte.c: Likewise.
+       * testsuite/libffi.call/cls_19byte.c: Likewise.
+       * testsuite/libffi.call/cls_1_1byte.c: Likewise.
+       * testsuite/libffi.call/cls_20byte.c: Likewise.
+       * testsuite/libffi.call/cls_20byte1.c: Likewise.
+       * testsuite/libffi.call/cls_24byte.c: Likewise.
+       * testsuite/libffi.call/cls_2byte.c: Likewise.
+       * testsuite/libffi.call/cls_3_1byte.c: Likewise.
+       * testsuite/libffi.call/cls_3byte1.c: Likewise.
+       * testsuite/libffi.call/cls_3byte2.c: Likewise.
+       * testsuite/libffi.call/cls_4_1byte.c: Likewise.
+       * testsuite/libffi.call/cls_4byte.c: Likewise.
+       * testsuite/libffi.call/cls_5_1_byte.c: Likewise.
+       * testsuite/libffi.call/cls_5byte.c: Likewise.
+       * testsuite/libffi.call/cls_64byte.c: Likewise.
+       * testsuite/libffi.call/cls_6_1_byte.c: Likewise.
+       * testsuite/libffi.call/cls_6byte.c: Likewise.
+       * testsuite/libffi.call/cls_7_1_byte.c: Likewise.
+       * testsuite/libffi.call/cls_7byte.c: Likewise.
+       * testsuite/libffi.call/cls_8byte.c: Likewise.
+       * testsuite/libffi.call/cls_9byte1.c: Likewise.
+       * testsuite/libffi.call/cls_9byte2.c: Likewise.
+       * testsuite/libffi.call/cls_align_double.c: Likewise.
+       * testsuite/libffi.call/cls_align_float.c: Likewise.
+       * testsuite/libffi.call/cls_align_longdouble.c: Likewise.
+       * testsuite/libffi.call/cls_align_longdouble_split.c: Likewise.
+       * testsuite/libffi.call/cls_align_longdouble_split2.c: Likewise.
+       * testsuite/libffi.call/cls_align_pointer.c: Likewise.
+       * testsuite/libffi.call/cls_align_sint16.c: Likewise.
+       * testsuite/libffi.call/cls_align_sint32.c: Likewise.
+       * testsuite/libffi.call/cls_align_sint64.c: Likewise.
+       * testsuite/libffi.call/cls_align_uint16.c: Likewise.
+       * testsuite/libffi.call/cls_align_uint32.c: Likewise.
+       * testsuite/libffi.call/cls_align_uint64.c: Likewise.
+       * testsuite/libffi.call/cls_dbls_struct.c: Likewise.
+       * testsuite/libffi.call/cls_pointer_stack.c: Likewise.
+       * testsuite/libffi.call/err_bad_typedef.c: Likewise.
+       * testsuite/libffi.call/huge_struct.c: Likewise.
+       * testsuite/libffi.call/nested_struct.c: Likewise.
+       * testsuite/libffi.call/nested_struct1.c: Likewise.
+       * testsuite/libffi.call/nested_struct10.c: Likewise.
+       * testsuite/libffi.call/nested_struct2.c: Likewise.
+       * testsuite/libffi.call/nested_struct3.c: Likewise.
+       * testsuite/libffi.call/nested_struct4.c: Likewise.
+       * testsuite/libffi.call/nested_struct5.c: Likewise.
+       * testsuite/libffi.call/nested_struct6.c: Likewise.
+       * testsuite/libffi.call/nested_struct7.c: Likewise.
+       * testsuite/libffi.call/nested_struct8.c: Likewise.
+       * testsuite/libffi.call/nested_struct9.c: Likewise.
+       * testsuite/libffi.call/stret_large.c: Likewise.
+       * testsuite/libffi.call/stret_large2.c: Likewise.
+       * testsuite/libffi.call/stret_medium.c: Likewise.
+       * testsuite/libffi.call/stret_medium2.c: Likewise.
+       * testsuite/libffi.call/struct1.c: Likewise.
+       * testsuite/libffi.call/struct1_win32.c: Likewise.
+       * testsuite/libffi.call/struct2.c: Likewise.
+       * testsuite/libffi.call/struct2_win32.c: Likewise.
+       * testsuite/libffi.call/struct3.c: Likewise.
+       * testsuite/libffi.call/struct4.c: Likewise.
+       * testsuite/libffi.call/struct5.c: Likewise.
+       * testsuite/libffi.call/struct6.c: Likewise.
+       * testsuite/libffi.call/struct7.c: Likewise.
+       * testsuite/libffi.call/struct8.c: Likewise.
+       * testsuite/libffi.call/struct9.c: Likewise.
+       * testsuite/libffi.call/testclosure.c: Likewise.
+
+2012-03-21  Peter Rosin         <peda@lysator.liu.se>
+
+       * testsuite/libffi.call/float_va.c (float_va_fn): Use %f when
+       printing doubles (%lf is for long doubles).
+       (main): Likewise.
+
+2012-03-21  Peter Rosin  <peda@lysator.liu.se>
+
+       * testsuite/lib/target-libpath.exp [*-*-cygwin*, *-*-mingw*]
+       (set_ld_library_path_env_vars): Add the library search dir to PATH
+       (and save PATH for later).
+       (restore_ld_library_path_env_vars): Restore PATH.
+
+2012-03-20  Peter Rosin  <peda@lysator.liu.se>
+
+       * testsuite/libffi.call/strlen2_win32.c (main): Remove bug.
+       * src/x86/win32.S [MSVC] (ffi_closure_SYSV): Make the 'stub' label
+       visible outside the PROC, so that ffi_closure_THISCALL can see it.
+
+2012-03-20  Peter Rosin  <peda@lysator.liu.se>
+
+       * testsuite/libffi.call/strlen2_win32.c (main): Remove bug.
+       * src/x86/win32.S [MSVC] (ffi_closure_SYSV): Make the 'stub' label
+       visible outside the PROC, so that ffi_closure_THISCALL can see it.
+
+2012-03-19  Alan Hourihane  <alanh@fairlite.co.uk>
+
+       * src/m68k/ffi.c: Add MINT support.
+       * src/m68k/sysv.S: Ditto.
+
+2012-03-19  chennam  <csit@axway.com>
+
+       * src/powerpc/ffi_darwin.c (ffi_prep_closure_loc): Fix AIX closure
+       support.
+
+2012-03-06  Chung-Lin Tang  <cltang@codesourcery.com>
+
+       * src/arm/ffi.c (ffi_call): Add __ARM_EABI__ guard around call to
+       ffi_call_VFP().
+       (ffi_prep_closure_loc): Add __ARM_EABI__ guard around use of
+       ffi_closure_VFP.
+       * src/arm/sysv.S: Add __ARM_EABI__ guard around VFP code.
+
 2012-04-02  Peter Bergner  <bergner@vnet.ibm.com>
 
        * src/powerpc/ffi.c (ffi_prep_args_SYSV): Declare double_tmp.
        (ffi_call): Silence possibly undefined warning.
        (ffi_closure_helper_SYSV): Declare variable type.
 
+2012-04-02  Peter Rosin  <peda@lysator.liu.se>
+
+       * src/x86/win32.S (ffi_call_win32): Sign/zero extend the return
+       value in the Intel version as is already done for the AT&T version.
+       (ffi_closure_SYSV): Likewise.
+       (ffi_closure_raw_SYSV): Likewise.
+       (ffi_closure_STDCALL): Likewise.
+
 2012-03-13  Kaz Kojima  <kkojima@gcc.gnu.org>
 
        * src/sh/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test,
diff --git a/libffi/ChangeLog.libffi b/libffi/ChangeLog.libffi
new file mode 100644 (file)
index 0000000..f3ee8b0
--- /dev/null
@@ -0,0 +1,584 @@
+2011-02-08  Andreas Tobler  <andreast@fgznet.ch>
+
+       * testsuite/lib/libffi.exp: Tweak for stand-alone mode.
+
+2009-12-25  Samuli Suominen  <ssuominen@gentoo.org>
+
+       * configure.ac: Undefine _AC_ARG_VAR_PRECIOUS for autoconf 2.64.
+       * configure: Rebuilt.
+       * fficonfig.h.in: Rebuilt.
+
+2009-06-16  Andrew Haley  <aph@redhat.com>
+
+       * testsuite/libffi.call/cls_align_sint64.c,
+       testsuite/libffi.call/cls_align_uint64.c,
+       testsuite/libffi.call/cls_longdouble_va.c,
+       testsuite/libffi.call/cls_ulonglong.c,
+       testsuite/libffi.call/return_ll1.c,
+       testsuite/libffi.call/stret_medium2.c: Fix printf format
+       specifiers.
+       * testsuite/libffi.call/huge_struct.c: Ad x86 XFAILs.
+       * testsuite/libffi.call/float2.c: Fix dg-excess-errors.
+       * testsuite/libffi.call/ffitest.h,
+       testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRIuLL): Define.
+
+2009-06-12  Andrew Haley  <aph@redhat.com>
+
+       * testsuite/libffi.call/cls_align_sint64.c,
+       testsuite/libffi.call/cls_align_uint64.c,
+       testsuite/libffi.call/cls_ulonglong.c,
+       testsuite/libffi.call/return_ll1.c,
+       testsuite/libffi.call/stret_medium2.c: Fix printf format
+       specifiers.
+       testsuite/libffi.special/unwindtest.cc: include stdint.h.
+
+2009-06-11  Timothy Wall  <twall@users.sf.net>
+
+       * Makefile.am,
+        configure.ac,
+        include/ffi.h.in,
+        include/ffi_common.h,
+        src/closures.c,
+        src/dlmalloc.c,
+        src/x86/ffi.c,
+        src/x86/ffitarget.h,
+        src/x86/win64.S (new),
+       README: Added win64 support (mingw or MSVC)
+        * Makefile.in,
+        include/Makefile.in,
+        man/Makefile.in,
+        testsuite/Makefile.in,
+        configure,
+        aclocal.m4: Regenerated
+        * ltcf-c.sh: properly escape cygwin/w32 path
+        * man/ffi_call.3: Clarify size requirements for return value.
+        * src/x86/ffi64.c: Fix filename in comment.
+        * src/x86/win32.S: Remove unused extern.
+
+        * testsuite/libffi.call/closure_fn0.c,
+        testsuite/libffi.call/closure_fn1.c,
+        testsuite/libffi.call/closure_fn2.c,
+        testsuite/libffi.call/closure_fn3.c,
+        testsuite/libffi.call/closure_fn4.c,
+        testsuite/libffi.call/closure_fn5.c,
+        testsuite/libffi.call/closure_fn6.c,
+       testsuite/libffi.call/closure_stdcall.c,
+       testsuite/libffi.call/cls_12byte.c,
+       testsuite/libffi.call/cls_16byte.c,
+       testsuite/libffi.call/cls_18byte.c,
+       testsuite/libffi.call/cls_19byte.c,
+       testsuite/libffi.call/cls_1_1byte.c,
+       testsuite/libffi.call/cls_20byte.c,
+       testsuite/libffi.call/cls_20byte1.c,
+       testsuite/libffi.call/cls_24byte.c,
+       testsuite/libffi.call/cls_2byte.c,
+       testsuite/libffi.call/cls_3_1byte.c,
+       testsuite/libffi.call/cls_3byte1.c,
+       testsuite/libffi.call/cls_3byte2.c,
+       testsuite/libffi.call/cls_4_1byte.c,
+       testsuite/libffi.call/cls_4byte.c,
+       testsuite/libffi.call/cls_5_1_byte.c,
+       testsuite/libffi.call/cls_5byte.c,
+       testsuite/libffi.call/cls_64byte.c,
+       testsuite/libffi.call/cls_6_1_byte.c,
+       testsuite/libffi.call/cls_6byte.c,
+       testsuite/libffi.call/cls_7_1_byte.c,
+       testsuite/libffi.call/cls_7byte.c,
+       testsuite/libffi.call/cls_8byte.c,
+       testsuite/libffi.call/cls_9byte1.c,
+       testsuite/libffi.call/cls_9byte2.c,
+       testsuite/libffi.call/cls_align_double.c,
+       testsuite/libffi.call/cls_align_float.c,
+       testsuite/libffi.call/cls_align_longdouble.c,
+       testsuite/libffi.call/cls_align_longdouble_split.c,
+       testsuite/libffi.call/cls_align_longdouble_split2.c,
+       testsuite/libffi.call/cls_align_pointer.c,
+       testsuite/libffi.call/cls_align_sint16.c,
+       testsuite/libffi.call/cls_align_sint32.c,
+       testsuite/libffi.call/cls_align_sint64.c,
+       testsuite/libffi.call/cls_align_uint16.c,
+       testsuite/libffi.call/cls_align_uint32.c,
+       testsuite/libffi.call/cls_align_uint64.c,
+       testsuite/libffi.call/cls_dbls_struct.c,
+       testsuite/libffi.call/cls_double.c,
+       testsuite/libffi.call/cls_double_va.c,
+       testsuite/libffi.call/cls_float.c,
+       testsuite/libffi.call/cls_longdouble.c,
+       testsuite/libffi.call/cls_longdouble_va.c,
+       testsuite/libffi.call/cls_multi_schar.c,
+       testsuite/libffi.call/cls_multi_sshort.c,
+       testsuite/libffi.call/cls_multi_sshortchar.c,
+       testsuite/libffi.call/cls_multi_uchar.c,
+       testsuite/libffi.call/cls_multi_ushort.c,
+       testsuite/libffi.call/cls_multi_ushortchar.c,
+       testsuite/libffi.call/cls_pointer.c,
+       testsuite/libffi.call/cls_pointer_stack.c,
+       testsuite/libffi.call/cls_schar.c,
+       testsuite/libffi.call/cls_sint.c,
+       testsuite/libffi.call/cls_sshort.c,
+       testsuite/libffi.call/cls_uchar.c,
+       testsuite/libffi.call/cls_uint.c,
+       testsuite/libffi.call/cls_ulonglong.c,
+       testsuite/libffi.call/cls_ushort.c,
+       testsuite/libffi.call/err_bad_abi.c,
+       testsuite/libffi.call/err_bad_typedef.c,
+       testsuite/libffi.call/float2.c,
+       testsuite/libffi.call/huge_struct.c,
+       testsuite/libffi.call/nested_struct.c,
+       testsuite/libffi.call/nested_struct1.c,
+       testsuite/libffi.call/nested_struct10.c,
+       testsuite/libffi.call/nested_struct2.c,
+       testsuite/libffi.call/nested_struct3.c,
+       testsuite/libffi.call/nested_struct4.c,
+       testsuite/libffi.call/nested_struct5.c,
+       testsuite/libffi.call/nested_struct6.c,
+       testsuite/libffi.call/nested_struct7.c,
+       testsuite/libffi.call/nested_struct8.c,
+       testsuite/libffi.call/nested_struct9.c,
+       testsuite/libffi.call/problem1.c,
+       testsuite/libffi.call/return_ldl.c,
+       testsuite/libffi.call/return_ll1.c,
+       testsuite/libffi.call/stret_large.c,
+       testsuite/libffi.call/stret_large2.c,
+       testsuite/libffi.call/stret_medium.c,
+       testsuite/libffi.call/stret_medium2.c,
+        testsuite/libffi.special/unwindtest.cc: use ffi_closure_alloc instead
+        of checking for MMAP.  Use intptr_t instead of long casts.
+
+2009-06-04  Andrew Haley  <aph@redhat.com>
+
+       * src/powerpc/ffitarget.h: Fix misapplied merge from gcc.
+
+2009-06-04  Andrew Haley  <aph@redhat.com>
+
+       * src/mips/o32.S,
+       src/mips/n32.S: Fix licence formatting.
+
+2009-06-04  Andrew Haley  <aph@redhat.com>
+
+       * src/x86/darwin.S: Fix licence formatting.
+       src/x86/win32.S: Likewise.
+       src/sh64/sysv.S: Likewise.
+       src/sh/sysv.S: Likewise.
+
+2009-06-04  Andrew Haley  <aph@redhat.com>
+
+       * src/sh64/ffi.c: Remove lint directives.  Was missing from merge
+       of Andreas Tobler's patch from 2006-04-22.
+       
+2009-06-04  Andrew Haley  <aph@redhat.com>
+
+       * src/sh/ffi.c: Apply missing hunk from Alexandre Oliva's patch of
+       2007-03-07.
+
+2008-12-26  Timothy Wall  <twall@users.sf.net>
+
+       * testsuite/libffi.call/cls_longdouble.c,
+        testsuite/libffi.call/cls_longdouble_va.c,
+        testsuite/libffi.call/cls_align_longdouble.c,
+        testsuite/libffi.call/cls_align_longdouble_split.c,
+        testsuite/libffi.call/cls_align_longdouble_split2.c: mark expected
+        failures on x86_64 cygwin/mingw.
+
+2008-12-22  Timothy Wall  <twall@users.sf.net>
+
+       * testsuite/libffi.call/closure_fn0.c,
+        testsuite/libffi.call/closure_fn1.c,    
+        testsuite/libffi.call/closure_fn2.c,    
+        testsuite/libffi.call/closure_fn3.c,    
+        testsuite/libffi.call/closure_fn4.c,    
+        testsuite/libffi.call/closure_fn5.c,    
+        testsuite/libffi.call/closure_fn6.c,    
+        testsuite/libffi.call/closure_loc_fn0.c,    
+        testsuite/libffi.call/closure_stdcall.c,    
+        testsuite/libffi.call/cls_align_pointer.c,    
+        testsuite/libffi.call/cls_pointer.c,    
+        testsuite/libffi.call/cls_pointer_stack.c: use portable cast from
+        pointer to integer (intptr_t).
+        * testsuite/libffi.call/cls_longdouble.c: disable for win64.
+       
+2008-12-19  Anthony Green  <green@redhat.com>
+
+       * configure.ac: Bump version to 3.0.8.
+       * configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+       * libtool-version: Increment revision.
+       * README: Update for new release.
+
+2008-11-11  Anthony Green  <green@redhat.com>
+
+       * configure.ac: Bump version to 3.0.7.
+       * configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+       * libtool-version: Increment revision.
+       * README: Update for new release.
+
+2008-08-25  Andreas Tobler  <a.tobler@schweiz.org>
+
+       * src/powerpc/ffitarget.h (ffi_abi): Add FFI_LINUX and
+       FFI_LINUX_SOFT_FLOAT to the POWERPC_FREEBSD enum.
+       Add note about flag bits used for FFI_SYSV_TYPE_SMALL_STRUCT.
+       Adjust copyright notice.
+       * src/powerpc/ffi.c: Add two new flags to indicate if we have one
+       register or two register to use for FFI_SYSV structs.
+       (ffi_prep_cif_machdep): Pass the right register flag introduced above.
+       (ffi_closure_helper_SYSV): Fix the return type for
+       FFI_SYSV_TYPE_SMALL_STRUCT. Comment.
+       Adjust copyright notice.
+
+2008-07-24  Anthony Green  <green@redhat.com>
+
+       * testsuite/libffi.call/cls_dbls_struct.c,
+       testsuite/libffi.call/cls_double_va.c,
+       testsuite/libffi.call/cls_longdouble.c,
+       testsuite/libffi.call/cls_longdouble_va.c,
+       testsuite/libffi.call/cls_pointer.c,
+       testsuite/libffi.call/cls_pointer_stack.c,
+       testsuite/libffi.call/err_bad_abi.c: Clean up failures from
+       compiler warnings.
+
+2008-07-17  Anthony Green  <green@redhat.com>
+
+       * configure.ac: Bump version to 3.0.6.
+       * configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+       * libtool-version: Increment revision.  Add documentation.
+       * README: Update for new release.
+
+2008-07-16  Kaz Kojima  <kkojima@gcc.gnu.org>
+
+       * src/sh/ffi.c (ffi_prep_closure_loc): Turn INSN into an unsigned
+       int.
+
+2008-07-16  Kaz Kojima  <kkojima@gcc.gnu.org>
+
+       * src/sh/sysv.S: Add .note.GNU-stack on Linux.
+       * src/sh64/sysv.S: Likewise.
+
+2008-04-03  Anthony Green  <green@redhat.com>
+
+       * libffi.pc.in (Libs): Add -L${libdir}.
+       * configure.ac: Bump version to 3.0.5.
+       * configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+       * libtool-version: Increment revision.
+       * README: Update for new release.
+
+2008-04-03  Anthony Green  <green@redhat.com>
+           Xerces Ranby  <xerxes@zafena.se>
+
+       * include/ffi.h.in: Wrap definition of target architecture to
+       protect from double definitions.
+
+2008-03-22  Moriyoshi Koizumi  <moriyoshi@gmail.com>
+
+       * src/x86/ffi.c (ffi_prep_closure_loc): Fix for bug revealed in
+       closure_loc_fn0.c.
+       * testsuite/libffi.call/closure_loc_fn0.c (closure_loc_test_fn0):
+       New test.
+
+2008-03-04  Anthony Green  <green@redhat.com>
+           Blake Chaffin
+           hos@tamanegi.org
+
+       * testsuite/libffi.call/cls_align_longdouble_split2.c
+          testsuite/libffi.call/cls_align_longdouble_split.c
+          testsuite/libffi.call/cls_dbls_struct.c
+          testsuite/libffi.call/cls_double_va.c
+          testsuite/libffi.call/cls_longdouble.c
+          testsuite/libffi.call/cls_longdouble_va.c
+          testsuite/libffi.call/cls_pointer.c
+          testsuite/libffi.call/cls_pointer_stack.c
+          testsuite/libffi.call/err_bad_abi.c
+          testsuite/libffi.call/err_bad_typedef.c
+          testsuite/libffi.call/huge_struct.c
+          testsuite/libffi.call/stret_large2.c
+          testsuite/libffi.call/stret_large.c
+          testsuite/libffi.call/stret_medium2.c
+          testsuite/libffi.call/stret_medium.c: New tests from Apple.
+
+2008-02-26  Jakub Jelinek  <jakub@redhat.com>
+            Anthony Green  <green@redhat.com>
+
+       * src/alpha/osf.S: Add .note.GNU-stack on Linux.
+       * src/s390/sysv.S: Likewise.
+       * src/powerpc/linux64.S: Likewise.
+       * src/powerpc/linux64_closure.S: Likewise.
+       * src/powerpc/ppc_closure.S: Likewise.
+       * src/powerpc/sysv.S: Likewise.
+       * src/x86/unix64.S: Likewise.
+       * src/x86/sysv.S: Likewise.
+       * src/sparc/v8.S: Likewise.
+       * src/sparc/v9.S: Likewise.
+       * src/m68k/sysv.S: Likewise.
+       * src/ia64/unix.S: Likewise.
+       * src/arm/sysv.S: Likewise.
+
+2008-02-26  Anthony Green  <green@redhat.com>
+            Thomas Heller  <theller@ctypes.org>
+
+       * src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C
+       comment.
+
+2008-02-26  Anthony Green  <green@redhat.org>
+            Thomas Heller  <theller@ctypes.org>
+
+       * include/ffi.h.in: Change void (*)() to void (*)(void).
+
+2008-02-26  Anthony Green  <green@redhat.org>
+            Thomas Heller  <theller@ctypes.org>
+
+       * src/alpha/ffi.c: Change void (*)() to void (*)(void).
+       src/alpha/osf.S, src/arm/ffi.c, src/frv/ffi.c, src/ia64/ffi.c,
+       src/ia64/unix.S, src/java_raw_api.c, src/m32r/ffi.c,
+       src/mips/ffi.c, src/pa/ffi.c, src/pa/hpux32.S, src/pa/linux.S,
+       src/powerpc/ffi.c, src/powerpc/ffi_darwin.c, src/raw_api.c,
+       src/s390/ffi.c, src/sh/ffi.c, src/sh64/ffi.c, src/sparc/ffi.c,
+       src/x86/ffi.c, src/x86/unix64.S, src/x86/darwin64.S,
+       src/x86/ffi64.c: Ditto.
+
+2008-02-24  Anthony Green  <green@redhat.org>
+
+       * configure.ac: Accept openbsd*, not just openbsd.
+       Bump version to 3.0.4.
+       * configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+       * libtool-version: Increment revision.
+       * README: Update for new release.
+
+2008-02-22  Anthony Green  <green@redhat.com>
+
+       * README: Clean up list of tested platforms.
+
+2008-02-22  Anthony Green  <green@redhat.com>
+
+       * configure.ac: Bump version to 3.0.3.
+       * configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+       * libtool-version: Increment revision.
+       * README: Update for new release.  Clean up test docs.
+
+2008-02-22  Bjoern Koenig  <bkoenig@alpha-tierchen.de>
+           Andreas Tobler  <a.tobler@schweiz.org>
+
+       * configure.ac: Add amd64-*-freebsd* target.
+       * configure: Regenerate.
+
+2008-02-22  Thomas Heller <theller@ctypes.org>
+
+       * configure.ac: Add x86 OpenBSD support.
+       * configure: Rebuilt.
+
+2008-02-21  Thomas Heller <theller@ctypes.org>
+
+       * README: Change "make test" to "make check".
+
+2008-02-21  Anthony Green  <green@redhat.com>
+
+       * configure.ac: Bump version to 3.0.2.
+       * configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+       * libtool-version: Increment revision.
+       * README: Update for new release.
+
+2008-02-21  Björn König <bkoenig@alpha-tierchen.de>
+
+       * src/x86/freebsd.S: New file.
+       * configure.ac: Add x86 FreeBSD support.
+       * Makefile.am: Ditto.
+
+2008-02-15  Anthony Green  <green@redhat.com>
+
+       * configure.ac: Bump version to 3.0.1.
+       * configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+       * libtool-version: Increment revision.
+       * README: Update for new release.
+
+2008-02-15  David Daney         <ddaney@avtrex.com>
+
+       * src/mips/ffi.c: Remove extra '>' from include directive.
+       (ffi_prep_closure_loc): Use clear_location instead of tramp.
+
+2008-02-15  Anthony Green  <green@redhat.com>
+
+       * configure.ac: Bump version to 3.0.0.
+       * configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+
+2008-02-15  David Daney         <ddaney@avtrex.com>
+
+       * src/mips/ffi.c (USE__BUILTIN___CLEAR_CACHE):
+       Define (conditionally), and use it to include cachectl.h.
+       (ffi_prep_closure_loc): Fix cache flushing.
+       * src/mips/ffitarget.h (_ABIN32, _ABI64, _ABIO32): Define.
+
+2008-02-15  Anthony Green  <green@redhat.com>
+
+        * man/ffi_call.3, man/ffi_prep_cif.3, man/ffi.3:
+       Update dates and remove all references to ffi_prep_closure.
+       * configure.ac: Bump version to 2.99.9.
+       * configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+
+2008-02-15  Anthony Green  <green@redhat.com>
+
+       * man/ffi_prep_closure.3: Delete.
+       * man/Makefile.am (EXTRA_DIST): Remove ffi_prep_closure.3.
+       (man_MANS): Ditto.
+       * man/Makefile.in: Rebuilt.
+       * configure.ac: Bump version to 2.99.8.
+       * configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+
+2008-02-14  Anthony Green  <green@redhat.com>
+
+       * configure.ac: Bump version to 2.99.7.
+       * configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+       * include/ffi.h.in LICENSE src/debug.c src/closures.c
+          src/ffitest.c src/s390/sysv.S src/s390/ffitarget.h
+          src/types.c src/m68k/ffitarget.h src/raw_api.c src/frv/ffi.c
+          src/frv/ffitarget.h src/sh/ffi.c src/sh/sysv.S
+          src/sh/ffitarget.h src/powerpc/ffitarget.h src/pa/ffi.c
+          src/pa/ffitarget.h src/pa/linux.S src/java_raw_api.c
+          src/cris/ffitarget.h src/x86/ffi.c src/x86/sysv.S
+          src/x86/unix64.S src/x86/win32.S src/x86/ffitarget.h
+          src/x86/ffi64.c src/x86/darwin.S src/ia64/ffi.c
+          src/ia64/ffitarget.h src/ia64/ia64_flags.h src/ia64/unix.S
+          src/sparc/ffi.c src/sparc/v9.S src/sparc/ffitarget.h
+          src/sparc/v8.S src/alpha/ffi.c src/alpha/ffitarget.h
+          src/alpha/osf.S src/sh64/ffi.c src/sh64/sysv.S
+          src/sh64/ffitarget.h src/mips/ffi.c src/mips/ffitarget.h
+          src/mips/n32.S src/mips/o32.S src/arm/ffi.c src/arm/sysv.S
+          src/arm/ffitarget.h src/prep_cif.c: Update license text.
+
+2008-02-14  Anthony Green  <green@redhat.com>
+
+       * README: Update tested platforms.
+       * configure.ac: Bump version to 2.99.6.
+       * configure: Rebuilt.
+
+2008-02-14  Anthony Green  <green@redhat.com>
+
+       * configure.ac: Bump version to 2.99.5.
+       * configure: Rebuilt.
+       * Makefile.am (EXTRA_DIST): Add darwin64.S
+       * Makefile.in: Rebuilt.
+       * testsuite/lib/libffi-dg.exp: Remove libstdc++ bits from GCC tree.
+       * LICENSE: Update WARRANTY.
+
+2008-02-14  Anthony Green  <green@redhat.com>
+
+       * libffi.pc.in (libdir): Fix libdir definition.
+       * configure.ac: Bump version to 2.99.4.
+       * configure: Rebuilt.
+
+2008-02-14  Anthony Green  <green@redhat.com>
+
+       * README: Update.
+       * libffi.info: New file.
+       * doc/stamp-vti: New file.
+       * configure.ac: Bump version to 2.99.3.
+       * configure: Rebuilt.
+
+2008-02-14  Anthony Green  <green@redhat.com>
+
+       * Makefile.am (SUBDIRS): Add man dir.
+       * Makefile.in: Rebuilt.
+       * configure.ac: Create Makefile.
+       * configure: Rebuilt.
+        * man/ffi_call.3 man/ffi_prep_cif.3 man/ffi_prep_closure.3
+          man/Makefile.am man/Makefile.in: New files.
+
+2008-02-14  Tom Tromey  <tromey@redhat.com>
+
+       * aclocal.m4, Makefile.in, configure, fficonfig.h.in: Rebuilt.
+       * mdate-sh, texinfo.tex: New files.
+       * Makefile.am (info_TEXINFOS): New variable.
+       * doc/libffi.texi: New file.
+       * doc/version.texi: Likewise.
+
+2008-02-14  Anthony Green  <green@redhat.com>
+
+       * Makefile.am (AM_CFLAGS): Don't compile with -D$(TARGET).
+       (lib_LTLIBRARIES): Define.
+       (toolexeclib_LIBRARIES): Undefine.
+       * Makefile.in: Rebuilt.
+       * configure.ac: Reset version to 2.99.1.
+       * configure.in: Rebuilt.
+
+2008-02-14  Anthony Green  <green@redhat.com>
+
+       * libffi.pc.in: Use @PACKAGE_NAME@ and @PACKAGE_VERSION@.
+       * configure.ac: Reset version to 2.99.1.
+       * configure.in: Rebuilt.
+       * Makefile.am (EXTRA_DIST): Add ChangeLog.libffi.
+       * Makefile.in: Rebuilt.
+       * LICENSE: Update copyright notice.
+
+2008-02-14  Anthony Green  <green@redhat.com>
+
+       * include/Makefile.am (nodist_includes_HEADERS): Define.  Don't
+       distribute ffitarget.h or ffi.h from the build include dir.
+       * Makefile.in: Rebuilt.
+
+2008-02-14  Anthony Green  <green@redhat.com>
+
+       * include/Makefile.am (includesdir): Install headers under libdir.
+       (pkgconfigdir): Define. Install libffi.pc.
+       * include/Makefile.in: Rebuilt.
+       * libffi.pc.in: Create.
+       * libtool-version: Increment CURRENT
+       * configure.ac: Add libffi.pc.in
+       * configure: Rebuilt.
+
+2008-02-03  Anthony Green  <green@redhat.com>
+
+       * include/Makefile.am (includesdir): Fix header install with
+       DESTDIR.
+       * include/Makefile.in: Rebuilt.
+
+2008-02-03  Timothy Wall  <twall@users.sf.net>
+
+       * src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL): Calculate jump return
+          offset based on code pointer, not data pointer.
+
+2008-02-01  Anthony Green  <green@redhat.com>
+
+       * include/Makefile.am: Fix header installs.
+       * Makefile.am: Ditto.
+       * include/Makefile.in: Rebuilt.
+       * Makefile.in: Ditto.
+
+2008-02-01  Anthony Green  <green@redhat.com>
+
+       * src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL,
+       FFI_INIT_TRAMPOLINE): Revert my broken changes to twall's last
+       patch.
+
+2008-01-31  Anthony Green  <green@redhat.com>
+
+       * Makefile.am (EXTRA_DIST): Add missing files.
+       * testsuite/Makefile.am: Ditto.
+       * Makefile.in, testsuite/Makefile.in: Rebuilt.
+
+2008-01-31  Timothy Wall <twall@users.sf.net>
+
+       * testsuite/libffi.call/closure_stdcall.c: Add test for stdcall
+       closures.
+       * src/x86/ffitarget.h: Increase size of trampoline for stdcall
+       closures.
+       * src/x86/win32.S: Add assembly for stdcall closure.
+       * src/x86/ffi.c: Initialize stdcall closure trampoline.
+
+2008-01-30  H.J. Lu <hongjiu.lu@intel.com>
+
+       PR libffi/34612
+       * src/x86/sysv.S (ffi_closure_SYSV): Pop 4 byte from stack when
+       returning struct.
+
+       * testsuite/libffi.call/call.exp: Add "-O2 -fomit-frame-pointer"
+       tests.
+
+2008-01-30  Anthony Green  <green@redhat.com>
+
+       * Makefile.am, include/Makefile.am: Move headers to
+       libffi_la_SOURCES for new automake.
+       * Makefile.in, include/Makefile.in: Rebuilt.
+       
+       * testsuite/lib/wrapper.exp: Copied from gcc tree to allow for 
+       execution outside of gcc tree.
+       * testsuite/lib/target-libpath.exp: Ditto.
+
+       * testsuite/lib/libffi-dg.exp: Many changes to allow for execution
+       outside of gcc tree.
+
index 23e002e96454a561b05406dc52b8dcb7eed29378..cda4670614165782de7c6f22941585c81e5c8c7c 100644 (file)
@@ -1,36 +1,45 @@
 ## Process this with automake to create Makefile.in
 
 AUTOMAKE_OPTIONS = foreign subdir-objects
-ACLOCAL_AMFLAGS = -I .. -I ../config
 
 SUBDIRS = include testsuite man
 
-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/avr32/ffi.c src/avr32/sysv.S src/avr32/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 \
-       src/m68k/ffi.c src/m68k/sysv.S src/m68k/ffitarget.h \
-       src/powerpc/ffi.c src/powerpc/sysv.S \
-       src/powerpc/linux64.S src/powerpc/linux64_closure.S \
-       src/powerpc/ppc_closure.S src/powerpc/asm.h \
-       src/powerpc/aix.S src/powerpc/darwin.S \
-       src/powerpc/aix_closure.S src/powerpc/darwin_closure.S \
-       src/powerpc/ffi_darwin.c src/powerpc/ffitarget.h \
-       src/s390/ffi.c src/s390/sysv.S src/s390/ffitarget.h \
-       src/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h \
-       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/darwin64.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/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 src/dlmalloc.c
+EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host      \
+        src/aarch64/ffi.c src/aarch64/ffitarget.h                      \
+        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/avr32/ffi.c src/avr32/sysv.S src/avr32/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 src/m68k/ffi.c src/m68k/sysv.S            \
+        src/m68k/ffitarget.h src/powerpc/ffi.c src/powerpc/sysv.S      \
+        src/powerpc/linux64.S src/powerpc/linux64_closure.S            \
+        src/powerpc/ppc_closure.S src/powerpc/asm.h                    \
+       src/powerpc/aix.S src/powerpc/darwin.S                          \
+       src/powerpc/aix_closure.S src/powerpc/darwin_closure.S          \
+       src/powerpc/ffi_darwin.c src/powerpc/ffitarget.h                \
+       src/s390/ffi.c src/s390/sysv.S src/s390/ffitarget.h             \
+       src/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h 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/darwin64.S src/x86/ffi.c src/x86/sysv.S                 \
+       src/x86/win32.S src/x86/darwin.S src/x86/win64.S                \
+       src/x86/freebsd.S src/x86/ffi64.c src/x86/unix64.S              \
+       src/x86/ffitarget.h src/pa/ffitarget.h src/pa/ffi.c             \
+       src/pa/linux.S src/pa/hpux32.S src/frv/ffi.c src/bfin/ffi.c     \
+       src/bfin/ffitarget.h src/bfin/sysv.S src/frv/eabi.S             \
+       src/frv/ffitarget.h src/dlmalloc.c src/tile/ffi.c               \
+       src/tile/ffitarget.h src/tile/tile.S libtool-version            \
+        ChangeLog.libffi m4/libtool.m4 m4/lt~obsolete.m4               \
+        m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4                  \
+        m4/ltversion.m4 src/arm/gentramp.sh src/debug.c msvcc.sh       \
+       generate-ios-source-and-headers.py                              \
+        generate-osx-source-and-headers.py                             \
+        libffi.xcodeproj/project.pbxproj src/arm/trampoline.S
+
+info_TEXINFOS = doc/libffi.texi
 
 ## ################################################################
 
@@ -84,14 +93,21 @@ MAKEOVERRIDES=
 toolexeclib_LTLIBRARIES = libffi.la
 noinst_LTLIBRARIES = libffi_convenience.la
 
-libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c \
+libffi_la_SOURCES = src/prep_cif.c src/types.c \
                src/raw_api.c src/java_raw_api.c src/closures.c
 
 nodist_libffi_la_SOURCES =
 
+if FFI_DEBUG
+nodist_libffi_la_SOURCES += src/debug.c
+endif
+
 if MIPS
 nodist_libffi_la_SOURCES += src/mips/ffi.c src/mips/o32.S src/mips/n32.S
 endif
+if BFIN
+nodist_libffi_la_SOURCES += src/bfin/ffi.c src/bfin/sysv.S
+endif
 if X86
 nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S
 endif
@@ -134,8 +150,14 @@ endif
 if POWERPC_FREEBSD
 nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
 endif
+if AARCH64
+nodist_libffi_la_SOURCES += src/aarch64/sysv.S src/aarch64/ffi.c
+endif
 if ARM
 nodist_libffi_la_SOURCES += src/arm/sysv.S src/arm/ffi.c
+if FFI_EXEC_TRAMPOLINE_TABLE
+nodist_libffi_la_SOURCES += src/arm/trampoline.S
+endif
 endif
 if AVR32
 nodist_libffi_la_SOURCES += src/avr32/sysv.S src/avr32/ffi.c
@@ -164,6 +186,9 @@ endif
 if PA_HPUX
 nodist_libffi_la_SOURCES += src/pa/hpux32.S src/pa/ffi.c
 endif
+if TILE
+nodist_libffi_la_SOURCES += src/tile/tile.S src/tile/ffi.c
+endif
 
 libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
 nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
index 1da4e89c73675407f65d38bf37f76fd9c6d2cc8d..a0fb7174bbafa6ad453cde3b65b4ff3735b81718 100644 (file)
@@ -1,8 +1,8 @@
 Status
 ======
 
-libffi-3.0.11 was released on *****************. Check the libffi web
-page for updates: <URL:http://sourceware.org/libffi/>.
+libffi-3.0.12 was released on XXXXXXX.  Check the libffi web page for
+updates: <URL:http://sourceware.org/libffi/>.
 
 
 What is libffi?
@@ -48,48 +48,52 @@ refer to the wiki page here:
 At the time of release, the following basic configurations have been
 tested:
 
-|--------------+------------------|
-| Architecture | Operating System |
-|--------------+------------------|
-| Alpha        | Linux            |
-| Alpha        | Tru64            |
-| ARM          | Linux            |
-| ARM          | iOS              |
-| AVR32        | Linux            |
-| HPPA         | HPUX             |
-| IA-64        | Linux            |
-| M68K         | RTEMS            |
-| MIPS         | IRIX             |
-| MIPS         | Linux            |
-| MIPS         | RTEMS            |
-| MIPS64       | Linux            |
-| PowerPC      | AMIGA            |
-| PowerPC      | Linux            |
-| PowerPC      | Mac OSX          |
-| PowerPC      | FreeBSD          |
-| PowerPC64    | Linux            |
-| S390         | Linux            |
-| S390X        | Linux            |
-| SPARC        | Linux            |
-| SPARC        | Solaris          |
-| SPARC64      | Linux            |
-| SPARC64      | FreeBSD          |
-| X86          | FreeBSD          |
-| X86          | Interix          |
-| X86          | kFreeBSD         |
-| X86          | Linux            |
-| X86          | Linux/x32        |
-| X86          | Mac OSX          |
-| X86          | OpenBSD          |
-| X86          | OS/2             |
-| X86          | Solaris          |
-| X86          | Windows/Cygwin   |
-| X86          | Windows/MingW    |
-| X86-64       | FreeBSD          |
-| X86-64       | Linux            |
-| X86-64       | OpenBSD          |
-| X86-64       | Windows/MingW    |
-|--------------+------------------|
+|-----------------+------------------|
+| Architecture    | Operating System |
+|-----------------+------------------|
+| AArch64         | Linux            |
+| Alpha           | Linux            |
+| Alpha           | Tru64            |
+| ARM             | Linux            |
+| ARM             | iOS              |
+| AVR32           | Linux            |
+| Blackfin        | uClinux          |
+| HPPA            | HPUX             |
+| IA-64           | Linux            |
+| M68K            | FreeMiNT         |
+| M68K            | RTEMS            |
+| MIPS            | IRIX             |
+| MIPS            | Linux            |
+| MIPS            | RTEMS            |
+| MIPS64          | Linux            |
+| PowerPC         | AMIGA            |
+| PowerPC         | Linux            |
+| PowerPC         | Mac OSX          |
+| PowerPC         | FreeBSD          |
+| PowerPC64       | Linux            |
+| S390            | Linux            |
+| S390X           | Linux            |
+| SPARC           | Linux            |
+| SPARC           | Solaris          |
+| SPARC64         | Linux            |
+| SPARC64         | FreeBSD          |
+| TILE-Gx/TILEPro | Linux            |
+| X86             | FreeBSD          |
+| X86             | Interix          |
+| X86             | kFreeBSD         |
+| X86             | Linux            |
+| X86             | Mac OSX          |
+| X86             | OpenBSD          |
+| X86             | OS/2             |
+| X86             | Solaris          |
+| X86             | Windows/Cygwin   |
+| X86             | Windows/MingW    |
+| X86-64          | FreeBSD          |
+| X86-64          | Linux            |
+| X86-64          | Linux/x32        |
+| X86-64          | OpenBSD          |
+| X86-64          | Windows/MingW    |
+|-----------------+------------------|
 
 Please send additional platform test results to
 libffi-discuss@sourceware.org and feel free to update the wiki page
@@ -128,7 +132,7 @@ under a MingW environment, you may need to remove the line in configure
 that sets 'fix_srcfile_path' to a 'cygpath' command. ('cygpath' is not
 present in MingW, and is not required when using MingW-style paths.)
 
-For iOS builds, refer to the build-ios.sh script for guidance.
+For iOS builds, the 'libffi.xcodeproj' Xcode project is available.
 
 Configure has many other options. Use "configure --help" to see them all.
 
@@ -146,13 +150,24 @@ History
 
 See the ChangeLog files for details.
 
-3.0.11 MMM-DD-YY
+3.0.12 XXX-XX-XX
+       Add Blackfin support.
+       Add TILE-Gx/TILEPro support.
+       Add AArch64 support.
+       Add support for PaX enabled kernels with MPROTECT.
+
+3.0.11 Apr-11-12
         Lots of build fixes.
-        Add Amiga newer MacOS support.
+       Add Amiga newer MacOS support.
+       Add support for variadic functions (ffi_prep_cif_var).
        Add Linux/x32 support.
-       Add thiscall and fastcall support on Windows.
+       Add thiscall, fastcall and MSVC cdecl support on Windows.
+       Add Amiga and newer MacOS support.
+       Add m68k FreeMiNT support.
+       Integration with iOS' xcode build tools.
        Fix Octeon and MC68881 support.
        Fix code pessimizations.
+       Lots of build fixes.
 
 3.0.10 Aug-23-11
         Add support for Apple's iOS.
@@ -311,8 +326,10 @@ Thorup.
 Major processor architecture ports were contributed by the following
 developers:
 
+aarch64                Marcus Shawcroft, James Greenhalgh
 alpha          Richard Henderson
 arm            Raffaele Sena
+blackfin        Alexandre Keunecke I. de Mendonca
 cris           Simon Posnjak, Hans-Peter Nilsson
 frv            Anthony Green
 ia64           Hans Boehm
@@ -328,6 +345,7 @@ s390                Gerhard Tonn, Ulrich Weigand
 sh             Kaz Kojima
 sh64           Kaz Kojima
 sparc          Anthony Green, Gordon Irlam
+tile-gx/tilepro Walter Lee
 x86            Anthony Green, Jon Beniston
 x86-64         Bo Thorsen
 
index 24b9f4181279cfa5aebf7c58a01569cdf139af11..706bd19163585c0b813ee1ca44c47d394ae6ffe7 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.64 for libffi 3.0.9.
+# Generated by GNU Autoconf 2.64 for libffi 3.0.11.
 #
 # Report bugs to <http://gcc.gnu.org/bugs.html>.
 #
@@ -559,8 +559,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='libffi'
 PACKAGE_TARNAME='libffi'
-PACKAGE_VERSION='3.0.9'
-PACKAGE_STRING='libffi 3.0.9'
+PACKAGE_VERSION='3.0.11'
+PACKAGE_STRING='libffi 3.0.11'
 PACKAGE_BUGREPORT='http://gcc.gnu.org/bugs.html'
 PACKAGE_URL=''
 
@@ -606,10 +606,17 @@ LTLIBOBJS
 LIBOBJS
 toolexeclibdir
 toolexecdir
+FFI_DEBUG_FALSE
+FFI_DEBUG_TRUE
 TARGETDIR
 TARGET
+FFI_EXEC_TRAMPOLINE_TABLE
+FFI_EXEC_TRAMPOLINE_TABLE_FALSE
+FFI_EXEC_TRAMPOLINE_TABLE_TRUE
 HAVE_LONG_DOUBLE
 ALLOCA
+TILE_FALSE
+TILE_TRUE
 PA64_HPUX_FALSE
 PA64_HPUX_TRUE
 PA_HPUX_FALSE
@@ -632,6 +639,8 @@ AVR32_FALSE
 AVR32_TRUE
 ARM_FALSE
 ARM_TRUE
+AARCH64_FALSE
+AARCH64_TRUE
 POWERPC_FREEBSD_FALSE
 POWERPC_FREEBSD_TRUE
 POWERPC_DARWIN_FALSE
@@ -660,6 +669,8 @@ X86_FALSE
 X86_TRUE
 SPARC_FALSE
 SPARC_TRUE
+BFIN_FALSE
+BFIN_TRUE
 MIPS_FALSE
 MIPS_TRUE
 AM_LTLDFLAGS
@@ -795,6 +806,7 @@ enable_fast_install
 with_gnu_ld
 enable_libtool_lock
 enable_maintainer_mode
+enable_pax_emutramp
 enable_debug
 enable_structs
 enable_raw_api
@@ -1348,7 +1360,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 3.0.9 to adapt to many kinds of systems.
+\`configure' configures libffi 3.0.11 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1419,7 +1431,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of libffi 3.0.9:";;
+     short | recursive ) echo "Configuration of libffi 3.0.11:";;
    esac
   cat <<\_ACEOF
 
@@ -1437,6 +1449,7 @@ Optional Features:
   --disable-libtool-lock  avoid locking (might break parallel builds)
   --enable-maintainer-mode  enable make rules and dependencies not useful
                          (and sometimes confusing) to the casual installer
+  --enable-pax_emutramp       enable pax emulated trampolines, for we can't use PROT_EXEC
   --enable-debug          debugging mode
   --disable-structs       omit code for struct support
   --disable-raw-api       make the raw api unavailable
@@ -1527,7 +1540,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-libffi configure 3.0.9
+libffi configure 3.0.11
 generated by GNU Autoconf 2.64
 
 Copyright (C) 2009 Free Software Foundation, Inc.
@@ -2076,7 +2089,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 3.0.9, which was
+It was created by libffi $as_me 3.0.11, which was
 generated by GNU Autoconf 2.64.  Invocation command line was
 
   $ $0 $@
@@ -3043,7 +3056,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='libffi'
- VERSION='3.0.9'
+ VERSION='3.0.11'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -10774,7 +10787,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 10777 "configure"
+#line 10790 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -10880,7 +10893,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 10883 "configure"
+#line 10896 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
 
 TARGETDIR="unknown"
 case "$host" in
+  aarch64*-*-*)
+       TARGET=AARCH64; TARGETDIR=aarch64
+       ;;
+
   alpha*-*-*)
        TARGET=ALPHA; TARGETDIR=alpha;
        # Support 128-bit long double, changeable via command-line switch.
@@ -11329,6 +11346,10 @@ case "$host" in
        ;;
 
   amd64-*-freebsd* | amd64-*-openbsd*)
+       TARGET=X86_64; TARGETDIR=x86
+       ;;
+
+  amd64-*-freebsd*)
        TARGET=X86_64; TARGETDIR=x86
        ;;
 
@@ -11336,6 +11357,10 @@ case "$host" in
        TARGET=AVR32; TARGETDIR=avr32
        ;;
 
+  bfin*)
+       TARGET=BFIN; TARGETDIR=bfin
+       ;;
+
   cris-*-*)
        TARGET=LIBFFI_CRIS; TARGETDIR=cris
        ;;
@@ -11344,7 +11369,7 @@ case "$host" in
        TARGET=FRV; TARGETDIR=frv
        ;;
 
-  hppa*-*-linux* | parisc*-*-linux*)
+  hppa*-*-linux* | parisc*-*-linux* | hppa*-*-openbsd*)
        TARGET=PA_LINUX; TARGETDIR=pa
        ;;
   hppa*64-*-hpux*)
@@ -11357,7 +11382,7 @@ case "$host" in
   i?86-*-freebsd* | i?86-*-openbsd*)
        TARGET=X86_FREEBSD; TARGETDIR=x86
        ;;
-  i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2*)
+  i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2* | i?86-*-interix*)
        TARGET=X86_WIN32; TARGETDIR=x86
        # All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
        # We must also check with_cross_host to decide if this is a native
@@ -11394,7 +11419,7 @@ case "$host" in
   mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
        TARGET=MIPS; TARGETDIR=mips
        ;;
-  mips*-*-linux*)
+  mips*-*-linux* | mips*-*-openbsd*)
        # Support 128-bit long double for NewABI.
        HAVE_LONG_DOUBLE='defined(__mips64)'
        TARGET=MIPS; TARGETDIR=mips
@@ -11403,19 +11428,22 @@ case "$host" in
   powerpc*-*-linux* | powerpc-*-sysv*)
        TARGET=POWERPC; TARGETDIR=powerpc
        ;;
+  powerpc-*-amigaos*)
+       TARGET=POWERPC; TARGETDIR=powerpc
+       ;;
   powerpc-*-beos*)
        TARGET=POWERPC; TARGETDIR=powerpc
        ;;
-  powerpc-*-darwin*)
+  powerpc-*-darwin* | powerpc64-*-darwin*)
        TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
        ;;
   powerpc-*-aix* | rs6000-*-aix*)
        TARGET=POWERPC_AIX; TARGETDIR=powerpc
        ;;
-  powerpc-*-freebsd*)
+  powerpc-*-freebsd* | powerpc-*-openbsd*)
        TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
        ;;
- powerpc64-*-freebsd*)
 powerpc64-*-freebsd*)
        TARGET=POWERPC; TARGETDIR=powerpc
        ;;
   powerpc*-*-rtems*)
@@ -11437,6 +11465,10 @@ case "$host" in
        TARGET=SPARC; TARGETDIR=sparc
        ;;
 
+  tile*-*)
+        TARGET=TILE; TARGETDIR=tile
+        ;;
+
   x86_64-*-darwin*)
        TARGET=X86_DARWIN; TARGETDIR=x86
        ;;
@@ -11474,6 +11506,14 @@ else
   MIPS_FALSE=
 fi
 
+ if test x$TARGET = xBFIN; then
+  BFIN_TRUE=
+  BFIN_FALSE='#'
+else
+  BFIN_TRUE='#'
+  BFIN_FALSE=
+fi
+
  if test x$TARGET = xSPARC; then
   SPARC_TRUE=
   SPARC_FALSE='#'
@@ -11586,6 +11626,14 @@ else
   POWERPC_FREEBSD_FALSE=
 fi
 
+ if test x$TARGET = xAARCH64; then
+  AARCH64_TRUE=
+  AARCH64_FALSE='#'
+else
+  AARCH64_TRUE='#'
+  AARCH64_FALSE=
+fi
+
  if test x$TARGET = xARM; then
   ARM_TRUE=
   ARM_FALSE='#'
@@ -11674,6 +11722,14 @@ else
   PA64_HPUX_FALSE=
 fi
 
+ if test x$TARGET = xTILE; then
+  TILE_TRUE=
+  TILE_FALSE='#'
+else
+  TILE_TRUE='#'
+  TILE_FALSE=
+fi
+
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
 $as_echo_n "checking for ANSI C header files... " >&6; }
@@ -12501,13 +12557,40 @@ $as_echo "#define HAVE_AS_STRING_PSEUDO_OP 1" >>confdefs.h
     fi
 fi
 
+# On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC.
+# Check whether --enable-pax_emutramp was given.
+if test "${enable_pax_emutramp+set}" = set; then :
+  enableval=$enable_pax_emutramp; if test "$enable_pax_emutramp" = "yes"; then
+
+$as_echo "#define FFI_MMAP_EXEC_EMUTRAMP_PAX 1" >>confdefs.h
+
+  fi
+fi
+
+
+FFI_EXEC_TRAMPOLINE_TABLE=0
 case "$target" in
-     *-apple-darwin10* | *-*-freebsd* | *-*-openbsd* | *-pc-solaris*)
+     *arm*-apple-darwin*)
+       FFI_EXEC_TRAMPOLINE_TABLE=1
+
+$as_echo "#define FFI_EXEC_TRAMPOLINE_TABLE 1" >>confdefs.h
+
+     ;;
+     *-apple-darwin1* | *-*-freebsd* | *-*-kfreebsd* | *-*-openbsd* | *-pc-solaris*)
 
 $as_echo "#define FFI_MMAP_EXEC_WRIT 1" >>confdefs.h
 
      ;;
 esac
+ if test x$FFI_EXEC_TRAMPOLINE_TABLE = x1; then
+  FFI_EXEC_TRAMPOLINE_TABLE_TRUE=
+  FFI_EXEC_TRAMPOLINE_TABLE_FALSE='#'
+else
+  FFI_EXEC_TRAMPOLINE_TABLE_TRUE='#'
+  FFI_EXEC_TRAMPOLINE_TABLE_FALSE=
+fi
+
+
 
 if test x$TARGET = xX86_64; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler supports unwind section type" >&5
@@ -12532,67 +12615,69 @@ $as_echo "#define HAVE_AS_X86_64_UNWIND_SECTION_TYPE 1" >>confdefs.h
     fi
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether .eh_frame section should be read-only" >&5
+if test "x$GCC" = "xyes"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether .eh_frame section should be read-only" >&5
 $as_echo_n "checking whether .eh_frame section should be read-only... " >&6; }
 if test "${libffi_cv_ro_eh_frame+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
 
-       libffi_cv_ro_eh_frame=no
-       echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
-       if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then
-           if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then
-               libffi_cv_ro_eh_frame=yes
-           elif grep '.section.*eh_frame.*#alloc' conftest.c \
-                | grep -v '#write' > /dev/null; then
-               libffi_cv_ro_eh_frame=yes
-           fi
-       fi
-       rm -f conftest.*
+       libffi_cv_ro_eh_frame=no
+       echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
+       if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then
+           if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then
+               libffi_cv_ro_eh_frame=yes
+           elif grep '.section.*eh_frame.*#alloc' conftest.c \
+                | grep -v '#write' > /dev/null; then
+               libffi_cv_ro_eh_frame=yes
+           fi
+       fi
+       rm -f conftest.*
 
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_ro_eh_frame" >&5
 $as_echo "$libffi_cv_ro_eh_frame" >&6; }
-if test "x$libffi_cv_ro_eh_frame" = xyes; then
+  if test "x$libffi_cv_ro_eh_frame" = xyes; then
 
 $as_echo "#define HAVE_RO_EH_FRAME 1" >>confdefs.h
 
 
 $as_echo "#define EH_FRAME_FLAGS \"a\"" >>confdefs.h
 
-else
+  else
 
 $as_echo "#define EH_FRAME_FLAGS \"aw\"" >>confdefs.h
 
-fi
+  fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __attribute__((visibility(\"hidden\")))" >&5
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __attribute__((visibility(\"hidden\")))" >&5
 $as_echo_n "checking for __attribute__((visibility(\"hidden\")))... " >&6; }
 if test "${libffi_cv_hidden_visibility_attribute+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
 
-       echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1; }' > conftest.c
-       libffi_cv_hidden_visibility_attribute=no
-       if { ac_try='${CC-cc} -Werror -S conftest.c -o conftest.s 1>&5'
+       echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1  ; }' > conftest.c
+       libffi_cv_hidden_visibility_attribute=no
+       if { ac_try='${CC-cc} -Werror -S conftest.c -o conftest.s 1>&5'
   { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
   (eval $ac_try) 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; }; then
-           if grep '\.hidden.*foo' conftest.s >/dev/null; then
-               libffi_cv_hidden_visibility_attribute=yes
-           fi
-       fi
-       rm -f conftest.*
+           if grep '\.hidden.*foo' conftest.s >/dev/null; then
+               libffi_cv_hidden_visibility_attribute=yes
+           fi
+       fi
+       rm -f conftest.*
 
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_hidden_visibility_attribute" >&5
 $as_echo "$libffi_cv_hidden_visibility_attribute" >&6; }
-if test $libffi_cv_hidden_visibility_attribute = yes; then
+  if test $libffi_cv_hidden_visibility_attribute = yes; then
 
 $as_echo "#define HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 1" >>confdefs.h
 
+  fi
 fi
 
 
@@ -12611,6 +12696,14 @@ $as_echo "#define FFI_DEBUG 1" >>confdefs.h
   fi
 fi
 
+ if test "$enable_debug" = "yes"; then
+  FFI_DEBUG_TRUE=
+  FFI_DEBUG_FALSE='#'
+else
+  FFI_DEBUG_TRUE='#'
+  FFI_DEBUG_FALSE=
+fi
+
 
 # Check whether --enable-structs was given.
 if test "${enable_structs+set}" = set; then :
@@ -12804,6 +12897,10 @@ if test -z "${MIPS_TRUE}" && test -z "${MIPS_FALSE}"; then
   as_fn_error "conditional \"MIPS\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${BFIN_TRUE}" && test -z "${BFIN_FALSE}"; then
+  as_fn_error "conditional \"BFIN\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${SPARC_TRUE}" && test -z "${SPARC_FALSE}"; then
   as_fn_error "conditional \"SPARC\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -12860,6 +12957,10 @@ if test -z "${POWERPC_FREEBSD_TRUE}" && test -z "${POWERPC_FREEBSD_FALSE}"; then
   as_fn_error "conditional \"POWERPC_FREEBSD\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${AARCH64_TRUE}" && test -z "${AARCH64_FALSE}"; then
+  as_fn_error "conditional \"AARCH64\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${ARM_TRUE}" && test -z "${ARM_FALSE}"; then
   as_fn_error "conditional \"ARM\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -12904,7 +13005,19 @@ if test -z "${PA64_HPUX_TRUE}" && test -z "${PA64_HPUX_FALSE}"; then
   as_fn_error "conditional \"PA64_HPUX\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${TILE_TRUE}" && test -z "${TILE_FALSE}"; then
+  as_fn_error "conditional \"TILE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 
+if test -z "${FFI_EXEC_TRAMPOLINE_TABLE_TRUE}" && test -z "${FFI_EXEC_TRAMPOLINE_TABLE_FALSE}"; then
+  as_fn_error "conditional \"FFI_EXEC_TRAMPOLINE_TABLE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${FFI_DEBUG_TRUE}" && test -z "${FFI_DEBUG_FALSE}"; then
+  as_fn_error "conditional \"FFI_DEBUG\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 
 : ${CONFIG_STATUS=./config.status}
 ac_write_fail=0
@@ -13313,7 +13426,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=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 3.0.9, which was
+This file was extended by libffi $as_me 3.0.11, which was
 generated by GNU Autoconf 2.64.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -13381,7 +13494,7 @@ Report bugs to <http://gcc.gnu.org/bugs.html>."
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_version="\\
-libffi config.status 3.0.9
+libffi config.status 3.0.11
 configured by $0, generated by GNU Autoconf 2.64,
   with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
index 5036e25a288c7a23c71d2d29d80beb497b194588..d7ab0666484ad75b9cffe3acfd72ff66ed215f14 100644 (file)
@@ -2,7 +2,7 @@ dnl Process this with autoconf to create configure
 
 AC_PREREQ(2.64)
 
-AC_INIT([libffi], [3.0.9], [http://gcc.gnu.org/bugs.html])
+AC_INIT([libffi], [3.0.11], [http://gcc.gnu.org/bugs.html])
 AC_CONFIG_HEADERS([fficonfig.h])
 
 AM_ENABLE_MULTILIB(, ..)
@@ -41,6 +41,10 @@ AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite)
 
 TARGETDIR="unknown"
 case "$host" in
+  aarch64*-*-*)
+       TARGET=AARCH64; TARGETDIR=aarch64
+       ;;
+
   alpha*-*-*)
        TARGET=ALPHA; TARGETDIR=alpha;
        # Support 128-bit long double, changeable via command-line switch.
@@ -52,6 +56,10 @@ case "$host" in
        ;;
 
   amd64-*-freebsd* | amd64-*-openbsd*)
+       TARGET=X86_64; TARGETDIR=x86
+       ;;
+
+  amd64-*-freebsd*)
        TARGET=X86_64; TARGETDIR=x86
        ;;
 
@@ -59,6 +67,10 @@ case "$host" in
        TARGET=AVR32; TARGETDIR=avr32
        ;;
 
+  bfin*)
+       TARGET=BFIN; TARGETDIR=bfin
+       ;;
+
   cris-*-*)
        TARGET=LIBFFI_CRIS; TARGETDIR=cris
        ;;
@@ -67,7 +79,7 @@ case "$host" in
        TARGET=FRV; TARGETDIR=frv
        ;;
 
-  hppa*-*-linux* | parisc*-*-linux*)
+  hppa*-*-linux* | parisc*-*-linux* | hppa*-*-openbsd*)
        TARGET=PA_LINUX; TARGETDIR=pa
        ;;
   hppa*64-*-hpux*)
@@ -80,7 +92,7 @@ case "$host" in
   i?86-*-freebsd* | i?86-*-openbsd*)
        TARGET=X86_FREEBSD; TARGETDIR=x86
        ;;
-  i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2*)
+  i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2* | i?86-*-interix*)
        TARGET=X86_WIN32; TARGETDIR=x86
        # All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
        # We must also check with_cross_host to decide if this is a native
@@ -117,7 +129,7 @@ case "$host" in
   mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
        TARGET=MIPS; TARGETDIR=mips
        ;;
-  mips*-*-linux*)
+  mips*-*-linux* | mips*-*-openbsd*)
        # Support 128-bit long double for NewABI.
        HAVE_LONG_DOUBLE='defined(__mips64)'
        TARGET=MIPS; TARGETDIR=mips
@@ -126,19 +138,22 @@ case "$host" in
   powerpc*-*-linux* | powerpc-*-sysv*)
        TARGET=POWERPC; TARGETDIR=powerpc
        ;;
+  powerpc-*-amigaos*)
+       TARGET=POWERPC; TARGETDIR=powerpc
+       ;;
   powerpc-*-beos*)
        TARGET=POWERPC; TARGETDIR=powerpc
        ;;
-  powerpc-*-darwin*)
+  powerpc-*-darwin* | powerpc64-*-darwin*)
        TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
        ;;
   powerpc-*-aix* | rs6000-*-aix*)
        TARGET=POWERPC_AIX; TARGETDIR=powerpc
        ;;
-  powerpc-*-freebsd*)
+  powerpc-*-freebsd* | powerpc-*-openbsd*)
        TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
        ;;
- powerpc64-*-freebsd*)
 powerpc64-*-freebsd*)
        TARGET=POWERPC; TARGETDIR=powerpc
        ;;
   powerpc*-*-rtems*)
@@ -160,6 +175,10 @@ case "$host" in
        TARGET=SPARC; TARGETDIR=sparc
        ;;
 
+  tile*-*)
+        TARGET=TILE; TARGETDIR=tile
+        ;;
+
   x86_64-*-darwin*)
        TARGET=X86_DARWIN; TARGETDIR=x86
        ;;
@@ -190,6 +209,7 @@ if test $TARGETDIR = unknown; then
 fi
 
 AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS)
+AM_CONDITIONAL(BFIN, test x$TARGET = xBFIN)
 AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC)
 AM_CONDITIONAL(X86, test x$TARGET = xX86)
 AM_CONDITIONAL(X86_FREEBSD, test x$TARGET = xX86_FREEBSD)
@@ -204,6 +224,7 @@ AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
 AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
 AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
 AM_CONDITIONAL(POWERPC_FREEBSD, test x$TARGET = xPOWERPC_FREEBSD)
+AM_CONDITIONAL(AARCH64, test x$TARGET = xAARCH64)
 AM_CONDITIONAL(ARM, test x$TARGET = xARM)
 AM_CONDITIONAL(AVR32, test x$TARGET = xAVR32)
 AM_CONDITIONAL(LIBFFI_CRIS, test x$TARGET = xLIBFFI_CRIS)
@@ -215,6 +236,7 @@ AM_CONDITIONAL(SH64, test x$TARGET = xSH64)
 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)
+AM_CONDITIONAL(TILE, test x$TARGET = xTILE)
 
 AC_HEADER_STDC
 AC_CHECK_FUNCS(memcpy)
@@ -311,13 +333,30 @@ if test x$TARGET = xX86 || test x$TARGET = xX86_WIN32 || test x$TARGET = xX86_64
     fi
 fi
 
+# On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC.
+AC_ARG_ENABLE(pax_emutramp,
+  [  --enable-pax_emutramp       enable pax emulated trampolines, for we can't use PROT_EXEC],
+  if test "$enable_pax_emutramp" = "yes"; then
+    AC_DEFINE(FFI_MMAP_EXEC_EMUTRAMP_PAX, 1,
+      [Define this if you want to enable pax emulated trampolines])
+  fi)
+
+FFI_EXEC_TRAMPOLINE_TABLE=0
 case "$target" in
-     *-apple-darwin10* | *-*-freebsd* | *-*-openbsd* | *-pc-solaris*)
+     *arm*-apple-darwin*)
+       FFI_EXEC_TRAMPOLINE_TABLE=1
+       AC_DEFINE(FFI_EXEC_TRAMPOLINE_TABLE, 1,
+                 [Cannot use PROT_EXEC on this target, so, we revert to
+                   alternative means])
+     ;;
+     *-apple-darwin1* | *-*-freebsd* | *-*-kfreebsd* | *-*-openbsd* | *-pc-solaris*)
        AC_DEFINE(FFI_MMAP_EXEC_WRIT, 1,
                  [Cannot use malloc on this target, so, we revert to
                    alternative means])
      ;;
 esac
+AM_CONDITIONAL(FFI_EXEC_TRAMPOLINE_TABLE, test x$FFI_EXEC_TRAMPOLINE_TABLE = x1)
+AC_SUBST(FFI_EXEC_TRAMPOLINE_TABLE)
 
 if test x$TARGET = xX86_64; then
     AC_CACHE_CHECK([assembler supports unwind section type],
@@ -334,44 +373,46 @@ if test x$TARGET = xX86_64; then
     fi
 fi
 
-AC_CACHE_CHECK([whether .eh_frame section should be read-only],
-    libffi_cv_ro_eh_frame, [
-       libffi_cv_ro_eh_frame=no
-       echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
-       if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then
-           if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then
-               libffi_cv_ro_eh_frame=yes
-           elif grep '.section.*eh_frame.*#alloc' conftest.c \
-                | grep -v '#write' > /dev/null; then
-               libffi_cv_ro_eh_frame=yes
-           fi
-       fi
-       rm -f conftest.*
-    ])
-if test "x$libffi_cv_ro_eh_frame" = xyes; then
-    AC_DEFINE(HAVE_RO_EH_FRAME, 1,
-             [Define if .eh_frame sections should be read-only.])
-    AC_DEFINE(EH_FRAME_FLAGS, "a",
-             [Define to the flags needed for the .section .eh_frame directive.])
-else
-    AC_DEFINE(EH_FRAME_FLAGS, "aw",
-             [Define to the flags needed for the .section .eh_frame directive.])
-fi
+if test "x$GCC" = "xyes"; then
+  AC_CACHE_CHECK([whether .eh_frame section should be read-only],
+      libffi_cv_ro_eh_frame, [
+       libffi_cv_ro_eh_frame=no
+       echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
+       if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then
+           if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then
+               libffi_cv_ro_eh_frame=yes
+           elif grep '.section.*eh_frame.*#alloc' conftest.c \
+                | grep -v '#write' > /dev/null; then
+               libffi_cv_ro_eh_frame=yes
+           fi
+       fi
+       rm -f conftest.*
+      ])
+  if test "x$libffi_cv_ro_eh_frame" = xyes; then
+      AC_DEFINE(HAVE_RO_EH_FRAME, 1,
+             [Define if .eh_frame sections should be read-only.])
+      AC_DEFINE(EH_FRAME_FLAGS, "a",
+             [Define to the flags needed for the .section .eh_frame directive.  ])
+  else
+      AC_DEFINE(EH_FRAME_FLAGS, "aw",
+             [Define to the flags needed for the .section .eh_frame directive.  ])
+  fi
 
-AC_CACHE_CHECK([for __attribute__((visibility("hidden")))],
-    libffi_cv_hidden_visibility_attribute, [
-       echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1; }' > conftest.c
-       libffi_cv_hidden_visibility_attribute=no
-       if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
-           if grep '\.hidden.*foo' conftest.s >/dev/null; then
-               libffi_cv_hidden_visibility_attribute=yes
-           fi
-       fi
-       rm -f conftest.*
-    ])
-if test $libffi_cv_hidden_visibility_attribute = yes; then
-    AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1,
-             [Define if __attribute__((visibility("hidden"))) is supported.])
+  AC_CACHE_CHECK([for __attribute__((visibility("hidden")))],
+      libffi_cv_hidden_visibility_attribute, [
+       echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1  ; }' > conftest.c
+       libffi_cv_hidden_visibility_attribute=no
+       if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
+           if grep '\.hidden.*foo' conftest.s >/dev/null; then
+               libffi_cv_hidden_visibility_attribute=yes
+           fi
+       fi
+       rm -f conftest.*
+      ])
+  if test $libffi_cv_hidden_visibility_attribute = yes; then
+      AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1,
+             [Define if __attribute__((visibility("hidden"))) is supported.])
+  fi
 fi
 
 AH_BOTTOM([
@@ -400,6 +441,7 @@ AC_ARG_ENABLE(debug,
   if test "$enable_debug" = "yes"; then
     AC_DEFINE(FFI_DEBUG, 1, [Define this if you want extra debugging.])
   fi)
+AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes")
 
 AC_ARG_ENABLE(structs,
 [  --disable-structs       omit code for struct support],
diff --git a/libffi/generate-ios-source-and-headers.py b/libffi/generate-ios-source-and-headers.py
new file mode 100644 (file)
index 0000000..c2bca73
--- /dev/null
@@ -0,0 +1,160 @@
+#!/usr/bin/env python
+
+import subprocess
+import re
+import os
+import errno
+import collections
+import sys
+
+class Platform(object):
+    pass
+
+sdk_re = re.compile(r'.*-sdk ([a-zA-Z0-9.]*)')
+
+def sdkinfo(sdkname):
+    ret = {}
+    for line in subprocess.Popen(['xcodebuild', '-sdk', sdkname, '-version'], stdout=subprocess.PIPE).stdout:
+        kv = line.strip().split(': ', 1)
+        if len(kv) == 2:
+            k,v = kv
+            ret[k] = v
+    return ret
+
+sim_sdk_info = sdkinfo('iphonesimulator')
+device_sdk_info = sdkinfo('iphoneos')
+
+def latest_sdks():
+    latest_sim = None
+    latest_device = None
+    for line in subprocess.Popen(['xcodebuild', '-showsdks'], stdout=subprocess.PIPE).stdout:
+        match = sdk_re.match(line)
+        if match:
+            if 'Simulator' in line:
+                latest_sim = match.group(1)
+            elif 'iOS' in line:
+                latest_device = match.group(1)
+
+    return latest_sim, latest_device
+
+sim_sdk, device_sdk = latest_sdks()
+
+class simulator_platform(Platform):
+    sdk='iphonesimulator'
+    arch = 'i386'
+    name = 'simulator'
+    triple = 'i386-apple-darwin10'
+    sdkroot = sim_sdk_info['Path']
+
+    prefix = "#if !defined(__arm__) && defined(__i386__)\n\n"
+    suffix = "\n\n#endif"
+
+class device_platform(Platform):
+    sdk='iphoneos'
+    name = 'ios'
+    arch = 'armv7'
+    triple = 'arm-apple-darwin10'
+    sdkroot = device_sdk_info['Path']
+
+    prefix = "#ifdef __arm__\n\n"
+    suffix = "\n\n#endif"
+
+
+def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''):
+    if not os.path.exists(dst_dir):
+        os.makedirs(dst_dir)
+
+    out_filename = filename
+
+    if file_suffix:
+        split_name = os.path.splitext(filename)
+        out_filename =  "%s_%s%s" % (split_name[0], file_suffix, split_name[1])
+
+    with open(os.path.join(src_dir, filename)) as in_file:
+        with open(os.path.join(dst_dir, out_filename), 'w') as out_file:
+            if prefix:
+                out_file.write(prefix)
+
+            out_file.write(in_file.read())
+
+            if suffix:
+                out_file.write(suffix)
+
+headers_seen = collections.defaultdict(set)
+
+def move_source_tree(src_dir, dest_dir, dest_include_dir, arch=None, prefix=None, suffix=None):
+    for root, dirs, files in os.walk(src_dir, followlinks=True):
+        relroot = os.path.relpath(root,src_dir)
+
+        def move_dir(arch, prefix='', suffix='', files=[]):
+            for file in files:
+                file_suffix = None
+                if file.endswith('.h'):
+                    if dest_include_dir:
+                        file_suffix = arch
+                        if arch:
+                            headers_seen[file].add(arch)
+                        move_file(root, dest_include_dir, file, arch, prefix=prefix, suffix=suffix)
+
+                elif dest_dir:
+                    outroot = os.path.join(dest_dir, relroot)
+                    move_file(root, outroot, file, prefix=prefix, suffix=suffix)
+
+        if relroot == '.':
+            move_dir(arch=arch,
+                     files=files,
+                     prefix=prefix,
+                     suffix=suffix)
+        elif relroot == 'arm':
+            move_dir(arch='arm',
+                     prefix="#ifdef __arm__\n\n",
+                     suffix="\n\n#endif",
+                     files=files)
+        elif relroot == 'x86':
+            move_dir(arch='i386',
+                     prefix="#if !defined(__arm__) && defined(__i386__)\n\n",
+                     suffix="\n\n#endif",
+                     files=files)
+
+def build_target(platform):
+    def xcrun_cmd(cmd):
+        return subprocess.check_output(['xcrun', '-sdk', platform.sdkroot, '-find', cmd]).strip()
+
+    build_dir = 'build_' + platform.name
+    if not os.path.exists(build_dir):
+        os.makedirs(build_dir)
+        env = dict(CC=xcrun_cmd('clang'),
+                   LD=xcrun_cmd('ld'),
+                   CFLAGS='-arch %s -isysroot %s -miphoneos-version-min=4.0' % (platform.arch, platform.sdkroot))
+        working_dir=os.getcwd()
+        try:
+            os.chdir(build_dir)
+            subprocess.check_call(['../configure', '-host', platform.triple], env=env)
+            move_source_tree('.', None, '../ios/include',
+                             arch=platform.arch,
+                             prefix=platform.prefix,
+                             suffix=platform.suffix)
+            move_source_tree('./include', None, '../ios/include',
+                            arch=platform.arch,
+                            prefix=platform.prefix,
+                            suffix=platform.suffix)
+        finally:
+            os.chdir(working_dir)
+
+        for header_name, archs in headers_seen.iteritems():
+            basename, suffix = os.path.splitext(header_name)
+
+def main():
+    move_source_tree('src', 'ios/src', 'ios/include')
+    move_source_tree('include', None, 'ios/include')
+    build_target(simulator_platform)
+    build_target(device_platform)
+
+    for header_name, archs in headers_seen.iteritems():
+        basename, suffix = os.path.splitext(header_name)
+        with open(os.path.join('ios/include', header_name), 'w') as header:
+            for arch in archs:
+                header.write('#include <%s_%s%s>\n' % (basename, arch, suffix))
+
+if __name__ == '__main__':
+    main()
diff --git a/libffi/generate-osx-source-and-headers.py b/libffi/generate-osx-source-and-headers.py
new file mode 100644 (file)
index 0000000..64313c1
--- /dev/null
@@ -0,0 +1,153 @@
+#!/usr/bin/env python
+import subprocess
+import re
+import os
+import errno
+import collections
+import sys
+
+class Platform(object):
+    pass
+
+sdk_re = re.compile(r'.*-sdk ([a-zA-Z0-9.]*)')
+
+def sdkinfo(sdkname):
+    ret = {}
+    for line in subprocess.Popen(['xcodebuild', '-sdk', sdkname, '-version'], stdout=subprocess.PIPE).stdout:
+        kv = line.strip().split(': ', 1)
+        if len(kv) == 2:
+            k,v = kv
+            ret[k] = v
+    return ret
+
+desktop_sdk_info = sdkinfo('macosx')
+
+def latest_sdks():
+    latest_desktop = None
+    for line in subprocess.Popen(['xcodebuild', '-showsdks'], stdout=subprocess.PIPE).stdout:
+        match = sdk_re.match(line)
+        if match:
+            if 'OS X' in line:
+                latest_desktop = match.group(1)
+
+    return latest_desktop
+
+desktop_sdk = latest_sdks()
+
+class desktop_platform_32(Platform):
+    sdk='macosx'
+    arch = 'i386'
+    name = 'mac32'
+    triple = 'i386-apple-darwin10'
+    sdkroot = desktop_sdk_info['Path']
+
+    prefix = "#if defined(__i386__) && !defined(__x86_64__)\n\n"
+    suffix = "\n\n#endif"
+
+class desktop_platform_64(Platform):
+    sdk='macosx'
+    arch = 'x86_64'
+    name = 'mac'
+    triple = 'x86_64-apple-darwin10'
+    sdkroot = desktop_sdk_info['Path']
+
+    prefix = "#if !defined(__i386__) && defined(__x86_64__)\n\n"
+    suffix = "\n\n#endif"
+
+def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''):
+    if not os.path.exists(dst_dir):
+        os.makedirs(dst_dir)
+
+    out_filename = filename
+
+    if file_suffix:
+        split_name = os.path.splitext(filename)
+        out_filename =  "%s_%s%s" % (split_name[0], file_suffix, split_name[1])
+
+    with open(os.path.join(src_dir, filename)) as in_file:
+        with open(os.path.join(dst_dir, out_filename), 'w') as out_file:
+            if prefix:
+                out_file.write(prefix)
+
+            out_file.write(in_file.read())
+
+            if suffix:
+                out_file.write(suffix)
+
+headers_seen = collections.defaultdict(set)
+
+def move_source_tree(src_dir, dest_dir, dest_include_dir, arch=None, prefix=None, suffix=None):
+    for root, dirs, files in os.walk(src_dir, followlinks=True):
+        relroot = os.path.relpath(root,src_dir)
+
+        def move_dir(arch, prefix='', suffix='', files=[]):
+            for file in files:
+                file_suffix = None
+                if file.endswith('.h'):
+                    if dest_include_dir:
+                        file_suffix = arch
+                        if arch:
+                            headers_seen[file].add(arch)
+                        move_file(root, dest_include_dir, file, arch, prefix=prefix, suffix=suffix)
+
+                elif dest_dir:
+                    outroot = os.path.join(dest_dir, relroot)
+                    move_file(root, outroot, file, prefix=prefix, suffix=suffix)
+
+        if relroot == '.':
+            move_dir(arch=arch,
+                     files=files,
+                     prefix=prefix,
+                     suffix=suffix)
+        elif relroot == 'x86':
+            move_dir(arch='i386',
+                     prefix="#if defined(__i386__) && !defined(__x86_64__)\n\n",
+                     suffix="\n\n#endif",
+                     files=files)
+            move_dir(arch='x86_64',
+                     prefix="#if !defined(__i386__) && defined(__x86_64__)\n\n",
+                     suffix="\n\n#endif",
+                     files=files)
+
+def build_target(platform):
+    def xcrun_cmd(cmd):
+        return subprocess.check_output(['xcrun', '-sdk', platform.sdkroot, '-find', cmd]).strip()
+
+    build_dir = 'build_' + platform.name
+    if not os.path.exists(build_dir):
+        os.makedirs(build_dir)
+        env = dict(CC=xcrun_cmd('clang'),
+                   LD=xcrun_cmd('ld'),
+                   CFLAGS='-arch %s -isysroot %s -mmacosx-version-min=10.6' % (platform.arch, platform.sdkroot))
+        working_dir=os.getcwd()
+        try:
+            os.chdir(build_dir)
+            subprocess.check_call(['../configure', '-host', platform.triple], env=env)
+            move_source_tree('.', None, '../osx/include',
+                             arch=platform.arch,
+                             prefix=platform.prefix,
+                             suffix=platform.suffix)
+            move_source_tree('./include', None, '../osx/include',
+                             arch=platform.arch,
+                             prefix=platform.prefix,
+                             suffix=platform.suffix)
+        finally:
+            os.chdir(working_dir)
+
+        for header_name, archs in headers_seen.iteritems():
+            basename, suffix = os.path.splitext(header_name)
+
+def main():
+    move_source_tree('src', 'osx/src', 'osx/include')
+    move_source_tree('include', None, 'osx/include')
+    build_target(desktop_platform_32)
+    build_target(desktop_platform_64)
+
+    for header_name, archs in headers_seen.iteritems():
+        basename, suffix = os.path.splitext(header_name)
+        with open(os.path.join('osx/include', header_name), 'w') as header:
+            for arch in archs:
+                header.write('#include <%s_%s%s>\n' % (basename, arch, suffix))
+
+if __name__ == '__main__':
+    main()
diff --git a/libffi/libffi.xcodeproj/project.pbxproj b/libffi/libffi.xcodeproj/project.pbxproj
new file mode 100644 (file)
index 0000000..14c39a2
--- /dev/null
@@ -0,0 +1,579 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 46;
+       objects = {
+
+/* Begin PBXBuildFile section */
+               6C43CBDC1534F76F00162364 /* ffi.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBBD1534F76F00162364 /* ffi.c */; };
+               6C43CBDD1534F76F00162364 /* sysv.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBBF1534F76F00162364 /* sysv.S */; };
+               6C43CBDE1534F76F00162364 /* trampoline.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBC01534F76F00162364 /* trampoline.S */; };
+               6C43CBE61534F76F00162364 /* darwin.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBC91534F76F00162364 /* darwin.S */; };
+               6C43CBE81534F76F00162364 /* ffi.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBCB1534F76F00162364 /* ffi.c */; };
+               6C43CC1F1534F77800162364 /* darwin.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC051534F77800162364 /* darwin.S */; };
+               6C43CC201534F77800162364 /* darwin64.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC061534F77800162364 /* darwin64.S */; };
+               6C43CC211534F77800162364 /* ffi.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC071534F77800162364 /* ffi.c */; };
+               6C43CC221534F77800162364 /* ffi64.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC081534F77800162364 /* ffi64.c */; };
+               6C43CC2F1534F7BE00162364 /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC281534F7BE00162364 /* closures.c */; };
+               6C43CC301534F7BE00162364 /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC281534F7BE00162364 /* closures.c */; };
+               6C43CC351534F7BE00162364 /* java_raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2B1534F7BE00162364 /* java_raw_api.c */; };
+               6C43CC361534F7BE00162364 /* java_raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2B1534F7BE00162364 /* java_raw_api.c */; };
+               6C43CC371534F7BE00162364 /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2C1534F7BE00162364 /* prep_cif.c */; };
+               6C43CC381534F7BE00162364 /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2C1534F7BE00162364 /* prep_cif.c */; };
+               6C43CC391534F7BE00162364 /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2D1534F7BE00162364 /* raw_api.c */; };
+               6C43CC3A1534F7BE00162364 /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2D1534F7BE00162364 /* raw_api.c */; };
+               6C43CC3B1534F7BE00162364 /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2E1534F7BE00162364 /* types.c */; };
+               6C43CC3C1534F7BE00162364 /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2E1534F7BE00162364 /* types.c */; };
+               6C43CC971535032600162364 /* ffi.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC8D1535032600162364 /* ffi.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               6C43CC981535032600162364 /* ffi_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC8E1535032600162364 /* ffi_common.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               6C43CC991535032600162364 /* ffi_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC8F1535032600162364 /* ffi_i386.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               6C43CC9A1535032600162364 /* ffi_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC901535032600162364 /* ffi_x86_64.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               6C43CC9B1535032600162364 /* fficonfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC911535032600162364 /* fficonfig.h */; };
+               6C43CC9C1535032600162364 /* fficonfig_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC921535032600162364 /* fficonfig_i386.h */; };
+               6C43CC9D1535032600162364 /* fficonfig_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC931535032600162364 /* fficonfig_x86_64.h */; };
+               6C43CC9E1535032600162364 /* ffitarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC941535032600162364 /* ffitarget.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               6C43CC9F1535032600162364 /* ffitarget_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC951535032600162364 /* ffitarget_i386.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               6C43CCA01535032600162364 /* ffitarget_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC961535032600162364 /* ffitarget_x86_64.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               6C43CCAD1535039600162364 /* ffi.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA21535039600162364 /* ffi.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               6C43CCAE1535039600162364 /* ffi_armv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA31535039600162364 /* ffi_armv7.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               6C43CCAF1535039600162364 /* ffi_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA41535039600162364 /* ffi_common.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               6C43CCB01535039600162364 /* ffi_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA51535039600162364 /* ffi_i386.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               6C43CCB11535039600162364 /* fficonfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA61535039600162364 /* fficonfig.h */; };
+               6C43CCB21535039600162364 /* fficonfig_armv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA71535039600162364 /* fficonfig_armv7.h */; };
+               6C43CCB31535039600162364 /* fficonfig_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA81535039600162364 /* fficonfig_i386.h */; };
+               6C43CCB41535039600162364 /* ffitarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA91535039600162364 /* ffitarget.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               6C43CCB51535039600162364 /* ffitarget_arm.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCAA1535039600162364 /* ffitarget_arm.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               6C43CCB61535039600162364 /* ffitarget_armv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCAB1535039600162364 /* ffitarget_armv7.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               6C43CCB71535039600162364 /* ffitarget_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCAC1535039600162364 /* ffitarget_i386.h */; settings = {ATTRIBUTES = (Public, ); }; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+               6C43CB3D1534E9D100162364 /* libffi.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; };
+               6C43CBBD1534F76F00162364 /* ffi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi.c; sourceTree = "<group>"; };
+               6C43CBBF1534F76F00162364 /* sysv.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sysv.S; sourceTree = "<group>"; };
+               6C43CBC01534F76F00162364 /* trampoline.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = trampoline.S; sourceTree = "<group>"; };
+               6C43CBC91534F76F00162364 /* darwin.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin.S; sourceTree = "<group>"; };
+               6C43CBCB1534F76F00162364 /* ffi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi.c; sourceTree = "<group>"; };
+               6C43CC051534F77800162364 /* darwin.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin.S; sourceTree = "<group>"; };
+               6C43CC061534F77800162364 /* darwin64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin64.S; sourceTree = "<group>"; };
+               6C43CC071534F77800162364 /* ffi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi.c; sourceTree = "<group>"; };
+               6C43CC081534F77800162364 /* ffi64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi64.c; sourceTree = "<group>"; };
+               6C43CC281534F7BE00162364 /* closures.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = closures.c; path = src/closures.c; sourceTree = SOURCE_ROOT; };
+               6C43CC2B1534F7BE00162364 /* java_raw_api.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = java_raw_api.c; path = src/java_raw_api.c; sourceTree = SOURCE_ROOT; };
+               6C43CC2C1534F7BE00162364 /* prep_cif.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = prep_cif.c; path = src/prep_cif.c; sourceTree = SOURCE_ROOT; };
+               6C43CC2D1534F7BE00162364 /* raw_api.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = raw_api.c; path = src/raw_api.c; sourceTree = SOURCE_ROOT; };
+               6C43CC2E1534F7BE00162364 /* types.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = types.c; path = src/types.c; sourceTree = SOURCE_ROOT; };
+               6C43CC8D1535032600162364 /* ffi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi.h; sourceTree = "<group>"; };
+               6C43CC8E1535032600162364 /* ffi_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_common.h; sourceTree = "<group>"; };
+               6C43CC8F1535032600162364 /* ffi_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_i386.h; sourceTree = "<group>"; };
+               6C43CC901535032600162364 /* ffi_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_x86_64.h; sourceTree = "<group>"; };
+               6C43CC911535032600162364 /* fficonfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig.h; sourceTree = "<group>"; };
+               6C43CC921535032600162364 /* fficonfig_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_i386.h; sourceTree = "<group>"; };
+               6C43CC931535032600162364 /* fficonfig_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_x86_64.h; sourceTree = "<group>"; };
+               6C43CC941535032600162364 /* ffitarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget.h; sourceTree = "<group>"; };
+               6C43CC951535032600162364 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = "<group>"; };
+               6C43CC961535032600162364 /* ffitarget_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_x86_64.h; sourceTree = "<group>"; };
+               6C43CCA21535039600162364 /* ffi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi.h; sourceTree = "<group>"; };
+               6C43CCA31535039600162364 /* ffi_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_armv7.h; sourceTree = "<group>"; };
+               6C43CCA41535039600162364 /* ffi_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_common.h; sourceTree = "<group>"; };
+               6C43CCA51535039600162364 /* ffi_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_i386.h; sourceTree = "<group>"; };
+               6C43CCA61535039600162364 /* fficonfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig.h; sourceTree = "<group>"; };
+               6C43CCA71535039600162364 /* fficonfig_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_armv7.h; sourceTree = "<group>"; };
+               6C43CCA81535039600162364 /* fficonfig_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_i386.h; sourceTree = "<group>"; };
+               6C43CCA91535039600162364 /* ffitarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget.h; sourceTree = "<group>"; };
+               6C43CCAA1535039600162364 /* ffitarget_arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_arm.h; sourceTree = "<group>"; };
+               6C43CCAB1535039600162364 /* ffitarget_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_armv7.h; sourceTree = "<group>"; };
+               6C43CCAC1535039600162364 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = "<group>"; };
+               F6F980BA147386130008F121 /* libffi.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+               6C43CB3A1534E9D100162364 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               F6F980B7147386130008F121 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+               6C43CBAF1534F76F00162364 /* iOS */ = {
+                       isa = PBXGroup;
+                       children = (
+                               6C43CCA11535039600162364 /* include */,
+                               6C43CBBB1534F76F00162364 /* src */,
+                       );
+                       name = iOS;
+                       path = ios;
+                       sourceTree = "<group>";
+               };
+               6C43CBBB1534F76F00162364 /* src */ = {
+                       isa = PBXGroup;
+                       children = (
+                               6C43CBC81534F76F00162364 /* x86 */,
+                               6C43CBBC1534F76F00162364 /* arm */,
+                       );
+                       path = src;
+                       sourceTree = "<group>";
+               };
+               6C43CBBC1534F76F00162364 /* arm */ = {
+                       isa = PBXGroup;
+                       children = (
+                               6C43CBBD1534F76F00162364 /* ffi.c */,
+                               6C43CBBF1534F76F00162364 /* sysv.S */,
+                               6C43CBC01534F76F00162364 /* trampoline.S */,
+                       );
+                       path = arm;
+                       sourceTree = "<group>";
+               };
+               6C43CBC81534F76F00162364 /* x86 */ = {
+                       isa = PBXGroup;
+                       children = (
+                               6C43CBC91534F76F00162364 /* darwin.S */,
+                               6C43CBCB1534F76F00162364 /* ffi.c */,
+                       );
+                       path = x86;
+                       sourceTree = "<group>";
+               };
+               6C43CBF01534F77800162364 /* OS X */ = {
+                       isa = PBXGroup;
+                       children = (
+                               6C43CC8C1535032600162364 /* include */,
+                               6C43CBFC1534F77800162364 /* src */,
+                       );
+                       name = "OS X";
+                       path = osx;
+                       sourceTree = "<group>";
+               };
+               6C43CBFC1534F77800162364 /* src */ = {
+                       isa = PBXGroup;
+                       children = (
+                               6C43CC041534F77800162364 /* x86 */,
+                       );
+                       path = src;
+                       sourceTree = "<group>";
+               };
+               6C43CC041534F77800162364 /* x86 */ = {
+                       isa = PBXGroup;
+                       children = (
+                               6C43CC051534F77800162364 /* darwin.S */,
+                               6C43CC061534F77800162364 /* darwin64.S */,
+                               6C43CC071534F77800162364 /* ffi.c */,
+                               6C43CC081534F77800162364 /* ffi64.c */,
+                       );
+                       path = x86;
+                       sourceTree = "<group>";
+               };
+               6C43CC3D1534F7C400162364 /* src */ = {
+                       isa = PBXGroup;
+                       children = (
+                               6C43CC281534F7BE00162364 /* closures.c */,
+                               6C43CC2B1534F7BE00162364 /* java_raw_api.c */,
+                               6C43CC2C1534F7BE00162364 /* prep_cif.c */,
+                               6C43CC2D1534F7BE00162364 /* raw_api.c */,
+                               6C43CC2E1534F7BE00162364 /* types.c */,
+                       );
+                       name = src;
+                       path = ios;
+                       sourceTree = "<group>";
+               };
+               6C43CC8C1535032600162364 /* include */ = {
+                       isa = PBXGroup;
+                       children = (
+                               6C43CC8D1535032600162364 /* ffi.h */,
+                               6C43CC8E1535032600162364 /* ffi_common.h */,
+                               6C43CC8F1535032600162364 /* ffi_i386.h */,
+                               6C43CC901535032600162364 /* ffi_x86_64.h */,
+                               6C43CC911535032600162364 /* fficonfig.h */,
+                               6C43CC921535032600162364 /* fficonfig_i386.h */,
+                               6C43CC931535032600162364 /* fficonfig_x86_64.h */,
+                               6C43CC941535032600162364 /* ffitarget.h */,
+                               6C43CC951535032600162364 /* ffitarget_i386.h */,
+                               6C43CC961535032600162364 /* ffitarget_x86_64.h */,
+                       );
+                       path = include;
+                       sourceTree = "<group>";
+               };
+               6C43CCA11535039600162364 /* include */ = {
+                       isa = PBXGroup;
+                       children = (
+                               6C43CCA21535039600162364 /* ffi.h */,
+                               6C43CCA31535039600162364 /* ffi_armv7.h */,
+                               6C43CCA41535039600162364 /* ffi_common.h */,
+                               6C43CCA51535039600162364 /* ffi_i386.h */,
+                               6C43CCA61535039600162364 /* fficonfig.h */,
+                               6C43CCA71535039600162364 /* fficonfig_armv7.h */,
+                               6C43CCA81535039600162364 /* fficonfig_i386.h */,
+                               6C43CCA91535039600162364 /* ffitarget.h */,
+                               6C43CCAA1535039600162364 /* ffitarget_arm.h */,
+                               6C43CCAB1535039600162364 /* ffitarget_armv7.h */,
+                               6C43CCAC1535039600162364 /* ffitarget_i386.h */,
+                       );
+                       path = include;
+                       sourceTree = "<group>";
+               };
+               F6B0839514721EE50031D8A1 = {
+                       isa = PBXGroup;
+                       children = (
+                               6C43CC3D1534F7C400162364 /* src */,
+                               6C43CBAF1534F76F00162364 /* iOS */,
+                               6C43CBF01534F77800162364 /* OS X */,
+                               F6F980C6147386260008F121 /* Products */,
+                       );
+                       sourceTree = "<group>";
+               };
+               F6F980C6147386260008F121 /* Products */ = {
+                       isa = PBXGroup;
+                       children = (
+                               F6F980BA147386130008F121 /* libffi.a */,
+                               6C43CB3D1534E9D100162364 /* libffi.a */,
+                       );
+                       name = Products;
+                       path = ../..;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+               6C43CB3B1534E9D100162364 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               6C43CC971535032600162364 /* ffi.h in Headers */,
+                               6C43CC981535032600162364 /* ffi_common.h in Headers */,
+                               6C43CC991535032600162364 /* ffi_i386.h in Headers */,
+                               6C43CC9A1535032600162364 /* ffi_x86_64.h in Headers */,
+                               6C43CC9E1535032600162364 /* ffitarget.h in Headers */,
+                               6C43CC9F1535032600162364 /* ffitarget_i386.h in Headers */,
+                               6C43CCA01535032600162364 /* ffitarget_x86_64.h in Headers */,
+                               6C43CC9B1535032600162364 /* fficonfig.h in Headers */,
+                               6C43CC9C1535032600162364 /* fficonfig_i386.h in Headers */,
+                               6C43CC9D1535032600162364 /* fficonfig_x86_64.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               F6F980B8147386130008F121 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               6C43CCAD1535039600162364 /* ffi.h in Headers */,
+                               6C43CCAE1535039600162364 /* ffi_armv7.h in Headers */,
+                               6C43CCAF1535039600162364 /* ffi_common.h in Headers */,
+                               6C43CCB01535039600162364 /* ffi_i386.h in Headers */,
+                               6C43CCB41535039600162364 /* ffitarget.h in Headers */,
+                               6C43CCB51535039600162364 /* ffitarget_arm.h in Headers */,
+                               6C43CCB61535039600162364 /* ffitarget_armv7.h in Headers */,
+                               6C43CCB71535039600162364 /* ffitarget_i386.h in Headers */,
+                               6C43CCB11535039600162364 /* fficonfig.h in Headers */,
+                               6C43CCB21535039600162364 /* fficonfig_armv7.h in Headers */,
+                               6C43CCB31535039600162364 /* fficonfig_i386.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+               6C43CB3C1534E9D100162364 /* libffi OS X */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 6C43CB4A1534E9D100162364 /* Build configuration list for PBXNativeTarget "libffi OS X" */;
+                       buildPhases = (
+                               6C43CC401534FF3B00162364 /* Generate Source and Headers */,
+                               6C43CB391534E9D100162364 /* Sources */,
+                               6C43CB3A1534E9D100162364 /* Frameworks */,
+                               6C43CB3B1534E9D100162364 /* Headers */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = "libffi OS X";
+                       productName = "ffi OS X";
+                       productReference = 6C43CB3D1534E9D100162364 /* libffi.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
+               F6F980B9147386130008F121 /* libffi iOS */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = F6F980C4147386130008F121 /* Build configuration list for PBXNativeTarget "libffi iOS" */;
+                       buildPhases = (
+                               6C43CC3E1534F8E200162364 /* Generate Trampoline */,
+                               6C43CC3F1534FF1B00162364 /* Generate Source and Headers */,
+                               F6F980B6147386130008F121 /* Sources */,
+                               F6F980B7147386130008F121 /* Frameworks */,
+                               F6F980B8147386130008F121 /* Headers */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = "libffi iOS";
+                       productName = ffi;
+                       productReference = F6F980BA147386130008F121 /* libffi.a */;
+                       productType = "com.apple.product-type.library.static";
+               };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+               F6B0839714721EE50031D8A1 /* Project object */ = {
+                       isa = PBXProject;
+                       attributes = {
+                               LastUpgradeCheck = 0430;
+                       };
+                       buildConfigurationList = F6B0839A14721EE50031D8A1 /* Build configuration list for PBXProject "libffi" */;
+                       compatibilityVersion = "Xcode 3.2";
+                       developmentRegion = English;
+                       hasScannedForEncodings = 0;
+                       knownRegions = (
+                               en,
+                       );
+                       mainGroup = F6B0839514721EE50031D8A1;
+                       productRefGroup = F6B0839514721EE50031D8A1;
+                       projectDirPath = "";
+                       projectRoot = "";
+                       targets = (
+                               F6F980B9147386130008F121 /* libffi iOS */,
+                               6C43CB3C1534E9D100162364 /* libffi OS X */,
+                       );
+               };
+/* End PBXProject section */
+
+/* Begin PBXShellScriptBuildPhase section */
+               6C43CC3E1534F8E200162364 /* Generate Trampoline */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Generate Trampoline";
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /usr/bin/python;
+                       shellScript = "import subprocess\nimport re\nimport os\nimport errno\nimport sys\n\ndef main():\n    with open('src/arm/trampoline.S', 'w') as tramp_out:\n        p = subprocess.Popen(['bash', 'src/arm/gentramp.sh'], stdout=tramp_out)\n        p.wait()\n\nif __name__ == '__main__':\n    main()";
+               };
+               6C43CC3F1534FF1B00162364 /* Generate Source and Headers */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Generate Source and Headers";
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "/usr/bin/python generate-ios-source-and-headers.py";
+               };
+               6C43CC401534FF3B00162364 /* Generate Source and Headers */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Generate Source and Headers";
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "/usr/bin/python generate-osx-source-and-headers.py";
+               };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+               6C43CB391534E9D100162364 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               6C43CC1F1534F77800162364 /* darwin.S in Sources */,
+                               6C43CC201534F77800162364 /* darwin64.S in Sources */,
+                               6C43CC211534F77800162364 /* ffi.c in Sources */,
+                               6C43CC221534F77800162364 /* ffi64.c in Sources */,
+                               6C43CC301534F7BE00162364 /* closures.c in Sources */,
+                               6C43CC361534F7BE00162364 /* java_raw_api.c in Sources */,
+                               6C43CC381534F7BE00162364 /* prep_cif.c in Sources */,
+                               6C43CC3A1534F7BE00162364 /* raw_api.c in Sources */,
+                               6C43CC3C1534F7BE00162364 /* types.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               F6F980B6147386130008F121 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               6C43CBDC1534F76F00162364 /* ffi.c in Sources */,
+                               6C43CBDD1534F76F00162364 /* sysv.S in Sources */,
+                               6C43CBDE1534F76F00162364 /* trampoline.S in Sources */,
+                               6C43CBE61534F76F00162364 /* darwin.S in Sources */,
+                               6C43CBE81534F76F00162364 /* ffi.c in Sources */,
+                               6C43CC2F1534F7BE00162364 /* closures.c in Sources */,
+                               6C43CC351534F7BE00162364 /* java_raw_api.c in Sources */,
+                               6C43CC371534F7BE00162364 /* prep_cif.c in Sources */,
+                               6C43CC391534F7BE00162364 /* raw_api.c in Sources */,
+                               6C43CC3B1534F7BE00162364 /* types.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+               6C43CB4B1534E9D100162364 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+                               DSTROOT = /tmp/ffi.dst;
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"",
+                               );
+                               GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+                               GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               MACOSX_DEPLOYMENT_TARGET = 10.6;
+                               ONLY_ACTIVE_ARCH = YES;
+                               PRODUCT_NAME = ffi;
+                               SDKROOT = macosx;
+                       };
+                       name = Debug;
+               };
+               6C43CB4C1534E9D100162364 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               DSTROOT = /tmp/ffi.dst;
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"",
+                               );
+                               GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+                               GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               MACOSX_DEPLOYMENT_TARGET = 10.6;
+                               PRODUCT_NAME = ffi;
+                               SDKROOT = macosx;
+                       };
+                       name = Release;
+               };
+               F6B083AB14721EE50031D8A1 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+                               COPY_PHASE_STRIP = NO;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "DEBUG=1",
+                                       "$(inherited)",
+                               );
+                               GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+                               GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNUSED_VALUE = NO;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = ios/include;
+                               SDKROOT = iphoneos;
+                       };
+                       name = Debug;
+               };
+               F6B083AC14721EE50031D8A1 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+                               COPY_PHASE_STRIP = YES;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_PREPROCESSOR_DEFINITIONS = "";
+                               GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNUSED_VALUE = NO;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = ios/include;
+                               SDKROOT = iphoneos;
+                               VALIDATE_PRODUCT = YES;
+                       };
+                       name = Release;
+               };
+               F6F980C2147386130008F121 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ARCHS = (
+                                       armv6,
+                                       armv7,
+                               );
+                               DSTROOT = /tmp/ffi.dst;
+                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
+                               GCC_THUMB_SUPPORT = NO;
+                               IPHONEOS_DEPLOYMENT_TARGET = 4.0;
+                               OTHER_LDFLAGS = "-ObjC";
+                               PRODUCT_NAME = ffi;
+                               SKIP_INSTALL = YES;
+                       };
+                       name = Debug;
+               };
+               F6F980C3147386130008F121 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ARCHS = (
+                                       armv6,
+                                       armv7,
+                               );
+                               DSTROOT = /tmp/ffi.dst;
+                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
+                               GCC_THUMB_SUPPORT = NO;
+                               IPHONEOS_DEPLOYMENT_TARGET = 4.0;
+                               OTHER_LDFLAGS = "-ObjC";
+                               PRODUCT_NAME = ffi;
+                               SKIP_INSTALL = YES;
+                       };
+                       name = Release;
+               };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+               6C43CB4A1534E9D100162364 /* Build configuration list for PBXNativeTarget "libffi OS X" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               6C43CB4B1534E9D100162364 /* Debug */,
+                               6C43CB4C1534E9D100162364 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               F6B0839A14721EE50031D8A1 /* Build configuration list for PBXProject "libffi" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               F6B083AB14721EE50031D8A1 /* Debug */,
+                               F6B083AC14721EE50031D8A1 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               F6F980C4147386130008F121 /* Build configuration list for PBXNativeTarget "libffi iOS" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               F6F980C2147386130008F121 /* Debug */,
+                               F6F980C3147386130008F121 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+/* End XCConfigurationList section */
+       };
+       rootObject = F6B0839714721EE50031D8A1 /* Project object */;
+}
index 25192774887b313893a01c5259233d90ab1db8b4..afcbfb69f1d3de0cce6c171f357c5927972db76b 100644 (file)
@@ -2,7 +2,7 @@
 
 AUTOMAKE_OPTIONS=foreign
 
-EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3
+EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3
 
-man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3
+man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3
 
index 79466b353b91a3504e86ac826cae7b9e02c3b21e..199fea6f4eff51956738c4643aabf1682663bf62 100644 (file)
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
 @SET_MAKE@
 VPATH = @srcdir@
+am__make_dryrun = \
+  { \
+    am__dry=no; \
+    case $$MAKEFLAGS in \
+      *\\[\ \  ]*) \
+        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
+          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+      *) \
+        for am__flg in $$MAKEFLAGS; do \
+          case $$am__flg in \
+            *=*|--*) ;; \
+            *n*) am__dry=yes; break;; \
+          esac; \
+        done;; \
+    esac; \
+    test $$am__dry = yes; \
+  }
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -37,22 +54,32 @@ target_triplet = @target@
 subdir = man
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
-       $(top_srcdir)/../config/lead-dot.m4 \
-       $(top_srcdir)/../config/multi.m4 \
-       $(top_srcdir)/../config/override.m4 \
-       $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
-       $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
-       $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \
+       $(top_srcdir)/m4/ax_cc_maxopt.m4 \
+       $(top_srcdir)/m4/ax_cflags_warn_all.m4 \
+       $(top_srcdir)/m4/ax_check_compile_flag.m4 \
+       $(top_srcdir)/m4/ax_compiler_vendor.m4 \
+       $(top_srcdir)/m4/ax_configure_args.m4 \
+       $(top_srcdir)/m4/ax_enable_builddir.m4 \
+       $(top_srcdir)/m4/ax_gcc_archflag.m4 \
+       $(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \
+       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+       $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+       $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
        $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/fficonfig.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 SOURCES =
 DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -74,6 +101,12 @@ am__nobase_list = $(am__nobase_strip_setup); \
 am__base_list = \
   sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
   sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
 man3dir = $(mandir)/man3
 am__installdirs = "$(DESTDIR)$(man3dir)"
 NROFF = nroff
@@ -100,6 +133,7 @@ CPPFLAGS = @CPPFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
@@ -107,6 +141,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@
 FGREP = @FGREP@
 GREP = @GREP@
 HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@
@@ -125,6 +160,7 @@ LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
 NM = @NM@
 NMEDIT = @NMEDIT@
@@ -140,6 +176,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
 PACKAGE_URL = @PACKAGE_URL@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
+PRTDIAG = @PRTDIAG@
 RANLIB = @RANLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
@@ -152,6 +189,7 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
@@ -159,6 +197,7 @@ am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_enable_builddir_sed = @ax_enable_builddir_sed@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
@@ -186,7 +225,6 @@ localedir = @localedir@
 localstatedir = @localstatedir@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
-multi_basedir = @multi_basedir@
 oldincludedir = @oldincludedir@
 pdfdir = @pdfdir@
 prefix = @prefix@
@@ -195,6 +233,7 @@ psdir = @psdir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+sys_symbol_underscore = @sys_symbol_underscore@
 sysconfdir = @sysconfdir@
 target = @target@
 target_alias = @target_alias@
@@ -207,8 +246,8 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 AUTOMAKE_OPTIONS = foreign
-EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3
-man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3
+EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3
+man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3
 all: all-am
 
 .SUFFIXES:
@@ -250,11 +289,18 @@ clean-libtool:
        -rm -rf .libs _libs
 install-man3: $(man_MANS)
        @$(NORMAL_INSTALL)
-       test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)"
-       @list=''; test -n "$(man3dir)" || exit 0; \
-       { for i in $$list; do echo "$$i"; done; \
-       l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
-         sed -n '/\.3[a-z]*$$/p'; \
+       @list1=''; \
+       list2='$(man_MANS)'; \
+       test -n "$(man3dir)" \
+         && test -n "`echo $$list1$$list2`" \
+         || exit 0; \
+       echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \
+       $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \
+       { for i in $$list1; do echo "$$i"; done;  \
+       if test -n "$$list2"; then \
+         for i in $$list2; do echo "$$i"; done \
+           | sed -n '/\.3[a-z]*$$/p'; \
+       fi; \
        } | while read p; do \
          if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
          echo "$$d$$p"; echo "$$p"; \
@@ -283,9 +329,7 @@ uninstall-man3:
          sed -n '/\.3[a-z]*$$/p'; \
        } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
              -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
-       test -z "$$files" || { \
-         echo " ( cd '$(DESTDIR)$(man3dir)' && rm -f" $$files ")"; \
-         cd "$(DESTDIR)$(man3dir)" && rm -f $$files; }
+       dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir)
 tags: TAGS
 TAGS:
 
@@ -353,10 +397,15 @@ install-am: all-am
 
 installcheck: installcheck-am
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-         `test -z '$(STRIP)' || \
-           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+       if test -z '$(STRIP)'; then \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+             install; \
+       else \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+           "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+       fi
 mostlyclean-generic:
 
 clean-generic:
diff --git a/libffi/src/aarch64/ffi.c b/libffi/src/aarch64/ffi.c
new file mode 100644 (file)
index 0000000..1405665
--- /dev/null
@@ -0,0 +1,1076 @@
+/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
+
+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
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#include <stdio.h>
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* Stack alignment requirement in bytes */
+#define AARCH64_STACK_ALIGN 16
+
+#define N_X_ARG_REG 8
+#define N_V_ARG_REG 8
+
+#define AARCH64_FFI_WITH_V (1 << AARCH64_FFI_WITH_V_BIT)
+
+union _d
+{
+  UINT64 d;
+  UINT32 s[2];
+};
+
+struct call_context
+{
+  UINT64 x [AARCH64_N_XREG];
+  struct
+  {
+    union _d d[2];
+  } v [AARCH64_N_VREG];
+};
+
+static void *
+get_x_addr (struct call_context *context, unsigned n)
+{
+  return &context->x[n];
+}
+
+static void *
+get_s_addr (struct call_context *context, unsigned n)
+{
+#if defined __AARCH64EB__
+  return &context->v[n].d[1].s[1];
+#else
+  return &context->v[n].d[0].s[0];
+#endif
+}
+
+static void *
+get_d_addr (struct call_context *context, unsigned n)
+{
+#if defined __AARCH64EB__
+  return &context->v[n].d[1];
+#else
+  return &context->v[n].d[0];
+#endif
+}
+
+static void *
+get_v_addr (struct call_context *context, unsigned n)
+{
+  return &context->v[n];
+}
+
+/* Return the memory location at which a basic type would reside
+   were it to have been stored in register n.  */
+
+static void *
+get_basic_type_addr (unsigned short type, struct call_context *context,
+                    unsigned n)
+{
+  switch (type)
+    {
+    case FFI_TYPE_FLOAT:
+      return get_s_addr (context, n);
+    case FFI_TYPE_DOUBLE:
+      return get_d_addr (context, n);
+    case FFI_TYPE_LONGDOUBLE:
+      return get_v_addr (context, n);
+    case FFI_TYPE_UINT8:
+    case FFI_TYPE_SINT8:
+    case FFI_TYPE_UINT16:
+    case FFI_TYPE_SINT16:
+    case FFI_TYPE_UINT32:
+    case FFI_TYPE_SINT32:
+    case FFI_TYPE_INT:
+    case FFI_TYPE_POINTER:
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_SINT64:
+      return get_x_addr (context, n);
+    default:
+      FFI_ASSERT (0);
+      return NULL;
+    }
+}
+
+/* Return the alignment width for each of the basic types.  */
+
+static size_t
+get_basic_type_alignment (unsigned short type)
+{
+  switch (type)
+    {
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+      return sizeof (UINT64);
+    case FFI_TYPE_LONGDOUBLE:
+      return sizeof (long double);
+    case FFI_TYPE_UINT8:
+    case FFI_TYPE_SINT8:
+    case FFI_TYPE_UINT16:
+    case FFI_TYPE_SINT16:
+    case FFI_TYPE_UINT32:
+    case FFI_TYPE_INT:
+    case FFI_TYPE_SINT32:
+    case FFI_TYPE_POINTER:
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_SINT64:
+      return sizeof (UINT64);
+
+    default:
+      FFI_ASSERT (0);
+      return 0;
+    }
+}
+
+/* Return the size in bytes for each of the basic types.  */
+
+static size_t
+get_basic_type_size (unsigned short type)
+{
+  switch (type)
+    {
+    case FFI_TYPE_FLOAT:
+      return sizeof (UINT32);
+    case FFI_TYPE_DOUBLE:
+      return sizeof (UINT64);
+    case FFI_TYPE_LONGDOUBLE:
+      return sizeof (long double);
+    case FFI_TYPE_UINT8:
+      return sizeof (UINT8);
+    case FFI_TYPE_SINT8:
+      return sizeof (SINT8);
+    case FFI_TYPE_UINT16:
+      return sizeof (UINT16);
+    case FFI_TYPE_SINT16:
+      return sizeof (SINT16);
+    case FFI_TYPE_UINT32:
+      return sizeof (UINT32);
+    case FFI_TYPE_INT:
+    case FFI_TYPE_SINT32:
+      return sizeof (SINT32);
+    case FFI_TYPE_POINTER:
+    case FFI_TYPE_UINT64:
+      return sizeof (UINT64);
+    case FFI_TYPE_SINT64:
+      return sizeof (SINT64);
+
+    default:
+      FFI_ASSERT (0);
+      return 0;
+    }
+}
+
+extern void
+ffi_call_SYSV (unsigned (*)(struct call_context *context, unsigned char *,
+                           extended_cif *),
+               struct call_context *context,
+               extended_cif *,
+               unsigned,
+               void (*fn)(void));
+
+extern void
+ffi_closure_SYSV (ffi_closure *);
+
+/* Test for an FFI floating point representation.  */
+
+static unsigned
+is_floating_type (unsigned short type)
+{
+  return (type == FFI_TYPE_FLOAT || type == FFI_TYPE_DOUBLE
+         || type == FFI_TYPE_LONGDOUBLE);
+}
+
+/* Test for a homogeneous structure.  */
+
+static unsigned short
+get_homogeneous_type (ffi_type *ty)
+{
+  if (ty->type == FFI_TYPE_STRUCT && ty->elements)
+    {
+      unsigned i;
+      unsigned short candidate_type
+       = get_homogeneous_type (ty->elements[0]);
+      for (i =1; ty->elements[i]; i++)
+       {
+         unsigned short iteration_type = 0;
+         /* If we have a nested struct, we must find its homogeneous type.
+            If that fits with our candidate type, we are still
+            homogeneous.  */
+         if (ty->elements[i]->type == FFI_TYPE_STRUCT
+             && ty->elements[i]->elements)
+           {
+             iteration_type = get_homogeneous_type (ty->elements[i]);
+           }
+         else
+           {
+             iteration_type = ty->elements[i]->type;
+           }
+
+         /* If we are not homogeneous, return FFI_TYPE_STRUCT.  */
+         if (candidate_type != iteration_type)
+           return FFI_TYPE_STRUCT;
+       }
+      return candidate_type;
+    }
+
+  /* Base case, we have no more levels of nesting, so we
+     are a basic type, and so, trivially homogeneous in that type.  */
+  return ty->type;
+}
+
+/* Determine the number of elements within a STRUCT.
+
+   Note, we must handle nested structs.
+
+   If ty is not a STRUCT this function will return 0.  */
+
+static unsigned
+element_count (ffi_type *ty)
+{
+  if (ty->type == FFI_TYPE_STRUCT && ty->elements)
+    {
+      unsigned n;
+      unsigned elems = 0;
+      for (n = 0; ty->elements[n]; n++)
+       {
+         if (ty->elements[n]->type == FFI_TYPE_STRUCT
+             && ty->elements[n]->elements)
+           elems += element_count (ty->elements[n]);
+         else
+           elems++;
+       }
+      return elems;
+    }
+  return 0;
+}
+
+/* Test for a homogeneous floating point aggregate.
+
+   A homogeneous floating point aggregate is a homogeneous aggregate of
+   a half- single- or double- precision floating point type with one
+   to four elements.  Note that this includes nested structs of the
+   basic type.  */
+
+static int
+is_hfa (ffi_type *ty)
+{
+  if (ty->type == FFI_TYPE_STRUCT
+      && ty->elements[0]
+      && is_floating_type (get_homogeneous_type (ty)))
+    {
+      unsigned n = element_count (ty);
+      return n >= 1 && n <= 4;
+    }
+  return 0;
+}
+
+/* Test if an ffi_type is a candidate for passing in a register.
+
+   This test does not check that sufficient registers of the
+   appropriate class are actually available, merely that IFF
+   sufficient registers are available then the argument will be passed
+   in register(s).
+
+   Note that an ffi_type that is deemed to be a register candidate
+   will always be returned in registers.
+
+   Returns 1 if a register candidate else 0.  */
+
+static int
+is_register_candidate (ffi_type *ty)
+{
+  switch (ty->type)
+    {
+    case FFI_TYPE_VOID:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+    case FFI_TYPE_LONGDOUBLE:
+    case FFI_TYPE_UINT8:
+    case FFI_TYPE_UINT16:
+    case FFI_TYPE_UINT32:
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_POINTER:
+    case FFI_TYPE_SINT8:
+    case FFI_TYPE_SINT16:
+    case FFI_TYPE_SINT32:
+    case FFI_TYPE_INT:
+    case FFI_TYPE_SINT64:
+      return 1;
+
+    case FFI_TYPE_STRUCT:
+      if (is_hfa (ty))
+        {
+          return 1;
+        }
+      else if (ty->size > 16)
+        {
+          /* Too large. Will be replaced with a pointer to memory. The
+             pointer MAY be passed in a register, but the value will
+             not. This test specifically fails since the argument will
+             never be passed by value in registers. */
+          return 0;
+        }
+      else
+        {
+          /* Might be passed in registers depending on the number of
+             registers required. */
+          return (ty->size + 7) / 8 < N_X_ARG_REG;
+        }
+      break;
+
+    default:
+      FFI_ASSERT (0);
+      break;
+    }
+
+  return 0;
+}
+
+/* Test if an ffi_type argument or result is a candidate for a vector
+   register.  */
+
+static int
+is_v_register_candidate (ffi_type *ty)
+{
+  return is_floating_type (ty->type)
+          || (ty->type == FFI_TYPE_STRUCT && is_hfa (ty));
+}
+
+/* Representation of the procedure call argument marshalling
+   state.
+
+   The terse state variable names match the names used in the AARCH64
+   PCS. */
+
+struct arg_state
+{
+  unsigned ngrn;                /* Next general-purpose register number. */
+  unsigned nsrn;                /* Next vector register number. */
+  unsigned nsaa;                /* Next stack offset. */
+};
+
+/* Initialize a procedure call argument marshalling state.  */
+static void
+arg_init (struct arg_state *state, unsigned call_frame_size)
+{
+  state->ngrn = 0;
+  state->nsrn = 0;
+  state->nsaa = 0;
+}
+
+/* Return the number of available consecutive core argument
+   registers.  */
+
+static unsigned
+available_x (struct arg_state *state)
+{
+  return N_X_ARG_REG - state->ngrn;
+}
+
+/* Return the number of available consecutive vector argument
+   registers.  */
+
+static unsigned
+available_v (struct arg_state *state)
+{
+  return N_V_ARG_REG - state->nsrn;
+}
+
+static void *
+allocate_to_x (struct call_context *context, struct arg_state *state)
+{
+  FFI_ASSERT (state->ngrn < N_X_ARG_REG)
+  return get_x_addr (context, (state->ngrn)++);
+}
+
+static void *
+allocate_to_s (struct call_context *context, struct arg_state *state)
+{
+  FFI_ASSERT (state->nsrn < N_V_ARG_REG)
+  return get_s_addr (context, (state->nsrn)++);
+}
+
+static void *
+allocate_to_d (struct call_context *context, struct arg_state *state)
+{
+  FFI_ASSERT (state->nsrn < N_V_ARG_REG)
+  return get_d_addr (context, (state->nsrn)++);
+}
+
+static void *
+allocate_to_v (struct call_context *context, struct arg_state *state)
+{
+  FFI_ASSERT (state->nsrn < N_V_ARG_REG)
+  return get_v_addr (context, (state->nsrn)++);
+}
+
+/* Allocate an aligned slot on the stack and return a pointer to it.  */
+static void *
+allocate_to_stack (struct arg_state *state, void *stack, unsigned alignment,
+                  unsigned size)
+{
+  void *allocation;
+
+  /* Round up the NSAA to the larger of 8 or the natural
+     alignment of the argument's type.  */
+  state->nsaa = ALIGN (state->nsaa, alignment);
+  state->nsaa = ALIGN (state->nsaa, alignment);
+  state->nsaa = ALIGN (state->nsaa, 8);
+
+  allocation = stack + state->nsaa;
+
+  state->nsaa += size;
+  return allocation;
+}
+
+static void
+copy_basic_type (void *dest, void *source, unsigned short type)
+{
+  /* This is neccessary to ensure that basic types are copied
+     sign extended to 64-bits as libffi expects.  */
+  switch (type)
+    {
+    case FFI_TYPE_FLOAT:
+      *(float *) dest = *(float *) source;
+      break;
+    case FFI_TYPE_DOUBLE:
+      *(double *) dest = *(double *) source;
+      break;
+    case FFI_TYPE_LONGDOUBLE:
+      *(long double *) dest = *(long double *) source;
+      break;
+    case FFI_TYPE_UINT8:
+      *(ffi_arg *) dest = *(UINT8 *) source;
+      break;
+    case FFI_TYPE_SINT8:
+      *(ffi_sarg *) dest = *(SINT8 *) source;
+      break;
+    case FFI_TYPE_UINT16:
+      *(ffi_arg *) dest = *(UINT16 *) source;
+      break;
+    case FFI_TYPE_SINT16:
+      *(ffi_sarg *) dest = *(SINT16 *) source;
+      break;
+    case FFI_TYPE_UINT32:
+      *(ffi_arg *) dest = *(UINT32 *) source;
+      break;
+    case FFI_TYPE_INT:
+    case FFI_TYPE_SINT32:
+      *(ffi_sarg *) dest = *(SINT32 *) source;
+      break;
+    case FFI_TYPE_POINTER:
+    case FFI_TYPE_UINT64:
+      *(ffi_arg *) dest = *(UINT64 *) source;
+      break;
+    case FFI_TYPE_SINT64:
+      *(ffi_sarg *) dest = *(SINT64 *) source;
+      break;
+
+    default:
+      FFI_ASSERT (0);
+    }
+}
+
+static void
+copy_hfa_to_reg_or_stack (void *memory,
+                         ffi_type *ty,
+                         struct call_context *context,
+                         unsigned char *stack,
+                         struct arg_state *state)
+{
+  unsigned elems = element_count (ty);
+  if (available_v (state) < elems)
+    {
+      /* There are insufficient V registers. Further V register allocations
+        are prevented, the NSAA is adjusted (by allocate_to_stack ())
+        and the argument is copied to memory at the adjusted NSAA.  */
+      state->nsrn = N_V_ARG_REG;
+      memcpy (allocate_to_stack (state, stack, ty->alignment, ty->size),
+             memory,
+             ty->size);
+    }
+  else
+    {
+      int i;
+      unsigned short type = get_homogeneous_type (ty);
+      unsigned elems = element_count (ty);
+      for (i = 0; i < elems; i++)
+       {
+         void *reg = allocate_to_v (context, state);
+         copy_basic_type (reg, memory, type);
+         memory += get_basic_type_size (type);
+       }
+    }
+}
+
+/* Either allocate an appropriate register for the argument type, or if
+   none are available, allocate a stack slot and return a pointer
+   to the allocated space.  */
+
+static void *
+allocate_to_register_or_stack (struct call_context *context,
+                              unsigned char *stack,
+                              struct arg_state *state,
+                              unsigned short type)
+{
+  size_t alignment = get_basic_type_alignment (type);
+  size_t size = alignment;
+  switch (type)
+    {
+    case FFI_TYPE_FLOAT:
+      /* This is the only case for which the allocated stack size
+        should not match the alignment of the type.  */
+      size = sizeof (UINT32);
+      /* Fall through.  */
+    case FFI_TYPE_DOUBLE:
+      if (state->nsrn < N_V_ARG_REG)
+       return allocate_to_d (context, state);
+      state->nsrn = N_V_ARG_REG;
+      break;
+    case FFI_TYPE_LONGDOUBLE:
+      if (state->nsrn < N_V_ARG_REG)
+       return allocate_to_v (context, state);
+      state->nsrn = N_V_ARG_REG;
+      break;
+    case FFI_TYPE_UINT8:
+    case FFI_TYPE_SINT8:
+    case FFI_TYPE_UINT16:
+    case FFI_TYPE_SINT16:
+    case FFI_TYPE_UINT32:
+    case FFI_TYPE_SINT32:
+    case FFI_TYPE_INT:
+    case FFI_TYPE_POINTER:
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_SINT64:
+      if (state->ngrn < N_X_ARG_REG)
+       return allocate_to_x (context, state);
+      state->ngrn = N_X_ARG_REG;
+      break;
+    default:
+      FFI_ASSERT (0);
+    }
+
+    return allocate_to_stack (state, stack, alignment, size);
+}
+
+/* Copy a value to an appropriate register, or if none are
+   available, to the stack.  */
+
+static void
+copy_to_register_or_stack (struct call_context *context,
+                          unsigned char *stack,
+                          struct arg_state *state,
+                          void *value,
+                          unsigned short type)
+{
+  copy_basic_type (
+         allocate_to_register_or_stack (context, stack, state, type),
+         value,
+         type);
+}
+
+/* Marshall the arguments from FFI representation to procedure call
+   context and stack.  */
+
+static unsigned
+aarch64_prep_args (struct call_context *context, unsigned char *stack,
+                  extended_cif *ecif)
+{
+  int i;
+  struct arg_state state;
+
+  arg_init (&state, ALIGN(ecif->cif->bytes, 16));
+
+  for (i = 0; i < ecif->cif->nargs; i++)
+    {
+      ffi_type *ty = ecif->cif->arg_types[i];
+      switch (ty->type)
+       {
+       case FFI_TYPE_VOID:
+         FFI_ASSERT (0);
+         break;
+
+       /* If the argument is a basic type the argument is allocated to an
+          appropriate register, or if none are available, to the stack.  */
+       case FFI_TYPE_FLOAT:
+       case FFI_TYPE_DOUBLE:
+       case FFI_TYPE_LONGDOUBLE:
+       case FFI_TYPE_UINT8:
+       case FFI_TYPE_SINT8:
+       case FFI_TYPE_UINT16:
+       case FFI_TYPE_SINT16:
+       case FFI_TYPE_UINT32:
+       case FFI_TYPE_INT:
+       case FFI_TYPE_SINT32:
+       case FFI_TYPE_POINTER:
+       case FFI_TYPE_UINT64:
+       case FFI_TYPE_SINT64:
+         copy_to_register_or_stack (context, stack, &state,
+                                    ecif->avalue[i], ty->type);
+         break;
+
+       case FFI_TYPE_STRUCT:
+         if (is_hfa (ty))
+           {
+             copy_hfa_to_reg_or_stack (ecif->avalue[i], ty, context,
+                                       stack, &state);
+           }
+         else if (ty->size > 16)
+           {
+             /* If the argument is a composite type that is larger than 16
+                bytes, then the argument has been copied to memory, and
+                the argument is replaced by a pointer to the copy.  */
+
+             copy_to_register_or_stack (context, stack, &state,
+                                        &(ecif->avalue[i]), FFI_TYPE_POINTER);
+           }
+         else if (available_x (&state) >= (ty->size + 7) / 8)
+           {
+             /* If the argument is a composite type and the size in
+                double-words is not more than the number of available
+                X registers, then the argument is copied into consecutive
+                X registers.  */
+             int j;
+             for (j = 0; j < (ty->size + 7) / 8; j++)
+               {
+                 memcpy (allocate_to_x (context, &state),
+                         &(((UINT64 *) ecif->avalue[i])[j]),
+                         sizeof (UINT64));
+               }
+           }
+         else
+           {
+             /* Otherwise, there are insufficient X registers. Further X
+                register allocations are prevented, the NSAA is adjusted
+                (by allocate_to_stack ()) and the argument is copied to
+                memory at the adjusted NSAA.  */
+             state.ngrn = N_X_ARG_REG;
+
+             memcpy (allocate_to_stack (&state, stack, ty->alignment,
+                                        ty->size), ecif->avalue + i, ty->size);
+           }
+         break;
+
+       default:
+         FFI_ASSERT (0);
+         break;
+       }
+    }
+
+  return ecif->cif->aarch64_flags;
+}
+
+ffi_status
+ffi_prep_cif_machdep (ffi_cif *cif)
+{
+  /* Round the stack up to a multiple of the stack alignment requirement. */
+  cif->bytes =
+    (cif->bytes + (AARCH64_STACK_ALIGN - 1)) & ~ (AARCH64_STACK_ALIGN - 1);
+
+  /* Initialize our flags. We are interested if this CIF will touch a
+     vector register, if so we will enable context save and load to
+     those registers, otherwise not. This is intended to be friendly
+     to lazy float context switching in the kernel.  */
+  cif->aarch64_flags = 0;
+
+  if (is_v_register_candidate (cif->rtype))
+    {
+      cif->aarch64_flags |= AARCH64_FFI_WITH_V;
+    }
+  else
+    {
+      int i;
+      for (i = 0; i < cif->nargs; i++)
+        if (is_v_register_candidate (cif->arg_types[i]))
+          {
+            cif->aarch64_flags |= AARCH64_FFI_WITH_V;
+            break;
+          }
+    }
+
+  return FFI_OK;
+}
+
+/* Call a function with the provided arguments and capture the return
+   value.  */
+void
+ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  ecif.rvalue = rvalue;
+
+  switch (cif->abi)
+    {
+    case FFI_SYSV:
+      {
+        struct call_context context;
+       unsigned stack_bytes;
+
+       /* Figure out the total amount of stack space we need, the
+          above call frame space needs to be 16 bytes aligned to
+          ensure correct alignment of the first object inserted in
+          that space hence the ALIGN applied to cif->bytes.*/
+       stack_bytes = ALIGN(cif->bytes, 16);
+
+       memset (&context, 0, sizeof (context));
+        if (is_register_candidate (cif->rtype))
+          {
+            ffi_call_SYSV (aarch64_prep_args, &context, &ecif, stack_bytes, fn);
+            switch (cif->rtype->type)
+              {
+              case FFI_TYPE_VOID:
+              case FFI_TYPE_FLOAT:
+              case FFI_TYPE_DOUBLE:
+              case FFI_TYPE_LONGDOUBLE:
+              case FFI_TYPE_UINT8:
+              case FFI_TYPE_SINT8:
+              case FFI_TYPE_UINT16:
+              case FFI_TYPE_SINT16:
+              case FFI_TYPE_UINT32:
+              case FFI_TYPE_SINT32:
+              case FFI_TYPE_POINTER:
+              case FFI_TYPE_UINT64:
+              case FFI_TYPE_INT:
+              case FFI_TYPE_SINT64:
+               {
+                 void *addr = get_basic_type_addr (cif->rtype->type,
+                                                   &context, 0);
+                 copy_basic_type (rvalue, addr, cif->rtype->type);
+                 break;
+               }
+
+              case FFI_TYPE_STRUCT:
+                if (is_hfa (cif->rtype))
+                 {
+                   int j;
+                   unsigned short type = get_homogeneous_type (cif->rtype);
+                   unsigned elems = element_count (cif->rtype);
+                   for (j = 0; j < elems; j++)
+                     {
+                       void *reg = get_basic_type_addr (type, &context, j);
+                       copy_basic_type (rvalue, reg, type);
+                       rvalue += get_basic_type_size (type);
+                     }
+                 }
+                else if ((cif->rtype->size + 7) / 8 < N_X_ARG_REG)
+                  {
+                    unsigned size = ALIGN (cif->rtype->size, sizeof (UINT64));
+                    memcpy (rvalue, get_x_addr (&context, 0), size);
+                  }
+                else
+                  {
+                    FFI_ASSERT (0);
+                  }
+                break;
+
+              default:
+                FFI_ASSERT (0);
+                break;
+              }
+          }
+        else
+          {
+            memcpy (get_x_addr (&context, 8), &rvalue, sizeof (UINT64));
+            ffi_call_SYSV (aarch64_prep_args, &context, &ecif,
+                          stack_bytes, fn);
+          }
+        break;
+      }
+
+    default:
+      FFI_ASSERT (0);
+      break;
+    }
+}
+
+static unsigned char trampoline [] =
+{ 0x70, 0x00, 0x00, 0x58,      /* ldr  x16, 1f */
+  0x91, 0x00, 0x00, 0x10,      /* adr  x17, 2f */
+  0x00, 0x02, 0x1f, 0xd6       /* br   x16     */
+};
+
+/* Build a trampoline.  */
+
+#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,FLAGS)                       \
+  ({unsigned char *__tramp = (unsigned char*)(TRAMP);                  \
+    UINT64  __fun = (UINT64)(FUN);                                     \
+    UINT64  __ctx = (UINT64)(CTX);                                     \
+    UINT64  __flags = (UINT64)(FLAGS);                                 \
+    memcpy (__tramp, trampoline, sizeof (trampoline));                 \
+    memcpy (__tramp + 12, &__fun, sizeof (__fun));                     \
+    memcpy (__tramp + 20, &__ctx, sizeof (__ctx));                     \
+    memcpy (__tramp + 28, &__flags, sizeof (__flags));                 \
+    __clear_cache(__tramp, __tramp + FFI_TRAMPOLINE_SIZE);             \
+  })
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure* closure,
+                      ffi_cif* cif,
+                      void (*fun)(ffi_cif*,void*,void**,void*),
+                      void *user_data,
+                      void *codeloc)
+{
+  if (cif->abi != FFI_SYSV)
+    return FFI_BAD_ABI;
+
+  FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_SYSV, codeloc,
+                      cif->aarch64_flags);
+
+  closure->cif  = cif;
+  closure->user_data = user_data;
+  closure->fun  = fun;
+
+  return FFI_OK;
+}
+
+/* Primary handler to setup and invoke a function within a closure.
+
+   A closure when invoked enters via the assembler wrapper
+   ffi_closure_SYSV(). The wrapper allocates a call context on the
+   stack, saves the interesting registers (from the perspective of
+   the calling convention) into the context then passes control to
+   ffi_closure_SYSV_inner() passing the saved context and a pointer to
+   the stack at the point ffi_closure_SYSV() was invoked.
+
+   On the return path the assembler wrapper will reload call context
+   regsiters.
+
+   ffi_closure_SYSV_inner() marshalls the call context into ffi value
+   desriptors, invokes the wrapped function, then marshalls the return
+   value back into the call context.  */
+
+void
+ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context,
+                       void *stack)
+{
+  ffi_cif *cif = closure->cif;
+  void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
+  void *rvalue = NULL;
+  int i;
+  struct arg_state state;
+
+  arg_init (&state, ALIGN(cif->bytes, 16));
+
+  for (i = 0; i < cif->nargs; i++)
+    {
+      ffi_type *ty = cif->arg_types[i];
+
+      switch (ty->type)
+       {
+       case FFI_TYPE_VOID:
+         FFI_ASSERT (0);
+         break;
+
+       case FFI_TYPE_UINT8:
+       case FFI_TYPE_SINT8:
+       case FFI_TYPE_UINT16:
+       case FFI_TYPE_SINT16:
+       case FFI_TYPE_UINT32:
+       case FFI_TYPE_SINT32:
+       case FFI_TYPE_INT:
+       case FFI_TYPE_POINTER:
+       case FFI_TYPE_UINT64:
+       case FFI_TYPE_SINT64:
+       case  FFI_TYPE_FLOAT:
+       case  FFI_TYPE_DOUBLE:
+       case  FFI_TYPE_LONGDOUBLE:
+         avalue[i] = allocate_to_register_or_stack (context, stack,
+                                                    &state, ty->type);
+         break;
+
+       case FFI_TYPE_STRUCT:
+         if (is_hfa (ty))
+           {
+             unsigned n = element_count (ty);
+             if (available_v (&state) < n)
+               {
+                 state.nsrn = N_V_ARG_REG;
+                 avalue[i] = allocate_to_stack (&state, stack, ty->alignment,
+                                                ty->size);
+               }
+             else
+               {
+                 switch (get_homogeneous_type (ty))
+                   {
+                   case FFI_TYPE_FLOAT:
+                     {
+                       /* Eeek! We need a pointer to the structure,
+                          however the homogeneous float elements are
+                          being passed in individual S registers,
+                          therefore the structure is not represented as
+                          a contiguous sequence of bytes in our saved
+                          register context. We need to fake up a copy
+                          of the structure layed out in memory
+                          correctly. The fake can be tossed once the
+                          closure function has returned hence alloca()
+                          is sufficient. */
+                       int j;
+                       UINT32 *p = avalue[i] = alloca (ty->size);
+                       for (j = 0; j < element_count (ty); j++)
+                         memcpy (&p[j],
+                                 allocate_to_s (context, &state),
+                                 sizeof (*p));
+                       break;
+                     }
+
+                   case FFI_TYPE_DOUBLE:
+                     {
+                       /* Eeek! We need a pointer to the structure,
+                          however the homogeneous float elements are
+                          being passed in individual S registers,
+                          therefore the structure is not represented as
+                          a contiguous sequence of bytes in our saved
+                          register context. We need to fake up a copy
+                          of the structure layed out in memory
+                          correctly. The fake can be tossed once the
+                          closure function has returned hence alloca()
+                          is sufficient. */
+                       int j;
+                       UINT64 *p = avalue[i] = alloca (ty->size);
+                       for (j = 0; j < element_count (ty); j++)
+                         memcpy (&p[j],
+                                 allocate_to_d (context, &state),
+                                 sizeof (*p));
+                       break;
+                     }
+
+                   case FFI_TYPE_LONGDOUBLE:
+                         memcpy (&avalue[i],
+                                 allocate_to_v (context, &state),
+                                 sizeof (*avalue));
+                     break;
+
+                   default:
+                     FFI_ASSERT (0);
+                     break;
+                   }
+               }
+           }
+         else if (ty->size > 16)
+           {
+             /* Replace Composite type of size greater than 16 with a
+                pointer.  */
+             memcpy (&avalue[i],
+                     allocate_to_register_or_stack (context, stack,
+                                                    &state, FFI_TYPE_POINTER),
+                     sizeof (avalue[i]));
+           }
+         else if (available_x (&state) >= (ty->size + 7) / 8)
+           {
+             avalue[i] = get_x_addr (context, state.ngrn);
+             state.ngrn += (ty->size + 7) / 8;
+           }
+         else
+           {
+             state.ngrn = N_X_ARG_REG;
+
+             avalue[i] = allocate_to_stack (&state, stack, ty->alignment,
+                                            ty->size);
+           }
+         break;
+
+       default:
+         FFI_ASSERT (0);
+         break;
+       }
+    }
+
+  /* Figure out where the return value will be passed, either in
+     registers or in a memory block allocated by the caller and passed
+     in x8.  */
+
+  if (is_register_candidate (cif->rtype))
+    {
+      /* Register candidates are *always* returned in registers. */
+
+      /* Allocate a scratchpad for the return value, we will let the
+         callee scrible the result into the scratch pad then move the
+         contents into the appropriate return value location for the
+         call convention.  */
+      rvalue = alloca (cif->rtype->size);
+      (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+      /* Copy the return value into the call context so that it is returned
+         as expected to our caller.  */
+      switch (cif->rtype->type)
+        {
+        case FFI_TYPE_VOID:
+          break;
+
+        case FFI_TYPE_UINT8:
+        case FFI_TYPE_UINT16:
+        case FFI_TYPE_UINT32:
+        case FFI_TYPE_POINTER:
+        case FFI_TYPE_UINT64:
+        case FFI_TYPE_SINT8:
+        case FFI_TYPE_SINT16:
+        case FFI_TYPE_INT:
+        case FFI_TYPE_SINT32:
+        case FFI_TYPE_SINT64:
+        case FFI_TYPE_FLOAT:
+        case FFI_TYPE_DOUBLE:
+        case FFI_TYPE_LONGDOUBLE:
+         {
+           void *addr = get_basic_type_addr (cif->rtype->type, context, 0);
+           copy_basic_type (addr, rvalue, cif->rtype->type);
+            break;
+         }
+        case FFI_TYPE_STRUCT:
+          if (is_hfa (cif->rtype))
+           {
+             int i;
+             unsigned short type = get_homogeneous_type (cif->rtype);
+             unsigned elems = element_count (cif->rtype);
+             for (i = 0; i < elems; i++)
+               {
+                 void *reg = get_basic_type_addr (type, context, i);
+                 copy_basic_type (reg, rvalue, type);
+                 rvalue += get_basic_type_size (type);
+               }
+           }
+          else if ((cif->rtype->size + 7) / 8 < N_X_ARG_REG)
+            {
+              unsigned size = ALIGN (cif->rtype->size, sizeof (UINT64)) ;
+              memcpy (get_x_addr (context, 0), rvalue, size);
+            }
+          else
+            {
+              FFI_ASSERT (0);
+            }
+          break;
+        default:
+          FFI_ASSERT (0);
+          break;
+        }
+    }
+  else
+    {
+      memcpy (&rvalue, get_x_addr (context, 8), sizeof (UINT64));
+      (closure->fun) (cif, rvalue, avalue, closure->user_data);
+    }
+}
+
diff --git a/libffi/src/aarch64/ffitarget.h b/libffi/src/aarch64/ffitarget.h
new file mode 100644 (file)
index 0000000..6f1a348
--- /dev/null
@@ -0,0 +1,59 @@
+/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
+
+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
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_H
+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."
+#endif
+
+#ifndef LIBFFI_ASM
+typedef unsigned long ffi_arg;
+typedef signed long ffi_sarg;
+
+typedef enum ffi_abi
+  {
+    FFI_FIRST_ABI = 0,
+    FFI_SYSV,
+    FFI_LAST_ABI,
+    FFI_DEFAULT_ABI = FFI_SYSV
+  } ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 36
+#define FFI_NATIVE_RAW_API 0
+
+/* ---- Internal ---- */
+
+
+#define FFI_EXTRA_CIF_FIELDS unsigned aarch64_flags
+
+#define AARCH64_FFI_WITH_V_BIT 0
+
+#define AARCH64_N_XREG 32
+#define AARCH64_N_VREG 32
+#define AARCH64_CALL_CONTEXT_SIZE (AARCH64_N_XREG * 8 + AARCH64_N_VREG * 16)
+
+#endif
diff --git a/libffi/src/aarch64/sysv.S b/libffi/src/aarch64/sysv.S
new file mode 100644 (file)
index 0000000..b8cd421
--- /dev/null
@@ -0,0 +1,307 @@
+/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
+
+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
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+#define cfi_adjust_cfa_offset(off)     .cfi_adjust_cfa_offset off
+#define cfi_rel_offset(reg, off)       .cfi_rel_offset reg, off
+#define cfi_restore(reg)               .cfi_restore reg
+#define cfi_def_cfa_register(reg)      .cfi_def_cfa_register reg
+
+        .text
+        .globl ffi_call_SYSV
+        .type ffi_call_SYSV, #function
+
+/* ffi_call_SYSV()
+
+   Create a stack frame, setup an argument context, call the callee
+   and extract the result.
+
+   The maximum required argument stack size is provided,
+   ffi_call_SYSV() allocates that stack space then calls the
+   prepare_fn to populate register context and stack.  The
+   argument passing registers are loaded from the register
+   context and the callee called, on return the register passing
+   register are saved back to the context.  Our caller will
+   extract the return value from the final state of the saved
+   register context.
+
+   Prototype:
+
+   extern unsigned
+   ffi_call_SYSV (void (*)(struct call_context *context, unsigned char *,
+                          extended_cif *),
+                  struct call_context *context,
+                  extended_cif *,
+                  unsigned required_stack_size,
+                  void (*fn)(void));
+
+   Therefore on entry we have:
+
+   x0 prepare_fn
+   x1 &context
+   x2 &ecif
+   x3 bytes
+   x4 fn
+
+   This function uses the following stack frame layout:
+
+   ==
+                saved x30(lr)
+   x29(fp)->    saved x29(fp)
+                saved x24
+                saved x23
+                saved x22
+   sp'    ->    saved x21
+                ...
+   sp     ->    (constructed callee stack arguments)
+   ==
+
+   Voila! */
+
+#define ffi_call_SYSV_FS (8 * 4)
+
+        .cfi_startproc
+ffi_call_SYSV:
+        stp     x29, x30, [sp, #-16]!
+       cfi_adjust_cfa_offset (16)
+        cfi_rel_offset (x29, 0)
+        cfi_rel_offset (x30, 8)
+
+        mov     x29, sp
+       cfi_def_cfa_register (x29)
+        sub     sp, sp, #ffi_call_SYSV_FS
+
+        stp     x21, x22, [sp, 0]
+        cfi_rel_offset (x21, 0 - ffi_call_SYSV_FS)
+        cfi_rel_offset (x22, 8 - ffi_call_SYSV_FS)
+
+        stp     x23, x24, [sp, 16]
+        cfi_rel_offset (x23, 16 - ffi_call_SYSV_FS)
+        cfi_rel_offset (x24, 24 - ffi_call_SYSV_FS)
+
+        mov     x21, x1
+        mov     x22, x2
+        mov     x24, x4
+
+        /* Allocate the stack space for the actual arguments, many
+           arguments will be passed in registers, but we assume
+           worst case and allocate sufficient stack for ALL of
+           the arguments.  */
+        sub     sp, sp, x3
+
+        /* unsigned (*prepare_fn) (struct call_context *context,
+                                  unsigned char *stack, extended_cif *ecif);
+        */
+        mov     x23, x0
+        mov     x0, x1
+        mov     x1, sp
+        /* x2 already in place */
+        blr     x23
+
+        /* Preserve the flags returned.  */
+        mov     x23, x0
+
+        /* Figure out if we should touch the vector registers.  */
+        tbz     x23, #AARCH64_FFI_WITH_V_BIT, 1f
+
+        /* Load the vector argument passing registers.  */
+        ldp     q0, q1, [x21, #8*32 +  0]
+        ldp     q2, q3, [x21, #8*32 + 32]
+        ldp     q4, q5, [x21, #8*32 + 64]
+        ldp     q6, q7, [x21, #8*32 + 96]
+1:
+        /* Load the core argument passing registers.  */
+        ldp     x0, x1, [x21,  #0]
+        ldp     x2, x3, [x21, #16]
+        ldp     x4, x5, [x21, #32]
+        ldp     x6, x7, [x21, #48]
+
+        /* Don't forget x8 which may be holding the address of a return buffer.
+        */
+        ldr     x8,     [x21, #8*8]
+
+        blr     x24
+
+        /* Save the core argument passing registers.  */
+        stp     x0, x1, [x21,  #0]
+        stp     x2, x3, [x21, #16]
+        stp     x4, x5, [x21, #32]
+        stp     x6, x7, [x21, #48]
+
+        /* Note nothing useful ever comes back in x8!  */
+
+        /* Figure out if we should touch the vector registers.  */
+        tbz     x23, #AARCH64_FFI_WITH_V_BIT, 1f
+
+        /* Save the vector argument passing registers.  */
+        stp     q0, q1, [x21, #8*32 + 0]
+        stp     q2, q3, [x21, #8*32 + 32]
+        stp     q4, q5, [x21, #8*32 + 64]
+        stp     q6, q7, [x21, #8*32 + 96]
+1:
+        /* All done, unwind our stack frame.  */
+        ldp     x21, x22, [x29,  # - ffi_call_SYSV_FS]
+        cfi_restore (x21)
+        cfi_restore (x22)
+
+        ldp     x23, x24, [x29,  # - ffi_call_SYSV_FS + 16]
+        cfi_restore (x23)
+        cfi_restore (x24)
+
+        mov     sp, x29
+       cfi_def_cfa_register (sp)
+
+        ldp     x29, x30, [sp], #16
+       cfi_adjust_cfa_offset (-16)
+        cfi_restore (x29)
+        cfi_restore (x30)
+
+        ret
+
+        .cfi_endproc
+        .size ffi_call_SYSV, .-ffi_call_SYSV
+
+#define ffi_closure_SYSV_FS (8 * 2 + AARCH64_CALL_CONTEXT_SIZE)
+
+/* ffi_closure_SYSV
+
+   Closure invocation glue. This is the low level code invoked directly by
+   the closure trampoline to setup and call a closure.
+
+   On entry x17 points to a struct trampoline_data, x16 has been clobbered
+   all other registers are preserved.
+
+   We allocate a call context and save the argument passing registers,
+   then invoked the generic C ffi_closure_SYSV_inner() function to do all
+   the real work, on return we load the result passing registers back from
+   the call context.
+
+   On entry
+
+   extern void
+   ffi_closure_SYSV (struct trampoline_data *);
+
+   struct trampoline_data
+   {
+        UINT64 *ffi_closure;
+        UINT64 flags;
+   };
+
+   This function uses the following stack frame layout:
+
+   ==
+                saved x30(lr)
+   x29(fp)->    saved x29(fp)
+                saved x22
+                saved x21
+                ...
+   sp     ->    call_context
+   ==
+
+   Voila!  */
+
+        .text
+        .globl ffi_closure_SYSV
+        .cfi_startproc
+ffi_closure_SYSV:
+        stp     x29, x30, [sp, #-16]!
+       cfi_adjust_cfa_offset (16)
+        cfi_rel_offset (x29, 0)
+        cfi_rel_offset (x30, 8)
+
+        mov     x29, sp
+
+        sub     sp, sp, #ffi_closure_SYSV_FS
+       cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
+
+        stp     x21, x22, [x29, #-16]
+        cfi_rel_offset (x21, 0)
+        cfi_rel_offset (x22, 8)
+
+        /* Load x21 with &call_context.  */
+        mov     x21, sp
+        /* Preserve our struct trampoline_data *  */
+        mov     x22, x17
+
+        /* Save the rest of the argument passing registers.  */
+        stp     x0, x1, [x21, #0]
+        stp     x2, x3, [x21, #16]
+        stp     x4, x5, [x21, #32]
+        stp     x6, x7, [x21, #48]
+        /* Don't forget we may have been given a result scratch pad address.
+        */
+        str     x8,     [x21, #64]
+
+        /* Figure out if we should touch the vector registers.  */
+        ldr     x0, [x22, #8]
+        tbz     x0, #AARCH64_FFI_WITH_V_BIT, 1f
+
+        /* Save the argument passing vector registers.  */
+        stp     q0, q1, [x21, #8*32 + 0]
+        stp     q2, q3, [x21, #8*32 + 32]
+        stp     q4, q5, [x21, #8*32 + 64]
+        stp     q6, q7, [x21, #8*32 + 96]
+1:
+        /* Load &ffi_closure..  */
+        ldr     x0, [x22, #0]
+        mov     x1, x21
+        /* Compute the location of the stack at the point that the
+           trampoline was called.  */
+        add     x2, x29, #16
+
+        bl      ffi_closure_SYSV_inner
+
+        /* Figure out if we should touch the vector registers.  */
+        ldr     x0, [x22, #8]
+        tbz     x0, #AARCH64_FFI_WITH_V_BIT, 1f
+
+        /* Load the result passing vector registers.  */
+        ldp     q0, q1, [x21, #8*32 + 0]
+        ldp     q2, q3, [x21, #8*32 + 32]
+        ldp     q4, q5, [x21, #8*32 + 64]
+        ldp     q6, q7, [x21, #8*32 + 96]
+1:
+        /* Load the result passing core registers.  */
+        ldp     x0, x1, [x21,  #0]
+        ldp     x2, x3, [x21, #16]
+        ldp     x4, x5, [x21, #32]
+        ldp     x6, x7, [x21, #48]
+        /* Note nothing usefull is returned in x8.  */
+
+        /* We are done, unwind our frame.  */
+        ldp     x21, x22, [x29,  #-16]
+        cfi_restore (x21)
+        cfi_restore (x22)
+
+        mov     sp, x29
+       cfi_adjust_cfa_offset (-ffi_closure_SYSV_FS)
+
+        ldp     x29, x30, [sp], #16
+       cfi_adjust_cfa_offset (-16)
+        cfi_restore (x29)
+        cfi_restore (x30)
+
+        ret
+        .cfi_endproc
+        .size ffi_closure_SYSV, .-ffi_closure_SYSV
index 1f8597da88cdb48668ec40d1bc35989376308579..3ccceb9a50811b5b8337cd16f55971043098dd66 100644 (file)
@@ -251,8 +251,10 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
       break;
 
     case FFI_VFP:
+#ifdef __ARM_EABI__
       ffi_call_VFP (fn, &ecif, cif->bytes, cif->flags, ecif.rvalue);
       break;
+#endif
 
     default:
       FFI_ASSERT(0);
@@ -609,8 +611,10 @@ ffi_prep_closure_loc (ffi_closure* closure,
 
   if (cif->abi == FFI_SYSV)
     closure_func = &ffi_closure_SYSV;
+#ifdef __ARM_EABI__
   else if (cif->abi == FFI_VFP)
     closure_func = &ffi_closure_VFP;
+#endif
   else
     return FFI_BAD_ABI;
     
index 60e2ae3d552c1d32ee857f5df567c3e197650ebc..fb38cd6406ad0713614f4eaed5bb84fb0cf3e37d 100644 (file)
@@ -41,7 +41,7 @@
 #define CNAME(x) x
 #endif
 #ifdef __APPLE__
-#define ENTRY(x) .globl CNAME(x); CNAME(x):
+#define ENTRY(x) .globl _##x; _##x:
 #else
 #define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
 #endif /* __APPLE__ */
@@ -187,7 +187,7 @@ ARM_FUNC_START ffi_call_SYSV
        @     r1 already set
 
        @ Call ffi_prep_args(stack, &ecif)
-       bl      ffi_prep_args
+       bl      CNAME(ffi_prep_args)
 
        @ move first 4 parameters in registers
        ldmia   sp, {r0-r3}
@@ -334,7 +334,9 @@ ARM_FUNC_START ffi_closure_SYSV
 
 
 /* Below are VFP hard-float ABI call and closure implementations.
-   Add VFP FPU directive here. */
+   Add VFP FPU directive here. This is only compiled into the library
+   under EABI.  */
+#ifdef __ARM_EABI__
        .fpu    vfp
 
        @ r0:   fn
@@ -362,7 +364,7 @@ ARM_FUNC_START ffi_call_VFP
        sub     r2, fp, #64   @ VFP scratch space
 
        @ Call ffi_prep_args(stack, &ecif, vfp_space)
-       bl      ffi_prep_args
+       bl      CNAME(ffi_prep_args)
 
        @ Load VFP register args if needed
        cmp     r0, #0
@@ -444,7 +446,7 @@ ARM_FUNC_START ffi_closure_VFP
        sub     sp, sp, #72
        str     sp, [sp, #64]
        add     r1, sp, #64
-       bl      ffi_closure_SYSV_inner
+       bl      CNAME(ffi_closure_SYSV_inner)
 
        cmp     r0, #FFI_TYPE_INT
        beq     .Lretint_vfp
@@ -491,6 +493,7 @@ ARM_FUNC_START ffi_closure_VFP
 .ffi_closure_VFP_end:
        UNWIND .fnend
         .size    CNAME(ffi_closure_VFP),.ffi_closure_VFP_end-CNAME(ffi_closure_VFP)
+#endif
 
 ENTRY(ffi_arm_trampoline)
        stmfd sp!, {r0-r3}
index 7b474291a25adf37f3820ad2e2bd79035a255bdc..935e8de179547ec64263237692aec2d6824f4b6f 100644 (file)
@@ -1,5 +1,5 @@
 # GENERATED CODE - DO NOT EDIT
-# This file was generated by ./gentramp.sh
+# This file was generated by src/arm/gentramp.sh
 
 #  Copyright (c) 2010, Plausible Labs Cooperative, Inc.
 #  
diff --git a/libffi/src/bfin/ffi.c b/libffi/src/bfin/ffi.c
new file mode 100644 (file)
index 0000000..0beccc1
--- /dev/null
@@ -0,0 +1,195 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2012  Alexandre K. I. de Mendonca <alexandre.keunecke@gmail.com>
+
+   Blackfin Foreign Function Interface
+
+   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
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/* Maximum number of GPRs available for argument passing.  */
+#define MAX_GPRARGS 3
+
+/*
+ * Return types
+ */
+#define FFIBFIN_RET_VOID 0
+#define FFIBFIN_RET_BYTE 1
+#define FFIBFIN_RET_HALFWORD 2
+#define FFIBFIN_RET_INT64 3
+#define FFIBFIN_RET_INT32 4
+
+/*====================================================================*/
+/*                          PROTOTYPE          *
+ /*====================================================================*/
+void ffi_prep_args(unsigned char *, extended_cif *);
+
+/*====================================================================*/
+/*                          Externals                                 */
+/*                          (Assembly)                                */
+/*====================================================================*/
+
+extern void ffi_call_SYSV(unsigned, extended_cif *, void(*)(unsigned char *, extended_cif *), unsigned, void *, void(*fn)(void));
+
+/*====================================================================*/
+/*                          Implementation                            */
+/*                                                            */
+/*====================================================================*/
+
+
+/*
+ * This function calculates the return type (size) based on type.
+ */
+
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+   /* --------------------------------------*
+    *   Return handling                *
+    * --------------------------------------*/
+   switch (cif->rtype->type) {
+      case FFI_TYPE_VOID:
+         cif->flags = FFIBFIN_RET_VOID;
+         break;
+      case FFI_TYPE_UINT16:
+      case FFI_TYPE_SINT16:
+         cif->flags = FFIBFIN_RET_HALFWORD;
+         break;
+      case FFI_TYPE_UINT8:
+         cif->flags = FFIBFIN_RET_BYTE;
+         break;
+      case FFI_TYPE_INT:
+      case FFI_TYPE_UINT32:
+      case FFI_TYPE_SINT32:
+      case FFI_TYPE_FLOAT:
+      case FFI_TYPE_POINTER:
+      case FFI_TYPE_SINT8:
+         cif->flags = FFIBFIN_RET_INT32;
+         break;
+      case FFI_TYPE_SINT64:
+      case FFI_TYPE_UINT64:
+      case FFI_TYPE_DOUBLE:
+          cif->flags = FFIBFIN_RET_INT64;
+          break;
+      case FFI_TYPE_STRUCT:
+         if (cif->rtype->size <= 4){
+                cif->flags = FFIBFIN_RET_INT32;
+         }else if (cif->rtype->size == 8){
+                cif->flags = FFIBFIN_RET_INT64;
+         }else{
+                //it will return via a hidden pointer in P0
+                cif->flags = FFIBFIN_RET_VOID;
+         }
+         break;
+      default:
+         FFI_ASSERT(0);
+         break;
+   }
+   return FFI_OK;
+}
+
+/*
+ * This will prepare the arguments and will call the assembly routine
+ * cif = the call interface
+ * fn = the function to be called
+ * rvalue = the return value
+ * avalue = the arguments
+ */
+void ffi_call(ffi_cif *cif, void(*fn)(void), void *rvalue, void **avalue)
+{
+   int ret_type = cif->flags;
+   extended_cif ecif;
+   ecif.cif = cif;
+   ecif.avalue = avalue;
+   ecif.rvalue = rvalue;
+
+   switch (cif->abi) {
+      case FFI_SYSV:
+         ffi_call_SYSV(cif->bytes, &ecif, ffi_prep_args, ret_type, ecif.rvalue, fn);
+         break;
+      default:
+         FFI_ASSERT(0);
+         break;
+   }
+}
+
+
+/*
+* This function prepares the parameters (copies them from the ecif to the stack)
+*  to call the function (ffi_prep_args is called by the assembly routine in file
+*  sysv.S, which also calls the actual function)
+*/
+void ffi_prep_args(unsigned char *stack, extended_cif *ecif)
+{
+   register unsigned int i = 0;
+   void **p_argv;
+   unsigned char *argp;
+   ffi_type **p_arg;
+   argp = stack;
+   p_argv = ecif->avalue;
+   for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+        (i != 0);
+        i--, p_arg++) {
+      size_t z;
+      z = (*p_arg)->size;
+      if (z < sizeof(int)) {
+         z = sizeof(int);
+         switch ((*p_arg)->type) {
+            case FFI_TYPE_SINT8: {
+                  signed char v = *(SINT8 *)(* p_argv);
+                  signed int t = v;
+                  *(signed int *) argp = t;
+               }
+               break;
+            case FFI_TYPE_UINT8: {
+                  unsigned char v = *(UINT8 *)(* p_argv);
+                  unsigned int t = v;
+                  *(unsigned int *) argp = t;
+               }
+               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, *p_argv, (*p_arg)->size);
+               break;
+            default:
+               FFI_ASSERT(0);
+               break;
+         }
+      } else if (z == sizeof(int)) {
+         *(unsigned int *) argp = (unsigned int) * (UINT32 *)(* p_argv);
+      } else {
+         memcpy(argp, *p_argv, z);
+      }
+      p_argv++;
+      argp += z;
+   }
+}
+
+
+
diff --git a/libffi/src/bfin/ffitarget.h b/libffi/src/bfin/ffitarget.h
new file mode 100644 (file)
index 0000000..2175c01
--- /dev/null
@@ -0,0 +1,43 @@
+/* -----------------------------------------------------------------------
+   ffitarget.h - Copyright (c) 2012  Alexandre K. I. de Mendonca <alexandre.keunecke@gmail.com>
+
+   Blackfin Foreign Function Interface
+
+   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
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed          long          ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_SYSV,
+  FFI_LAST_ABI,
+  FFI_DEFAULT_ABI = FFI_SYSV
+} ffi_abi;
+#endif
+
+#endif
+
diff --git a/libffi/src/bfin/sysv.S b/libffi/src/bfin/sysv.S
new file mode 100644 (file)
index 0000000..ae7a152
--- /dev/null
@@ -0,0 +1,177 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 2012  Alexandre K. I. de Mendonca <alexandre.keunecke@gmail.com>
+
+   Blackfin Foreign Function Interface
+
+   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
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+.text
+.align 4
+
+       /*
+        There is a "feature" in the bfin toolchain that it puts a _ before funcion names
+        that's why the function here it's called _ffi_call_SYSV and not ffi_call_SYSV
+        */
+       .global _ffi_call_SYSV;
+       .type _ffi_call_SYSV, STT_FUNC;
+       .func ffi_call_SYSV
+
+       /*
+       cif->bytes      = R0    (fp+8)
+       &ecif                   = R1    (fp+12)
+       ffi_prep_args   = R2    (fp+16)
+       ret_type                = stack (fp+20)
+       ecif.rvalue             = stack (fp+24)
+       fn                              = stack (fp+28)
+                                         got   (fp+32)
+    There is room for improvement here (we can use temporary registers
+        instead of saving the values in the memory)
+       REGS:
+               P5 => Stack pointer (function arguments)
+               R5 => cif->bytes
+               R4 => ret->type
+
+               FP-20 = P3
+               FP-16 = SP (parameters area)
+               FP-12 = SP (temp)
+               FP-08 = function return part 1 [R0]
+               FP-04 = function return part 2 [R1]
+       */
+
+_ffi_call_SYSV:
+.prologue:
+       LINK 20;
+       [FP-20] = P3;
+       [FP+8] = R0;
+       [FP+12] = R1;
+       [FP+16] = R2;
+
+.allocate_stack:
+       //alocate cif->bytes into the stack
+       R1 = [FP+8];
+       R0 = SP;
+       R0 = R0 - R1;
+       R1 = 4;
+       R0 = R0 - R1;
+       [FP-12] = SP;
+       SP = R0;
+       [FP-16] = SP;
+
+.call_prep_args:
+       //get the addr of prep_args
+       P0 = [P3 + _ffi_prep_args@FUNCDESC_GOT17M4];
+       P1 = [P0];
+       P3 = [P0+4];
+       R0 = [FP-16];//SP (parameter area)
+       R1 = [FP+12];//ecif
+       call (P1);
+
+.call_user_function:
+       //ajust SP so as to allow the user function access the parameters on the stack
+       SP = [FP-16]; //point to function parameters
+       R0 = [SP];
+       R1 = [SP+4];
+       R2 = [SP+8];
+       //load user function address
+       P0 = FP;
+       P0 +=28;
+       P1 = [P0];
+       P1 = [P1];
+       P3 = [P0+4];
+       /*
+               For functions returning aggregate values (struct) occupying more than 8 bytes,
+               the caller allocates the return value object on the stack and the address
+               of this object is passed to the callee as a hidden argument in register P0.
+       */
+       P0 = [FP+24];
+
+       call (P1);
+       SP = [FP-12];
+.compute_return:
+       P2 = [FP-20];
+       [FP-8] = R0;
+       [FP-4] = R1;
+
+       R0 = [FP+20];
+       R1 = R0 << 2;
+
+       R0 = [P2+.rettable@GOT17M4];
+       R0 = R1 + R0;
+       P2 = R0;
+       R1 = [P2];
+
+       P2 = [FP+-20];
+       R0 = [P2+.rettable@GOT17M4];
+       R0 = R1 + R0;
+       P2 = R0;
+       R0 = [FP-8];
+       R1 = [FP-4];
+       jump (P2);
+
+/*
+#define FFIBFIN_RET_VOID 0
+#define FFIBFIN_RET_BYTE 1
+#define FFIBFIN_RET_HALFWORD 2
+#define FFIBFIN_RET_INT64 3
+#define FFIBFIN_RET_INT32 4
+*/
+.align 4
+.align 4
+.rettable:
+       .dd .epilogue - .rettable
+       .dd     .rbyte - .rettable;
+       .dd     .rhalfword - .rettable;
+       .dd     .rint64 - .rettable;
+       .dd     .rint32 - .rettable;
+
+.rbyte:
+       P0 = [FP+24];
+       R0 = R0.B (Z);
+       [P0] = R0;
+       JUMP .epilogue
+.rhalfword:
+       P0 = [FP+24];
+       R0 = R0.L;
+       [P0] = R0;
+       JUMP .epilogue
+.rint64:
+       P0 = [FP+24];// &rvalue
+       [P0] = R0;
+       [P0+4] = R1;
+       JUMP .epilogue
+.rint32:
+       P0 = [FP+24];
+       [P0] = R0;
+.epilogue:
+       R0 = [FP+8];
+       R1 = [FP+12];
+       R2 = [FP+16];
+       P3 = [FP-20];
+       UNLINK;
+       RTS;
+
+.size _ffi_call_SYSV,.-_ffi_call_SYSV;
+.endfunc
index 1b378270363bed1b68e029f8a32247d4e54eecbd..fecbc4ae2c9e7056e84c2561f6537e453ea7efc7 100644 (file)
@@ -172,6 +172,27 @@ selinux_enabled_check (void)
 
 #endif /* !FFI_MMAP_EXEC_SELINUX */
 
+/* On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC. */
+#ifdef FFI_MMAP_EXEC_EMUTRAMP_PAX
+#include <stdlib.h>
+
+static int emutramp_enabled = -1;
+
+static int
+emutramp_enabled_check (void)
+{
+  if (getenv ("FFI_DISABLE_EMUTRAMP") == NULL)
+    return 1;
+  else
+    return 0;
+}
+
+#define is_emutramp_enabled() (emutramp_enabled >= 0 ? emutramp_enabled \
+                               : (emutramp_enabled = emutramp_enabled_check ()))
+#else
+#define is_emutramp_enabled() 0
+#endif /* FFI_MMAP_EXEC_EMUTRAMP_PAX */
+
 #elif defined (__CYGWIN__) || defined(__INTERIX)
 
 #include <sys/mman.h>
@@ -458,6 +479,12 @@ dlmmap (void *start, size_t length, int prot,
   printf ("mapping in %zi\n", length);
 #endif
 
+  if (execfd == -1 && is_emutramp_enabled ())
+    {
+      ptr = mmap (start, length, prot & ~PROT_EXEC, flags, fd, offset);
+      return ptr;
+    }
+
   if (execfd == -1 && !is_selinux_enabled ())
     {
       ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset);
index d95c72b93bd8b9f2591e4d4321a2ce1675e072e4..37a078437eac518b0c31e29cbfbeaeb75443b30e 100644 (file)
@@ -1,7 +1,7 @@
 /* -----------------------------------------------------------------------
    ffi.c
-   
-   m68k Foreign Function Interface 
+
+   m68k Foreign Function Interface
    ----------------------------------------------------------------------- */
 
 #include <ffi.h>
 void rtems_cache_flush_multiple_data_lines( const void *, size_t );
 #else
 #include <sys/syscall.h>
+#ifdef __MINT__
+#include <mint/mintbind.h>
+#include <mint/ssystem.h>
+#else
 #include <asm/cachectl.h>
 #endif
+#endif
 
 void ffi_call_SYSV (extended_cif *,
                    unsigned, unsigned,
@@ -39,8 +44,12 @@ ffi_prep_args (void *stack, extended_cif *ecif)
 
   argp = stack;
 
-  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT
-      && !ecif->cif->flags)
+  if (
+#ifdef __MINT__
+      (ecif->cif->rtype->type == FFI_TYPE_LONGDOUBLE) ||
+#endif
+      (((ecif->cif->rtype->type == FFI_TYPE_STRUCT)
+        && !ecif->cif->flags)))
     struct_value_ptr = ecif->rvalue;
   else
     struct_value_ptr = NULL;
@@ -51,12 +60,12 @@ ffi_prep_args (void *stack, extended_cif *ecif)
        i != 0;
        i--, p_arg++)
     {
-      size_t z;
+      size_t z = (*p_arg)->size;
+      int type = (*p_arg)->type;
 
-      z = (*p_arg)->size;
       if (z < sizeof (int))
        {
-         switch ((*p_arg)->type)
+         switch (type)
            {
            case FFI_TYPE_SINT8:
              *(signed int *) argp = (signed int) *(SINT8 *) *p_argv;
@@ -75,7 +84,14 @@ ffi_prep_args (void *stack, extended_cif *ecif)
              break;
 
            case FFI_TYPE_STRUCT:
+#ifdef __MINT__
+             if (z == 1 || z == 2)
+               memcpy (argp + 2, *p_argv, z);
+              else
+               memcpy (argp, *p_argv, z);
+#else
              memcpy (argp + sizeof (int) - z, *p_argv, z);
+#endif
              break;
 
            default:
@@ -120,17 +136,34 @@ ffi_prep_cif_machdep (ffi_cif *cif)
       break;
 
     case FFI_TYPE_STRUCT:
+      if (cif->rtype->elements[0]->type == FFI_TYPE_STRUCT &&
+          cif->rtype->elements[1])
+        {
+          cif->flags = 0;
+          break;
+        }
+
       switch (cif->rtype->size)
        {
        case 1:
+#ifdef __MINT__
+         cif->flags = CIF_FLAGS_STRUCT2;
+#else
          cif->flags = CIF_FLAGS_STRUCT1;
+#endif
          break;
        case 2:
          cif->flags = CIF_FLAGS_STRUCT2;
          break;
+#ifdef __MINT__
+       case 3:
+#endif
        case 4:
          cif->flags = CIF_FLAGS_INT;
          break;
+#ifdef __MINT__
+       case 7:
+#endif
        case 8:
          cif->flags = CIF_FLAGS_DINT;
          break;
@@ -150,7 +183,11 @@ ffi_prep_cif_machdep (ffi_cif *cif)
 
 #if (FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE)
     case FFI_TYPE_LONGDOUBLE:
+#ifdef __MINT__
+      cif->flags = 0;
+#else
       cif->flags = CIF_FLAGS_LDOUBLE;
+#endif
       break;
 #endif
 
@@ -218,6 +255,26 @@ ffi_prep_incoming_args_SYSV (char *stack, void **avalue, ffi_cif *cif)
       size_t z;
 
       z = (*p_arg)->size;
+#ifdef __MINT__
+      if (cif->flags &&
+          cif->rtype->type == FFI_TYPE_STRUCT &&
+          (z == 1 || z == 2))
+       {
+         *p_argv = (void *) (argp + 2);
+
+         z = 4;
+       }
+      else
+      if (cif->flags &&
+          cif->rtype->type == FFI_TYPE_STRUCT &&
+          (z == 3 || z == 4))
+       {
+         *p_argv = (void *) (argp);
+
+         z = 4;
+       }
+      else
+#endif
       if (z <= 4)
        {
          *p_argv = (void *) (argp + 4 - z);
@@ -267,14 +324,21 @@ ffi_prep_closure_loc (ffi_closure* closure,
   *(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)
+
+  if (
+#ifdef __MINT__
+      (cif->rtype->type == FFI_TYPE_LONGDOUBLE) ||
+#endif
+      (((cif->rtype->type == FFI_TYPE_STRUCT)
+         && !cif->flags)))
     *(void **)(closure->tramp + 8) = ffi_closure_struct_SYSV;
   else
     *(void **)(closure->tramp + 8) = ffi_closure_SYSV;
 
 #ifdef __rtems__
   rtems_cache_flush_multiple_data_lines( codeloc, FFI_TRAMPOLINE_SIZE );
+#elif defined(__MINT__)
+  Ssystem(S_FLUSHCACHE, codeloc, FFI_TRAMPOLINE_SIZE);
 #else
   syscall(SYS_cacheflush, codeloc, FLUSH_SCOPE_LINE,
          FLUSH_CACHE_BOTH, FFI_TRAMPOLINE_SIZE);
@@ -286,4 +350,3 @@ ffi_prep_closure_loc (ffi_closure* closure,
 
   return FFI_OK;
 }
-
index dfdd8644384387a8914a784fd33ce168ac8b618e..f6f4ef97eaf879f4e647fe221cb39889570c10c5 100644 (file)
@@ -1,6 +1,7 @@
 /* -----------------------------------------------------------------------
        
-   sysv.S - Copyright (c) 1998, 2012 Andreas Schwab
+   sysv.S - Copyright (c) 2012 Alan Hourihane
+           Copyright (c) 1998, 2012 Andreas Schwab
            Copyright (c) 2008 Red Hat, Inc. 
    
    m68k Foreign Function Interface 
 #define CFI_OFFSET(reg,off)
 #define CFI_DEF_CFA(reg,off)
 #define CFI_ENDPROC()
+#endif
+
+#ifdef __MINT__
+#define CALLFUNC(funcname) _ ## funcname
+#else
+#define CALLFUNC(funcname) funcname
 #endif
 
        .text
 
-       .globl  ffi_call_SYSV
-       .type   ffi_call_SYSV,@function
+       .globl  CALLFUNC(ffi_call_SYSV)
+       .type   CALLFUNC(ffi_call_SYSV),@function
        .align  4
 
-ffi_call_SYSV:
+CALLFUNC(ffi_call_SYSV):
        CFI_STARTPROC()
        link    %fp,#0
        CFI_OFFSET(14,-8)
@@ -63,14 +70,18 @@ ffi_call_SYSV:
        move.l  8(%fp),-(%sp)
        pea     4(%sp)
 #if !defined __PIC__
-       jsr     ffi_prep_args
+       jsr     CALLFUNC(ffi_prep_args)
 #else
-       bsr.l   ffi_prep_args@PLTPC
+       bsr.l   CALLFUNC(ffi_prep_args@PLTPC)
 #endif
        addq.l  #8,%sp  
 
        | Pass pointer to struct value, if any
+#ifdef __MINT__
+       move.l  %d0,%a1
+#else
        move.l  %a0,%a1
+#endif
 
        | Call the function
        move.l  24(%fp),%a0
@@ -142,7 +153,11 @@ retlongdouble:
 retpointer:
        btst    #5,%d2
        jbeq    retstruct1
+#ifdef __MINT__
+       move.l  %d0,(%a1)
+#else
        move.l  %a0,(%a1)
+#endif
        jbra    epilogue
 
 retstruct1:
@@ -162,13 +177,13 @@ epilogue:
        unlk    %fp
        rts
        CFI_ENDPROC()
-       .size   ffi_call_SYSV,.-ffi_call_SYSV
+       .size   CALLFUNC(ffi_call_SYSV),.-CALLFUNC(ffi_call_SYSV)
 
-       .globl  ffi_closure_SYSV
-       .type   ffi_closure_SYSV, @function
+       .globl  CALLFUNC(ffi_closure_SYSV)
+       .type   CALLFUNC(ffi_closure_SYSV), @function
        .align  4
 
-ffi_closure_SYSV:
+CALLFUNC(ffi_closure_SYSV):
        CFI_STARTPROC()
        link    %fp,#-12
        CFI_OFFSET(14,-8)
@@ -178,9 +193,9 @@ ffi_closure_SYSV:
        pea     -12(%fp)
        move.l  %a0,-(%sp)
 #if !defined __PIC__
-       jsr     ffi_closure_SYSV_inner
+       jsr     CALLFUNC(ffi_closure_SYSV_inner)
 #else
-       bsr.l   ffi_closure_SYSV_inner@PLTPC
+       bsr.l   CALLFUNC(ffi_closure_SYSV_inner@PLTPC)
 #endif
 
        lsr.l   #1,%d0
@@ -240,13 +255,13 @@ ffi_closure_SYSV:
        jra     .Lcls_epilogue
        CFI_ENDPROC()
 
-       .size   ffi_closure_SYSV,.-ffi_closure_SYSV
+       .size   CALLFUNC(ffi_closure_SYSV),.-CALLFUNC(ffi_closure_SYSV)
 
-       .globl  ffi_closure_struct_SYSV
-       .type   ffi_closure_struct_SYSV, @function
+       .globl  CALLFUNC(ffi_closure_struct_SYSV)
+       .type   CALLFUNC(ffi_closure_struct_SYSV), @function
        .align  4
 
-ffi_closure_struct_SYSV:
+CALLFUNC(ffi_closure_struct_SYSV):
        CFI_STARTPROC()
        link    %fp,#0
        CFI_OFFSET(14,-8)
@@ -256,14 +271,14 @@ ffi_closure_struct_SYSV:
        move.l  %a1,-(%sp)
        move.l  %a0,-(%sp)
 #if !defined __PIC__
-       jsr     ffi_closure_SYSV_inner
+       jsr     CALLFUNC(ffi_closure_SYSV_inner)
 #else
-       bsr.l   ffi_closure_SYSV_inner@PLTPC
+       bsr.l   CALLFUNC(ffi_closure_SYSV_inner@PLTPC)
 #endif
        unlk    %fp
        rts
        CFI_ENDPROC()
-       .size   ffi_closure_struct_SYSV,.-ffi_closure_struct_SYSV
+       .size   CALLFUNC(ffi_closure_struct_SYSV),.-CALLFUNC(ffi_closure_struct_SYSV)
 
 #if defined __ELF__ && defined __linux__
        .section        .note.GNU-stack,"",@progbits
index ee03dab698981e0bc43d94f0396e28af414c2e13..dd897f4c631c4f3f0d7f6490d1ad5a096eeebf23 100644 (file)
@@ -1065,10 +1065,10 @@ ffi_prep_closure_loc (ffi_closure* closure,
       closure->cif = cif;
       closure->fun = fun;
       closure->user_data = user_data;
+      break;
 
     default:
-
-      FFI_ASSERT(0);
+      return FFI_BAD_ABI;
       break;
     }
   return FFI_OK;
@@ -1235,7 +1235,7 @@ ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
          if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
            size_al = ALIGN(arg_types[i]->size, 8);
 #  if defined(POWERPC64)
-         FFI_ASSERT (cif->abi != FFI_DARWIN)
+         FFI_ASSERT (cif->abi != FFI_DARWIN);
          avalue[i] = pgr;
          pgr += (size_al + 7) / 8;
 #  else
index eb6834199b1ca0a5c15a042bcab0433ecab63343..5d1924bbe584cfd1fe1e6d5ed83101023b7a4d4f 100644 (file)
@@ -139,6 +139,9 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
   if (cif->rtype->type == FFI_TYPE_STRUCT
 #ifdef SPARC
       && (cif->abi != FFI_V9 || cif->rtype->size > 32)
+#endif
+#ifdef TILE
+      && (cif->rtype->size > 10 * FFI_SIZEOF_ARG)
 #endif
      )
     bytes = STACK_ARG_SIZE(sizeof(void*));
@@ -169,6 +172,16 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
          if (((*ptr)->alignment - 1) & bytes)
            bytes = ALIGN(bytes, (*ptr)->alignment);
 
+#ifdef TILE
+         if (bytes < 10 * FFI_SIZEOF_ARG &&
+             bytes + STACK_ARG_SIZE((*ptr)->size) > 10 * FFI_SIZEOF_ARG)
+           {
+             /* An argument is never split between the 10 parameter
+                registers and the stack.  */
+             bytes = 10 * FFI_SIZEOF_ARG;
+           }
+#endif
+
          bytes += STACK_ARG_SIZE((*ptr)->size);
        }
 #endif
diff --git a/libffi/src/tile/ffi.c b/libffi/src/tile/ffi.c
new file mode 100644 (file)
index 0000000..3a94469
--- /dev/null
@@ -0,0 +1,355 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2012 Tilera Corp.
+
+   TILE Foreign Function Interface
+
+   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
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <arch/abi.h>
+#include <arch/icache.h>
+#include <arch/opcode.h>
+
+
+/* The first 10 registers are used to pass arguments and return values. */
+#define NUM_ARG_REGS 10
+
+/* Performs a raw function call with the given NUM_ARG_REGS register arguments
+   and the specified additional stack arguments (if any). */
+extern void ffi_call_tile(ffi_sarg reg_args[NUM_ARG_REGS],
+                          const ffi_sarg *stack_args,
+                          size_t stack_args_bytes,
+                          void (*fnaddr)(void))
+  FFI_HIDDEN;
+
+/* This handles the raw call from the closure stub, cleaning up the
+   parameters and delegating to ffi_closure_tile_inner. */
+extern void ffi_closure_tile(void) FFI_HIDDEN;
+
+
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  /* We always allocate room for all registers. Even if we don't
+     use them as parameters, they get returned in the same array
+     as struct return values so we need to make room. */
+  if (cif->bytes < NUM_ARG_REGS * FFI_SIZEOF_ARG)
+    cif->bytes = NUM_ARG_REGS * FFI_SIZEOF_ARG;
+
+  if (cif->rtype->size > NUM_ARG_REGS * FFI_SIZEOF_ARG)
+    cif->flags = FFI_TYPE_STRUCT;
+  else
+    cif->flags = FFI_TYPE_INT;
+
+  /* Nothing to do. */
+  return FFI_OK;
+}
+
+
+static long
+assign_to_ffi_arg(ffi_sarg *out, void *in, const ffi_type *type,
+                  int write_to_reg)
+{
+  switch (type->type)
+    {
+    case FFI_TYPE_SINT8:
+      *out = *(SINT8 *)in;
+      return 1;
+
+    case FFI_TYPE_UINT8:
+      *out = *(UINT8 *)in;
+      return 1;
+
+    case FFI_TYPE_SINT16:
+      *out = *(SINT16 *)in;
+      return 1;
+
+    case FFI_TYPE_UINT16:
+      *out = *(UINT16 *)in;
+      return 1;
+
+    case FFI_TYPE_SINT32:
+    case FFI_TYPE_UINT32:
+#ifndef __LP64__
+    case FFI_TYPE_POINTER:
+#endif
+      /* Note that even unsigned 32-bit quantities are sign extended
+         on tilegx when stored in a register.  */
+      *out = *(SINT32 *)in;
+      return 1;
+
+    case FFI_TYPE_FLOAT:
+#ifdef __tilegx__
+      if (write_to_reg)
+        {
+          /* Properly sign extend the value.  */
+          union { float f; SINT32 s32; } val;
+          val.f = *(float *)in;
+          *out = val.s32;
+        }
+      else
+#endif
+        {
+          *(float *)out = *(float *)in;
+        }
+      return 1;
+
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_DOUBLE:
+#ifdef __LP64__
+    case FFI_TYPE_POINTER:
+#endif
+      *(UINT64 *)out = *(UINT64 *)in;
+      return sizeof(UINT64) / FFI_SIZEOF_ARG;
+
+    case FFI_TYPE_STRUCT:
+      memcpy(out, in, type->size);
+      return (type->size + FFI_SIZEOF_ARG - 1) / FFI_SIZEOF_ARG;
+
+    case FFI_TYPE_VOID:
+      /* Must be a return type. Nothing to do. */
+      return 0;
+
+    default:
+      FFI_ASSERT(0);
+      return -1;
+    }
+}
+
+
+void
+ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+{
+  ffi_sarg * const arg_mem = alloca(cif->bytes);
+  ffi_sarg * const reg_args = arg_mem;
+  ffi_sarg * const stack_args = &reg_args[NUM_ARG_REGS];
+  ffi_sarg *argp = arg_mem;
+  ffi_type ** const arg_types = cif->arg_types;
+  const long num_args = cif->nargs;
+  long i;
+
+  if (cif->flags == FFI_TYPE_STRUCT)
+    {
+      /* Pass a hidden pointer to the return value. We make sure there
+         is scratch space for the callee to store the return value even if
+         our caller doesn't care about it. */
+      *argp++ = (intptr_t)(rvalue ? rvalue : alloca(cif->rtype->size));
+
+      /* No more work needed to return anything. */
+      rvalue = NULL;
+    }
+
+  for (i = 0; i < num_args; i++)
+    {
+      ffi_type *type = arg_types[i];
+      void * const arg_in = avalue[i];
+      ptrdiff_t arg_word = argp - arg_mem;
+
+#ifndef __tilegx__
+      /* Doubleword-aligned values are always in an even-number register
+         pair, or doubleword-aligned stack slot if out of registers. */
+      long align = arg_word & (type->alignment > FFI_SIZEOF_ARG);
+      argp += align;
+      arg_word += align;
+#endif
+
+      if (type->type == FFI_TYPE_STRUCT)
+        {
+          const size_t arg_size_in_words =
+            (type->size + FFI_SIZEOF_ARG - 1) / FFI_SIZEOF_ARG;
+
+          if (arg_word < NUM_ARG_REGS &&
+              arg_word + arg_size_in_words > NUM_ARG_REGS)
+            {
+              /* Args are not allowed to span registers and the stack. */
+              argp = stack_args;
+            }
+
+          memcpy(argp, arg_in, type->size);
+          argp += arg_size_in_words;
+        }
+      else
+        {
+          argp += assign_to_ffi_arg(argp, arg_in, arg_types[i], 1);
+        }
+    }
+
+  /* Actually do the call. */
+  ffi_call_tile(reg_args, stack_args,
+                cif->bytes - (NUM_ARG_REGS * FFI_SIZEOF_ARG), fn);
+
+  if (rvalue != NULL)
+    assign_to_ffi_arg(rvalue, reg_args, cif->rtype, 0);
+}
+
+
+/* Template code for closure. */
+extern const UINT64 ffi_template_tramp_tile[] FFI_HIDDEN;
+
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure *closure,
+                      ffi_cif *cif,
+                      void (*fun)(ffi_cif*, void*, void**, void*),
+                      void *user_data,
+                      void *codeloc)
+{
+#ifdef __tilegx__
+  /* TILE-Gx */
+  SINT64 c;
+  SINT64 h;
+  int s;
+  UINT64 *out;
+
+  if (cif->abi != FFI_UNIX)
+    return FFI_BAD_ABI;
+
+  out = (UINT64 *)closure->tramp;
+
+  c = (intptr_t)closure;
+  h = (intptr_t)ffi_closure_tile;
+  s = 0;
+
+  /* Find the smallest shift count that doesn't lose information
+     (i.e. no need to explicitly insert high bits of the address that
+     are just the sign extension of the low bits). */
+  while ((c >> s) != (SINT16)(c >> s) || (h >> s) != (SINT16)(h >> s))
+    s += 16;
+
+#define OPS(a, b, shift) \
+  (create_Imm16_X0((a) >> (shift)) | create_Imm16_X1((b) >> (shift)))
+
+  /* Emit the moveli. */
+  *out++ = ffi_template_tramp_tile[0] | OPS(c, h, s);
+  for (s -= 16; s >= 0; s -= 16)
+    *out++ = ffi_template_tramp_tile[1] | OPS(c, h, s);
+
+#undef OPS
+
+  *out++ = ffi_template_tramp_tile[2];
+
+#else
+  /* TILEPro */
+  UINT64 *out;
+  intptr_t delta;
+
+  if (cif->abi != FFI_UNIX)
+    return FFI_BAD_ABI;
+
+  out = (UINT64 *)closure->tramp;
+  delta = (intptr_t)ffi_closure_tile - (intptr_t)codeloc;
+
+  *out++ = ffi_template_tramp_tile[0] | create_JOffLong_X1(delta >> 3);
+#endif
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+  invalidate_icache(closure->tramp, (char *)out - closure->tramp,
+                    getpagesize());
+
+  return FFI_OK;
+}
+
+
+/* This is called by the assembly wrapper for closures. This does
+   all of the work. On entry reg_args[0] holds the values the registers
+   had when the closure was invoked. On return reg_args[1] holds the register
+   values to be returned to the caller (many of which may be garbage). */
+void FFI_HIDDEN
+ffi_closure_tile_inner(ffi_closure *closure,
+                       ffi_sarg reg_args[2][NUM_ARG_REGS],
+                       ffi_sarg *stack_args)
+{
+  ffi_cif * const cif = closure->cif;
+  void ** const avalue = alloca(cif->nargs * sizeof(void *));
+  void *rvalue;
+  ffi_type ** const arg_types = cif->arg_types;
+  ffi_sarg * const reg_args_in = reg_args[0];
+  ffi_sarg * const reg_args_out = reg_args[1];
+  ffi_sarg * argp;
+  long i, arg_word, nargs = cif->nargs;
+  /* Use a union to guarantee proper alignment for double. */
+  union { ffi_sarg arg[NUM_ARG_REGS]; double d; UINT64 u64; } closure_ret;
+
+  /* Start out reading register arguments. */
+  argp = reg_args_in;
+
+  /* Copy the caller's structure return address to that the closure
+     returns the data directly to the caller.  */
+  if (cif->flags == FFI_TYPE_STRUCT)
+    {
+      /* Return by reference via hidden pointer. */
+      rvalue = (void *)(intptr_t)*argp++;
+      arg_word = 1;
+    }
+  else
+    {
+      /* Return the value in registers. */
+      rvalue = &closure_ret;
+      arg_word = 0;
+    }
+
+  /* Grab the addresses of the arguments. */
+  for (i = 0; i < nargs; i++)
+    {
+      ffi_type * const type = arg_types[i];
+      const size_t arg_size_in_words =
+        (type->size + FFI_SIZEOF_ARG - 1) / FFI_SIZEOF_ARG;
+
+#ifndef __tilegx__
+      /* Doubleword-aligned values are always in an even-number register
+         pair, or doubleword-aligned stack slot if out of registers. */
+      long align = arg_word & (type->alignment > FFI_SIZEOF_ARG);
+      argp += align;
+      arg_word += align;
+#endif
+
+      if (arg_word == NUM_ARG_REGS ||
+          (arg_word < NUM_ARG_REGS &&
+           arg_word + arg_size_in_words > NUM_ARG_REGS))
+        {
+          /* Switch to reading arguments from the stack. */
+          argp = stack_args;
+          arg_word = NUM_ARG_REGS;
+        }
+
+      avalue[i] = argp;
+      argp += arg_size_in_words;
+      arg_word += arg_size_in_words;
+    }
+
+  /* Invoke the closure.  */
+  closure->fun(cif, rvalue, avalue, closure->user_data);
+
+  if (cif->flags != FFI_TYPE_STRUCT)
+    {
+      /* Canonicalize for register representation. */
+      assign_to_ffi_arg(reg_args_out, &closure_ret, cif->rtype, 1);
+    }
+}
diff --git a/libffi/src/tile/ffitarget.h b/libffi/src/tile/ffitarget.h
new file mode 100644 (file)
index 0000000..679fb5d
--- /dev/null
@@ -0,0 +1,65 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 2012 Tilera Corp.
+   Target configuration macros for TILE.
+
+   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
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_H
+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."
+#endif
+
+#ifndef LIBFFI_ASM
+
+#include <arch/abi.h>
+
+typedef uint_reg_t ffi_arg;
+typedef int_reg_t  ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_UNIX,
+  FFI_LAST_ABI,
+  FFI_DEFAULT_ABI = FFI_UNIX
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+#define FFI_CLOSURES 1
+
+#ifdef __tilegx__
+/* We always pass 8-byte values, even in -m32 mode. */
+# define FFI_SIZEOF_ARG 8
+# ifdef __LP64__
+#  define FFI_TRAMPOLINE_SIZE (8 * 5)  /* 5 bundles */
+# else
+#  define FFI_TRAMPOLINE_SIZE (8 * 3)  /* 3 bundles */
+# endif
+#else
+# define FFI_SIZEOF_ARG 4
+# define FFI_TRAMPOLINE_SIZE 8 /* 1 bundle */
+#endif
+#define FFI_NATIVE_RAW_API 0
+
+#endif
diff --git a/libffi/src/tile/tile.S b/libffi/src/tile/tile.S
new file mode 100644 (file)
index 0000000..a186e1f
--- /dev/null
@@ -0,0 +1,360 @@
+/* -----------------------------------------------------------------------
+   tile.S - Copyright (c) 2011 Tilera Corp.
+
+   Tilera TILEPro and TILE-Gx Foreign Function Interface
+
+   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
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+/* Number of bytes in a register. */
+#define REG_SIZE FFI_SIZEOF_ARG
+
+/* Number of bytes in stack linkage area for backtracing.
+
+   A note about the ABI: on entry to a procedure, sp points to a stack
+   slot where it must spill the return address if it's not a leaf.
+   REG_SIZE bytes beyond that is a slot owned by the caller which
+   contains the sp value that the caller had when it was originally
+   entered (i.e. the caller's frame pointer). */
+#define LINKAGE_SIZE (2 * REG_SIZE)
+
+/* The first 10 registers are used to pass arguments and return values. */
+#define NUM_ARG_REGS 10
+
+#ifdef __tilegx__
+#define SW st
+#define LW ld
+#define BGZT bgtzt
+#else
+#define SW sw
+#define LW lw
+#define BGZT bgzt
+#endif
+
+
+/* void ffi_call_tile (int_reg_t reg_args[NUM_ARG_REGS],
+                       const int_reg_t *stack_args,
+                       unsigned long stack_args_bytes,
+                       void (*fnaddr)(void));
+
+        On entry, REG_ARGS contain the outgoing register values,
+        and STACK_ARGS containts STACK_ARG_BYTES of additional values
+        to be passed on the stack. If STACK_ARG_BYTES is zero, then
+        STACK_ARGS is ignored.
+
+        When the invoked function returns, the values of r0-r9 are
+        blindly stored back into REG_ARGS for the caller to examine. */
+
+        .section .text.ffi_call_tile, "ax", @progbits
+        .align  8
+        .globl  ffi_call_tile
+        FFI_HIDDEN(ffi_call_tile)
+ffi_call_tile:
+
+/* Incoming arguments. */
+#define REG_ARGS                r0
+#define INCOMING_STACK_ARGS     r1
+#define STACK_ARG_BYTES         r2
+#define ORIG_FNADDR             r3
+
+/* Temporary values. */
+#define FRAME_SIZE              r10
+#define TMP                     r11
+#define TMP2                    r12
+#define OUTGOING_STACK_ARGS     r13
+#define REG_ADDR_PTR            r14
+#define RETURN_REG_ADDR         r15
+#define FNADDR                  r16
+
+        .cfi_startproc
+        {
+         /* Save return address. */
+         SW     sp, lr
+         .cfi_offset lr, 0
+         /* Prepare to spill incoming r52. */
+         addi   TMP, sp, -REG_SIZE
+         /* Increase frame size to have room to spill r52 and REG_ARGS.
+            The +7 is to round up mod 8. */
+         addi   FRAME_SIZE, STACK_ARG_BYTES, \
+                REG_SIZE + REG_SIZE + LINKAGE_SIZE + 7
+        }
+        {
+         /* Round stack frame size to a multiple of 8 to satisfy ABI. */
+         andi   FRAME_SIZE, FRAME_SIZE, -8
+         /* Compute where to spill REG_ARGS value. */
+         addi   TMP2, sp, -(REG_SIZE * 2)
+        }
+        {
+         /* Spill incoming r52. */
+         SW     TMP, r52
+         .cfi_offset r52, -REG_SIZE
+         /* Set up our frame pointer. */
+         move   r52, sp
+         .cfi_def_cfa_register r52
+         /* Push stack frame. */
+         sub    sp, sp, FRAME_SIZE
+        }
+        {
+         /* Prepare to set up stack linkage. */
+         addi   TMP, sp, REG_SIZE
+         /* Prepare to memcpy stack args. */
+         addi   OUTGOING_STACK_ARGS, sp, LINKAGE_SIZE
+         /* Save REG_ARGS which we will need after we call the subroutine. */
+         SW     TMP2, REG_ARGS
+        }
+        {
+         /* Set up linkage info to hold incoming stack pointer. */
+         SW     TMP, r52
+        }
+        {
+         /* Skip stack args memcpy if we don't have any stack args (common). */
+         blezt  STACK_ARG_BYTES, .Ldone_stack_args_memcpy
+        }
+
+.Lmemcpy_stack_args:
+        {
+         /* Load incoming argument from stack_args. */
+         LW     TMP, INCOMING_STACK_ARGS
+         addi   INCOMING_STACK_ARGS, INCOMING_STACK_ARGS, REG_SIZE
+        }
+        {
+         /* Store stack argument into outgoing stack argument area. */
+         SW     OUTGOING_STACK_ARGS, TMP
+         addi   OUTGOING_STACK_ARGS, OUTGOING_STACK_ARGS, REG_SIZE
+         addi   STACK_ARG_BYTES, STACK_ARG_BYTES, -REG_SIZE
+        }
+        {
+         BGZT   STACK_ARG_BYTES, .Lmemcpy_stack_args
+        }
+.Ldone_stack_args_memcpy:
+
+        {
+         /* Copy aside ORIG_FNADDR so we can overwrite its register. */
+         move   FNADDR, ORIG_FNADDR
+         /* Prepare to load argument registers. */
+         addi   REG_ADDR_PTR, r0, REG_SIZE
+         /* Load outgoing r0. */
+         LW     r0, r0
+        }
+
+        /* Load up argument registers from the REG_ARGS array. */
+#define LOAD_REG(REG, PTR) \
+        { \
+         LW     REG, PTR ; \
+         addi   PTR, PTR, REG_SIZE \
+        }
+
+        LOAD_REG(r1, REG_ADDR_PTR)
+        LOAD_REG(r2, REG_ADDR_PTR)
+        LOAD_REG(r3, REG_ADDR_PTR)
+        LOAD_REG(r4, REG_ADDR_PTR)
+        LOAD_REG(r5, REG_ADDR_PTR)
+        LOAD_REG(r6, REG_ADDR_PTR)
+        LOAD_REG(r7, REG_ADDR_PTR)
+        LOAD_REG(r8, REG_ADDR_PTR)
+        LOAD_REG(r9, REG_ADDR_PTR)
+
+        {
+         /* Call the subroutine. */
+         jalr   FNADDR
+        }
+
+        {
+         /* Restore original lr. */
+         LW     lr, r52
+         /* Prepare to recover ARGS, which we spilled earlier. */
+         addi   TMP, r52, -(2 * REG_SIZE)
+        }
+        {
+         /* Restore ARGS, so we can fill it in with the return regs r0-r9. */
+         LW     RETURN_REG_ADDR, TMP
+         /* Prepare to restore original r52. */
+         addi   TMP, r52, -REG_SIZE
+        }
+
+        {
+         /* Pop stack frame. */
+         move   sp, r52
+         /* Restore original r52. */
+         LW     r52, TMP
+        }
+
+#define STORE_REG(REG, PTR) \
+        { \
+         SW     PTR, REG ; \
+         addi   PTR, PTR, REG_SIZE \
+        }
+
+        /* Return all register values by reference. */
+        STORE_REG(r0, RETURN_REG_ADDR)
+        STORE_REG(r1, RETURN_REG_ADDR)
+        STORE_REG(r2, RETURN_REG_ADDR)
+        STORE_REG(r3, RETURN_REG_ADDR)
+        STORE_REG(r4, RETURN_REG_ADDR)
+        STORE_REG(r5, RETURN_REG_ADDR)
+        STORE_REG(r6, RETURN_REG_ADDR)
+        STORE_REG(r7, RETURN_REG_ADDR)
+        STORE_REG(r8, RETURN_REG_ADDR)
+        STORE_REG(r9, RETURN_REG_ADDR)
+
+        {
+         jrp    lr
+        }
+
+        .cfi_endproc
+        .size ffi_call_tile, .-ffi_call_tile
+
+/* ffi_closure_tile(...)
+
+   On entry, lr points to the closure plus 8 bytes, and r10
+   contains the actual return address.
+
+   This function simply dumps all register parameters into a stack array
+   and passes the closure, the registers array, and the stack arguments
+   to C code that does all of the actual closure processing. */
+
+        .section .text.ffi_closure_tile, "ax", @progbits
+        .align  8
+        .globl  ffi_closure_tile
+        FFI_HIDDEN(ffi_closure_tile)
+
+        .cfi_startproc
+/* Room to spill all NUM_ARG_REGS incoming registers, plus frame linkage. */
+#define CLOSURE_FRAME_SIZE (((NUM_ARG_REGS * REG_SIZE * 2 + LINKAGE_SIZE) + 7) & -8)
+ffi_closure_tile:
+        {
+#ifdef __tilegx__
+         st     sp, lr
+         .cfi_offset lr, 0
+#else
+         /* Save return address (in r10 due to closure stub wrapper). */
+         SW     sp, r10
+         .cfi_return_column r10
+         .cfi_offset r10, 0
+#endif
+         /* Compute address for stack frame linkage. */
+         addli   r10, sp, -(CLOSURE_FRAME_SIZE - REG_SIZE)
+        }
+        {
+         /* Save incoming stack pointer in linkage area. */
+         SW     r10, sp
+         .cfi_offset sp, -(CLOSURE_FRAME_SIZE - REG_SIZE)
+         /* Push a new stack frame. */
+         addli   sp, sp, -CLOSURE_FRAME_SIZE
+         .cfi_adjust_cfa_offset CLOSURE_FRAME_SIZE
+        }
+
+        {
+         /* Create pointer to where to start spilling registers. */
+         addi   r10, sp, LINKAGE_SIZE
+        }
+
+        /* Spill all the incoming registers. */
+        STORE_REG(r0, r10)
+        STORE_REG(r1, r10)
+        STORE_REG(r2, r10)
+        STORE_REG(r3, r10)
+        STORE_REG(r4, r10)
+        STORE_REG(r5, r10)
+        STORE_REG(r6, r10)
+        STORE_REG(r7, r10)
+        STORE_REG(r8, r10)
+        {
+         /* Save r9. */
+         SW     r10, r9
+#ifdef __tilegx__
+         /* Pointer to closure is passed in r11. */
+         move  r0, r11
+#else
+         /* Compute pointer to the closure object. Because the closure
+            starts with a "jal ffi_closure_tile", we can just take the
+            value of lr (a phony return address pointing into the closure)
+            and subtract 8. */
+         addi   r0, lr, -8
+#endif
+         /* Compute a pointer to the register arguments we just spilled. */
+         addi   r1, sp, LINKAGE_SIZE
+        }
+        {
+         /* Compute a pointer to the extra stack arguments (if any). */
+         addli   r2, sp, CLOSURE_FRAME_SIZE + LINKAGE_SIZE
+         /* Call C code to deal with all of the grotty details. */
+         jal    ffi_closure_tile_inner
+        }
+        {
+         addli   r10, sp, CLOSURE_FRAME_SIZE
+        }
+        {
+         /* Restore the return address. */
+         LW     lr, r10
+         /* Compute pointer to registers array. */
+         addli   r10, sp, LINKAGE_SIZE + (NUM_ARG_REGS * REG_SIZE)
+        }
+        /* Return all the register values, which C code may have set. */
+        LOAD_REG(r0, r10)
+        LOAD_REG(r1, r10)
+        LOAD_REG(r2, r10)
+        LOAD_REG(r3, r10)
+        LOAD_REG(r4, r10)
+        LOAD_REG(r5, r10)
+        LOAD_REG(r6, r10)
+        LOAD_REG(r7, r10)
+        LOAD_REG(r8, r10)
+        LOAD_REG(r9, r10)
+        {
+         /* Pop the frame. */
+         addli   sp, sp, CLOSURE_FRAME_SIZE
+         jrp    lr
+        }
+
+        .cfi_endproc
+        .size   ffi_closure_tile, . - ffi_closure_tile
+
+
+/* What follows are code template instructions that get copied to the
+   closure trampoline by ffi_prep_closure_loc.  The zeroed operands
+   get replaced by their proper values at runtime. */
+
+        .section .text.ffi_template_tramp_tile, "ax", @progbits
+        .align  8
+        .globl  ffi_template_tramp_tile
+        FFI_HIDDEN(ffi_template_tramp_tile)
+ffi_template_tramp_tile:
+#ifdef __tilegx__
+        {
+          moveli r11, 0 /* backpatched to address of containing closure. */
+          moveli r10, 0 /* backpatched to ffi_closure_tile. */
+        }
+        /* Note: the following bundle gets generated multiple times
+           depending on the pointer value (esp. useful for -m32 mode). */
+        { shl16insli r11, r11, 0 ; shl16insli r10, r10, 0 }
+        { info 2+8 /* for backtracer: -> pc in lr, frame size 0 */ ; jr r10 }
+#else
+        /* 'jal .' yields a PC-relative offset of zero so we can OR in the
+           right offset at runtime. */
+        { move r10, lr ; jal . /* ffi_closure_tile */ }
+#endif
+
+        .size   ffi_template_tramp_tile, . - ffi_template_tramp_tile
index f643b345cba89196fbaa95fa8fb6787d4f1bd419..611e22197169a65b90f8eae1556fe83c04499be1 100644 (file)
@@ -58,7 +58,8 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
 
   argp = stack;
 
-  if (ecif->cif->flags == FFI_TYPE_STRUCT
+  if ((ecif->cif->flags == FFI_TYPE_STRUCT
+       || ecif->cif->flags == FFI_TYPE_MS_STRUCT)
 #ifdef X86_WIN64
       && (ecif->cif->rtype->size != 1 && ecif->cif->rtype->size != 2
           && ecif->cif->rtype->size != 4 && ecif->cif->rtype->size != 8)
@@ -279,7 +280,12 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
       else
 #endif
         {
-          cif->flags = FFI_TYPE_STRUCT;
+#ifdef X86_WIN32
+          if (cif->abi == FFI_MS_CDECL)
+            cif->flags = FFI_TYPE_MS_STRUCT;
+          else
+#endif
+            cif->flags = FFI_TYPE_STRUCT;
           /* allocate space for return value pointer */
           cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
         }
@@ -349,7 +355,8 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
     }
 #else
   if (rvalue == NULL
-      && cif->flags == FFI_TYPE_STRUCT)
+      && (cif->flags == FFI_TYPE_STRUCT
+          || cif->flags == FFI_TYPE_MS_STRUCT))
     {
       ecif.rvalue = alloca(cif->rtype->size);
     }
@@ -368,6 +375,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
 #elif defined(X86_WIN32)
     case FFI_SYSV:
     case FFI_STDCALL:
+    case FFI_MS_CDECL:
       ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags,
                     ecif.rvalue, fn);
       break;
@@ -513,7 +521,8 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
     argp += sizeof(void *);
   }
 #else
-  if ( cif->flags == FFI_TYPE_STRUCT ) {
+  if ( cif->flags == FFI_TYPE_STRUCT
+       || cif->flags == FFI_TYPE_MS_STRUCT ) {
     *rvalue = *(void **) argp;
     argp += sizeof(void *);
   }
@@ -673,6 +682,12 @@ ffi_prep_closure_loc (ffi_closure* closure,
                                    &ffi_closure_STDCALL,
                                    (void*)codeloc, cif->bytes);
     }
+  else if (cif->abi == FFI_MS_CDECL)
+    {
+      FFI_INIT_TRAMPOLINE (&closure->tramp[0],
+                           &ffi_closure_SYSV,
+                           (void*)codeloc);
+    }
 #endif /* X86_WIN32 */
 #endif /* !X86_WIN64 */
   else
@@ -762,8 +777,9 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
   /* 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->flags == FFI_TYPE_STRUCT
+          || cif->flags == FFI_TYPE_MS_STRUCT))
     {
       ecif.rvalue = alloca(cif->rtype->size);
     }
@@ -776,6 +792,7 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
 #ifdef X86_WIN32
     case FFI_SYSV:
     case FFI_STDCALL:
+    case FFI_MS_CDECL:
       ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags,
                     ecif.rvalue, fn);
       break;
index defd7744cce09b7d1bb59ee5019c5fa96fb72203..1daa1c0b6fd84ea47acd27a1d16047265ee980eb 100644 (file)
 #define MAX_GPR_REGS 6
 #define MAX_SSE_REGS 8
 
+#ifdef __INTEL_COMPILER
+#define UINT128 __m128
+#else
+#define UINT128 __int128_t
+#endif
+
 struct register_args
 {
   /* Registers for argument passing.  */
   UINT64 gpr[MAX_GPR_REGS];
-  __int128_t sse[MAX_SSE_REGS];
+  UINT128 sse[MAX_SSE_REGS];
 };
 
 extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
index fc01541097035d7a2e3b761165c5ac1c7e60804e..46f294cea723d2560ad7b848bce74ab751e1c919 100644 (file)
@@ -81,9 +81,13 @@ typedef enum ffi_abi {
   FFI_STDCALL,
   FFI_THISCALL,
   FFI_FASTCALL,
+  FFI_MS_CDECL,
   FFI_LAST_ABI,
-  /* TODO: Add fastcall support for the sake of completeness */
+#ifdef _MSC_VER
+  FFI_DEFAULT_ABI = FFI_MS_CDECL
+#else
   FFI_DEFAULT_ABI = FFI_SYSV
+#endif
 
 #elif defined(X86_WIN64)
   FFI_WIN64,
@@ -110,6 +114,7 @@ typedef enum ffi_abi {
 #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
 #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
 #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
+#define FFI_TYPE_MS_STRUCT       (FFI_TYPE_LAST + 4)
 
 #if defined (X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
 #define FFI_TRAMPOLINE_SIZE 24
index deb4a0394d866246f87af6e9bd78f9eee0163d4d..24b7bbd04235b6aa6c79848343aa8b21ad1a9078 100644 (file)
@@ -108,31 +108,37 @@ ca_jumpdata:
         dd offset ca_retfloat       ;; FFI_TYPE_FLOAT
         dd offset ca_retdouble      ;; FFI_TYPE_DOUBLE
         dd offset ca_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
-        dd offset ca_retint8        ;; FFI_TYPE_UINT8
-        dd offset ca_retint8        ;; FFI_TYPE_SINT8
-        dd offset ca_retint16       ;; FFI_TYPE_UINT16
-        dd offset ca_retint16       ;; FFI_TYPE_SINT16
+        dd offset ca_retuint8       ;; FFI_TYPE_UINT8
+        dd offset ca_retsint8       ;; FFI_TYPE_SINT8
+        dd offset ca_retuint16      ;; FFI_TYPE_UINT16
+        dd offset ca_retsint16      ;; FFI_TYPE_SINT16
         dd offset ca_retint         ;; FFI_TYPE_UINT32
         dd offset ca_retint         ;; FFI_TYPE_SINT32
         dd offset ca_retint64       ;; FFI_TYPE_UINT64
         dd offset ca_retint64       ;; FFI_TYPE_SINT64
         dd offset ca_epilogue       ;; FFI_TYPE_STRUCT
         dd offset ca_retint         ;; FFI_TYPE_POINTER
-        dd offset ca_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
-        dd offset ca_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
+        dd offset ca_retstruct1b    ;; FFI_TYPE_SMALL_STRUCT_1B
+        dd offset ca_retstruct2b    ;; FFI_TYPE_SMALL_STRUCT_2B
         dd offset ca_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+        dd offset ca_epilogue       ;; FFI_TYPE_MS_STRUCT
 
-ca_retint8:
-        ;; Load %ecx with the pointer to storage for the return value
-        mov   ecx, rvalue
-        mov   [ecx + 0], al
-        jmp   ca_epilogue
+        /* Sign/zero extend as appropriate.  */
+ca_retuint8:
+        movzx eax, al
+        jmp   ca_retint
 
-ca_retint16:
-        ;; Load %ecx with the pointer to storage for the return value
-        mov   ecx, rvalue
-        mov   [ecx + 0], ax
-        jmp   ca_epilogue
+ca_retsint8:
+        movsx eax, al
+        jmp   ca_retint
+
+ca_retuint16:
+        movzx eax, ax
+        jmp   ca_retint
+
+ca_retsint16:
+        movsx eax, ax
+        jmp   ca_retint
 
 ca_retint:
         ;; Load %ecx with the pointer to storage for the return value
@@ -165,14 +171,24 @@ ca_retlongdouble:
         fstp  TBYTE PTR [ecx]
         jmp   ca_epilogue
 
+ca_retstruct1b:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        mov   [ecx + 0], al
+        jmp   ca_epilogue
+
+ca_retstruct2b:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        mov   [ecx + 0], ax
+        jmp   ca_epilogue
+
 ca_epilogue:
         ;; Epilogue code is autogenerated.
         ret
 ffi_call_win32 ENDP
 
 ffi_closure_THISCALL PROC NEAR FORCEFRAME
-       push    ebp
-       mov     ebp, esp
        sub     esp, 40
        lea     edx, [ebp -24]
        mov     [ebp - 12], edx /* resp */
@@ -187,7 +203,7 @@ ffi_closure_SYSV PROC NEAR FORCEFRAME
         lea  edx, [ebp - 24]
         mov  [ebp - 12], edx         ;; resp
         lea  edx, [ebp + 8]
-stub:
+stub::
         mov  [esp + 8], edx          ;; args
         lea  edx, [ebp - 12]
         mov  [esp + 4], edx          ;; &resp
@@ -204,26 +220,35 @@ cs_jumpdata:
         dd offset cs_retfloat       ;; FFI_TYPE_FLOAT
         dd offset cs_retdouble      ;; FFI_TYPE_DOUBLE
         dd offset cs_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
-        dd offset cs_retint8        ;; FFI_TYPE_UINT8
-        dd offset cs_retint8        ;; FFI_TYPE_SINT8
-        dd offset cs_retint16       ;; FFI_TYPE_UINT16
-        dd offset cs_retint16       ;; FFI_TYPE_SINT16
+        dd offset cs_retuint8       ;; FFI_TYPE_UINT8
+        dd offset cs_retsint8       ;; FFI_TYPE_SINT8
+        dd offset cs_retuint16      ;; FFI_TYPE_UINT16
+        dd offset cs_retsint16      ;; FFI_TYPE_SINT16
         dd offset cs_retint         ;; FFI_TYPE_UINT32
         dd offset cs_retint         ;; FFI_TYPE_SINT32
         dd offset cs_retint64       ;; FFI_TYPE_UINT64
         dd offset cs_retint64       ;; FFI_TYPE_SINT64
         dd offset cs_retstruct      ;; FFI_TYPE_STRUCT
         dd offset cs_retint         ;; FFI_TYPE_POINTER
-        dd offset cs_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
-        dd offset cs_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
+        dd offset cs_retsint8       ;; FFI_TYPE_SMALL_STRUCT_1B
+        dd offset cs_retsint16      ;; FFI_TYPE_SMALL_STRUCT_2B
         dd offset cs_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+        dd offset cs_retmsstruct    ;; FFI_TYPE_MS_STRUCT
+
+cs_retuint8:
+        movzx eax, BYTE PTR [ecx]
+        jmp   cs_epilogue
+
+cs_retsint8:
+        movsx eax, BYTE PTR [ecx]
+        jmp   cs_epilogue
 
-cs_retint8:
-        mov   al, [ecx]
+cs_retuint16:
+        movzx eax, WORD PTR [ecx]
         jmp   cs_epilogue
 
-cs_retint16:
-        mov   ax, [ecx]
+cs_retsint16:
+        movsx eax, WORD PTR [ecx]
         jmp   cs_epilogue
 
 cs_retint:
@@ -252,6 +277,12 @@ cs_retstruct:
         ;; Epilogue code is autogenerated.
         ret    4
 
+cs_retmsstruct:
+        ;; Caller expects us to return a pointer to the real return value.
+        mov   eax, ecx
+        ;; Caller doesn't expects us to pop struct return value pointer hidden arg.
+        jmp   cs_epilogue
+
 cs_epilogue:
         ;; Epilogue code is autogenerated.
         ret
@@ -264,19 +295,16 @@ ffi_closure_SYSV ENDP
 #define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
 #define CIF_FLAGS_OFFSET 20
 
-ffi_closure_raw_THISCALL PROC NEAR
-       push ebp
-       mov  ebp, esp
-       push esi
+ffi_closure_raw_THISCALL PROC NEAR USES esi FORCEFRAME
        sub esp, 36
        mov  esi, [eax + RAW_CLOSURE_CIF_OFFSET]        ;; closure->cif
        mov  edx, [eax + RAW_CLOSURE_USER_DATA_OFFSET]  ;; closure->user_data
        mov [esp + 12], edx
-       lea edx, [ebp + 12], edx
+       lea edx, [ebp + 12]
        jmp stubraw
-ffi_closure_raw_SYSV ENDP
+ffi_closure_raw_THISCALL ENDP
 
-ffi_closure_raw_SYSV PROC NEAR USES esi
+ffi_closure_raw_SYSV PROC NEAR USES esi FORCEFRAME
     ;; the ffi_closure ctx is passed in eax by the trampoline.
 
         sub  esp, 40
@@ -284,7 +312,7 @@ ffi_closure_raw_SYSV PROC NEAR USES esi
         mov  edx, [eax + RAW_CLOSURE_USER_DATA_OFFSET]  ;; closure->user_data
         mov  [esp + 12], edx                            ;; user_data
         lea  edx, [ebp + 8]
-stubraw:
+stubraw::
         mov  [esp + 8], edx                             ;; raw_args
         lea  edx, [ebp - 24]
         mov  [esp + 4], edx                             ;; &res
@@ -302,26 +330,35 @@ cr_jumpdata:
         dd offset cr_retfloat       ;; FFI_TYPE_FLOAT
         dd offset cr_retdouble      ;; FFI_TYPE_DOUBLE
         dd offset cr_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
-        dd offset cr_retint8        ;; FFI_TYPE_UINT8
-        dd offset cr_retint8        ;; FFI_TYPE_SINT8
-        dd offset cr_retint16       ;; FFI_TYPE_UINT16
-        dd offset cr_retint16       ;; FFI_TYPE_SINT16
+        dd offset cr_retuint8       ;; FFI_TYPE_UINT8
+        dd offset cr_retsint8       ;; FFI_TYPE_SINT8
+        dd offset cr_retuint16      ;; FFI_TYPE_UINT16
+        dd offset cr_retsint16      ;; FFI_TYPE_SINT16
         dd offset cr_retint         ;; FFI_TYPE_UINT32
         dd offset cr_retint         ;; FFI_TYPE_SINT32
         dd offset cr_retint64       ;; FFI_TYPE_UINT64
         dd offset cr_retint64       ;; FFI_TYPE_SINT64
         dd offset cr_epilogue       ;; FFI_TYPE_STRUCT
         dd offset cr_retint         ;; FFI_TYPE_POINTER
-        dd offset cr_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
-        dd offset cr_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
+        dd offset cr_retsint8       ;; FFI_TYPE_SMALL_STRUCT_1B
+        dd offset cr_retsint16      ;; FFI_TYPE_SMALL_STRUCT_2B
         dd offset cr_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+        dd offset cr_epilogue       ;; FFI_TYPE_MS_STRUCT
+
+cr_retuint8:
+        movzx eax, BYTE PTR [ecx]
+        jmp   cr_epilogue
+
+cr_retsint8:
+        movsx eax, BYTE PTR [ecx]
+        jmp   cr_epilogue
 
-cr_retint8:
-        mov   al, [ecx]
+cr_retuint16:
+        movzx eax, WORD PTR [ecx]
         jmp   cr_epilogue
 
-cr_retint16:
-        mov   ax, [ecx]
+cr_retsint16:
+        movsx eax, WORD PTR [ecx]
         jmp   cr_epilogue
 
 cr_retint:
@@ -375,26 +412,34 @@ cd_jumpdata:
         dd offset cd_retfloat       ;; FFI_TYPE_FLOAT
         dd offset cd_retdouble      ;; FFI_TYPE_DOUBLE
         dd offset cd_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
-        dd offset cd_retint8        ;; FFI_TYPE_UINT8
-        dd offset cd_retint8        ;; FFI_TYPE_SINT8
-        dd offset cd_retint16       ;; FFI_TYPE_UINT16
-        dd offset cd_retint16       ;; FFI_TYPE_SINT16
+        dd offset cd_retuint8       ;; FFI_TYPE_UINT8
+        dd offset cd_retsint8       ;; FFI_TYPE_SINT8
+        dd offset cd_retuint16      ;; FFI_TYPE_UINT16
+        dd offset cd_retsint16      ;; FFI_TYPE_SINT16
         dd offset cd_retint         ;; FFI_TYPE_UINT32
         dd offset cd_retint         ;; FFI_TYPE_SINT32
         dd offset cd_retint64       ;; FFI_TYPE_UINT64
         dd offset cd_retint64       ;; FFI_TYPE_SINT64
         dd offset cd_epilogue       ;; FFI_TYPE_STRUCT
         dd offset cd_retint         ;; FFI_TYPE_POINTER
-        dd offset cd_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
-        dd offset cd_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
+        dd offset cd_retsint8       ;; FFI_TYPE_SMALL_STRUCT_1B
+        dd offset cd_retsint16      ;; FFI_TYPE_SMALL_STRUCT_2B
         dd offset cd_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
 
-cd_retint8:
-        mov   al, [ecx]
+cd_retuint8:
+        movzx eax, BYTE PTR [ecx]
+        jmp   cd_epilogue
+
+cd_retsint8:
+        movsx eax, BYTE PTR [ecx]
         jmp   cd_epilogue
 
-cd_retint16:
-        mov   ax, [ecx]
+cd_retuint16:
+        movzx eax, WORD PTR [ecx]
+        jmp   cd_epilogue
+
+cd_retsint16:
+        movsx eax, WORD PTR [ecx]
         jmp   cd_epilogue
 
 cd_retint:
@@ -515,6 +560,7 @@ _ffi_call_win32:
        .long   .Lretstruct1b           /* FFI_TYPE_SMALL_STRUCT_1B */
        .long   .Lretstruct2b           /* FFI_TYPE_SMALL_STRUCT_2B */
        .long   .Lretstruct4b           /* FFI_TYPE_SMALL_STRUCT_4B */
+       .long   .Lretstruct             /* FFI_TYPE_MS_STRUCT */
 1:
        add     %ecx, %ecx
        add     %ecx, %ecx
@@ -657,6 +703,7 @@ _ffi_closure_SYSV:
        .long   .Lcls_retstruct1        /* FFI_TYPE_SMALL_STRUCT_1B */
        .long   .Lcls_retstruct2        /* FFI_TYPE_SMALL_STRUCT_2B */
        .long   .Lcls_retstruct4        /* FFI_TYPE_SMALL_STRUCT_4B */
+       .long   .Lcls_retmsstruct       /* FFI_TYPE_MS_STRUCT */
 
 1:
        add     %eax, %eax
@@ -721,6 +768,12 @@ _ffi_closure_SYSV:
        popl    %ebp
        ret     $0x4
 
+.Lcls_retmsstruct:
+       # Caller expects us to return a pointer to the real return value.
+       mov     %ecx, %eax
+       # Caller doesn't expects us to pop struct return value pointer hidden arg.
+       jmp     .Lcls_epilogue
+
 .Lcls_noretval:
 .Lcls_epilogue:
        movl    %ebp, %esp
@@ -798,6 +851,7 @@ _ffi_closure_raw_SYSV:
        .long   .Lrcls_retstruct1       /* FFI_TYPE_SMALL_STRUCT_1B */
        .long   .Lrcls_retstruct2       /* FFI_TYPE_SMALL_STRUCT_2B */
        .long   .Lrcls_retstruct4       /* FFI_TYPE_SMALL_STRUCT_4B */
+       .long   .Lrcls_retstruct        /* FFI_TYPE_MS_STRUCT */
 1:
        add     %eax, %eax
        add     %eax, %eax
index f94ca00bc62550311edf0a4829e33e3d7e5b7842..146fdf9ed4a8a3eae6cb8c993b6c3eaf0ccf540f 100644 (file)
@@ -14,3 +14,72 @@ RUNTEST = `if [ -f $(top_srcdir)/../dejagnu/runtest ] ; then \
 AM_RUNTESTFLAGS =
 
 CLEANFILES = *.exe core* *.log *.sum
+
+EXTRA_DIST = config/default.exp libffi.call/cls_19byte.c \
+libffi.call/cls_align_longdouble_split.c libffi.call/closure_loc_fn0.c \
+libffi.call/cls_schar.c libffi.call/closure_fn1.c \
+libffi.call/many2_win32.c libffi.call/return_ul.c \
+libffi.call/cls_align_double.c libffi.call/return_fl2.c \
+libffi.call/cls_1_1byte.c libffi.call/cls_64byte.c \
+libffi.call/nested_struct7.c libffi.call/cls_align_sint32.c \
+libffi.call/nested_struct2.c libffi.call/ffitest.h \
+libffi.call/nested_struct4.c libffi.call/cls_multi_ushort.c \
+libffi.call/struct3.c libffi.call/cls_3byte1.c \
+libffi.call/cls_16byte.c libffi.call/struct8.c \
+libffi.call/nested_struct8.c libffi.call/cls_multi_sshort.c \
+libffi.call/cls_3byte2.c libffi.call/fastthis2_win32.c \
+libffi.call/cls_pointer.c libffi.call/err_bad_typedef.c \
+libffi.call/cls_4_1byte.c libffi.call/cls_9byte2.c \
+libffi.call/cls_multi_schar.c libffi.call/stret_medium2.c \
+libffi.call/cls_5_1_byte.c libffi.call/call.exp \
+libffi.call/cls_double.c libffi.call/cls_align_sint16.c \
+libffi.call/cls_uint.c libffi.call/return_ll1.c \
+libffi.call/nested_struct3.c libffi.call/cls_20byte1.c \
+libffi.call/closure_fn4.c libffi.call/cls_uchar.c \
+libffi.call/struct2.c libffi.call/cls_7byte.c libffi.call/strlen.c \
+libffi.call/many.c libffi.call/testclosure.c libffi.call/return_fl.c \
+libffi.call/struct5.c libffi.call/cls_12byte.c \
+libffi.call/cls_multi_sshortchar.c \
+libffi.call/cls_align_longdouble_split2.c libffi.call/return_dbl2.c \
+libffi.call/return_fl3.c libffi.call/stret_medium.c \
+libffi.call/nested_struct6.c libffi.call/a.out \
+libffi.call/closure_fn3.c libffi.call/float3.c libffi.call/many2.c \
+libffi.call/closure_stdcall.c libffi.call/cls_align_uint16.c \
+libffi.call/cls_9byte1.c libffi.call/closure_fn6.c \
+libffi.call/cls_double_va.c libffi.call/cls_align_pointer.c \
+libffi.call/cls_align_longdouble.c libffi.call/closure_fn2.c \
+libffi.call/cls_sshort.c libffi.call/many_win32.c \
+libffi.call/nested_struct.c libffi.call/cls_20byte.c \
+libffi.call/cls_longdouble.c libffi.call/cls_multi_uchar.c \
+libffi.call/return_uc.c libffi.call/closure_thiscall.c \
+libffi.call/cls_18byte.c libffi.call/cls_8byte.c \
+libffi.call/promotion.c libffi.call/struct1_win32.c \
+libffi.call/return_dbl.c libffi.call/cls_24byte.c \
+libffi.call/struct4.c libffi.call/cls_6byte.c \
+libffi.call/cls_align_uint32.c libffi.call/float.c \
+libffi.call/float1.c libffi.call/float_va.c libffi.call/negint.c \
+libffi.call/return_dbl1.c libffi.call/cls_3_1byte.c \
+libffi.call/cls_align_float.c libffi.call/return_fl1.c \
+libffi.call/nested_struct10.c libffi.call/nested_struct5.c \
+libffi.call/fastthis1_win32.c libffi.call/cls_align_sint64.c \
+libffi.call/stret_large2.c libffi.call/return_sl.c \
+libffi.call/closure_fn0.c libffi.call/cls_5byte.c \
+libffi.call/cls_2byte.c libffi.call/float2.c \
+libffi.call/cls_dbls_struct.c libffi.call/cls_sint.c \
+libffi.call/stret_large.c libffi.call/cls_ulonglong.c \
+libffi.call/cls_ushort.c libffi.call/nested_struct1.c \
+libffi.call/err_bad_abi.c libffi.call/cls_longdouble_va.c \
+libffi.call/cls_float.c libffi.call/cls_pointer_stack.c \
+libffi.call/pyobjc-tc.c libffi.call/cls_multi_ushortchar.c \
+libffi.call/struct1.c libffi.call/nested_struct9.c \
+libffi.call/huge_struct.c libffi.call/problem1.c libffi.call/float4.c \
+libffi.call/fastthis3_win32.c libffi.call/return_ldl.c \
+libffi.call/strlen2_win32.c libffi.call/closure_fn5.c \
+libffi.call/struct2_win32.c libffi.call/struct6.c \
+libffi.call/return_ll.c libffi.call/struct9.c libffi.call/return_sc.c \
+libffi.call/struct7.c libffi.call/cls_align_uint64.c \
+libffi.call/cls_4byte.c libffi.call/strlen_win32.c \
+libffi.call/cls_6_1_byte.c libffi.call/cls_7_1_byte.c \
+libffi.special/unwindtest.cc libffi.special/special.exp \
+libffi.special/unwindtest_ffi_call.cc libffi.special/ffitestcxx.h \
+lib/wrapper.exp lib/target-libpath.exp lib/libffi.exp
index fae969b85ff5367b7cc1ea528aca9abd1b5f7198..44ca9c23c1162111106c6498559949c26e5e7396 100644 (file)
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
 @SET_MAKE@
 VPATH = @srcdir@
+am__make_dryrun = \
+  { \
+    am__dry=no; \
+    case $$MAKEFLAGS in \
+      *\\[\ \  ]*) \
+        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
+          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+      *) \
+        for am__flg in $$MAKEFLAGS; do \
+          case $$am__flg in \
+            *=*|--*) ;; \
+            *n*) am__dry=yes; break;; \
+          esac; \
+        done;; \
+    esac; \
+    test $$am__dry = yes; \
+  }
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -37,22 +54,32 @@ target_triplet = @target@
 subdir = testsuite
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
-       $(top_srcdir)/../config/lead-dot.m4 \
-       $(top_srcdir)/../config/multi.m4 \
-       $(top_srcdir)/../config/override.m4 \
-       $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
-       $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
-       $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \
+       $(top_srcdir)/m4/ax_cc_maxopt.m4 \
+       $(top_srcdir)/m4/ax_cflags_warn_all.m4 \
+       $(top_srcdir)/m4/ax_check_compile_flag.m4 \
+       $(top_srcdir)/m4/ax_compiler_vendor.m4 \
+       $(top_srcdir)/m4/ax_configure_args.m4 \
+       $(top_srcdir)/m4/ax_enable_builddir.m4 \
+       $(top_srcdir)/m4/ax_gcc_archflag.m4 \
+       $(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \
+       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+       $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+       $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
        $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/fficonfig.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 SOURCES =
 DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
 DEJATOOL = $(PACKAGE)
 RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -77,6 +104,7 @@ CPPFLAGS = @CPPFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
@@ -84,6 +112,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@
 FGREP = @FGREP@
 GREP = @GREP@
 HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@
@@ -102,6 +131,7 @@ LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
 NM = @NM@
 NMEDIT = @NMEDIT@
@@ -117,6 +147,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
 PACKAGE_URL = @PACKAGE_URL@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
+PRTDIAG = @PRTDIAG@
 RANLIB = @RANLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
@@ -129,6 +160,7 @@ abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
@@ -136,6 +168,7 @@ am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_enable_builddir_sed = @ax_enable_builddir_sed@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
@@ -163,7 +196,6 @@ localedir = @localedir@
 localstatedir = @localstatedir@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
-multi_basedir = @multi_basedir@
 oldincludedir = @oldincludedir@
 pdfdir = @pdfdir@
 prefix = @prefix@
@@ -172,6 +204,7 @@ psdir = @psdir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
+sys_symbol_underscore = @sys_symbol_underscore@
 sysconfdir = @sysconfdir@
 target = @target@
 target_alias = @target_alias@
@@ -195,6 +228,75 @@ RUNTEST = `if [ -f $(top_srcdir)/../dejagnu/runtest ] ; then \
            else echo runtest; fi`
 
 CLEANFILES = *.exe core* *.log *.sum
+EXTRA_DIST = config/default.exp libffi.call/cls_19byte.c \
+libffi.call/cls_align_longdouble_split.c libffi.call/closure_loc_fn0.c \
+libffi.call/cls_schar.c libffi.call/closure_fn1.c \
+libffi.call/many2_win32.c libffi.call/return_ul.c \
+libffi.call/cls_align_double.c libffi.call/return_fl2.c \
+libffi.call/cls_1_1byte.c libffi.call/cls_64byte.c \
+libffi.call/nested_struct7.c libffi.call/cls_align_sint32.c \
+libffi.call/nested_struct2.c libffi.call/ffitest.h \
+libffi.call/nested_struct4.c libffi.call/cls_multi_ushort.c \
+libffi.call/struct3.c libffi.call/cls_3byte1.c \
+libffi.call/cls_16byte.c libffi.call/struct8.c \
+libffi.call/nested_struct8.c libffi.call/cls_multi_sshort.c \
+libffi.call/cls_3byte2.c libffi.call/fastthis2_win32.c \
+libffi.call/cls_pointer.c libffi.call/err_bad_typedef.c \
+libffi.call/cls_4_1byte.c libffi.call/cls_9byte2.c \
+libffi.call/cls_multi_schar.c libffi.call/stret_medium2.c \
+libffi.call/cls_5_1_byte.c libffi.call/call.exp \
+libffi.call/cls_double.c libffi.call/cls_align_sint16.c \
+libffi.call/cls_uint.c libffi.call/return_ll1.c \
+libffi.call/nested_struct3.c libffi.call/cls_20byte1.c \
+libffi.call/closure_fn4.c libffi.call/cls_uchar.c \
+libffi.call/struct2.c libffi.call/cls_7byte.c libffi.call/strlen.c \
+libffi.call/many.c libffi.call/testclosure.c libffi.call/return_fl.c \
+libffi.call/struct5.c libffi.call/cls_12byte.c \
+libffi.call/cls_multi_sshortchar.c \
+libffi.call/cls_align_longdouble_split2.c libffi.call/return_dbl2.c \
+libffi.call/return_fl3.c libffi.call/stret_medium.c \
+libffi.call/nested_struct6.c libffi.call/a.out \
+libffi.call/closure_fn3.c libffi.call/float3.c libffi.call/many2.c \
+libffi.call/closure_stdcall.c libffi.call/cls_align_uint16.c \
+libffi.call/cls_9byte1.c libffi.call/closure_fn6.c \
+libffi.call/cls_double_va.c libffi.call/cls_align_pointer.c \
+libffi.call/cls_align_longdouble.c libffi.call/closure_fn2.c \
+libffi.call/cls_sshort.c libffi.call/many_win32.c \
+libffi.call/nested_struct.c libffi.call/cls_20byte.c \
+libffi.call/cls_longdouble.c libffi.call/cls_multi_uchar.c \
+libffi.call/return_uc.c libffi.call/closure_thiscall.c \
+libffi.call/cls_18byte.c libffi.call/cls_8byte.c \
+libffi.call/promotion.c libffi.call/struct1_win32.c \
+libffi.call/return_dbl.c libffi.call/cls_24byte.c \
+libffi.call/struct4.c libffi.call/cls_6byte.c \
+libffi.call/cls_align_uint32.c libffi.call/float.c \
+libffi.call/float1.c libffi.call/float_va.c libffi.call/negint.c \
+libffi.call/return_dbl1.c libffi.call/cls_3_1byte.c \
+libffi.call/cls_align_float.c libffi.call/return_fl1.c \
+libffi.call/nested_struct10.c libffi.call/nested_struct5.c \
+libffi.call/fastthis1_win32.c libffi.call/cls_align_sint64.c \
+libffi.call/stret_large2.c libffi.call/return_sl.c \
+libffi.call/closure_fn0.c libffi.call/cls_5byte.c \
+libffi.call/cls_2byte.c libffi.call/float2.c \
+libffi.call/cls_dbls_struct.c libffi.call/cls_sint.c \
+libffi.call/stret_large.c libffi.call/cls_ulonglong.c \
+libffi.call/cls_ushort.c libffi.call/nested_struct1.c \
+libffi.call/err_bad_abi.c libffi.call/cls_longdouble_va.c \
+libffi.call/cls_float.c libffi.call/cls_pointer_stack.c \
+libffi.call/pyobjc-tc.c libffi.call/cls_multi_ushortchar.c \
+libffi.call/struct1.c libffi.call/nested_struct9.c \
+libffi.call/huge_struct.c libffi.call/problem1.c libffi.call/float4.c \
+libffi.call/fastthis3_win32.c libffi.call/return_ldl.c \
+libffi.call/strlen2_win32.c libffi.call/closure_fn5.c \
+libffi.call/struct2_win32.c libffi.call/struct6.c \
+libffi.call/return_ll.c libffi.call/struct9.c libffi.call/return_sc.c \
+libffi.call/struct7.c libffi.call/cls_align_uint64.c \
+libffi.call/cls_4byte.c libffi.call/strlen_win32.c \
+libffi.call/cls_6_1_byte.c libffi.call/cls_7_1_byte.c \
+libffi.special/unwindtest.cc libffi.special/special.exp \
+libffi.special/unwindtest_ffi_call.cc libffi.special/ffitestcxx.h \
+lib/wrapper.exp lib/target-libpath.exp lib/libffi.exp
+
 all: all-am
 
 .SUFFIXES:
@@ -242,7 +344,7 @@ CTAGS:
 
 
 check-DEJAGNU: site.exp
-       srcdir=`$(am__cd) $(srcdir) && pwd`; export srcdir; \
+       srcdir='$(srcdir)'; export srcdir; \
        EXPECT=$(EXPECT); export EXPECT; \
        runtest=$(RUNTEST); \
        if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
@@ -253,12 +355,12 @@ check-DEJAGNU: site.exp
        else echo "WARNING: could not find \`runtest'" 1>&2; :;\
        fi; \
        exit $$exit_status
-site.exp: Makefile
+site.exp: Makefile $(EXTRA_DEJAGNU_SITE_CONFIG)
        @echo 'Making a new site.exp file...'
        @echo '## these variables are automatically generated by make ##' >site.tmp
        @echo '# Do not edit here.  If you wish to override these values' >>site.tmp
        @echo '# edit the last section' >>site.tmp
-       @echo 'set srcdir $(srcdir)' >>site.tmp
+       @echo 'set srcdir "$(srcdir)"' >>site.tmp
        @echo "set objdir `pwd`" >>site.tmp
        @echo 'set build_alias "$(build_alias)"' >>site.tmp
        @echo 'set build_triplet $(build_triplet)' >>site.tmp
@@ -266,9 +368,16 @@ site.exp: Makefile
        @echo 'set host_triplet $(host_triplet)' >>site.tmp
        @echo 'set target_alias "$(target_alias)"' >>site.tmp
        @echo 'set target_triplet $(target_triplet)' >>site.tmp
-       @echo '## All variables above are generated by configure. Do Not Edit ##' >>site.tmp
-       @test ! -f site.exp || \
-         sed '1,/^## All variables above are.*##/ d' site.exp >> site.tmp
+       @list='$(EXTRA_DEJAGNU_SITE_CONFIG)'; for f in $$list; do \
+         echo "## Begin content included from file $$f.  Do not modify. ##" \
+          && cat `test -f "$$f" || echo '$(srcdir)/'`$$f \
+          && echo "## End content included from file $$f. ##" \
+          || exit 1; \
+        done >> site.tmp
+       @echo "## End of auto-generated content; you can edit from here. ##" >> site.tmp
+       @if test -f site.exp; then \
+          sed -e '1,/^## End of auto-generated content.*##/d' site.exp >> site.tmp; \
+        fi
        @-rm -f site.bak
        @test ! -f site.exp || mv site.exp site.bak
        @mv site.tmp site.exp
@@ -324,10 +433,15 @@ install-am: all-am
 
 installcheck: installcheck-am
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-         `test -z '$(STRIP)' || \
-           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+       if test -z '$(STRIP)'; then \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+             install; \
+       else \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+           "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+       fi
 mostlyclean-generic:
 
 clean-generic:
index 82d6652c183ab688a9fe737f6819c666bf6fd0fc..8ee3f1509fcb80e1ef97bd4e82e950fc9bacf10f 100644 (file)
@@ -1,4 +1,4 @@
-#   Copyright (C) 2003, 2005, 2008, 2009, 2010 Free Software Foundation, Inc.
+#   Copyright (C) 2003, 2005, 2008, 2009, 2010, 2011 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
@@ -16,7 +16,7 @@
 
 proc load_gcc_lib { filename } {
     global srcdir
-    load_file $srcdir/../../gcc/testsuite/lib/$filename
+    load_file $srcdir/lib/$filename
 }
 
 load_lib dg.exp
@@ -94,7 +94,6 @@ proc libffi-init { args } {
     global srcdir
     global blddirffi
     global objdir
-    global blddircxx
     global TOOL_OPTIONS
     global tool
     global libffi_include
@@ -102,10 +101,8 @@ proc libffi-init { args } {
     global tool_root_dir
     global ld_library_path
 
-    set blddirffi [lookfor_file [get_multilibs] libffi]
+    set blddirffi [pwd]/.. 
     verbose "libffi $blddirffi"
-    set blddircxx [lookfor_file [get_multilibs] libstdc++-v3]
-    verbose "libstdc++ $blddircxx"
 
     set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a]
     if {$gccdir != ""} {
@@ -132,8 +129,6 @@ proc libffi-init { args } {
     }
     # add the library path for libffi.
     append ld_library_path ":${blddirffi}/.libs"
-    # add the library path for libstdc++ as well.
-    append ld_library_path ":${blddircxx}/src/.libs"
 
     verbose "ld_library_path: $ld_library_path"
 
@@ -146,7 +141,6 @@ proc libffi-init { args } {
     if { $libffi_dir != "" } {
        set libffi_dir [file dirname ${libffi_dir}]
        set libffi_link_flags "-L${libffi_dir}/.libs"
-       lappend libffi_link_flags "-L${blddircxx}/src/.libs"
     }
 
     set_ld_library_path_env_vars
@@ -209,6 +203,10 @@ proc libffi_target_compile { source dest type options } {
 
     lappend options "libs= -lffi"
 
+    if { [string match "aarch64*-*-linux*" $target_triplet] } {
+       lappend options "libs= -lpthread"
+    }
+
     verbose "options: $options"
     return [target_compile $source $dest $type $options]
 }
index 6bfcc1fbb5b342867ddb69cf40f48d63688b3c2d..1407f024c1704f158529e80236e0727ba740f11f 100644 (file)
@@ -49,9 +49,17 @@ int main (void)
   CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_stdcall,
                              (void *) 3 /* userdata */, code) == FFI_OK);
 
+#ifdef _MSC_VER
+  __asm { mov sp_pre, esp }
+#else
   asm volatile (" movl %%esp,%0" : "=g" (sp_pre));
+#endif
   res = (*(closure_test_type0)code)(0, 1, 2, 3);
+#ifdef _MSC_VER
+  __asm { mov sp_post, esp }
+#else
   asm volatile (" movl %%esp,%0" : "=g" (sp_post));
+#endif
   /* { dg-output "0 1 2 3: 9" } */
 
   printf("res: %d\n",res);
index 6c46f353728acdd355e6eac0ba5d9cf8e3638770..0f93649ff752de1e97ba30e8c46ed282f12753e9 100644 (file)
@@ -49,9 +49,17 @@ int main (void)
   CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_thiscall,
                              (void *) 3 /* userdata */, code) == FFI_OK);
 
+#ifdef _MSC_VER
+  __asm { mov sp_pre, esp }
+#else
   asm volatile (" movl %%esp,%0" : "=g" (sp_pre));
+#endif
   res = (*(closure_test_type0)code)(0, 1, 2, 3);
+#ifdef _MSC_VER
+  __asm { mov sp_post, esp }
+#else
   asm volatile (" movl %%esp,%0" : "=g" (sp_post));
+#endif
   /* { dg-output "0 1 2 3: 9" } */
 
   printf("res: %d\n",res);
index f0a334fa797595d6ec684edcf65a3f5ff626be62..ea0825d175a6571e5706505010971bc1ea86bf6a 100644 (file)
@@ -49,15 +49,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_12byte h_dbl = { 7, 4, 9 };
+  struct cls_struct_12byte j_dbl = { 1, 5, 3 };
+  struct cls_struct_12byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_12byte h_dbl = { 7, 4, 9 };
-  struct cls_struct_12byte j_dbl = { 1, 5, 3 };
-  struct cls_struct_12byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_sint;
   cls_struct_fields[1] = &ffi_type_sint;
   cls_struct_fields[2] = &ffi_type_sint;
index 9b9292ab056c3aa6af43c2e700a5661993125c88..89a08a2d97bb1a45a41dede9fab9559ed20bab54 100644 (file)
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_16byte h_dbl = { 7, 8.0, 9 };
+  struct cls_struct_16byte j_dbl = { 1, 9.0, 3 };
+  struct cls_struct_16byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_16byte h_dbl = { 7, 8.0, 9 };
-  struct cls_struct_16byte j_dbl = { 1, 9.0, 3 };
-  struct cls_struct_16byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_sint;
   cls_struct_fields[1] = &ffi_type_double;
   cls_struct_fields[2] = &ffi_type_sint;
index 40c8c6d96a1b1b1c55d0bd0e075db75c591e0cfa..9f75da80aa05faa5aea74f237ac5c20e6fda0b09 100644 (file)
@@ -54,15 +54,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[3];
 
+  struct cls_struct_18byte g_dbl = { 1.0, 127, 126, 3.0 };
+  struct cls_struct_18byte f_dbl = { 4.0, 125, 124, 5.0 };
+  struct cls_struct_18byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_18byte g_dbl = { 1.0, 127, 126, 3.0 };
-  struct cls_struct_18byte f_dbl = { 4.0, 125, 124, 5.0 };
-  struct cls_struct_18byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_double;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = &ffi_type_uchar;
index aa6424818f769807d36ca542a39cdb6b9381a0ba..278794b5b8773039a5b1d7a9c9ddcc378f98bc27 100644 (file)
@@ -57,15 +57,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[3];
 
+  struct cls_struct_19byte g_dbl = { 1.0, 127, 126, 3.0, 120 };
+  struct cls_struct_19byte f_dbl = { 4.0, 125, 124, 5.0, 119 };
+  struct cls_struct_19byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_19byte g_dbl = { 1.0, 127, 126, 3.0, 120 };
-  struct cls_struct_19byte f_dbl = { 4.0, 125, 124, 5.0, 119 };
-  struct cls_struct_19byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_double;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = &ffi_type_uchar;
index b9402d678adaace5e12aec25a53aa79f5544ade7..82492c020e2bc8452b6064d5e64a88cfca910609 100644 (file)
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_1_1byte g_dbl = { 12 };
+  struct cls_struct_1_1byte f_dbl = { 178 };
+  struct cls_struct_1_1byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_1_1byte g_dbl = { 12 };
-  struct cls_struct_1_1byte f_dbl = { 178 };
-  struct cls_struct_1_1byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = NULL;
 
index 80dd7ac931bc18cc7ab45707a5c95acdf6c05b33..3f8bb28ad297cd77709923c824610128cef3fa06 100644 (file)
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_20byte g_dbl = { 1.0, 2.0, 3 };
+  struct cls_struct_20byte f_dbl = { 4.0, 5.0, 7 };
+  struct cls_struct_20byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_20byte g_dbl = { 1.0, 2.0, 3 };
-  struct cls_struct_20byte f_dbl = { 4.0, 5.0, 7 };
-  struct cls_struct_20byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_double;
   cls_struct_fields[1] = &ffi_type_double;
   cls_struct_fields[2] = &ffi_type_sint;
index 50bcbbf831a09bf5ca0147b23d215b128a8c974a..65627273c84b693415f4a6d43dcbf5cffdf1f513 100644 (file)
@@ -52,15 +52,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[3];
 
+  struct cls_struct_20byte g_dbl = { 1, 2.0, 3.0 };
+  struct cls_struct_20byte f_dbl = { 4, 5.0, 7.0 };
+  struct cls_struct_20byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_20byte g_dbl = { 1, 2.0, 3.0 };
-  struct cls_struct_20byte f_dbl = { 4, 5.0, 7.0 };
-  struct cls_struct_20byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_sint;
   cls_struct_fields[1] = &ffi_type_double;
   cls_struct_fields[2] = &ffi_type_double;
index 46a6eb4d31c0f60af7121a16d56abe8d615f87c7..1d82f6e4a45bbc8878fb9eec6a63f91c429fb55c 100644 (file)
@@ -61,17 +61,17 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
   struct cls_struct_24byte e_dbl = { 9.0, 2.0, 6, 5.0 };
   struct cls_struct_24byte f_dbl = { 1.0, 2.0, 3, 7.0 };
   struct cls_struct_24byte g_dbl = { 4.0, 5.0, 7, 9.0 };
   struct cls_struct_24byte h_dbl = { 8.0, 6.0, 1, 4.0 };
   struct cls_struct_24byte res_dbl;
 
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
   cls_struct_fields[0] = &ffi_type_double;
   cls_struct_fields[1] = &ffi_type_double;
   cls_struct_fields[2] = &ffi_type_sint;
index 101e130a1fc4b4a7db1e55a273e85a55a9b4cf19..81bb0a64a3ee50eeedfcb373b531f7e563a48913 100644 (file)
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_2byte g_dbl = { 12, 127 };
+  struct cls_struct_2byte f_dbl = { 1, 13 };
+  struct cls_struct_2byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_2byte g_dbl = { 12, 127 };
-  struct cls_struct_2byte f_dbl = { 1, 13 };
-  struct cls_struct_2byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = NULL;
index fc780c30d6c6787b65a2ed179e7902e11e8fda5a..b7827466f6ef43b17176c4abd0976f96d3491768 100644 (file)
@@ -54,15 +54,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_3_1byte g_dbl = { 12, 13, 14 };
+  struct cls_struct_3_1byte f_dbl = { 178, 179, 180 };
+  struct cls_struct_3_1byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_3_1byte g_dbl = { 12, 13, 14 };
-  struct cls_struct_3_1byte f_dbl = { 178, 179, 180 };
-  struct cls_struct_3_1byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = &ffi_type_uchar;
index 5705ce387980f62a8a226413af6250dec9434e5a..a02c463af9f0f36cd81a768bb1c6d05cf3f22460 100644 (file)
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_3byte g_dbl = { 12, 119 };
+  struct cls_struct_3byte f_dbl = { 1, 15 };
+  struct cls_struct_3byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_3byte g_dbl = { 12, 119 };
-  struct cls_struct_3byte f_dbl = { 1, 15 };
-  struct cls_struct_3byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_ushort;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = NULL;
index 01770a0750bc06350cc59a59bed3090cd10d9d84..c7251cead60308e21e2f889f92ba603bdee30fe8 100644 (file)
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_3byte_1 g_dbl = { 15, 125 };
+  struct cls_struct_3byte_1 f_dbl = { 9, 19 };
+  struct cls_struct_3byte_1 res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_3byte_1 g_dbl = { 15, 125 };
-  struct cls_struct_3byte_1 f_dbl = { 9, 19 };
-  struct cls_struct_3byte_1 res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_ushort;
   cls_struct_fields[2] = NULL;
index f3806d7ba1c9e764a2f7e939328402fc1a7b9797..2d6d8b622c3734c3b68c2a89294c1f5020294fae 100644 (file)
@@ -56,15 +56,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_4_1byte g_dbl = { 12, 13, 14, 15 };
+  struct cls_struct_4_1byte f_dbl = { 178, 179, 180, 181 };
+  struct cls_struct_4_1byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_4_1byte g_dbl = { 12, 13, 14, 15 };
-  struct cls_struct_4_1byte f_dbl = { 178, 179, 180, 181 };
-  struct cls_struct_4_1byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = &ffi_type_uchar;
index a1aba3c09d50d9ab50f60d017faa73358afae49d..4ac378776b5cd1ea6792b2ffdda31fb0549a0430 100644 (file)
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_4byte g_dbl = { 127, 120 };
+  struct cls_struct_4byte f_dbl = { 12, 128 };
+  struct cls_struct_4byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_4byte g_dbl = { 127, 120 };
-  struct cls_struct_4byte f_dbl = { 12, 128 };
-  struct cls_struct_4byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_ushort;
   cls_struct_fields[1] = &ffi_type_ushort;
   cls_struct_fields[2] = NULL;
index 2ceba3ddb2dabe94555c169fbdc4ddc2d986c0f1..ad9d51c248c2da4f3ee010b8e5df770e38f91dfb 100644 (file)
@@ -58,15 +58,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_5byte g_dbl = { 127, 120, 1, 3, 4 };
+  struct cls_struct_5byte f_dbl = { 12, 128, 9, 3, 4 };
+  struct cls_struct_5byte res_dbl = { 0, 0, 0, 0, 0 };
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_5byte g_dbl = { 127, 120, 1, 3, 4 };
-  struct cls_struct_5byte f_dbl = { 12, 128, 9, 3, 4 };
-  struct cls_struct_5byte res_dbl = { 0, 0, 0, 0, 0 };
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = &ffi_type_uchar;
index 61d595c2bf06a580d541137d977a67bc784024c8..4e0c0003c0aa5878c0bc327544bb279d7b5b94ed 100644 (file)
@@ -53,15 +53,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_5byte g_dbl = { 127, 120, 1 };
+  struct cls_struct_5byte f_dbl = { 12, 128, 9 };
+  struct cls_struct_5byte res_dbl = { 0, 0, 0 };
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_5byte g_dbl = { 127, 120, 1 };
-  struct cls_struct_5byte f_dbl = { 12, 128, 9 };
-  struct cls_struct_5byte res_dbl = { 0, 0, 0 };
-
   cls_struct_fields[0] = &ffi_type_ushort;
   cls_struct_fields[1] = &ffi_type_ushort;
   cls_struct_fields[2] = &ffi_type_uchar;
index 576ebe0cc2a4e8206c0ef0931bef532ad266b921..a55edc2c7b9df3e70689730920fab6dc03400074 100644 (file)
@@ -66,17 +66,17 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
   struct cls_struct_64byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0 };
   struct cls_struct_64byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0 };
   struct cls_struct_64byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0 };
   struct cls_struct_64byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0 };
   struct cls_struct_64byte res_dbl;
 
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
   cls_struct_fields[0] = &ffi_type_double;
   cls_struct_fields[1] = &ffi_type_double;
   cls_struct_fields[2] = &ffi_type_double;
index 9f2eff68c1ff91a1e113feb5e587e09b5e72545f..b4dcdba47283f770454bf10f806980e7bb6b9fef 100644 (file)
@@ -60,15 +60,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_6byte g_dbl = { 127, 120, 1, 3, 4, 5 };
+  struct cls_struct_6byte f_dbl = { 12, 128, 9, 3, 4, 5 };
+  struct cls_struct_6byte res_dbl = { 0, 0, 0, 0, 0, 0 };
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_6byte g_dbl = { 127, 120, 1, 3, 4, 5 };
-  struct cls_struct_6byte f_dbl = { 12, 128, 9, 3, 4, 5 };
-  struct cls_struct_6byte res_dbl = { 0, 0, 0, 0, 0, 0 };
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = &ffi_type_uchar;
index 73257b0989bb5ec3d8a2a6c3b84d60b190cf5166..740678017b3a021fd11a330eb7adc0e491d8209b 100644 (file)
@@ -56,15 +56,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_6byte g_dbl = { 127, 120, 1, 128 };
+  struct cls_struct_6byte f_dbl = { 12, 128, 9, 127 };
+  struct cls_struct_6byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_6byte g_dbl = { 127, 120, 1, 128 };
-  struct cls_struct_6byte f_dbl = { 12, 128, 9, 127 };
-  struct cls_struct_6byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_ushort;
   cls_struct_fields[1] = &ffi_type_ushort;
   cls_struct_fields[2] = &ffi_type_uchar;
index 50d09c9da72db12fc784495f76ecb94ff6fa0cba..14a7e96f9d6569b4f94247297ab58ba6e6a1a6da 100644 (file)
@@ -62,15 +62,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_7byte g_dbl = { 127, 120, 1, 3, 4, 5, 6 };
+  struct cls_struct_7byte f_dbl = { 12, 128, 9, 3, 4, 5, 6 };
+  struct cls_struct_7byte res_dbl = { 0, 0, 0, 0, 0, 0, 0 };
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_7byte g_dbl = { 127, 120, 1, 3, 4, 5, 6 };
-  struct cls_struct_7byte f_dbl = { 12, 128, 9, 3, 4, 5, 6 };
-  struct cls_struct_7byte res_dbl = { 0, 0, 0, 0, 0, 0, 0 };
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = &ffi_type_uchar;
index f5c00003153dc0f79d00d1d9063760d8c9b0723b..1645cc635f9afb6410c650bb68f2a066e7cee391 100644 (file)
@@ -55,15 +55,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_7byte g_dbl = { 127, 120, 1, 254 };
+  struct cls_struct_7byte f_dbl = { 12, 128, 9, 255 };
+  struct cls_struct_7byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_7byte g_dbl = { 127, 120, 1, 254 };
-  struct cls_struct_7byte f_dbl = { 12, 128, 9, 255 };
-  struct cls_struct_7byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_ushort;
   cls_struct_fields[1] = &ffi_type_ushort;
   cls_struct_fields[2] = &ffi_type_uchar;
index 4aa99d12e417c1fb47a6110571a29b917a49d629..f6c1ea570ac8638227b2e8541bc42f7f8ef71506 100644 (file)
@@ -49,15 +49,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_8byte g_dbl = { 1, 2.0 };
+  struct cls_struct_8byte f_dbl = { 4, 5.0 };
+  struct cls_struct_8byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_8byte g_dbl = { 1, 2.0 };
-  struct cls_struct_8byte f_dbl = { 4, 5.0 };
-  struct cls_struct_8byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_sint;
   cls_struct_fields[1] = &ffi_type_float;
   cls_struct_fields[2] = NULL;
index cc5e9d6c4e940e5efab1466418c118416873695a..0b8572223c9c5e5f6d8e2179535647c52916a28e 100644 (file)
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[3];
 
+  struct cls_struct_9byte h_dbl = { 7, 8.0};
+  struct cls_struct_9byte j_dbl = { 1, 9.0};
+  struct cls_struct_9byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_9byte h_dbl = { 7, 8.0};
-  struct cls_struct_9byte j_dbl = { 1, 9.0};
-  struct cls_struct_9byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_sint;
   cls_struct_fields[1] = &ffi_type_double;
   cls_struct_fields[2] = NULL;
index 5c0ba0d4b8d4a6581ffc8b4e6798e74be756371a..edf991de73eefcbf379294528ecb8727ff19b0f9 100644 (file)
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[3];
 
+  struct cls_struct_9byte h_dbl = { 7.0, 8};
+  struct cls_struct_9byte j_dbl = { 1.0, 9};
+  struct cls_struct_9byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_9byte h_dbl = { 7.0, 8};
-  struct cls_struct_9byte j_dbl = { 1.0, 9};
-  struct cls_struct_9byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_double;
   cls_struct_fields[1] = &ffi_type_sint;
   cls_struct_fields[2] = NULL;
index 22b94d5a09de1e21b90dad788982b8ded01ad82e..aad5f3ced6a038aa1b8e93b8f27f0dea350b534f 100644 (file)
@@ -52,15 +52,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_double;
   cls_struct_fields[2] = &ffi_type_uchar;
index 62637f21d182d1c4075bc192e6269ab7157672cb..37e085529e7a08314effe15244faf38b8ddfac78 100644 (file)
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_float;
   cls_struct_fields[2] = &ffi_type_uchar;
index af380603c99eb8f5c4d6390fd0718f3f67d22d8c..b3322d8615136813f541c3f051fbfc4c3803c328 100644 (file)
@@ -51,15 +51,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_longdouble;
   cls_struct_fields[2] = &ffi_type_uchar;
index a3732bd0f3b895e2d6645ba8955d40b37c1e6579..15f936546528f5c64463b941a3d9a94470e11f98 100644 (file)
@@ -87,15 +87,15 @@ int main (void)
        ffi_type cls_struct_type;
        ffi_type* dbl_arg_types[3];
 
+       struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 };
+       struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 };
+       struct cls_struct_align res_dbl;
+
        cls_struct_type.size = 0;
        cls_struct_type.alignment = 0;
        cls_struct_type.type = FFI_TYPE_STRUCT;
        cls_struct_type.elements = cls_struct_fields;
 
-       struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 };
-       struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 };
-       struct cls_struct_align res_dbl;
-
        cls_struct_fields[0] = &ffi_type_longdouble;
        cls_struct_fields[1] = &ffi_type_longdouble;
        cls_struct_fields[2] = &ffi_type_longdouble;
index 63a0f763368faf0d9db7919e8cfb179bdfac1901..ca1c356cbe76b5fb0ff86f2480d878c91d2d4dae 100644 (file)
@@ -67,15 +67,15 @@ int main (void)
        ffi_type cls_struct_type;
        ffi_type* dbl_arg_types[3];
 
+       struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 };
+       struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 };
+       struct cls_struct_align res_dbl;
+
        cls_struct_type.size = 0;
        cls_struct_type.alignment = 0;
        cls_struct_type.type = FFI_TYPE_STRUCT;
        cls_struct_type.elements = cls_struct_fields;
 
-       struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 };
-       struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 };
-       struct cls_struct_align res_dbl;
-
        cls_struct_fields[0] = &ffi_type_longdouble;
        cls_struct_fields[1] = &ffi_type_longdouble;
        cls_struct_fields[2] = &ffi_type_longdouble;
index cbc4f953ff625871d74f67a97da4dde9cd8ea7fe..8fbf36a5c1151513c0eb6faa0d71da6b2d32692c 100644 (file)
@@ -54,15 +54,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_align g_dbl = { 12, (void *)4951, 127 };
+  struct cls_struct_align f_dbl = { 1, (void *)9320, 13 };
+  struct cls_struct_align res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_align g_dbl = { 12, (void *)4951, 127 };
-  struct cls_struct_align f_dbl = { 1, (void *)9320, 13 };
-  struct cls_struct_align res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_pointer;
   cls_struct_fields[2] = &ffi_type_uchar;
index 383ea41d5a6603987711a010464960111b10ab27..039b874732005140eea0cb02f941b04f9972cfc6 100644 (file)
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_sshort;
   cls_struct_fields[2] = &ffi_type_uchar;
index 705d78cfa84cf12ab0c6ac5c6b9bdb11e31fd4f7..c96c6d136df1bba986759d2804edba9d1ccd698a 100644 (file)
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_sint;
   cls_struct_fields[2] = &ffi_type_uchar;
index 31d53aff05ab5e369c04edc13a955e95fe2566cd..9aa7bdddff7a5fee1e98917c6629143cdb0b3def 100644 (file)
@@ -51,15 +51,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_sint64;
   cls_struct_fields[2] = &ffi_type_uchar;
index cb6b74821ea427d62232512744b5cbaca1778126..97620b79d1fbec68d434a018453ab8db62aa723f 100644 (file)
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_ushort;
   cls_struct_fields[2] = &ffi_type_uchar;
index e453d3e5d9e0c6a570b493f4a0c95b68ffa63238..5766fadf0dc9b53934194558b7d7559830482693 100644 (file)
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_uint;
   cls_struct_fields[2] = &ffi_type_uchar;
index 495c79f4ea71cd0ec9d0822f2f48c95f4f97b205..a52cb8939c4fa161b383628a8d72e6b8fdd6a64e 100644 (file)
@@ -52,15 +52,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_uint64;
   cls_struct_fields[2] = &ffi_type_uchar;
index 660dabb883b1f7b86f501e3b29eefe80ed497c00..d6637911e584f9c11dce73d69e7d3da0811d800e 100644 (file)
@@ -37,6 +37,8 @@ int main(int argc __UNUSED__, char** argv __UNUSED__)
        ffi_type        ts1_type;
        ffi_type*       ts1_type_elements[4];
 
+       Dbls arg = { 1.0, 2.0 };
+
        ts1_type.size = 0;
        ts1_type.alignment = 0;
        ts1_type.type = FFI_TYPE_STRUCT;
@@ -48,8 +50,6 @@ int main(int argc __UNUSED__, char** argv __UNUSED__)
 
        cl_arg_types[0] = &ts1_type;
 
-       Dbls arg = { 1.0, 2.0 };
-
        /* Initialize the cif */
        CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
                                 &ffi_type_void, cl_arg_types) == FFI_OK);
index 67e44a4ed3d5667ba40db41d18992bd5c2523ca7..dbf20002dfc9c584446c463d727b0262d1812fd8 100644 (file)
@@ -7,7 +7,6 @@
 /* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
 /* { dg-output "" { xfail avr32*-*-* } } */
 /* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */
-/* { dg-skip-if "" arm*-*-* { "-mfloat-abi=hard" } { "" } } */
 
 #include "ffitest.h"
 
index 6b8484a8595d5db5359a218dee10ff45f8f0d405..4fa1ea28ace870fd70fd8102591e9114d6e000e1 100644 (file)
@@ -7,7 +7,6 @@
 /* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
 /* { dg-output "" { xfail avr32*-*-* x86_64-*-mingw* } } */
 /* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */
-/* { dg-skip-if "" arm*-*-* { "-mfloat-abi=hard" } { "" } } */
 
 #include "ffitest.h"
 
index d631cf848eecb2438af3d98d78d4737948528f96..e31139e428f66f3e89dc0b9230b0c305113d8217 100644 (file)
@@ -28,11 +28,12 @@ void* cls_pointer_fn2(void* a1, void* a2)
        char            trample6        = trample4 + ((char*)&a2)[1];
        long double     trample7        = (intptr_t)trample5 + (intptr_t)trample1;
        char            trample8        = trample6 + trample2;
+       void*           result;
 
        dummyVar        = dummy_func(trample1, trample2, trample3, trample4,
                trample5, trample6, trample7, trample8);
 
-       void*   result  = (void*)((intptr_t)a1 + (intptr_t)a2);
+       result  = (void*)((intptr_t)a1 + (intptr_t)a2);
 
        printf("0x%08x 0x%08x: 0x%08x\n", 
               (unsigned int)(uintptr_t) a1,
@@ -52,11 +53,12 @@ void* cls_pointer_fn1(void* a1, void* a2)
        char            trample6        = trample4 + ((char*)&a2)[1];
        long double     trample7        = (intptr_t)trample5 + (intptr_t)trample1;
        char            trample8        = trample6 + trample2;
+       void*           result;
 
        dummyVar        = dummy_func(trample1, trample2, trample3, trample4,
                trample5, trample6, trample7, trample8);
 
-       void*   result  = (void*)((intptr_t)a1 + (intptr_t)a2);
+       result  = (void*)((intptr_t)a1 + (intptr_t)a2);
 
        printf("0x%08x 0x%08x: 0x%08x\n",
                (unsigned int)(intptr_t) a1,
diff --git a/libffi/testsuite/libffi.call/cls_struct_va1.c b/libffi/testsuite/libffi.call/cls_struct_va1.c
new file mode 100644 (file)
index 0000000..91772bd
--- /dev/null
@@ -0,0 +1,114 @@
+/* Area:               ffi_call, closure_call
+   Purpose:            Test doubles passed in variable argument lists.
+   Limitations:        none.
+   PR:                 none.
+   Originator: Blake Chaffin 6/6/2007   */
+
+/* { dg-do run } */
+/* { dg-output "" { xfail avr32*-*-* } } */
+#include "ffitest.h"
+
+struct small_tag
+{
+  unsigned char a;
+  unsigned char b;
+};
+
+struct large_tag
+{
+  unsigned a;
+  unsigned b;
+  unsigned c;
+  unsigned d;
+  unsigned e;
+};
+
+static void
+test_fn (ffi_cif* cif __UNUSED__, void* resp,
+        void** args, void* userdata __UNUSED__)
+{
+  int n = *(int*)args[0];
+  struct small_tag s1 = * (struct small_tag *) args[1];
+  struct large_tag l1 = * (struct large_tag *) args[2];
+  struct small_tag s2 = * (struct small_tag *) args[3];
+
+  printf ("%d %d %d %d %d %d %d %d %d %d\n", n, s1.a, s1.b,
+         l1.a, l1.b, l1.c, l1.d, l1.e,
+         s2.a, s2.b);
+  * (int*) resp = 42;
+}
+
+int
+main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc (sizeof (ffi_closure), &code);
+  ffi_type* arg_types[5];
+
+  ffi_arg res = 0;
+
+  ffi_type s_type;
+  ffi_type *s_type_elements[3];
+
+  ffi_type l_type;
+  ffi_type *l_type_elements[6];
+
+  struct small_tag s1;
+  struct small_tag s2;
+  struct large_tag l1;
+
+  int si;
+
+  s_type.size = 0;
+  s_type.alignment = 0;
+  s_type.type = FFI_TYPE_STRUCT;
+  s_type.elements = s_type_elements;
+
+  s_type_elements[0] = &ffi_type_uchar;
+  s_type_elements[1] = &ffi_type_uchar;
+  s_type_elements[2] = NULL;
+
+  l_type.size = 0;
+  l_type.alignment = 0;
+  l_type.type = FFI_TYPE_STRUCT;
+  l_type.elements = l_type_elements;
+
+  l_type_elements[0] = &ffi_type_uint;
+  l_type_elements[1] = &ffi_type_uint;
+  l_type_elements[2] = &ffi_type_uint;
+  l_type_elements[3] = &ffi_type_uint;
+  l_type_elements[4] = &ffi_type_uint;
+  l_type_elements[5] = NULL;
+
+  arg_types[0] = &ffi_type_sint;
+  arg_types[1] = &s_type;
+  arg_types[2] = &l_type;
+  arg_types[3] = &s_type;
+  arg_types[4] = NULL;
+
+  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &ffi_type_sint,
+                        arg_types) == FFI_OK);
+
+  si = 4;
+  s1.a = 5;
+  s1.b = 6;
+
+  s2.a = 20;
+  s2.b = 21;
+
+  l1.a = 10;
+  l1.b = 11;
+  l1.c = 12;
+  l1.d = 13;
+  l1.e = 14;
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, test_fn, NULL, code) == FFI_OK);
+
+  res = ((int (*)(int, ...))(code))(si, s1, l1, s2);
+  // { dg-output "4 5 6 10 11 12 13 14 20 21" }
+  printf("res: %d\n", (int) res);
+  // { dg-output "\nres: 42" }
+
+  exit(0);
+}
diff --git a/libffi/testsuite/libffi.call/cls_uchar_va.c b/libffi/testsuite/libffi.call/cls_uchar_va.c
new file mode 100644 (file)
index 0000000..19cd4f3
--- /dev/null
@@ -0,0 +1,44 @@
+/* Area:       closure_call
+   Purpose:    Test anonymous unsigned char argument.
+   Limitations:        none.
+   PR:         none.
+   Originator: ARM Ltd. */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef unsigned char T;
+
+static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+                        void* userdata __UNUSED__)
+ {
+   *(T *)resp = *(T *)args[0];
+
+   printf("%d: %d %d\n", *(T *)resp, *(T *)args[0], *(T *)args[1]);
+ }
+
+typedef T (*cls_ret_T)(T, ...);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[3];
+  T res;
+
+  cl_arg_types[0] = &ffi_type_uchar;
+  cl_arg_types[1] = &ffi_type_uchar;
+  cl_arg_types[2] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
+                        &ffi_type_uchar, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code)  == FFI_OK);
+  res = ((((cls_ret_T)code)(67, 4)));
+  /* { dg-output "67: 67 4" } */
+  printf("res: %d\n", res);
+  /* { dg-output "\nres: 67" } */
+  exit(0);
+}
diff --git a/libffi/testsuite/libffi.call/cls_uint_va.c b/libffi/testsuite/libffi.call/cls_uint_va.c
new file mode 100644 (file)
index 0000000..150fddd
--- /dev/null
@@ -0,0 +1,45 @@
+/* Area:       closure_call
+   Purpose:    Test anonymous unsigned int argument.
+   Limitations:        none.
+   PR:         none.
+   Originator: ARM Ltd. */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+typedef unsigned int T;
+
+static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+                        void* userdata __UNUSED__)
+ {
+   *(T *)resp = *(T *)args[0];
+
+   printf("%d: %d %d\n", *(T *)resp, *(T *)args[0], *(T *)args[1]);
+ }
+
+typedef T (*cls_ret_T)(T, ...);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[3];
+  T res;
+
+  cl_arg_types[0] = &ffi_type_uint;
+  cl_arg_types[1] = &ffi_type_uint;
+  cl_arg_types[2] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
+                        &ffi_type_uint, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code)  == FFI_OK);
+  res = ((((cls_ret_T)code)(67, 4)));
+  /* { dg-output "67: 67 4" } */
+  printf("res: %d\n", res);
+  /* { dg-output "\nres: 67" } */
+  exit(0);
+}
diff --git a/libffi/testsuite/libffi.call/cls_ulong_va.c b/libffi/testsuite/libffi.call/cls_ulong_va.c
new file mode 100644 (file)
index 0000000..0315082
--- /dev/null
@@ -0,0 +1,45 @@
+/* Area:       closure_call
+   Purpose:    Test anonymous unsigned long argument.
+   Limitations:        none.
+   PR:         none.
+   Originator: ARM Ltd. */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+typedef unsigned long T;
+
+static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+                        void* userdata __UNUSED__)
+ {
+   *(T *)resp = *(T *)args[0];
+
+   printf("%ld: %ld %ld\n", *(T *)resp, *(T *)args[0], *(T *)args[1]);
+ }
+
+typedef T (*cls_ret_T)(T, ...);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[3];
+  T res;
+
+  cl_arg_types[0] = &ffi_type_ulong;
+  cl_arg_types[1] = &ffi_type_ulong;
+  cl_arg_types[2] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
+                        &ffi_type_ulong, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code)  == FFI_OK);
+  res = ((((cls_ret_T)code)(67, 4)));
+  /* { dg-output "67: 67 4" } */
+  printf("res: %ld\n", res);
+  /* { dg-output "\nres: 67" } */
+  exit(0);
+}
diff --git a/libffi/testsuite/libffi.call/cls_ushort_va.c b/libffi/testsuite/libffi.call/cls_ushort_va.c
new file mode 100644 (file)
index 0000000..b2b5a3b
--- /dev/null
@@ -0,0 +1,44 @@
+/* Area:       closure_call
+   Purpose:    Test anonymous unsigned short argument.
+   Limitations:        none.
+   PR:         none.
+   Originator: ARM Ltd. */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef unsigned short T;
+
+static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+                        void* userdata __UNUSED__)
+ {
+   *(T *)resp = *(T *)args[0];
+
+   printf("%d: %d %d\n", *(T *)resp, *(T *)args[0], *(T *)args[1]);
+ }
+
+typedef T (*cls_ret_T)(T, ...);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[3];
+  T res;
+
+  cl_arg_types[0] = &ffi_type_ushort;
+  cl_arg_types[1] = &ffi_type_ushort;
+  cl_arg_types[2] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
+                        &ffi_type_ushort, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code)  == FFI_OK);
+  res = ((((cls_ret_T)code)(67, 4)));
+  /* { dg-output "67: 67 4" } */
+  printf("res: %d\n", res);
+  /* { dg-output "\nres: 67" } */
+  exit(0);
+}
index 253927392d34cb4677f80c46c9f689556ef2602a..bf6016186170d4f892ee26c5b21ef48242f4dda6 100644 (file)
@@ -13,10 +13,10 @@ int main (void)
        ffi_cif cif;
        ffi_type* arg_types[1];
 
-       arg_types[0] = NULL;
-
        ffi_type        badType = ffi_type_void;
 
+       arg_types[0] = NULL;
+
        badType.size = 0;
 
        CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &badType,
index b3c4c733b6272a783ab7697e564f57ba00789341..cbc4724ef8c1c816a1ca23b4fa72f17f35e4255c 100644 (file)
@@ -8,7 +8,7 @@
 
 #include "ffitest.h"
 
-static size_t __attribute__((fastcall)) my_fastcall_f(char *s, float a)
+static size_t __FASTCALL__ my_fastcall_f(char *s, float a)
 {
   return (size_t) ((int) strlen(s) + (int) a);
 }
index f148a12fa66b1dcd822155be09cb6b8fcc70fe56..7bdd0e17584c389f6deb69409c6726a71eac1abb 100644 (file)
@@ -8,7 +8,7 @@
 
 #include "ffitest.h"
 
-static size_t __attribute__((fastcall)) my_fastcall_f(float a, char *s)
+static size_t __FASTCALL__ my_fastcall_f(float a, char *s)
 {
   return (size_t) ((int) strlen(s) + (int) a);
 }
index 5cf82bbfa99de2d258a6ac3e85dbc4563743ba13..b5d606d9a15ecb6ad8c4b7accc7df7543f45aebc 100644 (file)
@@ -8,7 +8,7 @@
 
 #include "ffitest.h"
 
-static size_t __attribute__((fastcall)) my_fastcall_f(float a, char *s, int i)
+static size_t __FASTCALL__ my_fastcall_f(float a, char *s, int i)
 {
   return (size_t) ((int) strlen(s) + (int) a + i);
 }
index 0e95e164f6e3003d938ab7cc09e49a32ffc9dbd0..d81d4dabade890effbd93027c69b1f2231be2a54 100644 (file)
 #define __UNUSED__
 #endif
 
+/* Define __FASTCALL__ so that other compilers than gcc can run the tests.  */
+#undef __FASTCALL__
+#if defined _MSC_VER
+#define __FASTCALL__ __fastcall
+#else
+#define __FASTCALL__ __attribute__((fastcall))
+#endif
+
 /* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a
    file open.  */
 #ifdef HAVE_MMAP_ANON
 #endif
 #endif
 
+/* MSVC kludge.  */
+#if defined _MSC_VER
+#define PRIuPTR "lu"
+#define PRIu8 "u"
+#define PRId8 "d"
+#define PRIu64 "I64u"
+#define PRId64 "I64d"
+#endif
+
 #ifdef USING_MMAP
 static inline void *
 allocate_mmap (size_t size)
index 2039ae547919abf0b9ae599163368f4614d38bad..aae158edcc1db4618280063f26fe6407533fe802 100644 (file)
@@ -25,18 +25,18 @@ double float_va_fn(unsigned int x, double y,...)
   total+=(double)x;
   total+=y;
 
-  printf("%u: %.1lf :", x, y);
+  printf("%u: %.1f :", x, y);
 
   va_start(ap, y);
   for(i=0;i<x;i++)
   {
     double arg=va_arg(ap, double);
     total+=arg;
-    printf(" %d:%.1lf ", i, arg);
+    printf(" %d:%.1f ", i, arg);
   }
   va_end(ap);
 
-  printf(" total: %.1lf\n", total);
+  printf(" total: %.1f\n", total);
 
   return total;
 }
@@ -57,7 +57,7 @@ int main (void)
   /* Call it statically and then via ffi */
   resfp=float_va_fn(0,2.0);
   // { dg-output "0: 2.0 : total: 2.0" }
-  printf("compiled: %.1lf\n", resfp);
+  printf("compiled: %.1f\n", resfp);
   // { dg-output "\ncompiled: 2.0" }
 
   arg_types[0] = &ffi_type_uint;
@@ -72,14 +72,14 @@ int main (void)
   values[1] = &doubles[0];
   ffi_call(&cif, FFI_FN(float_va_fn), &resfp, values);
   // { dg-output "\n0: 2.0 : total: 2.0" }
-  printf("ffi: %.1lf\n", resfp);
+  printf("ffi: %.1f\n", resfp);
   // { dg-output "\nffi: 2.0" }
 
   /* Second test, float_va_fn(2,2.0,3.0,4.0), now with variadic params */
   /* Call it statically and then via ffi */
   resfp=float_va_fn(2,2.0,3.0,4.0);
   // { dg-output "\n2: 2.0 : 0:3.0  1:4.0  total: 11.0" }
-  printf("compiled: %.1lf\n", resfp);
+  printf("compiled: %.1f\n", resfp);
   // { dg-output "\ncompiled: 11.0" }
 
   arg_types[0] = &ffi_type_uint;
@@ -100,7 +100,7 @@ int main (void)
   values[3] = &doubles[2];
   ffi_call(&cif, FFI_FN(float_va_fn), &resfp, values);
   // { dg-output "\n2: 2.0 : 0:3.0  1:4.0  total: 11.0" }
-  printf("ffi: %.1lf\n", resfp);
+  printf("ffi: %.1f\n", resfp);
   // { dg-output "\nffi: 11.0" }
 
   exit(0);
index e04e1d58a402aebb00366eb10e876601fff4ad79..380fedf485850e5c9bd3b3e33e16e451e5e0c557 100644 (file)
@@ -229,6 +229,19 @@ main(int argc __UNUSED__, const char** argv __UNUSED__)
        ffi_type*       st_fields[51];
        BigStruct       retVal;
 
+       uint8_t         ui8             = 1;
+       int8_t          si8             = 2;
+       uint16_t        ui16    = 3;
+       int16_t         si16    = 4;
+       uint32_t        ui32    = 5;
+       int32_t         si32    = 6;
+       uint64_t        ui64    = 7;
+       int64_t         si64    = 8;
+       float           f               = 9;
+       double          d               = 10;
+       long double     ld              = 11;
+       char*           p               = (char*)0x12345678;
+
        memset (&retVal, 0, sizeof(retVal));
 
        ret_struct_type.size = 0;
@@ -251,19 +264,6 @@ main(int argc __UNUSED__, const char** argv __UNUSED__)
 
        st_fields[50] = NULL;
 
-       uint8_t         ui8             = 1;
-       int8_t          si8             = 2;
-       uint16_t        ui16    = 3;
-       int16_t         si16    = 4;
-       uint32_t        ui32    = 5;
-       int32_t         si32    = 6;
-       uint64_t        ui64    = 7;
-       int64_t         si64    = 8;
-       float           f               = 9;
-       double          d               = 10;
-       long double     ld              = 11;
-       char*           p               = (char*)0x12345678;
-
        argTypes[0]             = argTypes[12]  = argTypes[24]  = argTypes[36]  = argTypes[48]  = &ffi_type_uint8;
        argValues[0]    = argValues[12] = argValues[24] = argValues[36] = argValues[48] = &ui8;
        argTypes[1]             = argTypes[13]  = argTypes[25]  = argTypes[37]  = argTypes[49]  = &ffi_type_sint8;
index 8aa527ede4e40077e43ffe0a8c124d69cc7c73f6..c15e3a0338294bfea5de2bf1652f2b01875c9253 100644 (file)
@@ -77,6 +77,12 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6};
+  struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0};
+  struct cls_struct_combined g_dbl = {{4.0, 5.0, 6},
+                                     {3, 1.0, 8.0}};
+  struct cls_struct_combined res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -92,12 +98,6 @@ int main (void)
   cls_struct_type2.type = FFI_TYPE_STRUCT;
   cls_struct_type2.elements = cls_struct_fields2;
 
-  struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6};
-  struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0};
-  struct cls_struct_combined g_dbl = {{4.0, 5.0, 6},
-                                     {3, 1.0, 8.0}};
-  struct cls_struct_combined res_dbl;
-
   cls_struct_fields[0] = &ffi_type_double;
   cls_struct_fields[1] = &ffi_type_float;
   cls_struct_fields[2] = &ffi_type_sint;
index 2a9f515cdedaf60d15169b57388e9cbc2ebe0f57..1087f7b1cfd6f8ef61e6fa51da288de281731dca 100644 (file)
@@ -81,6 +81,13 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6};
+  struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0};
+  struct cls_struct_combined g_dbl = {{4.0, 5.0, 6},
+                                     {3, 1.0, 8.0}};
+  struct cls_struct_16byte1 h_dbl = { 3.0, 2.0, 4};
+  struct cls_struct_combined res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -96,13 +103,6 @@ int main (void)
   cls_struct_type2.type = FFI_TYPE_STRUCT;
   cls_struct_type2.elements = cls_struct_fields2;
 
-  struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6};
-  struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0};
-  struct cls_struct_combined g_dbl = {{4.0, 5.0, 6},
-                                     {3, 1.0, 8.0}};
-  struct cls_struct_16byte1 h_dbl = { 3.0, 2.0, 4};
-  struct cls_struct_combined res_dbl;
-
   cls_struct_fields[0] = &ffi_type_double;
   cls_struct_fields[1] = &ffi_type_float;
   cls_struct_fields[2] = &ffi_type_sint;
index d6a718bdd019c9979796921a030dacbfb843d1ec..34a74e71874ddf129571c4e236226afabb2045df 100644 (file)
@@ -67,6 +67,12 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
   ffi_type* dbl_arg_types[4];
 
+  struct A e_dbl = { 1LL, 7};
+  struct B f_dbl = { 99, {12LL , 127}, 255};
+  struct C g_dbl = { 2LL, 9};
+
+  struct B res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -82,12 +88,6 @@ int main (void)
   cls_struct_type2.type = FFI_TYPE_STRUCT;
   cls_struct_type2.elements = cls_struct_fields2;
 
-  struct A e_dbl = { 1LL, 7};
-  struct B f_dbl = { 99, {12LL , 127}, 255};
-  struct C g_dbl = { 2LL, 9};
-
-  struct B res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uint64;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = NULL;
diff --git a/libffi/testsuite/libffi.call/nested_struct11.c b/libffi/testsuite/libffi.call/nested_struct11.c
new file mode 100644 (file)
index 0000000..fce6948
--- /dev/null
@@ -0,0 +1,121 @@
+/* Area:       ffi_call, closure_call
+   Purpose:    Check parameter passing with nested structs
+               of a single type.  This tests the special cases
+               for homogenous floating-point aggregates in the
+               AArch64 PCS.
+   Limitations:        none.
+   PR:         none.
+   Originator:  ARM Ltd.  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+  float a_x;
+  float a_y;
+} A;
+
+typedef struct B {
+  float b_x;
+  float b_y;
+} B;
+
+typedef struct C {
+  A a;
+  B b;
+} C;
+
+static C C_fn (int x, int y, int z, C source, int i, int j, int k)
+{
+  C result;
+  result.a.a_x = source.a.a_x;
+  result.a.a_y = source.a.a_y;
+  result.b.b_x = source.b.b_x;
+  result.b.b_y = source.b.b_y;
+
+  printf ("%d, %d, %d, %d, %d, %d\n", x, y, z, i, j, k);
+
+  printf ("%.1f, %.1f, %.1f, %.1f, "
+         "%.1f, %.1f, %.1f, %.1f\n",
+         source.a.a_x, source.a.a_y,
+         source.b.b_x, source.b.b_y,
+         result.a.a_x, result.a.a_y,
+         result.b.b_x, result.b.b_y);
+
+  return result;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+
+  ffi_type* struct_fields_source_a[3];
+  ffi_type* struct_fields_source_b[3];
+  ffi_type* struct_fields_source_c[3];
+  ffi_type* arg_types[8];
+
+  ffi_type struct_type_a, struct_type_b, struct_type_c;
+
+  struct A source_fld_a = {1.0, 2.0};
+  struct B source_fld_b = {4.0, 8.0};
+  int k = 1;
+
+  struct C result;
+  struct C source = {source_fld_a, source_fld_b};
+
+  struct_type_a.size = 0;
+  struct_type_a.alignment = 0;
+  struct_type_a.type = FFI_TYPE_STRUCT;
+  struct_type_a.elements = struct_fields_source_a;
+
+  struct_type_b.size = 0;
+  struct_type_b.alignment = 0;
+  struct_type_b.type = FFI_TYPE_STRUCT;
+  struct_type_b.elements = struct_fields_source_b;
+
+  struct_type_c.size = 0;
+  struct_type_c.alignment = 0;
+  struct_type_c.type = FFI_TYPE_STRUCT;
+  struct_type_c.elements = struct_fields_source_c;
+
+  struct_fields_source_a[0] = &ffi_type_float;
+  struct_fields_source_a[1] = &ffi_type_float;
+  struct_fields_source_a[2] = NULL;
+
+  struct_fields_source_b[0] = &ffi_type_float;
+  struct_fields_source_b[1] = &ffi_type_float;
+  struct_fields_source_b[2] = NULL;
+
+  struct_fields_source_c[0] = &struct_type_a;
+  struct_fields_source_c[1] = &struct_type_b;
+  struct_fields_source_c[2] = NULL;
+
+  arg_types[0] = &ffi_type_sint32;
+  arg_types[1] = &ffi_type_sint32;
+  arg_types[2] = &ffi_type_sint32;
+  arg_types[3] = &struct_type_c;
+  arg_types[4] = &ffi_type_sint32;
+  arg_types[5] = &ffi_type_sint32;
+  arg_types[6] = &ffi_type_sint32;
+  arg_types[7] = NULL;
+
+  void *args[7];
+  args[0] = &k;
+  args[1] = &k;
+  args[2] = &k;
+  args[3] = &source;
+  args[4] = &k;
+  args[5] = &k;
+  args[6] = &k;
+  CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 7, &struct_type_c,
+                      arg_types) == FFI_OK);
+
+  ffi_call (&cif, FFI_FN (C_fn), &result, args);
+  /* { dg-output "1, 1, 1, 1, 1, 1\n" } */
+  /* { dg-output "1.0, 2.0, 4.0, 8.0, 1.0, 2.0, 4.0, 8.0" } */
+  CHECK (result.a.a_x == source.a.a_x);
+  CHECK (result.a.a_y == source.a.a_y);
+  CHECK (result.b.b_x == source.b.b_x);
+  CHECK (result.b.b_y == source.b.b_y);
+  exit (0);
+}
index de1584c18a1ac138427474424dfe410bd8e9675d..69268cdb8af34d690e24970564c67315f4de66d0 100644 (file)
@@ -57,6 +57,11 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1;
   ffi_type* dbl_arg_types[3];
 
+  struct A e_dbl = { 1, 7};
+  struct B f_dbl = {{12 , 127}, 99};
+
+  struct B res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -67,11 +72,6 @@ int main (void)
   cls_struct_type1.type = FFI_TYPE_STRUCT;
   cls_struct_type1.elements = cls_struct_fields1;
 
-  struct A e_dbl = { 1, 7};
-  struct B f_dbl = {{12 , 127}, 99};
-
-  struct B res_dbl;
-
   cls_struct_fields[0] = &ffi_type_ulong;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = NULL;
index 58aa85362e8463615b4891fd4677f6482b9665c9..ab18cad733521046f936b8c7c672bfb0153064dd 100644 (file)
@@ -58,6 +58,11 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1;
   ffi_type* dbl_arg_types[3];
 
+  struct A e_dbl = { 1LL, 7};
+  struct B f_dbl = {{12LL , 127}, 99};
+
+  struct B res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -68,11 +73,6 @@ int main (void)
   cls_struct_type1.type = FFI_TYPE_STRUCT;
   cls_struct_type1.elements = cls_struct_fields1;
 
-  struct A e_dbl = { 1LL, 7};
-  struct B f_dbl = {{12LL , 127}, 99};
-
-  struct B res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uint64;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = NULL;
index 98e491e65cfae5ab85c7458b8d4f0c7c93b6080d..2ffb4d65a0635cafa530d0f2f35f597f12c50142 100644 (file)
@@ -58,6 +58,11 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1;
   ffi_type* dbl_arg_types[3];
 
+  struct A e_dbl = { 1.0, 7};
+  struct B f_dbl = {{12.0 , 127}, 99};
+
+  struct B res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -68,11 +73,6 @@ int main (void)
   cls_struct_type1.type = FFI_TYPE_STRUCT;
   cls_struct_type1.elements = cls_struct_fields1;
 
-  struct A e_dbl = { 1.0, 7};
-  struct B f_dbl = {{12.0 , 127}, 99};
-
-  struct B res_dbl;
-
   cls_struct_fields[0] = &ffi_type_double;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = NULL;
index d8e3537d5a0903216ce6662141eade5d5d0e95b8..6c79845d984a68693c4a21087ebb99b9afd52e8d 100644 (file)
@@ -58,6 +58,11 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1;
   ffi_type* dbl_arg_types[3];
 
+  struct A e_dbl = { 1.0, 7};
+  struct B f_dbl = {{12.0 , 127}, 99};
+
+  struct B res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -68,11 +73,6 @@ int main (void)
   cls_struct_type1.type = FFI_TYPE_STRUCT;
   cls_struct_type1.elements = cls_struct_fields1;
 
-  struct A e_dbl = { 1.0, 7};
-  struct B f_dbl = {{12.0 , 127}, 99};
-
-  struct B res_dbl;
-
   cls_struct_fields[0] = &ffi_type_longdouble;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = NULL;
index 2f2b25a15db14e43a241b4da9c2fad2288bb0239..59d35796f8def3db59580e42343f203d5c7de194 100644 (file)
@@ -66,6 +66,12 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
   ffi_type* dbl_arg_types[4];
 
+  struct A e_dbl = { 1.0, 7};
+  struct B f_dbl = {{12.0 , 127}, 99};
+  struct C g_dbl = { 2, 9};
+
+  struct B res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -81,12 +87,6 @@ int main (void)
   cls_struct_type2.type = FFI_TYPE_STRUCT;
   cls_struct_type2.elements = cls_struct_fields2;
 
-  struct A e_dbl = { 1.0, 7};
-  struct B f_dbl = {{12.0 , 127}, 99};
-  struct C g_dbl = { 2, 9};
-
-  struct B res_dbl;
-
   cls_struct_fields[0] = &ffi_type_double;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = NULL;
index 14c70239eb29025d4db59a44b3045e3e9944f369..27595e6f5c301c151cf192d4da680f863aefca90 100644 (file)
@@ -58,6 +58,11 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1;
   ffi_type* dbl_arg_types[3];
 
+  struct A e_dbl = { 1LL, 7};
+  struct B f_dbl = {{12.0 , 127}, 99};
+
+  struct B res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -68,11 +73,6 @@ int main (void)
   cls_struct_type1.type = FFI_TYPE_STRUCT;
   cls_struct_type1.elements = cls_struct_fields1;
 
-  struct A e_dbl = { 1LL, 7};
-  struct B f_dbl = {{12.0 , 127}, 99};
-
-  struct B res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uint64;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = NULL;
index bb77ead8d328f49f101a2b2e59d111c4f2d0c237..0e6c68281e1a0ff66d8afc5e93b9466dd7e6d93e 100644 (file)
@@ -66,6 +66,12 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
   ffi_type* dbl_arg_types[4];
 
+  struct A e_dbl = { 1LL, 7};
+  struct B f_dbl = {{12LL , 127}, 99};
+  struct C g_dbl = { 2LL, 9};
+
+  struct B res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -81,12 +87,6 @@ int main (void)
   cls_struct_type2.type = FFI_TYPE_STRUCT;
   cls_struct_type2.elements = cls_struct_fields2;
 
-  struct A e_dbl = { 1LL, 7};
-  struct B f_dbl = {{12LL , 127}, 99};
-  struct C g_dbl = { 2LL, 9};
-
-  struct B res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uint64;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = NULL;
index e9f541c83a85cde3d7e7380a86deccc07eb0dbc7..5f7ac67752caa154ed93eaeeff46b706795f8f95 100644 (file)
@@ -66,6 +66,12 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
   ffi_type* dbl_arg_types[4];
 
+  struct A e_dbl = { 1, 7LL};
+  struct B f_dbl = {{12.0 , 127}, 99};
+  struct C g_dbl = { 2, 9};
+
+  struct B res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -81,12 +87,6 @@ int main (void)
   cls_struct_type2.type = FFI_TYPE_STRUCT;
   cls_struct_type2.elements = cls_struct_fields2;
 
-  struct A e_dbl = { 1, 7LL};
-  struct B f_dbl = {{12.0 , 127}, 99};
-  struct C g_dbl = { 2, 9};
-
-  struct B res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_uint64;
   cls_struct_fields[2] = NULL;
index 23a93b900d99987e0417235030b614c53491b1c1..f32938c009ca06d6f680ba4f21961cb3b399c9ee 100644 (file)
@@ -82,17 +82,17 @@ int main (void)
        ffi_type cls_struct_type;
        ffi_type* dbl_arg_types[5];
 
-       cls_struct_type.size = 0;
-       cls_struct_type.alignment = 0;
-       cls_struct_type.type = FFI_TYPE_STRUCT;
-       cls_struct_type.elements = cls_struct_fields;
-
        struct_108byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 1.0, 2.0, 3.0, 7.0, 2.0, 7 };
        struct_108byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0, 5.0, 7.0, 9.0, 1.0, 4 };
        struct_108byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 8.0, 6.0, 1.0, 4.0, 0.0, 3 };
        struct_108byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 9.0, 2.0, 6.0, 5.0, 3.0, 2 };
        struct_108byte res_dbl;
 
+       cls_struct_type.size = 0;
+       cls_struct_type.alignment = 0;
+       cls_struct_type.type = FFI_TYPE_STRUCT;
+       cls_struct_type.elements = cls_struct_fields;
+
        cls_struct_fields[0] = &ffi_type_double;
        cls_struct_fields[1] = &ffi_type_double;
        cls_struct_fields[2] = &ffi_type_double;
index e2599d267377369ca2d976be8677a779b1321a69..3b0ef9ac4a009d0d651aaa05e01d9d18828ec745 100644 (file)
@@ -84,17 +84,17 @@ int main (void)
        ffi_type cls_struct_type;
        ffi_type* dbl_arg_types[5];
 
-       cls_struct_type.size = 0;
-       cls_struct_type.alignment = 0;
-       cls_struct_type.type = FFI_TYPE_STRUCT;
-       cls_struct_type.elements = cls_struct_fields;
-
        struct_116byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 7 };
        struct_116byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0, 5.0, 7.0, 9.0, 1.0, 6.0, 4 };
        struct_116byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 8.0, 6.0, 1.0, 4.0, 0.0, 7.0, 3 };
        struct_116byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 9.0, 2.0, 6.0, 5.0, 3.0, 8.0, 2 };
        struct_116byte res_dbl;
 
+       cls_struct_type.size = 0;
+       cls_struct_type.alignment = 0;
+       cls_struct_type.type = FFI_TYPE_STRUCT;
+       cls_struct_type.elements = cls_struct_fields;
+
        cls_struct_fields[0] = &ffi_type_double;
        cls_struct_fields[1] = &ffi_type_double;
        cls_struct_fields[2] = &ffi_type_double;
index 1fc6a9edd33471c59f0f5edcafd491cbe0d2c582..973ee02ede887cc20e3e76a4f4b279337e1be679 100644 (file)
@@ -68,17 +68,17 @@ int main (void)
        ffi_type cls_struct_type;
        ffi_type* dbl_arg_types[5];
 
-       cls_struct_type.size = 0;
-       cls_struct_type.alignment = 0;
-       cls_struct_type.type = FFI_TYPE_STRUCT;
-       cls_struct_type.elements = cls_struct_fields;
-
        struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7.0 };
        struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0 };
        struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3.0 };
        struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2.0 };
        struct_72byte res_dbl;
 
+       cls_struct_type.size = 0;
+       cls_struct_type.alignment = 0;
+       cls_struct_type.type = FFI_TYPE_STRUCT;
+       cls_struct_type.elements = cls_struct_fields;
+
        cls_struct_fields[0] = &ffi_type_double;
        cls_struct_fields[1] = &ffi_type_double;
        cls_struct_fields[2] = &ffi_type_double;
index cb2f2fba3317c84817f6d725533679f2ae45a40e..84323d16a918c87084c443a8dbefed8afbdfc696 100644 (file)
@@ -69,17 +69,17 @@ int main (void)
        ffi_type cls_struct_type;
        ffi_type* dbl_arg_types[5];
 
-       cls_struct_type.size = 0;
-       cls_struct_type.alignment = 0;
-       cls_struct_type.type = FFI_TYPE_STRUCT;
-       cls_struct_type.elements = cls_struct_fields;
-
        struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7 };
        struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4 };
        struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3 };
        struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2 };
        struct_72byte res_dbl;
 
+       cls_struct_type.size = 0;
+       cls_struct_type.alignment = 0;
+       cls_struct_type.type = FFI_TYPE_STRUCT;
+       cls_struct_type.elements = cls_struct_fields;
+
        cls_struct_fields[0] = &ffi_type_double;
        cls_struct_fields[1] = &ffi_type_double;
        cls_struct_fields[2] = &ffi_type_double;
index b348e434097904e54e74bd15430a111831cb7bb5..0d81061e75852ceb11c2c88eaf45f254b9a8c35a 100644 (file)
@@ -8,12 +8,11 @@
 
 #include "ffitest.h"
 
-static size_t __attribute__((fastcall)) my_fastcall_strlen(char *s)
+static size_t __FASTCALL__ my_fastcall_strlen(char *s)
 {
   return (strlen(s));
 }
 
-int d
 int main (void)
 {
   ffi_cif cif;
index ea76c8544902f5fafdc5e4965b9229b123977d2c..bfc23f642cc870ab19a48bc1d7fdc46109833df4 100644 (file)
@@ -30,6 +30,13 @@ int main (void)
   void *values[MAX_ARGS];
   ffi_type ts1_type;
   ffi_type *ts1_type_elements[4];
+
+  test_structure_1 ts1_arg;
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_1 *ts1_result =
+    (test_structure_1 *) malloc (sizeof(test_structure_1));
+
   ts1_type.size = 0;
   ts1_type.alignment = 0;
   ts1_type.type = FFI_TYPE_STRUCT;
@@ -39,11 +46,6 @@ int main (void)
   ts1_type_elements[2] = &ffi_type_uint;
   ts1_type_elements[3] = NULL;
   
-  test_structure_1 ts1_arg;
-  /* This is a hack to get a properly aligned result buffer */
-  test_structure_1 *ts1_result = 
-    (test_structure_1 *) malloc (sizeof(test_structure_1));
-  
   args[0] = &ts1_type;
   values[0] = &ts1_arg;
   
index 4a7eb9444bd412aa607c228ee5cf9b9256941b01..b756f5ad8b52f8d2e0e9596fc12a7b494926c323 100644 (file)
@@ -14,7 +14,7 @@ typedef struct
   unsigned int ui;
 } test_structure_1;
 
-static __attribute__ ((fastcall)) test_structure_1 struct1(test_structure_1 ts)
+static test_structure_1 __FASTCALL__ struct1(test_structure_1 ts)
 {
   ts.uc++;
   ts.d--;
@@ -30,6 +30,13 @@ int main (void)
   void *values[MAX_ARGS];
   ffi_type ts1_type;
   ffi_type *ts1_type_elements[4];
+
+  test_structure_1 ts1_arg;
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_1 *ts1_result =
+    (test_structure_1 *) malloc (sizeof(test_structure_1));
+
   ts1_type.size = 0;
   ts1_type.alignment = 0;
   ts1_type.type = FFI_TYPE_STRUCT;
@@ -39,11 +46,6 @@ int main (void)
   ts1_type_elements[2] = &ffi_type_uint;
   ts1_type_elements[3] = NULL;
   
-  test_structure_1 ts1_arg;
-  /* This is a hack to get a properly aligned result buffer */
-  test_structure_1 *ts1_result = 
-    (test_structure_1 *) malloc (sizeof(test_structure_1));
-  
   args[0] = &ts1_type;
   values[0] = &ts1_arg;
   
index 14bc9fdc6f217b924c5ea78ab2cc905d88dff081..d85385e7d3f235c09dd2d6809c25bc22e0be4531 100644 (file)
@@ -29,6 +29,11 @@ int main (void)
   test_structure_2 ts2_arg;
   ffi_type ts2_type;
   ffi_type *ts2_type_elements[3];
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_2 *ts2_result =
+    (test_structure_2 *) malloc (sizeof(test_structure_2));
+
   ts2_type.size = 0;
   ts2_type.alignment = 0;
   ts2_type.type = FFI_TYPE_STRUCT;
@@ -37,11 +42,6 @@ int main (void)
   ts2_type_elements[1] = &ffi_type_double;
   ts2_type_elements[2] = NULL;
 
-  
-  /* This is a hack to get a properly aligned result buffer */
-  test_structure_2 *ts2_result = 
-    (test_structure_2 *) malloc (sizeof(test_structure_2));
-  
   args[0] = &ts2_type;
   values[0] = &ts2_arg;
   
index 2bfbdc5ff81cec08d2e682cb31abd722ede343ad..5d022855c574ac62916de93b4a733b4e7094dd87 100644 (file)
@@ -13,7 +13,7 @@ typedef struct
   double d2;
 } test_structure_2;
 
-static test_structure_2 __attribute__ ((fastcall)) struct2(test_structure_2 ts)
+static test_structure_2 __FASTCALL__ struct2(test_structure_2 ts)
 {
   ts.d1--;
   ts.d2--;
@@ -29,6 +29,11 @@ int main (void)
   test_structure_2 ts2_arg;
   ffi_type ts2_type;
   ffi_type *ts2_type_elements[3];
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_2 *ts2_result =
+    (test_structure_2 *) malloc (sizeof(test_structure_2));
+
   ts2_type.size = 0;
   ts2_type.alignment = 0;
   ts2_type.type = FFI_TYPE_STRUCT;
@@ -37,11 +42,6 @@ int main (void)
   ts2_type_elements[1] = &ffi_type_double;
   ts2_type_elements[2] = NULL;
 
-  
-  /* This is a hack to get a properly aligned result buffer */
-  test_structure_2 *ts2_result = 
-    (test_structure_2 *) malloc (sizeof(test_structure_2));
-  
   args[0] = &ts2_type;
   values[0] = &ts2_arg;
   
index e0bb09b078858f9d5ec91d8c2f4d6ec4075e6896..de883c2638e0b952c24f59c18589773ef74f1aee 100644 (file)
@@ -27,6 +27,11 @@ int main (void)
   int compare_value;
   ffi_type ts3_type;
   ffi_type *ts3_type_elements[2];
+
+  test_structure_3 ts3_arg;
+  test_structure_3 *ts3_result =
+    (test_structure_3 *) malloc (sizeof(test_structure_3));
+
   ts3_type.size = 0;
   ts3_type.alignment = 0;
   ts3_type.type = FFI_TYPE_STRUCT;
@@ -34,10 +39,6 @@ int main (void)
   ts3_type_elements[0] = &ffi_type_sint;
   ts3_type_elements[1] = NULL;
 
-  test_structure_3 ts3_arg;
-  test_structure_3 *ts3_result = 
-    (test_structure_3 *) malloc (sizeof(test_structure_3));
-  
   args[0] = &ts3_type;
   values[0] = &ts3_arg;
   
index 0ad0a83ba12253b9ff1bc7400c9f53a1b2b29aca..48e03495441c0dcb6d0aae7b1c45f7028a5a4ce0 100644 (file)
@@ -28,21 +28,22 @@ int main (void)
   void *values[MAX_ARGS];
   ffi_type ts4_type;
   ffi_type *ts4_type_elements[4];  
+
+  test_structure_4 ts4_arg;
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_4 *ts4_result =
+    (test_structure_4 *) malloc (sizeof(test_structure_4));
+
   ts4_type.size = 0;
   ts4_type.alignment = 0;
   ts4_type.type = FFI_TYPE_STRUCT;
-  test_structure_4 ts4_arg;
   ts4_type.elements = ts4_type_elements;
   ts4_type_elements[0] = &ffi_type_uint;
   ts4_type_elements[1] = &ffi_type_uint;
   ts4_type_elements[2] = &ffi_type_uint;
   ts4_type_elements[3] = NULL;
 
-  
-  /* This is a hack to get a properly aligned result buffer */
-  test_structure_4 *ts4_result = 
-    (test_structure_4 *) malloc (sizeof(test_structure_4));
-  
   args[0] = &ts4_type;
   values[0] = &ts4_arg;
   
index c03cc97ac990bff32e84adc0d3832284cd8dff2c..28b1f0c4265e42b25a8806ad1f23a02b5df0e5d7 100644 (file)
@@ -27,6 +27,13 @@ int main (void)
   void *values[MAX_ARGS];
   ffi_type ts5_type;
   ffi_type *ts5_type_elements[3];
+
+  test_structure_5 ts5_arg1, ts5_arg2;
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_5 *ts5_result =
+    (test_structure_5 *) malloc (sizeof(test_structure_5));
+
   ts5_type.size = 0;
   ts5_type.alignment = 0;
   ts5_type.type = FFI_TYPE_STRUCT;
@@ -35,12 +42,6 @@ int main (void)
   ts5_type_elements[1] = &ffi_type_schar;
   ts5_type_elements[2] = NULL;
 
-  test_structure_5 ts5_arg1, ts5_arg2;
-  
-  /* This is a hack to get a properly aligned result buffer */
-  test_structure_5 *ts5_result = 
-    (test_structure_5 *) malloc (sizeof(test_structure_5));
-  
   args[0] = &ts5_type;
   args[1] = &ts5_type;
   values[0] = &ts5_arg1;
index 83db9afbbeecf8f8acd05dd61b8ddbeaee6ccacd..0e267467a7b08dc44c7f4ef8072c7f7272a430e3 100644 (file)
@@ -27,6 +27,13 @@ int main (void)
   void *values[MAX_ARGS];
   ffi_type ts6_type;
   ffi_type *ts6_type_elements[3];
+
+  test_structure_6 ts6_arg;
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_6 *ts6_result =
+    (test_structure_6 *) malloc (sizeof(test_structure_6));
+
   ts6_type.size = 0;
   ts6_type.alignment = 0;
   ts6_type.type = FFI_TYPE_STRUCT;
@@ -35,13 +42,6 @@ int main (void)
   ts6_type_elements[1] = &ffi_type_double;
   ts6_type_elements[2] = NULL;
 
-
-  test_structure_6 ts6_arg;
-
-  /* This is a hack to get a properly aligned result buffer */
-  test_structure_6 *ts6_result = 
-    (test_structure_6 *) malloc (sizeof(test_structure_6));
-  
   args[0] = &ts6_type;
   values[0] = &ts6_arg;
 
index 58aac4c9922e0e82a1c355b0b4ff92b3d93c55a9..8f2bbfd949c52240a8f8f2b8fbc9665c222f7cf4 100644 (file)
@@ -29,6 +29,13 @@ int main (void)
   void *values[MAX_ARGS];
   ffi_type ts7_type;
   ffi_type *ts7_type_elements[4];
+
+  test_structure_7 ts7_arg;
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_7 *ts7_result =
+    (test_structure_7 *) malloc (sizeof(test_structure_7));
+
   ts7_type.size = 0;
   ts7_type.alignment = 0;
   ts7_type.type = FFI_TYPE_STRUCT;
@@ -38,13 +45,6 @@ int main (void)
   ts7_type_elements[2] = &ffi_type_double;
   ts7_type_elements[3] = NULL;
 
-
-  test_structure_7 ts7_arg;
-  
-  /* This is a hack to get a properly aligned result buffer */
-  test_structure_7 *ts7_result = 
-    (test_structure_7 *) malloc (sizeof(test_structure_7));
-  
   args[0] = &ts7_type;
   values[0] = &ts7_arg;
   
index c773ac7b5ac6d751878acaba7f1c914120949a74..266e1f0ad606e7b85fb589bd74f2057816acb2dd 100644 (file)
@@ -31,6 +31,13 @@ int main (void)
   void *values[MAX_ARGS];
   ffi_type ts8_type;
   ffi_type *ts8_type_elements[5];
+
+  test_structure_8 ts8_arg;
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_8 *ts8_result =
+    (test_structure_8 *) malloc (sizeof(test_structure_8));
+
   ts8_type.size = 0;
   ts8_type.alignment = 0;
   ts8_type.type = FFI_TYPE_STRUCT;
@@ -41,12 +48,6 @@ int main (void)
   ts8_type_elements[3] = &ffi_type_float;
   ts8_type_elements[4] = NULL;
 
-  test_structure_8 ts8_arg;
-  
-  /* This is a hack to get a properly aligned result buffer */
-  test_structure_8 *ts8_result = 
-    (test_structure_8 *) malloc (sizeof(test_structure_8));
-  
   args[0] = &ts8_type;
   values[0] = &ts8_arg;
   
index f30091f54f129040ffbd8cb22534bd5e8639943a..efeb7161b845f29e0da17c482c891e5377708871 100644 (file)
@@ -28,6 +28,13 @@ int main (void)
   void *values[MAX_ARGS];
   ffi_type ts9_type;
   ffi_type *ts9_type_elements[3];
+
+  test_structure_9 ts9_arg;
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_9 *ts9_result =
+    (test_structure_9 *) malloc (sizeof(test_structure_9));
+
   ts9_type.size = 0;
   ts9_type.alignment = 0;
   ts9_type.type = FFI_TYPE_STRUCT;
@@ -36,12 +43,6 @@ int main (void)
   ts9_type_elements[1] = &ffi_type_sint;
   ts9_type_elements[2] = NULL;
 
-  test_structure_9 ts9_arg;
-  
-  /* This is a hack to get a properly aligned result buffer */
-  test_structure_9 *ts9_result = 
-    (test_structure_9 *) malloc (sizeof(test_structure_9));
-  
   args[0] = &ts9_type;
   values[0] = &ts9_arg;
   
index 161cc891798670dfbe12e7001f72a376cd827bc4..ca31056d8c834059a936ab625cd96f967bfc6235 100644 (file)
@@ -43,13 +43,13 @@ int main (void)
   ffi_type cls_struct_type0;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_combined g_dbl = {4.0, 5.0, 1.0, 8.0};
+
   cls_struct_type0.size = 0;
   cls_struct_type0.alignment = 0;
   cls_struct_type0.type = FFI_TYPE_STRUCT;
   cls_struct_type0.elements = cls_struct_fields0;
 
-  struct cls_struct_combined g_dbl = {4.0, 5.0, 1.0, 8.0};
-
   cls_struct_fields0[0] = &ffi_type_float;
   cls_struct_fields0[1] = &ffi_type_float;
   cls_struct_fields0[2] = &ffi_type_float;
diff --git a/libffi/testsuite/libffi.call/uninitialized.c b/libffi/testsuite/libffi.call/uninitialized.c
new file mode 100644 (file)
index 0000000..f00d830
--- /dev/null
@@ -0,0 +1,61 @@
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct
+{
+  unsigned char uc;
+  double d;
+  unsigned int ui;
+} test_structure_1;
+
+static test_structure_1 struct1(test_structure_1 ts)
+{
+  ts.uc++;
+  ts.d--;
+  ts.ui++;
+
+  return ts;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  ffi_type ts1_type;
+  ffi_type *ts1_type_elements[4];
+
+  memset(&cif, 1, sizeof(cif));
+  ts1_type.size = 0;
+  ts1_type.alignment = 0;
+  ts1_type.type = FFI_TYPE_STRUCT;
+  ts1_type.elements = ts1_type_elements;
+  ts1_type_elements[0] = &ffi_type_uchar;
+  ts1_type_elements[1] = &ffi_type_double;
+  ts1_type_elements[2] = &ffi_type_uint;
+  ts1_type_elements[3] = NULL;
+
+  test_structure_1 ts1_arg;
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_1 *ts1_result =
+    (test_structure_1 *) malloc (sizeof(test_structure_1));
+
+  args[0] = &ts1_type;
+  values[0] = &ts1_arg;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+                    &ts1_type, args) == FFI_OK);
+
+  ts1_arg.uc = '\x01';
+  ts1_arg.d = 3.14159;
+  ts1_arg.ui = 555;
+
+  ffi_call(&cif, FFI_FN(struct1), ts1_result, values);
+
+  CHECK(ts1_result->ui == 556);
+  CHECK(ts1_result->d == 3.14159 - 1);
+
+  free (ts1_result);
+  exit(0);
+}
diff --git a/libffi/testsuite/libffi.call/va_1.c b/libffi/testsuite/libffi.call/va_1.c
new file mode 100644 (file)
index 0000000..5c7cce9
--- /dev/null
@@ -0,0 +1,196 @@
+/* Area:               ffi_call
+   Purpose:            Test passing struct in variable argument lists.
+   Limitations:        none.
+   PR:                 none.
+   Originator:         ARM Ltd. */
+
+/* { dg-do run } */
+/* { dg-output "" { xfail avr32*-*-* x86_64-*-*-* } } */
+
+#include "ffitest.h"
+#include <stdarg.h>
+
+struct small_tag
+{
+  unsigned char a;
+  unsigned char b;
+};
+
+struct large_tag
+{
+  unsigned a;
+  unsigned b;
+  unsigned c;
+  unsigned d;
+  unsigned e;
+};
+
+static int
+test_fn (int n, ...)
+{
+  va_list ap;
+  struct small_tag s1;
+  struct small_tag s2;
+  struct large_tag l;
+  unsigned char uc;
+  signed char sc;
+  unsigned short us;
+  signed short ss;
+  unsigned int ui;
+  signed int si;
+  unsigned long ul;
+  signed long sl;
+  float f;
+  double d;
+
+  va_start (ap, n);
+  s1 = va_arg (ap, struct small_tag);
+  l = va_arg (ap, struct large_tag);
+  s2 = va_arg (ap, struct small_tag);
+
+  uc = va_arg (ap, unsigned);
+  sc = va_arg (ap, signed);
+
+  us = va_arg (ap, unsigned);
+  ss = va_arg (ap, signed);
+
+  ui = va_arg (ap, unsigned int);
+  si = va_arg (ap, signed int);
+
+  ul = va_arg (ap, unsigned long);
+  sl = va_arg (ap, signed long);
+
+  f = va_arg (ap, double);     /* C standard promotes float->double
+                                  when anonymous */
+  d = va_arg (ap, double);
+
+  printf ("%u %u %u %u %u %u %u %u %u uc=%u sc=%d %u %d %u %d %lu %ld %f %f\n",
+         s1.a, s1.b, l.a, l.b, l.c, l.d, l.e,
+         s2.a, s2.b,
+         uc, sc,
+         us, ss,
+         ui, si,
+         ul, sl,
+         f, d);
+  va_end (ap);
+  return n + 1;
+}
+
+int
+main (void)
+{
+  ffi_cif cif;
+  void* args[15];
+  ffi_type* arg_types[15];
+
+  ffi_type s_type;
+  ffi_type *s_type_elements[3];
+
+  ffi_type l_type;
+  ffi_type *l_type_elements[6];
+
+  struct small_tag s1;
+  struct small_tag s2;
+  struct large_tag l1;
+
+  int n;
+  int res;
+
+  unsigned char uc;
+  signed char sc;
+  unsigned short us;
+  signed short ss;
+  unsigned int ui;
+  signed int si;
+  unsigned long ul;
+  signed long sl;
+  double d1;
+  double f1;
+
+  s_type.size = 0;
+  s_type.alignment = 0;
+  s_type.type = FFI_TYPE_STRUCT;
+  s_type.elements = s_type_elements;
+
+  s_type_elements[0] = &ffi_type_uchar;
+  s_type_elements[1] = &ffi_type_uchar;
+  s_type_elements[2] = NULL;
+
+  l_type.size = 0;
+  l_type.alignment = 0;
+  l_type.type = FFI_TYPE_STRUCT;
+  l_type.elements = l_type_elements;
+
+  l_type_elements[0] = &ffi_type_uint;
+  l_type_elements[1] = &ffi_type_uint;
+  l_type_elements[2] = &ffi_type_uint;
+  l_type_elements[3] = &ffi_type_uint;
+  l_type_elements[4] = &ffi_type_uint;
+  l_type_elements[5] = NULL;
+
+  arg_types[0] = &ffi_type_sint;
+  arg_types[1] = &s_type;
+  arg_types[2] = &l_type;
+  arg_types[3] = &s_type;
+  arg_types[4] = &ffi_type_uint;
+  arg_types[5] = &ffi_type_sint;
+  arg_types[6] = &ffi_type_uint;
+  arg_types[7] = &ffi_type_sint;
+  arg_types[8] = &ffi_type_uint;
+  arg_types[9] = &ffi_type_sint;
+  arg_types[10] = &ffi_type_ulong;
+  arg_types[11] = &ffi_type_slong;
+  arg_types[12] = &ffi_type_double;
+  arg_types[13] = &ffi_type_double;
+  arg_types[14] = NULL;
+
+  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 14, &ffi_type_sint, arg_types) == FFI_OK);
+
+  s1.a = 5;
+  s1.b = 6;
+
+  l1.a = 10;
+  l1.b = 11;
+  l1.c = 12;
+  l1.d = 13;
+  l1.e = 14;
+
+  s2.a = 7;
+  s2.b = 8;
+
+  n = 41;
+
+  uc = 9;
+  sc = 10;
+  us = 11;
+  ss = 12;
+  ui = 13;
+  si = 14;
+  ul = 15;
+  sl = 16;
+  f1 = 2.12;
+  d1 = 3.13;
+
+  args[0] = &n;
+  args[1] = &s1;
+  args[2] = &l1;
+  args[3] = &s2;
+  args[4] = &uc;
+  args[5] = &sc;
+  args[6] = &us;
+  args[7] = &ss;
+  args[8] = &ui;
+  args[9] = &si;
+  args[10] = &ul;
+  args[11] = &sl;
+  args[12] = &f1;
+  args[13] = &d1;
+  args[14] = NULL;
+
+  ffi_call(&cif, FFI_FN(test_fn), &res, args);
+  /* { dg-output "5 6 10 11 12 13 14 7 8 uc=9 sc=10 11 12 13 14 15 16 2.120000 3.130000" } */
+  printf("res: %d\n", (int) res);
+  /* { dg-output "\nres: 42" } */
+
+  return 0;
+}
diff --git a/libffi/testsuite/libffi.call/va_struct1.c b/libffi/testsuite/libffi.call/va_struct1.c
new file mode 100644 (file)
index 0000000..11d1f10
--- /dev/null
@@ -0,0 +1,121 @@
+/* Area:               ffi_call
+   Purpose:            Test passing struct in variable argument lists.
+   Limitations:        none.
+   PR:                 none.
+   Originator: ARM Ltd. */
+
+/* { dg-do run } */
+/* { dg-output "" { xfail avr32*-*-* } } */
+
+#include "ffitest.h"
+#include <stdarg.h>
+
+struct small_tag
+{
+  unsigned char a;
+  unsigned char b;
+};
+
+struct large_tag
+{
+  unsigned a;
+  unsigned b;
+  unsigned c;
+  unsigned d;
+  unsigned e;
+};
+
+static int
+test_fn (int n, ...)
+{
+  va_list ap;
+  struct small_tag s1;
+  struct small_tag s2;
+  struct large_tag l;
+
+  va_start (ap, n);
+  s1 = va_arg (ap, struct small_tag);
+  l = va_arg (ap, struct large_tag);
+  s2 = va_arg (ap, struct small_tag);
+  printf ("%u %u %u %u %u %u %u %u %u\n", s1.a, s1.b, l.a, l.b, l.c, l.d, l.e,
+         s2.a, s2.b);
+  va_end (ap);
+  return n + 1;
+}
+
+int
+main (void)
+{
+  ffi_cif cif;
+  void* args[5];
+  ffi_type* arg_types[5];
+
+  ffi_type s_type;
+  ffi_type *s_type_elements[3];
+
+  ffi_type l_type;
+  ffi_type *l_type_elements[6];
+
+  struct small_tag s1;
+  struct small_tag s2;
+  struct large_tag l1;
+
+  int n;
+  int res;
+
+  s_type.size = 0;
+  s_type.alignment = 0;
+  s_type.type = FFI_TYPE_STRUCT;
+  s_type.elements = s_type_elements;
+
+  s_type_elements[0] = &ffi_type_uchar;
+  s_type_elements[1] = &ffi_type_uchar;
+  s_type_elements[2] = NULL;
+
+  l_type.size = 0;
+  l_type.alignment = 0;
+  l_type.type = FFI_TYPE_STRUCT;
+  l_type.elements = l_type_elements;
+
+  l_type_elements[0] = &ffi_type_uint;
+  l_type_elements[1] = &ffi_type_uint;
+  l_type_elements[2] = &ffi_type_uint;
+  l_type_elements[3] = &ffi_type_uint;
+  l_type_elements[4] = &ffi_type_uint;
+  l_type_elements[5] = NULL;
+
+  arg_types[0] = &ffi_type_sint;
+  arg_types[1] = &s_type;
+  arg_types[2] = &l_type;
+  arg_types[3] = &s_type;
+  arg_types[4] = NULL;
+
+  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &ffi_type_sint, arg_types) == FFI_OK);
+
+  s1.a = 5;
+  s1.b = 6;
+
+  l1.a = 10;
+  l1.b = 11;
+  l1.c = 12;
+  l1.d = 13;
+  l1.e = 14;
+
+  s2.a = 7;
+  s2.b = 8;
+
+  n = 41;
+
+  args[0] = &n;
+  args[1] = &s1;
+  args[2] = &l1;
+  args[3] = &s2;
+  args[4] = NULL;
+
+  ffi_call(&cif, FFI_FN(test_fn), &res, args);
+  /* { dg-output "5 6 10 11 12 13 14 7 8" } */
+  printf("res: %d\n", (int) res);
+  /* { dg-output "\nres: 42" } */
+
+  return 0;
+}
diff --git a/libffi/testsuite/libffi.call/va_struct2.c b/libffi/testsuite/libffi.call/va_struct2.c
new file mode 100644 (file)
index 0000000..56f5b9c
--- /dev/null
@@ -0,0 +1,123 @@
+/* Area:               ffi_call
+   Purpose:            Test passing struct in variable argument lists.
+   Limitations:        none.
+   PR:                 none.
+   Originator: ARM Ltd. */
+
+/* { dg-do run } */
+/* { dg-output "" { xfail avr32*-*-* } } */
+
+#include "ffitest.h"
+#include <stdarg.h>
+
+struct small_tag
+{
+  unsigned char a;
+  unsigned char b;
+};
+
+struct large_tag
+{
+  unsigned a;
+  unsigned b;
+  unsigned c;
+  unsigned d;
+  unsigned e;
+};
+
+static struct small_tag
+test_fn (int n, ...)
+{
+  va_list ap;
+  struct small_tag s1;
+  struct small_tag s2;
+  struct large_tag l;
+
+  va_start (ap, n);
+  s1 = va_arg (ap, struct small_tag);
+  l = va_arg (ap, struct large_tag);
+  s2 = va_arg (ap, struct small_tag);
+  printf ("%u %u %u %u %u %u %u %u %u\n", s1.a, s1.b, l.a, l.b, l.c, l.d, l.e,
+         s2.a, s2.b);
+  va_end (ap);
+  s1.a += s2.a;
+  s1.b += s2.b;
+  return s1;
+}
+
+int
+main (void)
+{
+  ffi_cif cif;
+  void* args[5];
+  ffi_type* arg_types[5];
+
+  ffi_type s_type;
+  ffi_type *s_type_elements[3];
+
+  ffi_type l_type;
+  ffi_type *l_type_elements[6];
+
+  struct small_tag s1;
+  struct small_tag s2;
+  struct large_tag l1;
+
+  int n;
+  struct small_tag res;
+
+  s_type.size = 0;
+  s_type.alignment = 0;
+  s_type.type = FFI_TYPE_STRUCT;
+  s_type.elements = s_type_elements;
+
+  s_type_elements[0] = &ffi_type_uchar;
+  s_type_elements[1] = &ffi_type_uchar;
+  s_type_elements[2] = NULL;
+
+  l_type.size = 0;
+  l_type.alignment = 0;
+  l_type.type = FFI_TYPE_STRUCT;
+  l_type.elements = l_type_elements;
+
+  l_type_elements[0] = &ffi_type_uint;
+  l_type_elements[1] = &ffi_type_uint;
+  l_type_elements[2] = &ffi_type_uint;
+  l_type_elements[3] = &ffi_type_uint;
+  l_type_elements[4] = &ffi_type_uint;
+  l_type_elements[5] = NULL;
+
+  arg_types[0] = &ffi_type_sint;
+  arg_types[1] = &s_type;
+  arg_types[2] = &l_type;
+  arg_types[3] = &s_type;
+  arg_types[4] = NULL;
+
+  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &s_type, arg_types) == FFI_OK);
+
+  s1.a = 5;
+  s1.b = 6;
+
+  l1.a = 10;
+  l1.b = 11;
+  l1.c = 12;
+  l1.d = 13;
+  l1.e = 14;
+
+  s2.a = 7;
+  s2.b = 8;
+
+  n = 41;
+
+  args[0] = &n;
+  args[1] = &s1;
+  args[2] = &l1;
+  args[3] = &s2;
+  args[4] = NULL;
+
+  ffi_call(&cif, FFI_FN(test_fn), &res, args);
+  /* { dg-output "5 6 10 11 12 13 14 7 8" } */
+  printf("res: %d %d\n", res.a, res.b);
+  /* { dg-output "\nres: 12 14" } */
+
+  return 0;
+}
diff --git a/libffi/testsuite/libffi.call/va_struct3.c b/libffi/testsuite/libffi.call/va_struct3.c
new file mode 100644 (file)
index 0000000..9a27e7f
--- /dev/null
@@ -0,0 +1,125 @@
+/* Area:               ffi_call
+   Purpose:            Test passing struct in variable argument lists.
+   Limitations:        none.
+   PR:                 none.
+   Originator: ARM Ltd. */
+
+/* { dg-do run } */
+/* { dg-output "" { xfail avr32*-*-* } } */
+
+#include "ffitest.h"
+#include <stdarg.h>
+
+struct small_tag
+{
+  unsigned char a;
+  unsigned char b;
+};
+
+struct large_tag
+{
+  unsigned a;
+  unsigned b;
+  unsigned c;
+  unsigned d;
+  unsigned e;
+};
+
+static struct large_tag
+test_fn (int n, ...)
+{
+  va_list ap;
+  struct small_tag s1;
+  struct small_tag s2;
+  struct large_tag l;
+
+  va_start (ap, n);
+  s1 = va_arg (ap, struct small_tag);
+  l = va_arg (ap, struct large_tag);
+  s2 = va_arg (ap, struct small_tag);
+  printf ("%u %u %u %u %u %u %u %u %u\n", s1.a, s1.b, l.a, l.b, l.c, l.d, l.e,
+         s2.a, s2.b);
+  va_end (ap);
+  l.a += s1.a;
+  l.b += s1.b;
+  l.c += s2.a;
+  l.d += s2.b;
+  return l;
+}
+
+int
+main (void)
+{
+  ffi_cif cif;
+  void* args[5];
+  ffi_type* arg_types[5];
+
+  ffi_type s_type;
+  ffi_type *s_type_elements[3];
+
+  ffi_type l_type;
+  ffi_type *l_type_elements[6];
+
+  struct small_tag s1;
+  struct small_tag s2;
+  struct large_tag l1;
+
+  int n;
+  struct large_tag res;
+
+  s_type.size = 0;
+  s_type.alignment = 0;
+  s_type.type = FFI_TYPE_STRUCT;
+  s_type.elements = s_type_elements;
+
+  s_type_elements[0] = &ffi_type_uchar;
+  s_type_elements[1] = &ffi_type_uchar;
+  s_type_elements[2] = NULL;
+
+  l_type.size = 0;
+  l_type.alignment = 0;
+  l_type.type = FFI_TYPE_STRUCT;
+  l_type.elements = l_type_elements;
+
+  l_type_elements[0] = &ffi_type_uint;
+  l_type_elements[1] = &ffi_type_uint;
+  l_type_elements[2] = &ffi_type_uint;
+  l_type_elements[3] = &ffi_type_uint;
+  l_type_elements[4] = &ffi_type_uint;
+  l_type_elements[5] = NULL;
+
+  arg_types[0] = &ffi_type_sint;
+  arg_types[1] = &s_type;
+  arg_types[2] = &l_type;
+  arg_types[3] = &s_type;
+  arg_types[4] = NULL;
+
+  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &l_type, arg_types) == FFI_OK);
+
+  s1.a = 5;
+  s1.b = 6;
+
+  l1.a = 10;
+  l1.b = 11;
+  l1.c = 12;
+  l1.d = 13;
+  l1.e = 14;
+
+  s2.a = 7;
+  s2.b = 8;
+
+  n = 41;
+
+  args[0] = &n;
+  args[1] = &s1;
+  args[2] = &l1;
+  args[3] = &s2;
+  args[4] = NULL;
+
+  ffi_call(&cif, FFI_FN(test_fn), &res, args);
+  /* { dg-output "5 6 10 11 12 13 14 7 8" } */
+  printf("res: %d %d %d %d %d\n", res.a, res.b, res.c, res.d, res.e);
+  /* { dg-output "\nres: 15 17 19 21 14" } */
+
+  return 0;
+}