This separates the 32-bit sysv/linux/bsd code from the 64-bit linux

code, and makes it possible to link code compiled with different
options to those used to compile libffi.  For example, a
-mlong-double-128 libffi can be used with -mlong-double-64 code.

Using the return value area as a place to pass parameters wasn't such
a good idea, causing a failure of cls_ulonglong.c.  I didn't see this
when running the mainline gcc libffi testsuite because that version of
the test is inferior to the upstreamm libffi test.

Using NUM_FPR_ARG_REGISTERS rather than NUM_FPR_ARG_REGISTERS64 meant
that a parameter save area could be allocated before it was strictly
necessary.  Wrong but harmless.  Found when splitting apart ffi.c
into 32-bit and 64-bit support.
This commit is contained in:
Alan Modra
2013-11-21 21:24:56 -05:00
committed by Anthony Green
parent 69df91cfb4
commit ab79d6e219
21 changed files with 2193 additions and 1777 deletions
+63 -34
View File
@@ -60,45 +60,76 @@ typedef signed long ffi_sarg;
typedef enum ffi_abi {
FFI_FIRST_ABI = 0,
#ifdef POWERPC
FFI_SYSV,
FFI_GCC_SYSV,
FFI_LINUX64,
FFI_LINUX,
FFI_LINUX_SOFT_FLOAT,
# if defined(POWERPC64)
FFI_DEFAULT_ABI = FFI_LINUX64,
# elif defined(__NO_FPRS__)
FFI_DEFAULT_ABI = FFI_LINUX_SOFT_FLOAT,
# elif (__LDBL_MANT_DIG__ == 106)
FFI_DEFAULT_ABI = FFI_LINUX,
# else
FFI_DEFAULT_ABI = FFI_GCC_SYSV,
# endif
#endif
#ifdef POWERPC_AIX
#if defined (POWERPC_AIX)
FFI_AIX,
FFI_DARWIN,
FFI_DEFAULT_ABI = FFI_AIX,
#endif
FFI_LAST_ABI
#ifdef POWERPC_DARWIN
#elif defined (POWERPC_DARWIN)
FFI_AIX,
FFI_DARWIN,
FFI_DEFAULT_ABI = FFI_DARWIN,
#endif
#ifdef POWERPC_FREEBSD
FFI_SYSV,
FFI_GCC_SYSV,
FFI_LINUX64,
FFI_LINUX,
FFI_LINUX_SOFT_FLOAT,
FFI_DEFAULT_ABI = FFI_SYSV,
#endif
FFI_LAST_ABI
#else
/* The FFI_COMPAT values are used by old code. Since libffi may be
a shared library we have to support old values for backwards
compatibility. */
FFI_COMPAT_SYSV,
FFI_COMPAT_GCC_SYSV,
FFI_COMPAT_LINUX64,
FFI_COMPAT_LINUX,
FFI_COMPAT_LINUX_SOFT_FLOAT,
# if defined (POWERPC64)
/* This bit, always set in new code, must not be set in any of the
old FFI_COMPAT values that might be used for 64-bit linux. We
only need worry about FFI_COMPAT_LINUX64, but to be safe avoid
all old values. */
FFI_LINUX = 8,
/* This and following bits can reuse FFI_COMPAT values. */
FFI_LINUX_STRUCT_ALIGN = 1,
FFI_LINUX_LONG_DOUBLE_128 = 2,
FFI_DEFAULT_ABI = (FFI_LINUX
# ifdef __STRUCT_PARM_ALIGN__
| FFI_LINUX_STRUCT_ALIGN
# endif
# ifdef __LONG_DOUBLE_128__
| FFI_LINUX_LONG_DOUBLE_128
# endif
),
FFI_LAST_ABI = 12
# else
/* This bit, always set in new code, must not be set in any of the
old FFI_COMPAT values that might be used for 32-bit linux/sysv/bsd. */
FFI_SYSV = 8,
/* This and following bits can reuse FFI_COMPAT values. */
FFI_SYSV_SOFT_FLOAT = 1,
FFI_SYSV_STRUCT_RET = 2,
FFI_SYSV_IBM_LONG_DOUBLE = 4,
FFI_SYSV_LONG_DOUBLE_128 = 16,
FFI_DEFAULT_ABI = (FFI_SYSV
# ifdef __NO_FPRS__
| FFI_SYSV_SOFT_FLOAT
# endif
# if (defined (__SVR4_STRUCT_RETURN) \
|| defined (POWERPC_FREEBSD) && !defined (__AIX_STRUCT_RETURN))
| FFI_SYSV_STRUCT_RET
# endif
# if __LDBL_MANT_DIG__ == 106
| FFI_SYSV_IBM_LONG_DOUBLE
# endif
# ifdef __LONG_DOUBLE_128__
| FFI_SYSV_LONG_DOUBLE_128
# endif
),
FFI_LAST_ABI = 32
# endif
#endif
} ffi_abi;
#endif
@@ -117,9 +148,7 @@ typedef enum ffi_abi {
/* Needed for soft-float long-double-128 support. */
#define FFI_TYPE_UINT128 (FFI_TYPE_LAST + 1)
/* Needed for FFI_SYSV small structure returns.
We use two flag bits, (FLAG_SYSV_SMST_R3, FLAG_SYSV_SMST_R4) which are
defined in ffi.c, to determine the exact return type and its size. */
/* Needed for FFI_SYSV small structure returns. */
#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 2)
/* Used by ELFv2 for homogenous structure returns. */