Commit bf8da5fc by Richard Henderson Committed by Richard Henderson

configure.ac: Tidy target case.

        * configure.ac: Tidy target case.
        (HAVE_LONG_DOUBLE): Allow the target to override.
        * configure: Regenerate.
        * include/ffi.h.in: Don't define ffi_type_foo if
        LIBFFI_HIDE_BASIC_TYPES is defined.
        (ffi_type_longdouble): If not HAVE_LONG_DOUBLE, define
        to ffi_type_double.
        * types.c (LIBFFI_HIDE_BASIC_TYPES): Define.
        (FFI_TYPEDEF, ffi_type_void): Mark the data const.
        (ffi_type_longdouble): Special case for Alpha.  Don't define
        if long double == double.

        * src/alpha/ffi.c (FFI_TYPE_LONGDOUBLE): Assert unique value.
        (ffi_prep_cif_machdep): Handle it as the 128-bit type.
        (ffi_call, ffi_closure_osf_inner): Likewise.
        (ffi_closure_osf_inner): Likewise.  Mark hidden.
        (ffi_call_osf, ffi_closure_osf): Mark hidden.
        * src/alpha/ffitarget.h (FFI_LAST_ABI): Tidy definition.
        * src/alpha/osf.S (ffi_call_osf, ffi_closure_osf): Mark hidden.
        (load_table): Handle 128-bit long double.

        * testsuite/libffi.call/float4.c: Add -mieee for alpha.

From-SVN: r123622
parent 8fbba42a
2007-04-06 Richard Henderson <rth@redhat.com>
* configure.ac: Tidy target case.
(HAVE_LONG_DOUBLE): Allow the target to override.
* configure: Regenerate.
* include/ffi.h.in: Don't define ffi_type_foo if
LIBFFI_HIDE_BASIC_TYPES is defined.
(ffi_type_longdouble): If not HAVE_LONG_DOUBLE, define
to ffi_type_double.
* types.c (LIBFFI_HIDE_BASIC_TYPES): Define.
(FFI_TYPEDEF, ffi_type_void): Mark the data const.
(ffi_type_longdouble): Special case for Alpha. Don't define
if long double == double.
* src/alpha/ffi.c (FFI_TYPE_LONGDOUBLE): Assert unique value.
(ffi_prep_cif_machdep): Handle it as the 128-bit type.
(ffi_call, ffi_closure_osf_inner): Likewise.
(ffi_closure_osf_inner): Likewise. Mark hidden.
(ffi_call_osf, ffi_closure_osf): Mark hidden.
* src/alpha/ffitarget.h (FFI_LAST_ABI): Tidy definition.
* src/alpha/osf.S (ffi_call_osf, ffi_closure_osf): Mark hidden.
(load_table): Handle 128-bit long double.
* testsuite/libffi.call/float4.c: Add -mieee for alpha.
2007-04-06 Tom Tromey <tromey@redhat.com> 2007-04-06 Tom Tromey <tromey@redhat.com>
PR libffi/31491: PR libffi/31491:
......
...@@ -5383,52 +5383,107 @@ fi ...@@ -5383,52 +5383,107 @@ fi
TARGETDIR="unknown" TARGETDIR="unknown"
case "$host" in case "$host" in
i*86-*-linux*) TARGET=X86; TARGETDIR=x86;; alpha*-*-*)
i*86-*-gnu*) TARGET=X86; TARGETDIR=x86;; TARGET=ALPHA; TARGETDIR=alpha;
i*86-*-solaris2.1[0-9]*) TARGET=X86_64; TARGETDIR=x86;; # Support 128-bit long double, changable via command-line switch.
i*86-*-solaris*) TARGET=X86; TARGETDIR=x86;; HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
i*86-*-beos*) TARGET=X86; TARGETDIR=x86;; ;;
i*86-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86;;
i*86-*-freebsd* | i*86-*-kfreebsd*-gnu) TARGET=X86; TARGETDIR=x86;; arm*-*-*)
i*86-*-netbsdelf* | i*86-*-knetbsd*-gnu) TARGET=X86; TARGETDIR=x86;; TARGET=ARM; TARGETDIR=arm
i*86-*-rtems*) TARGET=X86; TARGETDIR=x86;; ;;
i*86-*-win32*) TARGET=X86_WIN32; TARGETDIR=x86;;
i*86-*-cygwin*) TARGET=X86_WIN32; TARGETDIR=x86;; cris-*-*)
i*86-*-mingw*) TARGET=X86_WIN32; TARGETDIR=x86;; TARGET=LIBFFI_CRIS; TARGETDIR=cris
frv-*-*) TARGET=FRV; TARGETDIR=frv;; ;;
sparc-sun-4*) TARGET=SPARC; TARGETDIR=sparc;;
sparc*-sun-*) TARGET=SPARC; TARGETDIR=sparc;; frv-*-*)
sparc-*-linux* | sparc-*-netbsdelf* | sparc-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;; TARGET=FRV; TARGETDIR=frv
sparc*-*-rtems*) TARGET=SPARC; TARGETDIR=sparc;; ;;
sparc64-*-linux* | sparc64-*-freebsd* | sparc64-*-netbsd* | sparc64-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;;
alpha*-*-linux* | alpha*-*-osf* | alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu | alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu) TARGET=ALPHA; TARGETDIR=alpha;; hppa*-*-linux* | parisc*-*-linux*)
ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;; TARGET=PA_LINUX; TARGETDIR=pa
m32r*-*-linux* ) TARGET=M32R; TARGETDIR=m32r;; ;;
m68k-*-linux*) TARGET=M68K; TARGETDIR=m68k;; hppa*64-*-hpux*)
mips64*-*);; TARGET=PA64_HPUX; TARGETDIR=pa
mips-sgi-irix5.* | mips-sgi-irix6.*) TARGET=MIPS_IRIX; TARGETDIR=mips;; ;;
mips*-*-linux*) TARGET=MIPS_LINUX; TARGETDIR=mips;; hppa*-*-hpux*)
powerpc*-*-linux* | powerpc-*-sysv*) TARGET=POWERPC; TARGETDIR=powerpc;; TARGET=PA_HPUX; TARGETDIR=pa
powerpc-*-beos*) TARGET=POWERPC; TARGETDIR=powerpc;; ;;
powerpc-*-darwin*) TARGET=POWERPC_DARWIN; TARGETDIR=powerpc;;
powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; i?86-win32* | i?86-*-cygwin* | i?86-*-mingw*)
powerpc-*-freebsd*) TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc;; TARGET=X86_WIN32; TARGETDIR=x86
powerpc*-*-rtems*) TARGET=POWERPC; TARGETDIR=powerpc;; ;;
rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; i?86-*-darwin*)
arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;; TARGET=X86_DARWIN; TARGETDIR=x86
arm*-*-netbsdelf* | arm*-*-knetbsd*-gnu) TARGET=ARM; TARGETDIR=arm;; ;;
arm*-*-rtems*) TARGET=ARM; TARGETDIR=arm;; i?86-*-*)
cris-*-*) TARGET=LIBFFI_CRIS; TARGETDIR=cris;; TARGET=X86; TARGETDIR=x86
s390-*-linux-*) TARGET=S390; TARGETDIR=s390;; ;;
s390x-*-linux-*) TARGET=S390; TARGETDIR=s390;;
x86_64-*-linux* | x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) TARGET=X86_64; TARGETDIR=x86;; ia64*-*-*)
x86_64-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86;; TARGET=IA64; TARGETDIR=ia64
sh-*-linux* | sh[34]*-*-linux*) TARGET=SH; TARGETDIR=sh;; ;;
sh-*-rtems*) TARGET=SH; TARGETDIR=sh;;
sh64-*-linux* | sh5*-*-linux*) TARGET=SH64; TARGETDIR=sh64;; m32r*-*-*)
hppa*-*-linux* | parisc*-*-linux*) TARGET=PA_LINUX; TARGETDIR=pa;; TARGET=M32R; TARGETDIR=m32r
hppa*64-*-hpux*) TARGET=PA64_HPUX; TARGETDIR=pa;; ;;
hppa*-*-hpux*) TARGET=PA_HPUX; TARGETDIR=pa;;
m68k-*-*)
TARGET=M68K; TARGETDIR=m68k
;;
mips64*-*)
;;
mips-sgi-irix5.* | mips-sgi-irix6.*)
TARGET=MIPS_IRIX; TARGETDIR=mips
;;
mips*-*-linux*)
TARGET=MIPS_LINUX; TARGETDIR=mips
;;
powerpc*-*-linux* | powerpc-*-sysv*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-beos*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-darwin*)
TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
;;
powerpc-*-aix* | rs6000-*-aix*)
TARGET=POWERPC_AIX; TARGETDIR=powerpc
;;
powerpc-*-freebsd*)
TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
;;
powerpc*-*-rtems*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
s390-*-* | s390x-*-*)
TARGET=S390; TARGETDIR=s390
;;
sh-*-* | sh[34]*-*-*)
TARGET=SH; TARGETDIR=sh
;;
sh64-*-* | sh5*-*-*)
TARGET=SH64; TARGETDIR=sh64
;;
sparc*-*-*)
TARGET=SPARC; TARGETDIR=sparc
;;
x86_64-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86
;;
x86_64-*-cygwin* | x86_64-*-mingw*)
;;
x86_64-*-*)
TARGET=X86_64; TARGETDIR=x86
;;
esac esac
...@@ -7143,15 +7198,17 @@ _ACEOF ...@@ -7143,15 +7198,17 @@ _ACEOF
# Also AC_SUBST this variable for ffi.h. # Also AC_SUBST this variable for ffi.h.
HAVE_LONG_DOUBLE=0 if test -z "$HAVE_LONG_DOUBLE"; then
if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then HAVE_LONG_DOUBLE=0
if test $ac_cv_sizeof_long_double != 0; then if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then
HAVE_LONG_DOUBLE=1 if test $ac_cv_sizeof_long_double != 0; then
HAVE_LONG_DOUBLE=1
cat >>confdefs.h <<\_ACEOF cat >>confdefs.h <<\_ACEOF
#define HAVE_LONG_DOUBLE 1 #define HAVE_LONG_DOUBLE 1
_ACEOF _ACEOF
fi
fi fi
fi fi
......
...@@ -41,52 +41,107 @@ AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite) ...@@ -41,52 +41,107 @@ AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite)
TARGETDIR="unknown" TARGETDIR="unknown"
case "$host" in case "$host" in
i*86-*-linux*) TARGET=X86; TARGETDIR=x86;; alpha*-*-*)
i*86-*-gnu*) TARGET=X86; TARGETDIR=x86;; TARGET=ALPHA; TARGETDIR=alpha;
i*86-*-solaris2.1[[0-9]]*) TARGET=X86_64; TARGETDIR=x86;; # Support 128-bit long double, changable via command-line switch.
i*86-*-solaris*) TARGET=X86; TARGETDIR=x86;; HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
i*86-*-beos*) TARGET=X86; TARGETDIR=x86;; ;;
i*86-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86;;
i*86-*-freebsd* | i*86-*-kfreebsd*-gnu) TARGET=X86; TARGETDIR=x86;; arm*-*-*)
i*86-*-netbsdelf* | i*86-*-knetbsd*-gnu) TARGET=X86; TARGETDIR=x86;; TARGET=ARM; TARGETDIR=arm
i*86-*-rtems*) TARGET=X86; TARGETDIR=x86;; ;;
i*86-*-win32*) TARGET=X86_WIN32; TARGETDIR=x86;;
i*86-*-cygwin*) TARGET=X86_WIN32; TARGETDIR=x86;; cris-*-*)
i*86-*-mingw*) TARGET=X86_WIN32; TARGETDIR=x86;; TARGET=LIBFFI_CRIS; TARGETDIR=cris
frv-*-*) TARGET=FRV; TARGETDIR=frv;; ;;
sparc-sun-4*) TARGET=SPARC; TARGETDIR=sparc;;
sparc*-sun-*) TARGET=SPARC; TARGETDIR=sparc;; frv-*-*)
sparc-*-linux* | sparc-*-netbsdelf* | sparc-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;; TARGET=FRV; TARGETDIR=frv
sparc*-*-rtems*) TARGET=SPARC; TARGETDIR=sparc;; ;;
sparc64-*-linux* | sparc64-*-freebsd* | sparc64-*-netbsd* | sparc64-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;;
alpha*-*-linux* | alpha*-*-osf* | alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu | alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu) TARGET=ALPHA; TARGETDIR=alpha;; hppa*-*-linux* | parisc*-*-linux*)
ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;; TARGET=PA_LINUX; TARGETDIR=pa
m32r*-*-linux* ) TARGET=M32R; TARGETDIR=m32r;; ;;
m68k-*-linux*) TARGET=M68K; TARGETDIR=m68k;; hppa*64-*-hpux*)
mips64*-*);; TARGET=PA64_HPUX; TARGETDIR=pa
mips-sgi-irix5.* | mips-sgi-irix6.*) TARGET=MIPS_IRIX; TARGETDIR=mips;; ;;
mips*-*-linux*) TARGET=MIPS_LINUX; TARGETDIR=mips;; hppa*-*-hpux*)
powerpc*-*-linux* | powerpc-*-sysv*) TARGET=POWERPC; TARGETDIR=powerpc;; TARGET=PA_HPUX; TARGETDIR=pa
powerpc-*-beos*) TARGET=POWERPC; TARGETDIR=powerpc;; ;;
powerpc-*-darwin*) TARGET=POWERPC_DARWIN; TARGETDIR=powerpc;;
powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; i?86-win32* | i?86-*-cygwin* | i?86-*-mingw*)
powerpc-*-freebsd*) TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc;; TARGET=X86_WIN32; TARGETDIR=x86
powerpc*-*-rtems*) TARGET=POWERPC; TARGETDIR=powerpc;; ;;
rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; i?86-*-darwin*)
arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;; TARGET=X86_DARWIN; TARGETDIR=x86
arm*-*-netbsdelf* | arm*-*-knetbsd*-gnu) TARGET=ARM; TARGETDIR=arm;; ;;
arm*-*-rtems*) TARGET=ARM; TARGETDIR=arm;; i?86-*-*)
cris-*-*) TARGET=LIBFFI_CRIS; TARGETDIR=cris;; TARGET=X86; TARGETDIR=x86
s390-*-linux-*) TARGET=S390; TARGETDIR=s390;; ;;
s390x-*-linux-*) TARGET=S390; TARGETDIR=s390;;
x86_64-*-linux* | x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) TARGET=X86_64; TARGETDIR=x86;; ia64*-*-*)
x86_64-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86;; TARGET=IA64; TARGETDIR=ia64
sh-*-linux* | sh[[34]]*-*-linux*) TARGET=SH; TARGETDIR=sh;; ;;
sh-*-rtems*) TARGET=SH; TARGETDIR=sh;;
sh64-*-linux* | sh5*-*-linux*) TARGET=SH64; TARGETDIR=sh64;; m32r*-*-*)
hppa*-*-linux* | parisc*-*-linux*) TARGET=PA_LINUX; TARGETDIR=pa;; TARGET=M32R; TARGETDIR=m32r
hppa*64-*-hpux*) TARGET=PA64_HPUX; TARGETDIR=pa;; ;;
hppa*-*-hpux*) TARGET=PA_HPUX; TARGETDIR=pa;;
m68k-*-*)
TARGET=M68K; TARGETDIR=m68k
;;
mips64*-*)
;;
mips-sgi-irix5.* | mips-sgi-irix6.*)
TARGET=MIPS_IRIX; TARGETDIR=mips
;;
mips*-*-linux*)
TARGET=MIPS_LINUX; TARGETDIR=mips
;;
powerpc*-*-linux* | powerpc-*-sysv*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-beos*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-darwin*)
TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
;;
powerpc-*-aix* | rs6000-*-aix*)
TARGET=POWERPC_AIX; TARGETDIR=powerpc
;;
powerpc-*-freebsd*)
TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
;;
powerpc*-*-rtems*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
s390-*-* | s390x-*-*)
TARGET=S390; TARGETDIR=s390
;;
sh-*-* | sh[[34]]*-*-*)
TARGET=SH; TARGETDIR=sh
;;
sh64-*-* | sh5*-*-*)
TARGET=SH64; TARGETDIR=sh64
;;
sparc*-*-*)
TARGET=SPARC; TARGETDIR=sparc
;;
x86_64-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86
;;
x86_64-*-cygwin* | x86_64-*-mingw*)
;;
x86_64-*-*)
TARGET=X86_64; TARGETDIR=x86
;;
esac esac
AC_SUBST(AM_RUNTESTFLAGS) AC_SUBST(AM_RUNTESTFLAGS)
...@@ -133,11 +188,13 @@ AC_CHECK_SIZEOF(double) ...@@ -133,11 +188,13 @@ AC_CHECK_SIZEOF(double)
AC_CHECK_SIZEOF(long double) AC_CHECK_SIZEOF(long double)
# Also AC_SUBST this variable for ffi.h. # Also AC_SUBST this variable for ffi.h.
HAVE_LONG_DOUBLE=0 if test -z "$HAVE_LONG_DOUBLE"; then
if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then HAVE_LONG_DOUBLE=0
if test $ac_cv_sizeof_long_double != 0; then if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then
HAVE_LONG_DOUBLE=1 if test $ac_cv_sizeof_long_double != 0; then
AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the long double type and it is bigger than a double]) HAVE_LONG_DOUBLE=1
AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the long double type and it is bigger than a double])
fi
fi fi
fi fi
AC_SUBST(HAVE_LONG_DOUBLE) AC_SUBST(HAVE_LONG_DOUBLE)
......
...@@ -82,6 +82,18 @@ extern "C" { ...@@ -82,6 +82,18 @@ extern "C" {
# endif # endif
#endif #endif
/* The closure code assumes that this works on pointers, i.e. a size_t */
/* can hold a pointer. */
typedef struct _ffi_type
{
size_t size;
unsigned short alignment;
unsigned short type;
struct _ffi_type **elements;
} ffi_type;
#ifndef LIBFFI_HIDE_BASIC_TYPES
#if SCHAR_MAX == 127 #if SCHAR_MAX == 127
# define ffi_type_uchar ffi_type_uint8 # define ffi_type_uchar ffi_type_uint8
# define ffi_type_schar ffi_type_sint8 # define ffi_type_schar ffi_type_sint8
...@@ -130,17 +142,6 @@ extern "C" { ...@@ -130,17 +142,6 @@ extern "C" {
#error "long size not supported" #error "long size not supported"
#endif #endif
/* The closure code assumes that this works on pointers, i.e. a size_t */
/* can hold a pointer. */
typedef struct _ffi_type
{
size_t size;
unsigned short alignment;
unsigned short type;
struct _ffi_type **elements;
} ffi_type;
/* These are defined in types.c */ /* These are defined in types.c */
extern ffi_type ffi_type_void; extern ffi_type ffi_type_void;
extern ffi_type ffi_type_uint8; extern ffi_type ffi_type_uint8;
...@@ -153,9 +154,14 @@ extern ffi_type ffi_type_uint64; ...@@ -153,9 +154,14 @@ extern ffi_type ffi_type_uint64;
extern ffi_type ffi_type_sint64; extern ffi_type ffi_type_sint64;
extern ffi_type ffi_type_float; extern ffi_type ffi_type_float;
extern ffi_type ffi_type_double; extern ffi_type ffi_type_double;
extern ffi_type ffi_type_longdouble;
extern ffi_type ffi_type_pointer; extern ffi_type ffi_type_pointer;
#if @HAVE_LONG_DOUBLE@
extern ffi_type ffi_type_longdouble;
#else
#define ffi_type_longdouble ffi_type_double
#endif
#endif /* LIBFFI_HIDE_BASIC_TYPES */
typedef enum { typedef enum {
FFI_OK = 0, FFI_OK = 0,
...@@ -342,4 +348,3 @@ void ffi_call(ffi_cif *cif, ...@@ -342,4 +348,3 @@ void ffi_call(ffi_cif *cif,
#endif #endif
#endif #endif
...@@ -25,11 +25,22 @@ ...@@ -25,11 +25,22 @@
#include <ffi.h> #include <ffi.h>
#include <ffi_common.h> #include <ffi_common.h>
#include <stdlib.h> #include <stdlib.h>
extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)()); /* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
extern void ffi_closure_osf(void); all further uses in this file will refer to the 128-bit type. */
#if defined(__LONG_DOUBLE_128__)
# if FFI_TYPE_LONGDOUBLE != 4
# error FFI_TYPE_LONGDOUBLE out of date
# endif
#else
# undef FFI_TYPE_LONGDOUBLE
# define FFI_TYPE_LONGDOUBLE 4
#endif
extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)())
FFI_HIDDEN;
extern void ffi_closure_osf(void) FFI_HIDDEN;
ffi_status ffi_status
...@@ -49,6 +60,11 @@ ffi_prep_cif_machdep(ffi_cif *cif) ...@@ -49,6 +60,11 @@ ffi_prep_cif_machdep(ffi_cif *cif)
cif->flags = cif->rtype->type; cif->flags = cif->rtype->type;
break; break;
case FFI_TYPE_LONGDOUBLE:
/* 128-bit long double is returned in memory, like a struct. */
cif->flags = FFI_TYPE_STRUCT;
break;
default: default:
cif->flags = FFI_TYPE_INT; cif->flags = FFI_TYPE_INT;
break; break;
...@@ -57,6 +73,7 @@ ffi_prep_cif_machdep(ffi_cif *cif) ...@@ -57,6 +73,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
return FFI_OK; return FFI_OK;
} }
void void
ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
{ {
...@@ -64,8 +81,6 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) ...@@ -64,8 +81,6 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
long i, avn; long i, avn;
ffi_type **arg_types; ffi_type **arg_types;
FFI_ASSERT (cif->abi == FFI_OSF);
/* 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 && cif->flags == FFI_TYPE_STRUCT) if (rvalue == NULL && cif->flags == FFI_TYPE_STRUCT)
...@@ -84,6 +99,8 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) ...@@ -84,6 +99,8 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
while (i < avn) while (i < avn)
{ {
size_t size = (*arg_types)->size;
switch ((*arg_types)->type) switch ((*arg_types)->type)
{ {
case FFI_TYPE_SINT8: case FFI_TYPE_SINT8:
...@@ -129,6 +146,12 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) ...@@ -129,6 +146,12 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
*(double *) argp = *(double *)(* avalue); *(double *) argp = *(double *)(* avalue);
break; break;
case FFI_TYPE_LONGDOUBLE:
/* 128-bit long double is passed by reference. */
*(long double **) argp = (long double *)(* avalue);
size = sizeof (long double *);
break;
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:
memcpy(argp, *avalue, (*arg_types)->size); memcpy(argp, *avalue, (*arg_types)->size);
break; break;
...@@ -137,7 +160,7 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) ...@@ -137,7 +160,7 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
FFI_ASSERT(0); FFI_ASSERT(0);
} }
argp += ALIGN((*arg_types)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; argp += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
i++, arg_types++, avalue++; i++, arg_types++, avalue++;
} }
...@@ -154,8 +177,6 @@ ffi_prep_closure_loc (ffi_closure* closure, ...@@ -154,8 +177,6 @@ ffi_prep_closure_loc (ffi_closure* closure,
{ {
unsigned int *tramp; unsigned int *tramp;
FFI_ASSERT (cif->abi == FFI_OSF);
tramp = (unsigned int *) &closure->tramp[0]; tramp = (unsigned int *) &closure->tramp[0];
tramp[0] = 0x47fb0401; /* mov $27,$1 */ tramp[0] = 0x47fb0401; /* mov $27,$1 */
tramp[1] = 0xa77b0010; /* ldq $27,16($27) */ tramp[1] = 0xa77b0010; /* ldq $27,16($27) */
...@@ -178,7 +199,8 @@ ffi_prep_closure_loc (ffi_closure* closure, ...@@ -178,7 +199,8 @@ ffi_prep_closure_loc (ffi_closure* closure,
return FFI_OK; return FFI_OK;
} }
int
long FFI_HIDDEN
ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp) ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
{ {
ffi_cif *cif; ffi_cif *cif;
...@@ -206,6 +228,8 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp) ...@@ -206,6 +228,8 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
/* Grab the addresses of the arguments from the stack frame. */ /* Grab the addresses of the arguments from the stack frame. */
while (i < avn) while (i < avn)
{ {
size_t size = arg_types[i]->size;
switch (arg_types[i]->type) switch (arg_types[i]->type)
{ {
case FFI_TYPE_SINT8: case FFI_TYPE_SINT8:
...@@ -237,16 +261,22 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp) ...@@ -237,16 +261,22 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)]; avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)];
break; break;
case FFI_TYPE_LONGDOUBLE:
/* 128-bit long double is passed by reference. */
avalue[i] = (long double *) argp[argn];
size = sizeof (long double *);
break;
default: default:
FFI_ASSERT(0); abort ();
} }
argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; argn += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
i++; i++;
} }
/* Invoke the closure. */ /* Invoke the closure. */
(closure->fun) (cif, rvalue, avalue, closure->user_data); closure->fun (cif, rvalue, avalue, closure->user_data);
/* Tell ffi_closure_osf how to perform return type promotions. */ /* Tell ffi_closure_osf how to perform return type promotions. */
return cif->rtype->type; return cif->rtype->type;
......
...@@ -33,8 +33,8 @@ typedef signed long ffi_sarg; ...@@ -33,8 +33,8 @@ typedef signed long ffi_sarg;
typedef enum ffi_abi { typedef enum ffi_abi {
FFI_FIRST_ABI = 0, FFI_FIRST_ABI = 0,
FFI_OSF, FFI_OSF,
FFI_DEFAULT_ABI = FFI_OSF, FFI_LAST_ABI,
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 FFI_DEFAULT_ABI = FFI_OSF
} ffi_abi; } ffi_abi;
#endif #endif
...@@ -45,4 +45,3 @@ typedef enum ffi_abi { ...@@ -45,4 +45,3 @@ typedef enum ffi_abi {
#define FFI_NATIVE_RAW_API 0 #define FFI_NATIVE_RAW_API 0
#endif #endif
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
osf.S - Copyright (c) 1998, 2001 Red Hat osf.S - Copyright (c) 1998, 2001, 2007 Red Hat
Alpha/OSF Foreign Function Interface Alpha/OSF Foreign Function Interface
$Id: osf.S,v 1.1.1.1 1998/11/29 16:48:16 green Exp $
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including ``Software''), to deal in the Software without restriction, including
...@@ -42,6 +40,8 @@ ...@@ -42,6 +40,8 @@
.align 3 .align 3
.globl ffi_call_osf .globl ffi_call_osf
.ent ffi_call_osf .ent ffi_call_osf
FFI_HIDDEN(ffi_call_osf)
ffi_call_osf: ffi_call_osf:
.frame $15, 32, $26, 0 .frame $15, 32, $26, 0
.mask 0x4008000, -32 .mask 0x4008000, -32
...@@ -129,6 +129,8 @@ $LFE1: ...@@ -129,6 +129,8 @@ $LFE1:
.align 3 .align 3
.globl ffi_closure_osf .globl ffi_closure_osf
.ent ffi_closure_osf .ent ffi_closure_osf
FFI_HIDDEN(ffi_closure_osf)
ffi_closure_osf: ffi_closure_osf:
.frame $30, 16*8, $26, 0 .frame $30, 16*8, $26, 0
.mask 0x4000000, -16*8 .mask 0x4000000, -16*8
...@@ -265,7 +267,7 @@ $load_table: ...@@ -265,7 +267,7 @@ $load_table:
.gprel32 $load_32 # FFI_TYPE_INT .gprel32 $load_32 # FFI_TYPE_INT
.gprel32 $load_float # FFI_TYPE_FLOAT .gprel32 $load_float # FFI_TYPE_FLOAT
.gprel32 $load_double # FFI_TYPE_DOUBLE .gprel32 $load_double # FFI_TYPE_DOUBLE
.gprel32 $load_double # FFI_TYPE_LONGDOUBLE .gprel32 $load_none # FFI_TYPE_LONGDOUBLE
.gprel32 $load_u8 # FFI_TYPE_UINT8 .gprel32 $load_u8 # FFI_TYPE_UINT8
.gprel32 $load_s8 # FFI_TYPE_SINT8 .gprel32 $load_s8 # FFI_TYPE_SINT8
.gprel32 $load_u16 # FFI_TYPE_UINT16 .gprel32 $load_u16 # FFI_TYPE_UINT16
......
...@@ -23,6 +23,10 @@ ...@@ -23,6 +23,10 @@
OTHER DEALINGS IN THE SOFTWARE. OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */ ----------------------------------------------------------------------- */
/* Hide the basic type definitions from the header file, so that we
can redefine them here as "const". */
#define LIBFFI_HIDE_BASIC_TYPES
#include <ffi.h> #include <ffi.h>
#include <ffi_common.h> #include <ffi_common.h>
...@@ -33,14 +37,14 @@ struct struct_align_##name { \ ...@@ -33,14 +37,14 @@ struct struct_align_##name { \
char c; \ char c; \
type x; \ type x; \
}; \ }; \
ffi_type ffi_type_##name = { \ const ffi_type ffi_type_##name = { \
sizeof(type), \ sizeof(type), \
offsetof(struct struct_align_##name, x), \ offsetof(struct struct_align_##name, x), \
id, NULL \ id, NULL \
} }
/* Size and alignment are fake here. They must not be 0. */ /* Size and alignment are fake here. They must not be 0. */
ffi_type ffi_type_void = { const ffi_type ffi_type_void = {
1, 1, FFI_TYPE_VOID, NULL 1, 1, FFI_TYPE_VOID, NULL
}; };
...@@ -57,4 +61,16 @@ FFI_TYPEDEF(pointer, void*, FFI_TYPE_POINTER); ...@@ -57,4 +61,16 @@ FFI_TYPEDEF(pointer, void*, FFI_TYPE_POINTER);
FFI_TYPEDEF(float, float, FFI_TYPE_FLOAT); FFI_TYPEDEF(float, float, FFI_TYPE_FLOAT);
FFI_TYPEDEF(double, double, FFI_TYPE_DOUBLE); FFI_TYPEDEF(double, double, FFI_TYPE_DOUBLE);
#ifdef __alpha__
/* Even if we're not configured to default to 128-bit long double,
maintain binary compatibility, as -mlong-double-128 can be used
at any time. */
/* Validate the hard-coded number below. */
# if defined(__LONG_DOUBLE_128__) && FFI_TYPE_LONGDOUBLE != 4
# error FFI_TYPE_LONGDOUBLE out of date
# endif
const ffi_type ffi_type_longdouble = { 16, 16, 4, NULL };
#elif FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
FFI_TYPEDEF(longdouble, long double, FFI_TYPE_LONGDOUBLE); FFI_TYPEDEF(longdouble, long double, FFI_TYPE_LONGDOUBLE);
#endif
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
Originator: From the original ffitest.c */ Originator: From the original ffitest.c */
/* { dg-do run } */ /* { dg-do run } */
/* { dg-options "-mieee" { target alpha*-*-* } } */
#include "ffitest.h" #include "ffitest.h"
#include "float.h" #include "float.h"
......
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