TARGETDIR="unknown"
case "$host" in
+i*86-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86;;
i*86-*-linux*) TARGET=X86; TARGETDIR=x86;;
i*86-*-gnu*) TARGET=X86; TARGETDIR=x86;;
i*86-*-solaris2.1[0-9]*) TARGET=X86_64; TARGETDIR=x86;;
esac
+
+
+
if test x$TARGET = xSPARC; then
echo "$as_me:$LINENO: checking assembler and linker support unaligned pc related relocs" >&5
echo $ECHO_N "checking assembler and linker support unaligned pc related relocs... $ECHO_C" >&6
ac_config_commands="$ac_config_commands src"
- ac_config_links="$ac_config_links include/ffitarget.h:src/$TARGETDIR/ffitarget.h"
+TARGETINCDIR=$TARGETDIR
+case $host in
+*-*-darwin*)
+ TARGETINCDIR="darwin"
+ ;;
+esac
+
+
+ ac_config_links="$ac_config_links include/ffitarget.h:src/$TARGETINCDIR/ffitarget.h"
ac_config_links="$ac_config_links include/ffi_common.h:include/ffi_common.h"
# Handling of arguments.
"include/ffi.h" ) CONFIG_FILES="$CONFIG_FILES include/ffi.h" ;;
"fficonfig.py" ) CONFIG_FILES="$CONFIG_FILES fficonfig.py" ;;
- "include/ffitarget.h" ) CONFIG_LINKS="$CONFIG_LINKS include/ffitarget.h:src/$TARGETDIR/ffitarget.h" ;;
+ "include/ffitarget.h" ) CONFIG_LINKS="$CONFIG_LINKS include/ffitarget.h:src/$TARGETINCDIR/ffitarget.h" ;;
"include/ffi_common.h" ) CONFIG_LINKS="$CONFIG_LINKS include/ffi_common.h:include/ffi_common.h" ;;
"include" ) CONFIG_COMMANDS="$CONFIG_COMMANDS include" ;;
"src" ) CONFIG_COMMANDS="$CONFIG_COMMANDS src" ;;
TARGETDIR="unknown"
case "$host" in
+i*86-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86;;
i*86-*-linux*) TARGET=X86; TARGETDIR=x86;;
i*86-*-gnu*) TARGET=X86; TARGETDIR=x86;;
i*86-*-solaris2.1[[0-9]]*) TARGET=X86_64; TARGETDIR=x86;;
AC_SUBST(HAVE_LONG_DOUBLE)
AC_C_BIGENDIAN
+AH_VERBATIM([WORDS_BIGENDIAN],
+[
+/* Define to 1 if your processor stores words with the most significant byte
+ first (like Motorola and SPARC, unlike Intel and VAX).
+
+ The block below does compile-time checking for endianness on platforms
+ that use GCC and therefore allows compiling fat binaries on OSX by using
+ '-arch ppc -arch i386' as the compile flags. The phrasing was choosen
+ such that the configure-result is used on systems that don't use GCC.
+*/
+#ifdef __BIG_ENDIAN__
+#define WORDS_BIGENDIAN 1
+#else
+#ifndef __LITTLE_ENDIAN__
+#undef WORDS_BIGENDIAN
+#endif
+#endif])
+
if test x$TARGET = xSPARC; then
AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs],
test -d src/$TARGETDIR || mkdir src/$TARGETDIR
], [TARGETDIR="$TARGETDIR"])
-AC_CONFIG_LINKS(include/ffitarget.h:src/$TARGETDIR/ffitarget.h)
+TARGETINCDIR=$TARGETDIR
+case $host in
+*-*-darwin*)
+ TARGETINCDIR="darwin"
+ ;;
+esac
+
+
+AC_CONFIG_LINKS(include/ffitarget.h:src/$TARGETINCDIR/ffitarget.h)
AC_CONFIG_LINKS(include/ffi_common.h:include/ffi_common.h)
AC_CONFIG_FILES(include/ffi.h fficonfig.py)
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
+
/* Define to 1 if your processor stores words with the most significant byte
- first (like Motorola and SPARC, unlike Intel and VAX). */
+ first (like Motorola and SPARC, unlike Intel and VAX).
+
+ The block below does compile-time checking for endianness on platforms
+ that use GCC and therefore allows compiling fat binaries on OSX by using
+ '-arch ppc -arch i386' as the compile flags. The phrasing was choosen
+ such that the configure-result is used on systems that don't use GCC.
+*/
+#ifdef __BIG_ENDIAN__
+#define WORDS_BIGENDIAN 1
+#else
+#ifndef __LITTLE_ENDIAN__
#undef WORDS_BIGENDIAN
+#endif
+#endif
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
'MIPS_IRIX': ['src/mips/ffi.c', 'src/mips/o32.S', 'src/mips/n32.S'],
'MIPS_LINUX': ['src/mips/ffi.c', 'src/mips/o32.S'],
'X86': ['src/x86/ffi.c', 'src/x86/sysv.S'],
+ 'X86_DARWIN': ['src/x86/ffi_darwin.c', 'src/x86/darwin.S'],
'X86_WIN32': ['src/x86/ffi.c', 'src/x86/win32.S'],
'SPARC': ['src/sparc/ffi.c', 'src/sparc/v8.S', 'src/sparc/v9.S'],
'ALPHA': ['src/alpha/ffi.c', 'src/alpha/osf.S'],
'PA': ['src/pa/linux.S', 'src/pa/ffi.c'],
}
+# Build all darwin related files on all supported darwin architectures, this
+# makes it easier to build universal binaries.
+if 0:
+ all_darwin = ('X86_DARWIN', 'POWERPC_DARWIN')
+ all_darwin_files = []
+ for pn in all_darwin:
+ all_darwin_files.extend(ffi_platforms[pn])
+ for pn in all_darwin:
+ ffi_platforms[pn] = all_darwin_files
+ del all_darwin, all_darwin_files, pn
+
ffi_srcdir = '@srcdir@'
ffi_sources += ffi_platforms['@MKTARGET@']
ffi_sources = [os.path.join('@srcdir@', f) for f in ffi_sources]
+#ifdef __ppc__
/* -----------------------------------------------------------------------
darwin.S - Copyright (c) 2000 John Hornkvist
Copyright (c) 2004 Free Software Foundation, Inc.
.align LOG2_GPR_BYTES
LLFB0$non_lazy_ptr:
.g_long LFB0
+#endif
+#ifdef __ppc__
/* -----------------------------------------------------------------------
darwin_closure.S - Copyright (c) 2002, 2003, 2004, Free Software Foundation,
Inc. based on ppc_closure.S
.align LOG2_GPR_BYTES
LLFB1$non_lazy_ptr:
.g_long LFB1
+#endif
+#ifdef __ppc__
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 1998 Geoffrey Keating
/* Tell ffi_closure_ASM to perform return type promotions. */
return cif->rtype->type;
}
+#endif
/* Perform a sanity check on the argument type */
FFI_ASSERT_VALID_TYPE(*ptr);
+#ifdef POWERPC_DARWIN
+ {
+ int curalign;
+
+ curalign = (*ptr)->alignment;
+ if (ptr != &(arg->elements[0])) {
+ if (curalign > 4 && curalign != 16) {
+ curalign = 4;
+ }
+ }
+ arg->size = ALIGN(arg->size, curalign);
+ arg->size += (*ptr)->size;
+
+ arg->alignment = (arg->alignment > curalign) ?
+ arg->alignment : curalign;
+ }
+#else
arg->size = ALIGN(arg->size, (*ptr)->alignment);
arg->size += (*ptr)->size;
arg->alignment = (arg->alignment > (*ptr)->alignment) ?
arg->alignment : (*ptr)->alignment;
+#endif
ptr++;
}
/* Perform machine independent ffi_cif preparation, then call
machine dependent routine. */
+#ifdef X86_DARWIN
+static inline int struct_on_stack(int size)
+{
+ if (size > 8) return 1;
+ /* This is not what the ABI says, but is what is really implemented */
+ switch (size) {
+ case 1: case 2: case 4: case 8: return 0;
+ return 1;
+ }
+}
+#endif
+
+
ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
ffi_abi abi, unsigned int nargs,
/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype,
if (cif->rtype->type == FFI_TYPE_STRUCT
#ifdef SPARC
&& (cif->abi != FFI_V9 || cif->rtype->size > 32)
+#endif
+#ifdef X86_DARWIN
+
+ && (struct_on_stack(cif->rtype->size))
#endif
)
bytes = STACK_ARG_SIZE(sizeof(void*));
check after the initialization. */
FFI_ASSERT_VALID_TYPE(*ptr);
-#if !defined __x86_64__ && !defined S390 && !defined PA
+#if defined(X86_DARWIN)
+ {
+ int align = (*ptr)->alignment;
+ if (align > 4) align = 4;
+ if ((align - 1) & bytes)
+ bytes = ALIGN(bytes, align);
+ bytes += STACK_ARG_SIZE((*ptr)->size);
+ }
+
+#elif !defined __x86_64__ && !defined S390 && !defined PA
#ifdef SPARC
if (((*ptr)->type == FFI_TYPE_STRUCT
&& ((*ptr)->size > 16 || cif->abi != FFI_V9))
#endif
/* ---- Intel x86 and AMD x86-64 - */
-#if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__))
+#if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__))
FFI_SYSV,
FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */
#ifdef __i386__