Commit b4b575ce by Anthony Green

libffi merge

From-SVN: r194722
parent dc3a31d4
## Process this with automake to create Makefile.in ## Process this with automake to create Makefile.in
AUTOMAKE_OPTIONS = foreign subdir-objects AUTOMAKE_OPTIONS = foreign subdir-objects
ACLOCAL_AMFLAGS = -I .. -I ../config
SUBDIRS = include testsuite man SUBDIRS = include testsuite man
EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \ src/aarch64/ffi.c src/aarch64/ffitarget.h \
src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \ src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \
src/avr32/ffi.c src/avr32/sysv.S src/avr32/ffitarget.h \ src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \
src/cris/ffi.c src/cris/sysv.S src/cris/ffitarget.h \ src/avr32/ffi.c src/avr32/sysv.S src/avr32/ffitarget.h \
src/ia64/ffi.c src/ia64/ffitarget.h src/ia64/ia64_flags.h \ src/cris/ffi.c src/cris/sysv.S src/cris/ffitarget.h \
src/ia64/unix.S \ src/ia64/ffi.c src/ia64/ffitarget.h src/ia64/ia64_flags.h \
src/mips/ffi.c src/mips/n32.S src/mips/o32.S \ src/ia64/unix.S src/mips/ffi.c src/mips/n32.S src/mips/o32.S \
src/mips/ffitarget.h \ src/mips/ffitarget.h src/m32r/ffi.c src/m32r/sysv.S \
src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h \ src/m32r/ffitarget.h src/m68k/ffi.c src/m68k/sysv.S \
src/m68k/ffi.c src/m68k/sysv.S src/m68k/ffitarget.h \ src/m68k/ffitarget.h src/powerpc/ffi.c src/powerpc/sysv.S \
src/powerpc/ffi.c src/powerpc/sysv.S \ src/powerpc/linux64.S src/powerpc/linux64_closure.S \
src/powerpc/linux64.S src/powerpc/linux64_closure.S \ src/powerpc/ppc_closure.S src/powerpc/asm.h \
src/powerpc/ppc_closure.S src/powerpc/asm.h \ src/powerpc/aix.S src/powerpc/darwin.S \
src/powerpc/aix.S src/powerpc/darwin.S \ src/powerpc/aix_closure.S src/powerpc/darwin_closure.S \
src/powerpc/aix_closure.S src/powerpc/darwin_closure.S \ src/powerpc/ffi_darwin.c src/powerpc/ffitarget.h \
src/powerpc/ffi_darwin.c src/powerpc/ffitarget.h \ src/s390/ffi.c src/s390/sysv.S src/s390/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/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h \ src/sh64/sysv.S src/sh64/ffitarget.h src/sparc/v8.S \
src/sh64/ffi.c src/sh64/sysv.S src/sh64/ffitarget.h \ src/sparc/v9.S src/sparc/ffitarget.h src/sparc/ffi.c \
src/sparc/v8.S src/sparc/v9.S src/sparc/ffitarget.h \ src/x86/darwin64.S src/x86/ffi.c src/x86/sysv.S \
src/sparc/ffi.c src/x86/darwin64.S \ src/x86/win32.S src/x86/darwin.S src/x86/win64.S \
src/x86/ffi.c src/x86/sysv.S src/x86/win32.S src/x86/darwin.S \ src/x86/freebsd.S src/x86/ffi64.c src/x86/unix64.S \
src/x86/ffi64.c src/x86/unix64.S src/x86/ffitarget.h \ src/x86/ffitarget.h src/pa/ffitarget.h src/pa/ffi.c \
src/pa/ffitarget.h src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S \ src/pa/linux.S src/pa/hpux32.S src/frv/ffi.c src/bfin/ffi.c \
src/frv/ffi.c src/frv/eabi.S src/frv/ffitarget.h src/dlmalloc.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= ...@@ -84,14 +93,21 @@ MAKEOVERRIDES=
toolexeclib_LTLIBRARIES = libffi.la toolexeclib_LTLIBRARIES = libffi.la
noinst_LTLIBRARIES = libffi_convenience.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 src/raw_api.c src/java_raw_api.c src/closures.c
nodist_libffi_la_SOURCES = nodist_libffi_la_SOURCES =
if FFI_DEBUG
nodist_libffi_la_SOURCES += src/debug.c
endif
if MIPS if MIPS
nodist_libffi_la_SOURCES += src/mips/ffi.c src/mips/o32.S src/mips/n32.S nodist_libffi_la_SOURCES += src/mips/ffi.c src/mips/o32.S src/mips/n32.S
endif endif
if BFIN
nodist_libffi_la_SOURCES += src/bfin/ffi.c src/bfin/sysv.S
endif
if X86 if X86
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S
endif endif
...@@ -134,8 +150,14 @@ endif ...@@ -134,8 +150,14 @@ endif
if POWERPC_FREEBSD if POWERPC_FREEBSD
nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
endif endif
if AARCH64
nodist_libffi_la_SOURCES += src/aarch64/sysv.S src/aarch64/ffi.c
endif
if ARM if ARM
nodist_libffi_la_SOURCES += src/arm/sysv.S src/arm/ffi.c 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 endif
if AVR32 if AVR32
nodist_libffi_la_SOURCES += src/avr32/sysv.S src/avr32/ffi.c nodist_libffi_la_SOURCES += src/avr32/sysv.S src/avr32/ffi.c
...@@ -164,6 +186,9 @@ endif ...@@ -164,6 +186,9 @@ endif
if PA_HPUX if PA_HPUX
nodist_libffi_la_SOURCES += src/pa/hpux32.S src/pa/ffi.c nodist_libffi_la_SOURCES += src/pa/hpux32.S src/pa/ffi.c
endif endif
if TILE
nodist_libffi_la_SOURCES += src/tile/tile.S src/tile/ffi.c
endif
libffi_convenience_la_SOURCES = $(libffi_la_SOURCES) libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES) nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
......
Status Status
====== ======
libffi-3.0.11 was released on *****************. Check the libffi web libffi-3.0.12 was released on XXXXXXX. Check the libffi web page for
page for updates: <URL:http://sourceware.org/libffi/>. updates: <URL:http://sourceware.org/libffi/>.
What is libffi? What is libffi?
...@@ -48,48 +48,52 @@ refer to the wiki page here: ...@@ -48,48 +48,52 @@ refer to the wiki page here:
At the time of release, the following basic configurations have been At the time of release, the following basic configurations have been
tested: tested:
|--------------+------------------| |-----------------+------------------|
| Architecture | Operating System | | Architecture | Operating System |
|--------------+------------------| |-----------------+------------------|
| Alpha | Linux | | AArch64 | Linux |
| Alpha | Tru64 | | Alpha | Linux |
| ARM | Linux | | Alpha | Tru64 |
| ARM | iOS | | ARM | Linux |
| AVR32 | Linux | | ARM | iOS |
| HPPA | HPUX | | AVR32 | Linux |
| IA-64 | Linux | | Blackfin | uClinux |
| M68K | RTEMS | | HPPA | HPUX |
| MIPS | IRIX | | IA-64 | Linux |
| MIPS | Linux | | M68K | FreeMiNT |
| MIPS | RTEMS | | M68K | RTEMS |
| MIPS64 | Linux | | MIPS | IRIX |
| PowerPC | AMIGA | | MIPS | Linux |
| PowerPC | Linux | | MIPS | RTEMS |
| PowerPC | Mac OSX | | MIPS64 | Linux |
| PowerPC | FreeBSD | | PowerPC | AMIGA |
| PowerPC64 | Linux | | PowerPC | Linux |
| S390 | Linux | | PowerPC | Mac OSX |
| S390X | Linux | | PowerPC | FreeBSD |
| SPARC | Linux | | PowerPC64 | Linux |
| SPARC | Solaris | | S390 | Linux |
| SPARC64 | Linux | | S390X | Linux |
| SPARC64 | FreeBSD | | SPARC | Linux |
| X86 | FreeBSD | | SPARC | Solaris |
| X86 | Interix | | SPARC64 | Linux |
| X86 | kFreeBSD | | SPARC64 | FreeBSD |
| X86 | Linux | | TILE-Gx/TILEPro | Linux |
| X86 | Linux/x32 | | X86 | FreeBSD |
| X86 | Mac OSX | | X86 | Interix |
| X86 | OpenBSD | | X86 | kFreeBSD |
| X86 | OS/2 | | X86 | Linux |
| X86 | Solaris | | X86 | Mac OSX |
| X86 | Windows/Cygwin | | X86 | OpenBSD |
| X86 | Windows/MingW | | X86 | OS/2 |
| X86-64 | FreeBSD | | X86 | Solaris |
| X86-64 | Linux | | X86 | Windows/Cygwin |
| X86-64 | OpenBSD | | X86 | Windows/MingW |
| X86-64 | 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 Please send additional platform test results to
libffi-discuss@sourceware.org and feel free to update the wiki page 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 ...@@ -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 that sets 'fix_srcfile_path' to a 'cygpath' command. ('cygpath' is not
present in MingW, and is not required when using MingW-style paths.) 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. Configure has many other options. Use "configure --help" to see them all.
...@@ -146,13 +150,24 @@ History ...@@ -146,13 +150,24 @@ History
See the ChangeLog files for details. 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. 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 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 Octeon and MC68881 support.
Fix code pessimizations. Fix code pessimizations.
Lots of build fixes.
3.0.10 Aug-23-11 3.0.10 Aug-23-11
Add support for Apple's iOS. Add support for Apple's iOS.
...@@ -311,8 +326,10 @@ Thorup. ...@@ -311,8 +326,10 @@ Thorup.
Major processor architecture ports were contributed by the following Major processor architecture ports were contributed by the following
developers: developers:
aarch64 Marcus Shawcroft, James Greenhalgh
alpha Richard Henderson alpha Richard Henderson
arm Raffaele Sena arm Raffaele Sena
blackfin Alexandre Keunecke I. de Mendonca
cris Simon Posnjak, Hans-Peter Nilsson cris Simon Posnjak, Hans-Peter Nilsson
frv Anthony Green frv Anthony Green
ia64 Hans Boehm ia64 Hans Boehm
...@@ -328,6 +345,7 @@ s390 Gerhard Tonn, Ulrich Weigand ...@@ -328,6 +345,7 @@ s390 Gerhard Tonn, Ulrich Weigand
sh Kaz Kojima sh Kaz Kojima
sh64 Kaz Kojima sh64 Kaz Kojima
sparc Anthony Green, Gordon Irlam sparc Anthony Green, Gordon Irlam
tile-gx/tilepro Walter Lee
x86 Anthony Green, Jon Beniston x86 Anthony Green, Jon Beniston
x86-64 Bo Thorsen x86-64 Bo Thorsen
......
...@@ -2,7 +2,7 @@ dnl Process this with autoconf to create configure ...@@ -2,7 +2,7 @@ dnl Process this with autoconf to create configure
AC_PREREQ(2.64) 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]) AC_CONFIG_HEADERS([fficonfig.h])
AM_ENABLE_MULTILIB(, ..) AM_ENABLE_MULTILIB(, ..)
...@@ -41,6 +41,10 @@ AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite) ...@@ -41,6 +41,10 @@ AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite)
TARGETDIR="unknown" TARGETDIR="unknown"
case "$host" in case "$host" in
aarch64*-*-*)
TARGET=AARCH64; TARGETDIR=aarch64
;;
alpha*-*-*) alpha*-*-*)
TARGET=ALPHA; TARGETDIR=alpha; TARGET=ALPHA; TARGETDIR=alpha;
# Support 128-bit long double, changeable via command-line switch. # Support 128-bit long double, changeable via command-line switch.
...@@ -53,12 +57,20 @@ case "$host" in ...@@ -53,12 +57,20 @@ case "$host" in
amd64-*-freebsd* | amd64-*-openbsd*) amd64-*-freebsd* | amd64-*-openbsd*)
TARGET=X86_64; TARGETDIR=x86 TARGET=X86_64; TARGETDIR=x86
;;
amd64-*-freebsd*)
TARGET=X86_64; TARGETDIR=x86
;; ;;
avr32*-*-*) avr32*-*-*)
TARGET=AVR32; TARGETDIR=avr32 TARGET=AVR32; TARGETDIR=avr32
;; ;;
bfin*)
TARGET=BFIN; TARGETDIR=bfin
;;
cris-*-*) cris-*-*)
TARGET=LIBFFI_CRIS; TARGETDIR=cris TARGET=LIBFFI_CRIS; TARGETDIR=cris
;; ;;
...@@ -67,7 +79,7 @@ case "$host" in ...@@ -67,7 +79,7 @@ case "$host" in
TARGET=FRV; TARGETDIR=frv TARGET=FRV; TARGETDIR=frv
;; ;;
hppa*-*-linux* | parisc*-*-linux*) hppa*-*-linux* | parisc*-*-linux* | hppa*-*-openbsd*)
TARGET=PA_LINUX; TARGETDIR=pa TARGET=PA_LINUX; TARGETDIR=pa
;; ;;
hppa*64-*-hpux*) hppa*64-*-hpux*)
...@@ -80,7 +92,7 @@ case "$host" in ...@@ -80,7 +92,7 @@ case "$host" in
i?86-*-freebsd* | i?86-*-openbsd*) i?86-*-freebsd* | i?86-*-openbsd*)
TARGET=X86_FREEBSD; TARGETDIR=x86 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 TARGET=X86_WIN32; TARGETDIR=x86
# All mingw/cygwin/win32 builds require -no-undefined for sharedlib. # All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
# We must also check with_cross_host to decide if this is a native # We must also check with_cross_host to decide if this is a native
...@@ -117,7 +129,7 @@ case "$host" in ...@@ -117,7 +129,7 @@ case "$host" in
mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*) mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
TARGET=MIPS; TARGETDIR=mips TARGET=MIPS; TARGETDIR=mips
;; ;;
mips*-*-linux*) mips*-*-linux* | mips*-*-openbsd*)
# Support 128-bit long double for NewABI. # Support 128-bit long double for NewABI.
HAVE_LONG_DOUBLE='defined(__mips64)' HAVE_LONG_DOUBLE='defined(__mips64)'
TARGET=MIPS; TARGETDIR=mips TARGET=MIPS; TARGETDIR=mips
...@@ -126,19 +138,22 @@ case "$host" in ...@@ -126,19 +138,22 @@ case "$host" in
powerpc*-*-linux* | powerpc-*-sysv*) powerpc*-*-linux* | powerpc-*-sysv*)
TARGET=POWERPC; TARGETDIR=powerpc TARGET=POWERPC; TARGETDIR=powerpc
;; ;;
powerpc-*-amigaos*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-beos*) powerpc-*-beos*)
TARGET=POWERPC; TARGETDIR=powerpc TARGET=POWERPC; TARGETDIR=powerpc
;; ;;
powerpc-*-darwin*) powerpc-*-darwin* | powerpc64-*-darwin*)
TARGET=POWERPC_DARWIN; TARGETDIR=powerpc TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
;; ;;
powerpc-*-aix* | rs6000-*-aix*) powerpc-*-aix* | rs6000-*-aix*)
TARGET=POWERPC_AIX; TARGETDIR=powerpc TARGET=POWERPC_AIX; TARGETDIR=powerpc
;; ;;
powerpc-*-freebsd*) powerpc-*-freebsd* | powerpc-*-openbsd*)
TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
;; ;;
powerpc64-*-freebsd*) powerpc64-*-freebsd*)
TARGET=POWERPC; TARGETDIR=powerpc TARGET=POWERPC; TARGETDIR=powerpc
;; ;;
powerpc*-*-rtems*) powerpc*-*-rtems*)
...@@ -160,6 +175,10 @@ case "$host" in ...@@ -160,6 +175,10 @@ case "$host" in
TARGET=SPARC; TARGETDIR=sparc TARGET=SPARC; TARGETDIR=sparc
;; ;;
tile*-*)
TARGET=TILE; TARGETDIR=tile
;;
x86_64-*-darwin*) x86_64-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86 TARGET=X86_DARWIN; TARGETDIR=x86
;; ;;
...@@ -190,6 +209,7 @@ if test $TARGETDIR = unknown; then ...@@ -190,6 +209,7 @@ if test $TARGETDIR = unknown; then
fi fi
AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS) AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS)
AM_CONDITIONAL(BFIN, test x$TARGET = xBFIN)
AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC) AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC)
AM_CONDITIONAL(X86, test x$TARGET = xX86) AM_CONDITIONAL(X86, test x$TARGET = xX86)
AM_CONDITIONAL(X86_FREEBSD, test x$TARGET = xX86_FREEBSD) AM_CONDITIONAL(X86_FREEBSD, test x$TARGET = xX86_FREEBSD)
...@@ -204,6 +224,7 @@ AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC) ...@@ -204,6 +224,7 @@ AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX) AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN) AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
AM_CONDITIONAL(POWERPC_FREEBSD, test x$TARGET = xPOWERPC_FREEBSD) 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(ARM, test x$TARGET = xARM)
AM_CONDITIONAL(AVR32, test x$TARGET = xAVR32) AM_CONDITIONAL(AVR32, test x$TARGET = xAVR32)
AM_CONDITIONAL(LIBFFI_CRIS, test x$TARGET = xLIBFFI_CRIS) AM_CONDITIONAL(LIBFFI_CRIS, test x$TARGET = xLIBFFI_CRIS)
...@@ -215,6 +236,7 @@ AM_CONDITIONAL(SH64, test x$TARGET = xSH64) ...@@ -215,6 +236,7 @@ AM_CONDITIONAL(SH64, test x$TARGET = xSH64)
AM_CONDITIONAL(PA_LINUX, test x$TARGET = xPA_LINUX) AM_CONDITIONAL(PA_LINUX, test x$TARGET = xPA_LINUX)
AM_CONDITIONAL(PA_HPUX, test x$TARGET = xPA_HPUX) AM_CONDITIONAL(PA_HPUX, test x$TARGET = xPA_HPUX)
AM_CONDITIONAL(PA64_HPUX, test x$TARGET = xPA64_HPUX) AM_CONDITIONAL(PA64_HPUX, test x$TARGET = xPA64_HPUX)
AM_CONDITIONAL(TILE, test x$TARGET = xTILE)
AC_HEADER_STDC AC_HEADER_STDC
AC_CHECK_FUNCS(memcpy) AC_CHECK_FUNCS(memcpy)
...@@ -311,13 +333,30 @@ if test x$TARGET = xX86 || test x$TARGET = xX86_WIN32 || test x$TARGET = xX86_64 ...@@ -311,13 +333,30 @@ if test x$TARGET = xX86 || test x$TARGET = xX86_WIN32 || test x$TARGET = xX86_64
fi fi
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 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, AC_DEFINE(FFI_MMAP_EXEC_WRIT, 1,
[Cannot use malloc on this target, so, we revert to [Cannot use malloc on this target, so, we revert to
alternative means]) alternative means])
;; ;;
esac 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 if test x$TARGET = xX86_64; then
AC_CACHE_CHECK([assembler supports unwind section type], AC_CACHE_CHECK([assembler supports unwind section type],
...@@ -334,44 +373,46 @@ if test x$TARGET = xX86_64; then ...@@ -334,44 +373,46 @@ if test x$TARGET = xX86_64; then
fi fi
fi fi
AC_CACHE_CHECK([whether .eh_frame section should be read-only], if test "x$GCC" = "xyes"; then
libffi_cv_ro_eh_frame, [ AC_CACHE_CHECK([whether .eh_frame section should be read-only],
libffi_cv_ro_eh_frame=no libffi_cv_ro_eh_frame, [
echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c libffi_cv_ro_eh_frame=no
if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then
libffi_cv_ro_eh_frame=yes if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then
elif grep '.section.*eh_frame.*#alloc' conftest.c \ libffi_cv_ro_eh_frame=yes
| grep -v '#write' > /dev/null; then elif grep '.section.*eh_frame.*#alloc' conftest.c \
libffi_cv_ro_eh_frame=yes | grep -v '#write' > /dev/null; then
fi libffi_cv_ro_eh_frame=yes
fi fi
rm -f conftest.* fi
]) rm -f conftest.*
if test "x$libffi_cv_ro_eh_frame" = xyes; then ])
AC_DEFINE(HAVE_RO_EH_FRAME, 1, if test "x$libffi_cv_ro_eh_frame" = xyes; then
[Define if .eh_frame sections should be read-only.]) AC_DEFINE(HAVE_RO_EH_FRAME, 1,
AC_DEFINE(EH_FRAME_FLAGS, "a", [Define if .eh_frame sections should be read-only.])
[Define to the flags needed for the .section .eh_frame directive.]) AC_DEFINE(EH_FRAME_FLAGS, "a",
else [Define to the flags needed for the .section .eh_frame directive. ])
AC_DEFINE(EH_FRAME_FLAGS, "aw", else
[Define to the flags needed for the .section .eh_frame directive.]) AC_DEFINE(EH_FRAME_FLAGS, "aw",
fi [Define to the flags needed for the .section .eh_frame directive. ])
fi
AC_CACHE_CHECK([for __attribute__((visibility("hidden")))], AC_CACHE_CHECK([for __attribute__((visibility("hidden")))],
libffi_cv_hidden_visibility_attribute, [ libffi_cv_hidden_visibility_attribute, [
echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1; }' > conftest.c echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1 ; }' > conftest.c
libffi_cv_hidden_visibility_attribute=no 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 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 if grep '\.hidden.*foo' conftest.s >/dev/null; then
libffi_cv_hidden_visibility_attribute=yes libffi_cv_hidden_visibility_attribute=yes
fi fi
fi fi
rm -f conftest.* rm -f conftest.*
]) ])
if test $libffi_cv_hidden_visibility_attribute = yes; then if test $libffi_cv_hidden_visibility_attribute = yes; then
AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1, AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1,
[Define if __attribute__((visibility("hidden"))) is supported.]) [Define if __attribute__((visibility("hidden"))) is supported.])
fi
fi fi
AH_BOTTOM([ AH_BOTTOM([
...@@ -400,6 +441,7 @@ AC_ARG_ENABLE(debug, ...@@ -400,6 +441,7 @@ AC_ARG_ENABLE(debug,
if test "$enable_debug" = "yes"; then if test "$enable_debug" = "yes"; then
AC_DEFINE(FFI_DEBUG, 1, [Define this if you want extra debugging.]) AC_DEFINE(FFI_DEBUG, 1, [Define this if you want extra debugging.])
fi) fi)
AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes")
AC_ARG_ENABLE(structs, AC_ARG_ENABLE(structs,
[ --disable-structs omit code for struct support], [ --disable-structs omit code for struct support],
......
#!/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()
#!/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()
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
AUTOMAKE_OPTIONS=foreign 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
# Makefile.in generated by automake 1.11.1 from Makefile.am. # Makefile.in generated by automake 1.11.6 from Makefile.am.
# @configure_input@ # @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
# Inc. # Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation # This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved. # with or without modifications, as long as this notice is preserved.
...@@ -15,6 +15,23 @@ ...@@ -15,6 +15,23 @@
@SET_MAKE@ @SET_MAKE@
VPATH = @srcdir@ 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@ pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@
...@@ -37,22 +54,32 @@ target_triplet = @target@ ...@@ -37,22 +54,32 @@ target_triplet = @target@
subdir = man subdir = man
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \ am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \
$(top_srcdir)/../config/lead-dot.m4 \ $(top_srcdir)/m4/ax_cc_maxopt.m4 \
$(top_srcdir)/../config/multi.m4 \ $(top_srcdir)/m4/ax_cflags_warn_all.m4 \
$(top_srcdir)/../config/override.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \ $(top_srcdir)/m4/ax_compiler_vendor.m4 \
$(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \ $(top_srcdir)/m4/ax_configure_args.m4 \
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.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 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4) $(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/fficonfig.h CONFIG_HEADER = $(top_builddir)/fficonfig.h
CONFIG_CLEAN_FILES = CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES = CONFIG_CLEAN_VPATH_FILES =
SOURCES = SOURCES =
DIST_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_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \ am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
...@@ -74,6 +101,12 @@ am__nobase_list = $(am__nobase_strip_setup); \ ...@@ -74,6 +101,12 @@ am__nobase_list = $(am__nobase_strip_setup); \
am__base_list = \ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!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 man3dir = $(mandir)/man3
am__installdirs = "$(DESTDIR)$(man3dir)" am__installdirs = "$(DESTDIR)$(man3dir)"
NROFF = nroff NROFF = nroff
...@@ -100,6 +133,7 @@ CPPFLAGS = @CPPFLAGS@ ...@@ -100,6 +133,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@ CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@ DEFS = @DEFS@
DEPDIR = @DEPDIR@ DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@ DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@ DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@ ECHO_C = @ECHO_C@
...@@ -107,6 +141,7 @@ ECHO_N = @ECHO_N@ ...@@ -107,6 +141,7 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@ ECHO_T = @ECHO_T@
EGREP = @EGREP@ EGREP = @EGREP@
EXEEXT = @EXEEXT@ EXEEXT = @EXEEXT@
FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@
FGREP = @FGREP@ FGREP = @FGREP@
GREP = @GREP@ GREP = @GREP@
HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@ HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@
...@@ -125,6 +160,7 @@ LN_S = @LN_S@ ...@@ -125,6 +160,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@ LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@ MAINT = @MAINT@
MAKEINFO = @MAKEINFO@ MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@ MKDIR_P = @MKDIR_P@
NM = @NM@ NM = @NM@
NMEDIT = @NMEDIT@ NMEDIT = @NMEDIT@
...@@ -140,6 +176,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ ...@@ -140,6 +176,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@ PATH_SEPARATOR = @PATH_SEPARATOR@
PRTDIAG = @PRTDIAG@
RANLIB = @RANLIB@ RANLIB = @RANLIB@
SED = @SED@ SED = @SED@
SET_MAKE = @SET_MAKE@ SET_MAKE = @SET_MAKE@
...@@ -152,6 +189,7 @@ abs_builddir = @abs_builddir@ ...@@ -152,6 +189,7 @@ abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@ abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@ abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@ abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@ ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@ am__include = @am__include@
...@@ -159,6 +197,7 @@ am__leading_dot = @am__leading_dot@ ...@@ -159,6 +197,7 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@ am__quote = @am__quote@
am__tar = @am__tar@ am__tar = @am__tar@
am__untar = @am__untar@ am__untar = @am__untar@
ax_enable_builddir_sed = @ax_enable_builddir_sed@
bindir = @bindir@ bindir = @bindir@
build = @build@ build = @build@
build_alias = @build_alias@ build_alias = @build_alias@
...@@ -186,7 +225,6 @@ localedir = @localedir@ ...@@ -186,7 +225,6 @@ localedir = @localedir@
localstatedir = @localstatedir@ localstatedir = @localstatedir@
mandir = @mandir@ mandir = @mandir@
mkdir_p = @mkdir_p@ mkdir_p = @mkdir_p@
multi_basedir = @multi_basedir@
oldincludedir = @oldincludedir@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@ pdfdir = @pdfdir@
prefix = @prefix@ prefix = @prefix@
...@@ -195,6 +233,7 @@ psdir = @psdir@ ...@@ -195,6 +233,7 @@ psdir = @psdir@
sbindir = @sbindir@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@ sharedstatedir = @sharedstatedir@
srcdir = @srcdir@ srcdir = @srcdir@
sys_symbol_underscore = @sys_symbol_underscore@
sysconfdir = @sysconfdir@ sysconfdir = @sysconfdir@
target = @target@ target = @target@
target_alias = @target_alias@ target_alias = @target_alias@
...@@ -207,8 +246,8 @@ top_build_prefix = @top_build_prefix@ ...@@ -207,8 +246,8 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@ top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign 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
all: all-am all: all-am
.SUFFIXES: .SUFFIXES:
...@@ -250,11 +289,18 @@ clean-libtool: ...@@ -250,11 +289,18 @@ clean-libtool:
-rm -rf .libs _libs -rm -rf .libs _libs
install-man3: $(man_MANS) install-man3: $(man_MANS)
@$(NORMAL_INSTALL) @$(NORMAL_INSTALL)
test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)" @list1=''; \
@list=''; test -n "$(man3dir)" || exit 0; \ list2='$(man_MANS)'; \
{ for i in $$list; do echo "$$i"; done; \ test -n "$(man3dir)" \
l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ && test -n "`echo $$list1$$list2`" \
sed -n '/\.3[a-z]*$$/p'; \ || 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 \ } | while read p; do \
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; echo "$$p"; \ echo "$$d$$p"; echo "$$p"; \
...@@ -283,9 +329,7 @@ uninstall-man3: ...@@ -283,9 +329,7 @@ uninstall-man3:
sed -n '/\.3[a-z]*$$/p'; \ sed -n '/\.3[a-z]*$$/p'; \
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
test -z "$$files" || { \ dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir)
echo " ( cd '$(DESTDIR)$(man3dir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(man3dir)" && rm -f $$files; }
tags: TAGS tags: TAGS
TAGS: TAGS:
...@@ -353,10 +397,15 @@ install-am: all-am ...@@ -353,10 +397,15 @@ install-am: all-am
installcheck: installcheck-am installcheck: installcheck-am
install-strip: install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ if test -z '$(STRIP)'; then \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
`test -z '$(STRIP)' || \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install 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: mostlyclean-generic:
clean-generic: clean-generic:
......
/* 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
/* 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
...@@ -251,8 +251,10 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) ...@@ -251,8 +251,10 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
break; break;
case FFI_VFP: case FFI_VFP:
#ifdef __ARM_EABI__
ffi_call_VFP (fn, &ecif, cif->bytes, cif->flags, ecif.rvalue); ffi_call_VFP (fn, &ecif, cif->bytes, cif->flags, ecif.rvalue);
break; break;
#endif
default: default:
FFI_ASSERT(0); FFI_ASSERT(0);
...@@ -609,8 +611,10 @@ ffi_prep_closure_loc (ffi_closure* closure, ...@@ -609,8 +611,10 @@ ffi_prep_closure_loc (ffi_closure* closure,
if (cif->abi == FFI_SYSV) if (cif->abi == FFI_SYSV)
closure_func = &ffi_closure_SYSV; closure_func = &ffi_closure_SYSV;
#ifdef __ARM_EABI__
else if (cif->abi == FFI_VFP) else if (cif->abi == FFI_VFP)
closure_func = &ffi_closure_VFP; closure_func = &ffi_closure_VFP;
#endif
else else
return FFI_BAD_ABI; return FFI_BAD_ABI;
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
#define CNAME(x) x #define CNAME(x) x
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
#define ENTRY(x) .globl CNAME(x); CNAME(x): #define ENTRY(x) .globl _##x; _##x:
#else #else
#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x): #define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
#endif /* __APPLE__ */ #endif /* __APPLE__ */
...@@ -187,7 +187,7 @@ ARM_FUNC_START ffi_call_SYSV ...@@ -187,7 +187,7 @@ ARM_FUNC_START ffi_call_SYSV
@ r1 already set @ r1 already set
@ Call ffi_prep_args(stack, &ecif) @ Call ffi_prep_args(stack, &ecif)
bl ffi_prep_args bl CNAME(ffi_prep_args)
@ move first 4 parameters in registers @ move first 4 parameters in registers
ldmia sp, {r0-r3} ldmia sp, {r0-r3}
...@@ -334,7 +334,9 @@ ARM_FUNC_START ffi_closure_SYSV ...@@ -334,7 +334,9 @@ ARM_FUNC_START ffi_closure_SYSV
/* Below are VFP hard-float ABI call and closure implementations. /* 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 .fpu vfp
@ r0: fn @ r0: fn
...@@ -362,7 +364,7 @@ ARM_FUNC_START ffi_call_VFP ...@@ -362,7 +364,7 @@ ARM_FUNC_START ffi_call_VFP
sub r2, fp, #64 @ VFP scratch space sub r2, fp, #64 @ VFP scratch space
@ Call ffi_prep_args(stack, &ecif, vfp_space) @ Call ffi_prep_args(stack, &ecif, vfp_space)
bl ffi_prep_args bl CNAME(ffi_prep_args)
@ Load VFP register args if needed @ Load VFP register args if needed
cmp r0, #0 cmp r0, #0
...@@ -444,7 +446,7 @@ ARM_FUNC_START ffi_closure_VFP ...@@ -444,7 +446,7 @@ ARM_FUNC_START ffi_closure_VFP
sub sp, sp, #72 sub sp, sp, #72
str sp, [sp, #64] str sp, [sp, #64]
add r1, sp, #64 add r1, sp, #64
bl ffi_closure_SYSV_inner bl CNAME(ffi_closure_SYSV_inner)
cmp r0, #FFI_TYPE_INT cmp r0, #FFI_TYPE_INT
beq .Lretint_vfp beq .Lretint_vfp
...@@ -491,6 +493,7 @@ ARM_FUNC_START ffi_closure_VFP ...@@ -491,6 +493,7 @@ ARM_FUNC_START ffi_closure_VFP
.ffi_closure_VFP_end: .ffi_closure_VFP_end:
UNWIND .fnend UNWIND .fnend
.size CNAME(ffi_closure_VFP),.ffi_closure_VFP_end-CNAME(ffi_closure_VFP) .size CNAME(ffi_closure_VFP),.ffi_closure_VFP_end-CNAME(ffi_closure_VFP)
#endif
ENTRY(ffi_arm_trampoline) ENTRY(ffi_arm_trampoline)
stmfd sp!, {r0-r3} stmfd sp!, {r0-r3}
......
# GENERATED CODE - DO NOT EDIT # 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. # Copyright (c) 2010, Plausible Labs Cooperative, Inc.
# #
......
/* -----------------------------------------------------------------------
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;
}
}
/* -----------------------------------------------------------------------
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
/* -----------------------------------------------------------------------
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
...@@ -172,6 +172,27 @@ selinux_enabled_check (void) ...@@ -172,6 +172,27 @@ selinux_enabled_check (void)
#endif /* !FFI_MMAP_EXEC_SELINUX */ #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) #elif defined (__CYGWIN__) || defined(__INTERIX)
#include <sys/mman.h> #include <sys/mman.h>
...@@ -458,6 +479,12 @@ dlmmap (void *start, size_t length, int prot, ...@@ -458,6 +479,12 @@ dlmmap (void *start, size_t length, int prot,
printf ("mapping in %zi\n", length); printf ("mapping in %zi\n", length);
#endif #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 ()) if (execfd == -1 && !is_selinux_enabled ())
{ {
ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset); ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset);
......
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
ffi.c ffi.c
m68k Foreign Function Interface m68k Foreign Function Interface
----------------------------------------------------------------------- */ ----------------------------------------------------------------------- */
#include <ffi.h> #include <ffi.h>
...@@ -13,8 +13,13 @@ ...@@ -13,8 +13,13 @@
void rtems_cache_flush_multiple_data_lines( const void *, size_t ); void rtems_cache_flush_multiple_data_lines( const void *, size_t );
#else #else
#include <sys/syscall.h> #include <sys/syscall.h>
#ifdef __MINT__
#include <mint/mintbind.h>
#include <mint/ssystem.h>
#else
#include <asm/cachectl.h> #include <asm/cachectl.h>
#endif #endif
#endif
void ffi_call_SYSV (extended_cif *, void ffi_call_SYSV (extended_cif *,
unsigned, unsigned, unsigned, unsigned,
...@@ -39,8 +44,12 @@ ffi_prep_args (void *stack, extended_cif *ecif) ...@@ -39,8 +44,12 @@ ffi_prep_args (void *stack, extended_cif *ecif)
argp = stack; argp = stack;
if (ecif->cif->rtype->type == FFI_TYPE_STRUCT if (
&& !ecif->cif->flags) #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; struct_value_ptr = ecif->rvalue;
else else
struct_value_ptr = NULL; struct_value_ptr = NULL;
...@@ -51,12 +60,12 @@ ffi_prep_args (void *stack, extended_cif *ecif) ...@@ -51,12 +60,12 @@ ffi_prep_args (void *stack, extended_cif *ecif)
i != 0; i != 0;
i--, p_arg++) 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)) if (z < sizeof (int))
{ {
switch ((*p_arg)->type) switch (type)
{ {
case FFI_TYPE_SINT8: case FFI_TYPE_SINT8:
*(signed int *) argp = (signed int) *(SINT8 *) *p_argv; *(signed int *) argp = (signed int) *(SINT8 *) *p_argv;
...@@ -75,7 +84,14 @@ ffi_prep_args (void *stack, extended_cif *ecif) ...@@ -75,7 +84,14 @@ ffi_prep_args (void *stack, extended_cif *ecif)
break; break;
case FFI_TYPE_STRUCT: 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); memcpy (argp + sizeof (int) - z, *p_argv, z);
#endif
break; break;
default: default:
...@@ -120,17 +136,34 @@ ffi_prep_cif_machdep (ffi_cif *cif) ...@@ -120,17 +136,34 @@ ffi_prep_cif_machdep (ffi_cif *cif)
break; break;
case FFI_TYPE_STRUCT: 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) switch (cif->rtype->size)
{ {
case 1: case 1:
#ifdef __MINT__
cif->flags = CIF_FLAGS_STRUCT2;
#else
cif->flags = CIF_FLAGS_STRUCT1; cif->flags = CIF_FLAGS_STRUCT1;
#endif
break; break;
case 2: case 2:
cif->flags = CIF_FLAGS_STRUCT2; cif->flags = CIF_FLAGS_STRUCT2;
break; break;
#ifdef __MINT__
case 3:
#endif
case 4: case 4:
cif->flags = CIF_FLAGS_INT; cif->flags = CIF_FLAGS_INT;
break; break;
#ifdef __MINT__
case 7:
#endif
case 8: case 8:
cif->flags = CIF_FLAGS_DINT; cif->flags = CIF_FLAGS_DINT;
break; break;
...@@ -150,7 +183,11 @@ ffi_prep_cif_machdep (ffi_cif *cif) ...@@ -150,7 +183,11 @@ ffi_prep_cif_machdep (ffi_cif *cif)
#if (FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE) #if (FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE)
case FFI_TYPE_LONGDOUBLE: case FFI_TYPE_LONGDOUBLE:
#ifdef __MINT__
cif->flags = 0;
#else
cif->flags = CIF_FLAGS_LDOUBLE; cif->flags = CIF_FLAGS_LDOUBLE;
#endif
break; break;
#endif #endif
...@@ -218,6 +255,26 @@ ffi_prep_incoming_args_SYSV (char *stack, void **avalue, ffi_cif *cif) ...@@ -218,6 +255,26 @@ ffi_prep_incoming_args_SYSV (char *stack, void **avalue, ffi_cif *cif)
size_t z; size_t z;
z = (*p_arg)->size; 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) if (z <= 4)
{ {
*p_argv = (void *) (argp + 4 - z); *p_argv = (void *) (argp + 4 - z);
...@@ -267,14 +324,21 @@ ffi_prep_closure_loc (ffi_closure* closure, ...@@ -267,14 +324,21 @@ ffi_prep_closure_loc (ffi_closure* closure,
*(unsigned short *)closure->tramp = 0x207c; *(unsigned short *)closure->tramp = 0x207c;
*(void **)(closure->tramp + 2) = codeloc; *(void **)(closure->tramp + 2) = codeloc;
*(unsigned short *)(closure->tramp + 6) = 0x4ef9; *(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; *(void **)(closure->tramp + 8) = ffi_closure_struct_SYSV;
else else
*(void **)(closure->tramp + 8) = ffi_closure_SYSV; *(void **)(closure->tramp + 8) = ffi_closure_SYSV;
#ifdef __rtems__ #ifdef __rtems__
rtems_cache_flush_multiple_data_lines( codeloc, FFI_TRAMPOLINE_SIZE ); rtems_cache_flush_multiple_data_lines( codeloc, FFI_TRAMPOLINE_SIZE );
#elif defined(__MINT__)
Ssystem(S_FLUSHCACHE, codeloc, FFI_TRAMPOLINE_SIZE);
#else #else
syscall(SYS_cacheflush, codeloc, FLUSH_SCOPE_LINE, syscall(SYS_cacheflush, codeloc, FLUSH_SCOPE_LINE,
FLUSH_CACHE_BOTH, FFI_TRAMPOLINE_SIZE); FLUSH_CACHE_BOTH, FFI_TRAMPOLINE_SIZE);
...@@ -286,4 +350,3 @@ ffi_prep_closure_loc (ffi_closure* closure, ...@@ -286,4 +350,3 @@ ffi_prep_closure_loc (ffi_closure* closure,
return FFI_OK; return FFI_OK;
} }
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
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. Copyright (c) 2008 Red Hat, Inc.
m68k Foreign Function Interface m68k Foreign Function Interface
...@@ -42,13 +43,19 @@ ...@@ -42,13 +43,19 @@
#define CFI_ENDPROC() #define CFI_ENDPROC()
#endif #endif
#ifdef __MINT__
#define CALLFUNC(funcname) _ ## funcname
#else
#define CALLFUNC(funcname) funcname
#endif
.text .text
.globl ffi_call_SYSV .globl CALLFUNC(ffi_call_SYSV)
.type ffi_call_SYSV,@function .type CALLFUNC(ffi_call_SYSV),@function
.align 4 .align 4
ffi_call_SYSV: CALLFUNC(ffi_call_SYSV):
CFI_STARTPROC() CFI_STARTPROC()
link %fp,#0 link %fp,#0
CFI_OFFSET(14,-8) CFI_OFFSET(14,-8)
...@@ -63,14 +70,18 @@ ffi_call_SYSV: ...@@ -63,14 +70,18 @@ ffi_call_SYSV:
move.l 8(%fp),-(%sp) move.l 8(%fp),-(%sp)
pea 4(%sp) pea 4(%sp)
#if !defined __PIC__ #if !defined __PIC__
jsr ffi_prep_args jsr CALLFUNC(ffi_prep_args)
#else #else
bsr.l ffi_prep_args@PLTPC bsr.l CALLFUNC(ffi_prep_args@PLTPC)
#endif #endif
addq.l #8,%sp addq.l #8,%sp
| Pass pointer to struct value, if any | Pass pointer to struct value, if any
#ifdef __MINT__
move.l %d0,%a1
#else
move.l %a0,%a1 move.l %a0,%a1
#endif
| Call the function | Call the function
move.l 24(%fp),%a0 move.l 24(%fp),%a0
...@@ -142,7 +153,11 @@ retlongdouble: ...@@ -142,7 +153,11 @@ retlongdouble:
retpointer: retpointer:
btst #5,%d2 btst #5,%d2
jbeq retstruct1 jbeq retstruct1
#ifdef __MINT__
move.l %d0,(%a1)
#else
move.l %a0,(%a1) move.l %a0,(%a1)
#endif
jbra epilogue jbra epilogue
retstruct1: retstruct1:
...@@ -162,13 +177,13 @@ epilogue: ...@@ -162,13 +177,13 @@ epilogue:
unlk %fp unlk %fp
rts rts
CFI_ENDPROC() CFI_ENDPROC()
.size ffi_call_SYSV,.-ffi_call_SYSV .size CALLFUNC(ffi_call_SYSV),.-CALLFUNC(ffi_call_SYSV)
.globl ffi_closure_SYSV .globl CALLFUNC(ffi_closure_SYSV)
.type ffi_closure_SYSV, @function .type CALLFUNC(ffi_closure_SYSV), @function
.align 4 .align 4
ffi_closure_SYSV: CALLFUNC(ffi_closure_SYSV):
CFI_STARTPROC() CFI_STARTPROC()
link %fp,#-12 link %fp,#-12
CFI_OFFSET(14,-8) CFI_OFFSET(14,-8)
...@@ -178,9 +193,9 @@ ffi_closure_SYSV: ...@@ -178,9 +193,9 @@ ffi_closure_SYSV:
pea -12(%fp) pea -12(%fp)
move.l %a0,-(%sp) move.l %a0,-(%sp)
#if !defined __PIC__ #if !defined __PIC__
jsr ffi_closure_SYSV_inner jsr CALLFUNC(ffi_closure_SYSV_inner)
#else #else
bsr.l ffi_closure_SYSV_inner@PLTPC bsr.l CALLFUNC(ffi_closure_SYSV_inner@PLTPC)
#endif #endif
lsr.l #1,%d0 lsr.l #1,%d0
...@@ -240,13 +255,13 @@ ffi_closure_SYSV: ...@@ -240,13 +255,13 @@ ffi_closure_SYSV:
jra .Lcls_epilogue jra .Lcls_epilogue
CFI_ENDPROC() CFI_ENDPROC()
.size ffi_closure_SYSV,.-ffi_closure_SYSV .size CALLFUNC(ffi_closure_SYSV),.-CALLFUNC(ffi_closure_SYSV)
.globl ffi_closure_struct_SYSV .globl CALLFUNC(ffi_closure_struct_SYSV)
.type ffi_closure_struct_SYSV, @function .type CALLFUNC(ffi_closure_struct_SYSV), @function
.align 4 .align 4
ffi_closure_struct_SYSV: CALLFUNC(ffi_closure_struct_SYSV):
CFI_STARTPROC() CFI_STARTPROC()
link %fp,#0 link %fp,#0
CFI_OFFSET(14,-8) CFI_OFFSET(14,-8)
...@@ -256,14 +271,14 @@ ffi_closure_struct_SYSV: ...@@ -256,14 +271,14 @@ ffi_closure_struct_SYSV:
move.l %a1,-(%sp) move.l %a1,-(%sp)
move.l %a0,-(%sp) move.l %a0,-(%sp)
#if !defined __PIC__ #if !defined __PIC__
jsr ffi_closure_SYSV_inner jsr CALLFUNC(ffi_closure_SYSV_inner)
#else #else
bsr.l ffi_closure_SYSV_inner@PLTPC bsr.l CALLFUNC(ffi_closure_SYSV_inner@PLTPC)
#endif #endif
unlk %fp unlk %fp
rts rts
CFI_ENDPROC() 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__ #if defined __ELF__ && defined __linux__
.section .note.GNU-stack,"",@progbits .section .note.GNU-stack,"",@progbits
......
...@@ -1065,10 +1065,10 @@ ffi_prep_closure_loc (ffi_closure* closure, ...@@ -1065,10 +1065,10 @@ ffi_prep_closure_loc (ffi_closure* closure,
closure->cif = cif; closure->cif = cif;
closure->fun = fun; closure->fun = fun;
closure->user_data = user_data; closure->user_data = user_data;
break;
default: default:
return FFI_BAD_ABI;
FFI_ASSERT(0);
break; break;
} }
return FFI_OK; return FFI_OK;
...@@ -1235,7 +1235,7 @@ ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue, ...@@ -1235,7 +1235,7 @@ ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE) if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
size_al = ALIGN(arg_types[i]->size, 8); size_al = ALIGN(arg_types[i]->size, 8);
# if defined(POWERPC64) # if defined(POWERPC64)
FFI_ASSERT (cif->abi != FFI_DARWIN) FFI_ASSERT (cif->abi != FFI_DARWIN);
avalue[i] = pgr; avalue[i] = pgr;
pgr += (size_al + 7) / 8; pgr += (size_al + 7) / 8;
# else # else
......
...@@ -140,6 +140,9 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, ...@@ -140,6 +140,9 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
#ifdef SPARC #ifdef SPARC
&& (cif->abi != FFI_V9 || cif->rtype->size > 32) && (cif->abi != FFI_V9 || cif->rtype->size > 32)
#endif #endif
#ifdef TILE
&& (cif->rtype->size > 10 * FFI_SIZEOF_ARG)
#endif
) )
bytes = STACK_ARG_SIZE(sizeof(void*)); bytes = STACK_ARG_SIZE(sizeof(void*));
#endif #endif
...@@ -169,6 +172,16 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, ...@@ -169,6 +172,16 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
if (((*ptr)->alignment - 1) & bytes) if (((*ptr)->alignment - 1) & bytes)
bytes = ALIGN(bytes, (*ptr)->alignment); 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); bytes += STACK_ARG_SIZE((*ptr)->size);
} }
#endif #endif
......
/* -----------------------------------------------------------------*-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
...@@ -58,7 +58,8 @@ void ffi_prep_args(char *stack, extended_cif *ecif) ...@@ -58,7 +58,8 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
argp = stack; 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 #ifdef X86_WIN64
&& (ecif->cif->rtype->size != 1 && ecif->cif->rtype->size != 2 && (ecif->cif->rtype->size != 1 && ecif->cif->rtype->size != 2
&& ecif->cif->rtype->size != 4 && ecif->cif->rtype->size != 8) && ecif->cif->rtype->size != 4 && ecif->cif->rtype->size != 8)
...@@ -279,7 +280,12 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) ...@@ -279,7 +280,12 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
else else
#endif #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 */ /* allocate space for return value pointer */
cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG); 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) ...@@ -349,7 +355,8 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
} }
#else #else
if (rvalue == NULL 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); ecif.rvalue = alloca(cif->rtype->size);
} }
...@@ -368,6 +375,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) ...@@ -368,6 +375,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
#elif defined(X86_WIN32) #elif defined(X86_WIN32)
case FFI_SYSV: case FFI_SYSV:
case FFI_STDCALL: case FFI_STDCALL:
case FFI_MS_CDECL:
ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags, ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags,
ecif.rvalue, fn); ecif.rvalue, fn);
break; break;
...@@ -513,7 +521,8 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, ...@@ -513,7 +521,8 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
argp += sizeof(void *); argp += sizeof(void *);
} }
#else #else
if ( cif->flags == FFI_TYPE_STRUCT ) { if ( cif->flags == FFI_TYPE_STRUCT
|| cif->flags == FFI_TYPE_MS_STRUCT ) {
*rvalue = *(void **) argp; *rvalue = *(void **) argp;
argp += sizeof(void *); argp += sizeof(void *);
} }
...@@ -673,6 +682,12 @@ ffi_prep_closure_loc (ffi_closure* closure, ...@@ -673,6 +682,12 @@ ffi_prep_closure_loc (ffi_closure* closure,
&ffi_closure_STDCALL, &ffi_closure_STDCALL,
(void*)codeloc, cif->bytes); (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_WIN32 */
#endif /* !X86_WIN64 */ #endif /* !X86_WIN64 */
else else
...@@ -762,8 +777,9 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue) ...@@ -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 */ /* If the return value is a struct and we don't have a return */
/* value address then we need to make one */ /* value address then we need to make one */
if ((rvalue == NULL) && if (rvalue == NULL
(cif->rtype->type == FFI_TYPE_STRUCT)) && (cif->flags == FFI_TYPE_STRUCT
|| cif->flags == FFI_TYPE_MS_STRUCT))
{ {
ecif.rvalue = alloca(cif->rtype->size); 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) ...@@ -776,6 +792,7 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
#ifdef X86_WIN32 #ifdef X86_WIN32
case FFI_SYSV: case FFI_SYSV:
case FFI_STDCALL: case FFI_STDCALL:
case FFI_MS_CDECL:
ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags, ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags,
ecif.rvalue, fn); ecif.rvalue, fn);
break; break;
......
...@@ -37,11 +37,17 @@ ...@@ -37,11 +37,17 @@
#define MAX_GPR_REGS 6 #define MAX_GPR_REGS 6
#define MAX_SSE_REGS 8 #define MAX_SSE_REGS 8
#ifdef __INTEL_COMPILER
#define UINT128 __m128
#else
#define UINT128 __int128_t
#endif
struct register_args struct register_args
{ {
/* Registers for argument passing. */ /* Registers for argument passing. */
UINT64 gpr[MAX_GPR_REGS]; 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, extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
......
...@@ -81,9 +81,13 @@ typedef enum ffi_abi { ...@@ -81,9 +81,13 @@ typedef enum ffi_abi {
FFI_STDCALL, FFI_STDCALL,
FFI_THISCALL, FFI_THISCALL,
FFI_FASTCALL, FFI_FASTCALL,
FFI_MS_CDECL,
FFI_LAST_ABI, 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 FFI_DEFAULT_ABI = FFI_SYSV
#endif
#elif defined(X86_WIN64) #elif defined(X86_WIN64)
FFI_WIN64, FFI_WIN64,
...@@ -110,6 +114,7 @@ typedef enum ffi_abi { ...@@ -110,6 +114,7 @@ typedef enum ffi_abi {
#define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1) #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_2B (FFI_TYPE_LAST + 2)
#define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3) #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)) #if defined (X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
#define FFI_TRAMPOLINE_SIZE 24 #define FFI_TRAMPOLINE_SIZE 24
......
...@@ -14,3 +14,72 @@ RUNTEST = `if [ -f $(top_srcdir)/../dejagnu/runtest ] ; then \ ...@@ -14,3 +14,72 @@ RUNTEST = `if [ -f $(top_srcdir)/../dejagnu/runtest ] ; then \
AM_RUNTESTFLAGS = AM_RUNTESTFLAGS =
CLEANFILES = *.exe core* *.log *.sum 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
# 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 # 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 # it under the terms of the GNU General Public License as published by
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
proc load_gcc_lib { filename } { proc load_gcc_lib { filename } {
global srcdir global srcdir
load_file $srcdir/../../gcc/testsuite/lib/$filename load_file $srcdir/lib/$filename
} }
load_lib dg.exp load_lib dg.exp
...@@ -94,7 +94,6 @@ proc libffi-init { args } { ...@@ -94,7 +94,6 @@ proc libffi-init { args } {
global srcdir global srcdir
global blddirffi global blddirffi
global objdir global objdir
global blddircxx
global TOOL_OPTIONS global TOOL_OPTIONS
global tool global tool
global libffi_include global libffi_include
...@@ -102,10 +101,8 @@ proc libffi-init { args } { ...@@ -102,10 +101,8 @@ proc libffi-init { args } {
global tool_root_dir global tool_root_dir
global ld_library_path global ld_library_path
set blddirffi [lookfor_file [get_multilibs] libffi] set blddirffi [pwd]/..
verbose "libffi $blddirffi" verbose "libffi $blddirffi"
set blddircxx [lookfor_file [get_multilibs] libstdc++-v3]
verbose "libstdc++ $blddircxx"
set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a] set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a]
if {$gccdir != ""} { if {$gccdir != ""} {
...@@ -132,8 +129,6 @@ proc libffi-init { args } { ...@@ -132,8 +129,6 @@ proc libffi-init { args } {
} }
# add the library path for libffi. # add the library path for libffi.
append ld_library_path ":${blddirffi}/.libs" 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" verbose "ld_library_path: $ld_library_path"
...@@ -146,7 +141,6 @@ proc libffi-init { args } { ...@@ -146,7 +141,6 @@ proc libffi-init { args } {
if { $libffi_dir != "" } { if { $libffi_dir != "" } {
set libffi_dir [file dirname ${libffi_dir}] set libffi_dir [file dirname ${libffi_dir}]
set libffi_link_flags "-L${libffi_dir}/.libs" set libffi_link_flags "-L${libffi_dir}/.libs"
lappend libffi_link_flags "-L${blddircxx}/src/.libs"
} }
set_ld_library_path_env_vars set_ld_library_path_env_vars
...@@ -209,6 +203,10 @@ proc libffi_target_compile { source dest type options } { ...@@ -209,6 +203,10 @@ proc libffi_target_compile { source dest type options } {
lappend options "libs= -lffi" lappend options "libs= -lffi"
if { [string match "aarch64*-*-linux*" $target_triplet] } {
lappend options "libs= -lpthread"
}
verbose "options: $options" verbose "options: $options"
return [target_compile $source $dest $type $options] return [target_compile $source $dest $type $options]
} }
......
...@@ -49,9 +49,17 @@ int main (void) ...@@ -49,9 +49,17 @@ int main (void)
CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_stdcall, CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_stdcall,
(void *) 3 /* userdata */, code) == FFI_OK); (void *) 3 /* userdata */, code) == FFI_OK);
#ifdef _MSC_VER
__asm { mov sp_pre, esp }
#else
asm volatile (" movl %%esp,%0" : "=g" (sp_pre)); asm volatile (" movl %%esp,%0" : "=g" (sp_pre));
#endif
res = (*(closure_test_type0)code)(0, 1, 2, 3); 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)); asm volatile (" movl %%esp,%0" : "=g" (sp_post));
#endif
/* { dg-output "0 1 2 3: 9" } */ /* { dg-output "0 1 2 3: 9" } */
printf("res: %d\n",res); printf("res: %d\n",res);
......
...@@ -49,9 +49,17 @@ int main (void) ...@@ -49,9 +49,17 @@ int main (void)
CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_thiscall, CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_thiscall,
(void *) 3 /* userdata */, code) == FFI_OK); (void *) 3 /* userdata */, code) == FFI_OK);
#ifdef _MSC_VER
__asm { mov sp_pre, esp }
#else
asm volatile (" movl %%esp,%0" : "=g" (sp_pre)); asm volatile (" movl %%esp,%0" : "=g" (sp_pre));
#endif
res = (*(closure_test_type0)code)(0, 1, 2, 3); 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)); asm volatile (" movl %%esp,%0" : "=g" (sp_post));
#endif
/* { dg-output "0 1 2 3: 9" } */ /* { dg-output "0 1 2 3: 9" } */
printf("res: %d\n",res); printf("res: %d\n",res);
......
...@@ -49,15 +49,15 @@ int main (void) ...@@ -49,15 +49,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_sint;
cls_struct_fields[1] = &ffi_type_sint; cls_struct_fields[1] = &ffi_type_sint;
cls_struct_fields[2] = &ffi_type_sint; cls_struct_fields[2] = &ffi_type_sint;
......
...@@ -50,15 +50,15 @@ int main (void) ...@@ -50,15 +50,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_sint;
cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = &ffi_type_sint; cls_struct_fields[2] = &ffi_type_sint;
......
...@@ -54,15 +54,15 @@ int main (void) ...@@ -54,15 +54,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
......
...@@ -57,15 +57,15 @@ int main (void) ...@@ -57,15 +57,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
......
...@@ -50,15 +50,15 @@ int main (void) ...@@ -50,15 +50,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_uchar;
cls_struct_fields[1] = NULL; cls_struct_fields[1] = NULL;
......
...@@ -50,15 +50,15 @@ int main (void) ...@@ -50,15 +50,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = &ffi_type_sint; cls_struct_fields[2] = &ffi_type_sint;
......
...@@ -52,15 +52,15 @@ int main (void) ...@@ -52,15 +52,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_sint;
cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = &ffi_type_double; cls_struct_fields[2] = &ffi_type_double;
......
...@@ -61,17 +61,17 @@ int main (void) ...@@ -61,17 +61,17 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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 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 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 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 h_dbl = { 8.0, 6.0, 1, 4.0 };
struct cls_struct_24byte res_dbl; 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[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = &ffi_type_sint; cls_struct_fields[2] = &ffi_type_sint;
......
...@@ -50,15 +50,15 @@ int main (void) ...@@ -50,15 +50,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = NULL; cls_struct_fields[2] = NULL;
......
...@@ -54,15 +54,15 @@ int main (void) ...@@ -54,15 +54,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
......
...@@ -50,15 +50,15 @@ int main (void) ...@@ -50,15 +50,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_ushort;
cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = NULL; cls_struct_fields[2] = NULL;
......
...@@ -50,15 +50,15 @@ int main (void) ...@@ -50,15 +50,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_ushort; cls_struct_fields[1] = &ffi_type_ushort;
cls_struct_fields[2] = NULL; cls_struct_fields[2] = NULL;
......
...@@ -56,15 +56,15 @@ int main (void) ...@@ -56,15 +56,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
......
...@@ -50,15 +50,15 @@ int main (void) ...@@ -50,15 +50,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_ushort;
cls_struct_fields[1] = &ffi_type_ushort; cls_struct_fields[1] = &ffi_type_ushort;
cls_struct_fields[2] = NULL; cls_struct_fields[2] = NULL;
......
...@@ -58,15 +58,15 @@ int main (void) ...@@ -58,15 +58,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
......
...@@ -53,15 +53,15 @@ int main (void) ...@@ -53,15 +53,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_ushort;
cls_struct_fields[1] = &ffi_type_ushort; cls_struct_fields[1] = &ffi_type_ushort;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
......
...@@ -66,17 +66,17 @@ int main (void) ...@@ -66,17 +66,17 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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 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 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 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 h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0 };
struct cls_struct_64byte res_dbl; 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[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = &ffi_type_double; cls_struct_fields[2] = &ffi_type_double;
......
...@@ -60,15 +60,15 @@ int main (void) ...@@ -60,15 +60,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
......
...@@ -56,15 +56,15 @@ int main (void) ...@@ -56,15 +56,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_ushort;
cls_struct_fields[1] = &ffi_type_ushort; cls_struct_fields[1] = &ffi_type_ushort;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
......
...@@ -62,15 +62,15 @@ int main (void) ...@@ -62,15 +62,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
......
...@@ -55,15 +55,15 @@ int main (void) ...@@ -55,15 +55,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_ushort;
cls_struct_fields[1] = &ffi_type_ushort; cls_struct_fields[1] = &ffi_type_ushort;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
......
...@@ -49,15 +49,15 @@ int main (void) ...@@ -49,15 +49,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_sint;
cls_struct_fields[1] = &ffi_type_float; cls_struct_fields[1] = &ffi_type_float;
cls_struct_fields[2] = NULL; cls_struct_fields[2] = NULL;
......
...@@ -50,15 +50,15 @@ int main (void) ...@@ -50,15 +50,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_sint;
cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = NULL; cls_struct_fields[2] = NULL;
......
...@@ -50,15 +50,15 @@ int main (void) ...@@ -50,15 +50,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_sint; cls_struct_fields[1] = &ffi_type_sint;
cls_struct_fields[2] = NULL; cls_struct_fields[2] = NULL;
......
...@@ -52,15 +52,15 @@ int main (void) ...@@ -52,15 +52,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
......
...@@ -50,15 +50,15 @@ int main (void) ...@@ -50,15 +50,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_float; cls_struct_fields[1] = &ffi_type_float;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
......
...@@ -51,15 +51,15 @@ int main (void) ...@@ -51,15 +51,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_longdouble; cls_struct_fields[1] = &ffi_type_longdouble;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
......
...@@ -87,15 +87,15 @@ int main (void) ...@@ -87,15 +87,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_longdouble;
cls_struct_fields[1] = &ffi_type_longdouble; cls_struct_fields[1] = &ffi_type_longdouble;
cls_struct_fields[2] = &ffi_type_longdouble; cls_struct_fields[2] = &ffi_type_longdouble;
......
...@@ -67,15 +67,15 @@ int main (void) ...@@ -67,15 +67,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_longdouble;
cls_struct_fields[1] = &ffi_type_longdouble; cls_struct_fields[1] = &ffi_type_longdouble;
cls_struct_fields[2] = &ffi_type_longdouble; cls_struct_fields[2] = &ffi_type_longdouble;
......
...@@ -54,15 +54,15 @@ int main (void) ...@@ -54,15 +54,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_pointer; cls_struct_fields[1] = &ffi_type_pointer;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
......
...@@ -50,15 +50,15 @@ int main (void) ...@@ -50,15 +50,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_sshort; cls_struct_fields[1] = &ffi_type_sshort;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
......
...@@ -50,15 +50,15 @@ int main (void) ...@@ -50,15 +50,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_sint; cls_struct_fields[1] = &ffi_type_sint;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
......
...@@ -51,15 +51,15 @@ int main (void) ...@@ -51,15 +51,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_sint64; cls_struct_fields[1] = &ffi_type_sint64;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
......
...@@ -50,15 +50,15 @@ int main (void) ...@@ -50,15 +50,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_ushort; cls_struct_fields[1] = &ffi_type_ushort;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
......
...@@ -50,15 +50,15 @@ int main (void) ...@@ -50,15 +50,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_uint; cls_struct_fields[1] = &ffi_type_uint;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
......
...@@ -52,15 +52,15 @@ int main (void) ...@@ -52,15 +52,15 @@ int main (void)
ffi_type cls_struct_type; ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields; 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[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_uint64; cls_struct_fields[1] = &ffi_type_uint64;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
......
...@@ -37,6 +37,8 @@ int main(int argc __UNUSED__, char** argv __UNUSED__) ...@@ -37,6 +37,8 @@ int main(int argc __UNUSED__, char** argv __UNUSED__)
ffi_type ts1_type; ffi_type ts1_type;
ffi_type* ts1_type_elements[4]; ffi_type* ts1_type_elements[4];
Dbls arg = { 1.0, 2.0 };
ts1_type.size = 0; ts1_type.size = 0;
ts1_type.alignment = 0; ts1_type.alignment = 0;
ts1_type.type = FFI_TYPE_STRUCT; ts1_type.type = FFI_TYPE_STRUCT;
...@@ -48,8 +50,6 @@ int main(int argc __UNUSED__, char** argv __UNUSED__) ...@@ -48,8 +50,6 @@ int main(int argc __UNUSED__, char** argv __UNUSED__)
cl_arg_types[0] = &ts1_type; cl_arg_types[0] = &ts1_type;
Dbls arg = { 1.0, 2.0 };
/* Initialize the cif */ /* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_void, cl_arg_types) == FFI_OK); &ffi_type_void, cl_arg_types) == FFI_OK);
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ /* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
/* { dg-output "" { xfail avr32*-*-* } } */ /* { dg-output "" { xfail avr32*-*-* } } */
/* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */ /* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */
/* { dg-skip-if "" arm*-*-* { "-mfloat-abi=hard" } { "" } } */
#include "ffitest.h" #include "ffitest.h"
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ /* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
/* { dg-output "" { xfail avr32*-*-* x86_64-*-mingw* } } */ /* { dg-output "" { xfail avr32*-*-* x86_64-*-mingw* } } */
/* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */ /* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */
/* { dg-skip-if "" arm*-*-* { "-mfloat-abi=hard" } { "" } } */
#include "ffitest.h" #include "ffitest.h"
......
...@@ -28,11 +28,12 @@ void* cls_pointer_fn2(void* a1, void* a2) ...@@ -28,11 +28,12 @@ void* cls_pointer_fn2(void* a1, void* a2)
char trample6 = trample4 + ((char*)&a2)[1]; char trample6 = trample4 + ((char*)&a2)[1];
long double trample7 = (intptr_t)trample5 + (intptr_t)trample1; long double trample7 = (intptr_t)trample5 + (intptr_t)trample1;
char trample8 = trample6 + trample2; char trample8 = trample6 + trample2;
void* result;
dummyVar = dummy_func(trample1, trample2, trample3, trample4, dummyVar = dummy_func(trample1, trample2, trample3, trample4,
trample5, trample6, trample7, trample8); 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", printf("0x%08x 0x%08x: 0x%08x\n",
(unsigned int)(uintptr_t) a1, (unsigned int)(uintptr_t) a1,
...@@ -52,11 +53,12 @@ void* cls_pointer_fn1(void* a1, void* a2) ...@@ -52,11 +53,12 @@ void* cls_pointer_fn1(void* a1, void* a2)
char trample6 = trample4 + ((char*)&a2)[1]; char trample6 = trample4 + ((char*)&a2)[1];
long double trample7 = (intptr_t)trample5 + (intptr_t)trample1; long double trample7 = (intptr_t)trample5 + (intptr_t)trample1;
char trample8 = trample6 + trample2; char trample8 = trample6 + trample2;
void* result;
dummyVar = dummy_func(trample1, trample2, trample3, trample4, dummyVar = dummy_func(trample1, trample2, trample3, trample4,
trample5, trample6, trample7, trample8); 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", printf("0x%08x 0x%08x: 0x%08x\n",
(unsigned int)(intptr_t) a1, (unsigned int)(intptr_t) a1,
......
/* 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);
}
/* 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);
}
/* 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);
}
/* 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);
}
/* 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);
}
...@@ -13,10 +13,10 @@ int main (void) ...@@ -13,10 +13,10 @@ int main (void)
ffi_cif cif; ffi_cif cif;
ffi_type* arg_types[1]; ffi_type* arg_types[1];
arg_types[0] = NULL;
ffi_type badType = ffi_type_void; ffi_type badType = ffi_type_void;
arg_types[0] = NULL;
badType.size = 0; badType.size = 0;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &badType, CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &badType,
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include "ffitest.h" #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); return (size_t) ((int) strlen(s) + (int) a);
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include "ffitest.h" #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); return (size_t) ((int) strlen(s) + (int) a);
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include "ffitest.h" #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); return (size_t) ((int) strlen(s) + (int) a + i);
} }
......
...@@ -25,6 +25,14 @@ ...@@ -25,6 +25,14 @@
#define __UNUSED__ #define __UNUSED__
#endif #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 /* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a
file open. */ file open. */
#ifdef HAVE_MMAP_ANON #ifdef HAVE_MMAP_ANON
...@@ -110,6 +118,15 @@ ...@@ -110,6 +118,15 @@
#endif #endif
#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 #ifdef USING_MMAP
static inline void * static inline void *
allocate_mmap (size_t size) allocate_mmap (size_t size)
......
...@@ -25,18 +25,18 @@ double float_va_fn(unsigned int x, double y,...) ...@@ -25,18 +25,18 @@ double float_va_fn(unsigned int x, double y,...)
total+=(double)x; total+=(double)x;
total+=y; total+=y;
printf("%u: %.1lf :", x, y); printf("%u: %.1f :", x, y);
va_start(ap, y); va_start(ap, y);
for(i=0;i<x;i++) for(i=0;i<x;i++)
{ {
double arg=va_arg(ap, double); double arg=va_arg(ap, double);
total+=arg; total+=arg;
printf(" %d:%.1lf ", i, arg); printf(" %d:%.1f ", i, arg);
} }
va_end(ap); va_end(ap);
printf(" total: %.1lf\n", total); printf(" total: %.1f\n", total);
return total; return total;
} }
...@@ -57,7 +57,7 @@ int main (void) ...@@ -57,7 +57,7 @@ int main (void)
/* Call it statically and then via ffi */ /* Call it statically and then via ffi */
resfp=float_va_fn(0,2.0); resfp=float_va_fn(0,2.0);
// { dg-output "0: 2.0 : total: 2.0" } // { dg-output "0: 2.0 : total: 2.0" }
printf("compiled: %.1lf\n", resfp); printf("compiled: %.1f\n", resfp);
// { dg-output "\ncompiled: 2.0" } // { dg-output "\ncompiled: 2.0" }
arg_types[0] = &ffi_type_uint; arg_types[0] = &ffi_type_uint;
...@@ -72,14 +72,14 @@ int main (void) ...@@ -72,14 +72,14 @@ int main (void)
values[1] = &doubles[0]; values[1] = &doubles[0];
ffi_call(&cif, FFI_FN(float_va_fn), &resfp, values); ffi_call(&cif, FFI_FN(float_va_fn), &resfp, values);
// { dg-output "\n0: 2.0 : total: 2.0" } // { dg-output "\n0: 2.0 : total: 2.0" }
printf("ffi: %.1lf\n", resfp); printf("ffi: %.1f\n", resfp);
// { dg-output "\nffi: 2.0" } // { dg-output "\nffi: 2.0" }
/* Second test, float_va_fn(2,2.0,3.0,4.0), now with variadic params */ /* Second test, float_va_fn(2,2.0,3.0,4.0), now with variadic params */
/* Call it statically and then via ffi */ /* Call it statically and then via ffi */
resfp=float_va_fn(2,2.0,3.0,4.0); resfp=float_va_fn(2,2.0,3.0,4.0);
// { dg-output "\n2: 2.0 : 0:3.0 1:4.0 total: 11.0" } // { dg-output "\n2: 2.0 : 0:3.0 1:4.0 total: 11.0" }
printf("compiled: %.1lf\n", resfp); printf("compiled: %.1f\n", resfp);
// { dg-output "\ncompiled: 11.0" } // { dg-output "\ncompiled: 11.0" }
arg_types[0] = &ffi_type_uint; arg_types[0] = &ffi_type_uint;
...@@ -100,7 +100,7 @@ int main (void) ...@@ -100,7 +100,7 @@ int main (void)
values[3] = &doubles[2]; values[3] = &doubles[2];
ffi_call(&cif, FFI_FN(float_va_fn), &resfp, values); ffi_call(&cif, FFI_FN(float_va_fn), &resfp, values);
// { dg-output "\n2: 2.0 : 0:3.0 1:4.0 total: 11.0" } // { dg-output "\n2: 2.0 : 0:3.0 1:4.0 total: 11.0" }
printf("ffi: %.1lf\n", resfp); printf("ffi: %.1f\n", resfp);
// { dg-output "\nffi: 11.0" } // { dg-output "\nffi: 11.0" }
exit(0); exit(0);
......
...@@ -229,6 +229,19 @@ main(int argc __UNUSED__, const char** argv __UNUSED__) ...@@ -229,6 +229,19 @@ main(int argc __UNUSED__, const char** argv __UNUSED__)
ffi_type* st_fields[51]; ffi_type* st_fields[51];
BigStruct retVal; 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)); memset (&retVal, 0, sizeof(retVal));
ret_struct_type.size = 0; ret_struct_type.size = 0;
...@@ -251,19 +264,6 @@ main(int argc __UNUSED__, const char** argv __UNUSED__) ...@@ -251,19 +264,6 @@ main(int argc __UNUSED__, const char** argv __UNUSED__)
st_fields[50] = NULL; 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; argTypes[0] = argTypes[12] = argTypes[24] = argTypes[36] = argTypes[48] = &ffi_type_uint8;
argValues[0] = argValues[12] = argValues[24] = argValues[36] = argValues[48] = &ui8; argValues[0] = argValues[12] = argValues[24] = argValues[36] = argValues[48] = &ui8;
argTypes[1] = argTypes[13] = argTypes[25] = argTypes[37] = argTypes[49] = &ffi_type_sint8; argTypes[1] = argTypes[13] = argTypes[25] = argTypes[37] = argTypes[49] = &ffi_type_sint8;
......
...@@ -77,6 +77,12 @@ int main (void) ...@@ -77,6 +77,12 @@ int main (void)
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
...@@ -92,12 +98,6 @@ int main (void) ...@@ -92,12 +98,6 @@ int main (void)
cls_struct_type2.type = FFI_TYPE_STRUCT; cls_struct_type2.type = FFI_TYPE_STRUCT;
cls_struct_type2.elements = cls_struct_fields2; 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[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_float; cls_struct_fields[1] = &ffi_type_float;
cls_struct_fields[2] = &ffi_type_sint; cls_struct_fields[2] = &ffi_type_sint;
......
...@@ -81,6 +81,13 @@ int main (void) ...@@ -81,6 +81,13 @@ int main (void)
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
ffi_type* dbl_arg_types[5]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
...@@ -96,13 +103,6 @@ int main (void) ...@@ -96,13 +103,6 @@ int main (void)
cls_struct_type2.type = FFI_TYPE_STRUCT; cls_struct_type2.type = FFI_TYPE_STRUCT;
cls_struct_type2.elements = cls_struct_fields2; 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[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_float; cls_struct_fields[1] = &ffi_type_float;
cls_struct_fields[2] = &ffi_type_sint; cls_struct_fields[2] = &ffi_type_sint;
......
...@@ -67,6 +67,12 @@ int main (void) ...@@ -67,6 +67,12 @@ int main (void)
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
ffi_type* dbl_arg_types[4]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
...@@ -82,12 +88,6 @@ int main (void) ...@@ -82,12 +88,6 @@ int main (void)
cls_struct_type2.type = FFI_TYPE_STRUCT; cls_struct_type2.type = FFI_TYPE_STRUCT;
cls_struct_type2.elements = cls_struct_fields2; 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[0] = &ffi_type_uint64;
cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = NULL; cls_struct_fields[2] = NULL;
......
/* 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);
}
...@@ -57,6 +57,11 @@ int main (void) ...@@ -57,6 +57,11 @@ int main (void)
ffi_type cls_struct_type, cls_struct_type1; ffi_type cls_struct_type, cls_struct_type1;
ffi_type* dbl_arg_types[3]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
...@@ -67,11 +72,6 @@ int main (void) ...@@ -67,11 +72,6 @@ int main (void)
cls_struct_type1.type = FFI_TYPE_STRUCT; cls_struct_type1.type = FFI_TYPE_STRUCT;
cls_struct_type1.elements = cls_struct_fields1; 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[0] = &ffi_type_ulong;
cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = NULL; cls_struct_fields[2] = NULL;
......
...@@ -58,6 +58,11 @@ int main (void) ...@@ -58,6 +58,11 @@ int main (void)
ffi_type cls_struct_type, cls_struct_type1; ffi_type cls_struct_type, cls_struct_type1;
ffi_type* dbl_arg_types[3]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
...@@ -68,11 +73,6 @@ int main (void) ...@@ -68,11 +73,6 @@ int main (void)
cls_struct_type1.type = FFI_TYPE_STRUCT; cls_struct_type1.type = FFI_TYPE_STRUCT;
cls_struct_type1.elements = cls_struct_fields1; 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[0] = &ffi_type_uint64;
cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = NULL; cls_struct_fields[2] = NULL;
......
...@@ -58,6 +58,11 @@ int main (void) ...@@ -58,6 +58,11 @@ int main (void)
ffi_type cls_struct_type, cls_struct_type1; ffi_type cls_struct_type, cls_struct_type1;
ffi_type* dbl_arg_types[3]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
...@@ -68,11 +73,6 @@ int main (void) ...@@ -68,11 +73,6 @@ int main (void)
cls_struct_type1.type = FFI_TYPE_STRUCT; cls_struct_type1.type = FFI_TYPE_STRUCT;
cls_struct_type1.elements = cls_struct_fields1; 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[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = NULL; cls_struct_fields[2] = NULL;
......
...@@ -58,6 +58,11 @@ int main (void) ...@@ -58,6 +58,11 @@ int main (void)
ffi_type cls_struct_type, cls_struct_type1; ffi_type cls_struct_type, cls_struct_type1;
ffi_type* dbl_arg_types[3]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
...@@ -68,11 +73,6 @@ int main (void) ...@@ -68,11 +73,6 @@ int main (void)
cls_struct_type1.type = FFI_TYPE_STRUCT; cls_struct_type1.type = FFI_TYPE_STRUCT;
cls_struct_type1.elements = cls_struct_fields1; 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[0] = &ffi_type_longdouble;
cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = NULL; cls_struct_fields[2] = NULL;
......
...@@ -66,6 +66,12 @@ int main (void) ...@@ -66,6 +66,12 @@ int main (void)
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
ffi_type* dbl_arg_types[4]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
...@@ -81,12 +87,6 @@ int main (void) ...@@ -81,12 +87,6 @@ int main (void)
cls_struct_type2.type = FFI_TYPE_STRUCT; cls_struct_type2.type = FFI_TYPE_STRUCT;
cls_struct_type2.elements = cls_struct_fields2; 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[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = NULL; cls_struct_fields[2] = NULL;
......
...@@ -58,6 +58,11 @@ int main (void) ...@@ -58,6 +58,11 @@ int main (void)
ffi_type cls_struct_type, cls_struct_type1; ffi_type cls_struct_type, cls_struct_type1;
ffi_type* dbl_arg_types[3]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
...@@ -68,11 +73,6 @@ int main (void) ...@@ -68,11 +73,6 @@ int main (void)
cls_struct_type1.type = FFI_TYPE_STRUCT; cls_struct_type1.type = FFI_TYPE_STRUCT;
cls_struct_type1.elements = cls_struct_fields1; 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[0] = &ffi_type_uint64;
cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = NULL; cls_struct_fields[2] = NULL;
......
...@@ -66,6 +66,12 @@ int main (void) ...@@ -66,6 +66,12 @@ int main (void)
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
ffi_type* dbl_arg_types[4]; 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.size = 0;
cls_struct_type.alignment = 0; cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.type = FFI_TYPE_STRUCT;
...@@ -81,12 +87,6 @@ int main (void) ...@@ -81,12 +87,6 @@ int main (void)
cls_struct_type2.type = FFI_TYPE_STRUCT; cls_struct_type2.type = FFI_TYPE_STRUCT;
cls_struct_type2.elements = cls_struct_fields2; 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[0] = &ffi_type_uint64;
cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = NULL; cls_struct_fields[2] = NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment