diff --git a/libffi/ChangeLog b/libffi/ChangeLog index 4d5a8b82203..22295f8e89d 100644 --- a/libffi/ChangeLog +++ b/libffi/ChangeLog @@ -1,3 +1,28 @@ +2007-04-06 Richard Henderson + + * 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 PR libffi/31491: diff --git a/libffi/configure b/libffi/configure index 0d289de3b36..0b8c79ccb38 100755 --- a/libffi/configure +++ b/libffi/configure @@ -5383,52 +5383,107 @@ fi TARGETDIR="unknown" case "$host" in -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;; -i*86-*-solaris*) TARGET=X86; TARGETDIR=x86;; -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;; -i*86-*-netbsdelf* | i*86-*-knetbsd*-gnu) TARGET=X86; TARGETDIR=x86;; -i*86-*-rtems*) TARGET=X86; TARGETDIR=x86;; -i*86-*-win32*) TARGET=X86_WIN32; TARGETDIR=x86;; -i*86-*-cygwin*) TARGET=X86_WIN32; TARGETDIR=x86;; -i*86-*-mingw*) TARGET=X86_WIN32; TARGETDIR=x86;; -frv-*-*) TARGET=FRV; TARGETDIR=frv;; -sparc-sun-4*) TARGET=SPARC; TARGETDIR=sparc;; -sparc*-sun-*) TARGET=SPARC; TARGETDIR=sparc;; -sparc-*-linux* | sparc-*-netbsdelf* | sparc-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;; -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;; -ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;; -m32r*-*-linux* ) TARGET=M32R; TARGETDIR=m32r;; -m68k-*-linux*) 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*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; -powerpc-*-freebsd*) TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc;; -powerpc*-*-rtems*) TARGET=POWERPC; TARGETDIR=powerpc;; -rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; -arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;; -arm*-*-netbsdelf* | arm*-*-knetbsd*-gnu) TARGET=ARM; TARGETDIR=arm;; -arm*-*-rtems*) TARGET=ARM; TARGETDIR=arm;; -cris-*-*) TARGET=LIBFFI_CRIS; TARGETDIR=cris;; -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;; -x86_64-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86;; -sh-*-linux* | sh[34]*-*-linux*) TARGET=SH; TARGETDIR=sh;; -sh-*-rtems*) TARGET=SH; TARGETDIR=sh;; -sh64-*-linux* | sh5*-*-linux*) TARGET=SH64; TARGETDIR=sh64;; -hppa*-*-linux* | parisc*-*-linux*) TARGET=PA_LINUX; TARGETDIR=pa;; -hppa*64-*-hpux*) TARGET=PA64_HPUX; TARGETDIR=pa;; -hppa*-*-hpux*) TARGET=PA_HPUX; TARGETDIR=pa;; + alpha*-*-*) + TARGET=ALPHA; TARGETDIR=alpha; + # Support 128-bit long double, changable via command-line switch. + HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)' + ;; + + arm*-*-*) + TARGET=ARM; TARGETDIR=arm + ;; + + cris-*-*) + TARGET=LIBFFI_CRIS; TARGETDIR=cris + ;; + + frv-*-*) + TARGET=FRV; TARGETDIR=frv + ;; + + hppa*-*-linux* | parisc*-*-linux*) + TARGET=PA_LINUX; TARGETDIR=pa + ;; + hppa*64-*-hpux*) + TARGET=PA64_HPUX; TARGETDIR=pa + ;; + hppa*-*-hpux*) + TARGET=PA_HPUX; TARGETDIR=pa + ;; + + i?86-win32* | i?86-*-cygwin* | i?86-*-mingw*) + TARGET=X86_WIN32; TARGETDIR=x86 + ;; + i?86-*-darwin*) + TARGET=X86_DARWIN; TARGETDIR=x86 + ;; + i?86-*-*) + TARGET=X86; TARGETDIR=x86 + ;; + + ia64*-*-*) + TARGET=IA64; TARGETDIR=ia64 + ;; + + m32r*-*-*) + TARGET=M32R; TARGETDIR=m32r + ;; + + 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 @@ -7143,15 +7198,17 @@ _ACEOF # Also AC_SUBST this variable for ffi.h. -HAVE_LONG_DOUBLE=0 -if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then - if test $ac_cv_sizeof_long_double != 0; then - HAVE_LONG_DOUBLE=1 +if test -z "$HAVE_LONG_DOUBLE"; then + HAVE_LONG_DOUBLE=0 + if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then + if test $ac_cv_sizeof_long_double != 0; then + HAVE_LONG_DOUBLE=1 cat >>confdefs.h <<\_ACEOF #define HAVE_LONG_DOUBLE 1 _ACEOF + fi fi fi diff --git a/libffi/configure.ac b/libffi/configure.ac index 46c4ee3214f..c171d922f8b 100644 --- a/libffi/configure.ac +++ b/libffi/configure.ac @@ -41,52 +41,107 @@ AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite) TARGETDIR="unknown" case "$host" in -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;; -i*86-*-solaris*) TARGET=X86; TARGETDIR=x86;; -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;; -i*86-*-netbsdelf* | i*86-*-knetbsd*-gnu) TARGET=X86; TARGETDIR=x86;; -i*86-*-rtems*) TARGET=X86; TARGETDIR=x86;; -i*86-*-win32*) TARGET=X86_WIN32; TARGETDIR=x86;; -i*86-*-cygwin*) TARGET=X86_WIN32; TARGETDIR=x86;; -i*86-*-mingw*) TARGET=X86_WIN32; TARGETDIR=x86;; -frv-*-*) TARGET=FRV; TARGETDIR=frv;; -sparc-sun-4*) TARGET=SPARC; TARGETDIR=sparc;; -sparc*-sun-*) TARGET=SPARC; TARGETDIR=sparc;; -sparc-*-linux* | sparc-*-netbsdelf* | sparc-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;; -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;; -ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;; -m32r*-*-linux* ) TARGET=M32R; TARGETDIR=m32r;; -m68k-*-linux*) 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*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; -powerpc-*-freebsd*) TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc;; -powerpc*-*-rtems*) TARGET=POWERPC; TARGETDIR=powerpc;; -rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; -arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;; -arm*-*-netbsdelf* | arm*-*-knetbsd*-gnu) TARGET=ARM; TARGETDIR=arm;; -arm*-*-rtems*) TARGET=ARM; TARGETDIR=arm;; -cris-*-*) TARGET=LIBFFI_CRIS; TARGETDIR=cris;; -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;; -x86_64-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86;; -sh-*-linux* | sh[[34]]*-*-linux*) TARGET=SH; TARGETDIR=sh;; -sh-*-rtems*) TARGET=SH; TARGETDIR=sh;; -sh64-*-linux* | sh5*-*-linux*) TARGET=SH64; TARGETDIR=sh64;; -hppa*-*-linux* | parisc*-*-linux*) TARGET=PA_LINUX; TARGETDIR=pa;; -hppa*64-*-hpux*) TARGET=PA64_HPUX; TARGETDIR=pa;; -hppa*-*-hpux*) TARGET=PA_HPUX; TARGETDIR=pa;; + alpha*-*-*) + TARGET=ALPHA; TARGETDIR=alpha; + # Support 128-bit long double, changable via command-line switch. + HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)' + ;; + + arm*-*-*) + TARGET=ARM; TARGETDIR=arm + ;; + + cris-*-*) + TARGET=LIBFFI_CRIS; TARGETDIR=cris + ;; + + frv-*-*) + TARGET=FRV; TARGETDIR=frv + ;; + + hppa*-*-linux* | parisc*-*-linux*) + TARGET=PA_LINUX; TARGETDIR=pa + ;; + hppa*64-*-hpux*) + TARGET=PA64_HPUX; TARGETDIR=pa + ;; + hppa*-*-hpux*) + TARGET=PA_HPUX; TARGETDIR=pa + ;; + + i?86-win32* | i?86-*-cygwin* | i?86-*-mingw*) + TARGET=X86_WIN32; TARGETDIR=x86 + ;; + i?86-*-darwin*) + TARGET=X86_DARWIN; TARGETDIR=x86 + ;; + i?86-*-*) + TARGET=X86; TARGETDIR=x86 + ;; + + ia64*-*-*) + TARGET=IA64; TARGETDIR=ia64 + ;; + + m32r*-*-*) + TARGET=M32R; TARGETDIR=m32r + ;; + + 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 AC_SUBST(AM_RUNTESTFLAGS) @@ -133,11 +188,13 @@ AC_CHECK_SIZEOF(double) AC_CHECK_SIZEOF(long double) # Also AC_SUBST this variable for ffi.h. -HAVE_LONG_DOUBLE=0 -if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then - if test $ac_cv_sizeof_long_double != 0; then - 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]) +if test -z "$HAVE_LONG_DOUBLE"; then + HAVE_LONG_DOUBLE=0 + if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then + if test $ac_cv_sizeof_long_double != 0; then + 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 AC_SUBST(HAVE_LONG_DOUBLE) diff --git a/libffi/include/ffi.h.in b/libffi/include/ffi.h.in index be32981d53f..bffe7ffc96d 100644 --- a/libffi/include/ffi.h.in +++ b/libffi/include/ffi.h.in @@ -82,6 +82,18 @@ extern "C" { # 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 # define ffi_type_uchar ffi_type_uint8 # define ffi_type_schar ffi_type_sint8 @@ -130,17 +142,6 @@ extern "C" { #error "long size not supported" #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 */ extern ffi_type ffi_type_void; extern ffi_type ffi_type_uint8; @@ -153,9 +154,14 @@ extern ffi_type ffi_type_uint64; extern ffi_type ffi_type_sint64; extern ffi_type ffi_type_float; extern ffi_type ffi_type_double; -extern ffi_type ffi_type_longdouble; 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 { FFI_OK = 0, @@ -342,4 +348,3 @@ void ffi_call(ffi_cif *cif, #endif #endif - diff --git a/libffi/src/alpha/ffi.c b/libffi/src/alpha/ffi.c index d139423f90e..cfa7b69e839 100644 --- a/libffi/src/alpha/ffi.c +++ b/libffi/src/alpha/ffi.c @@ -25,11 +25,22 @@ #include #include - #include -extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)()); -extern void ffi_closure_osf(void); +/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE; + 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 @@ -49,6 +60,11 @@ ffi_prep_cif_machdep(ffi_cif *cif) cif->flags = cif->rtype->type; break; + case FFI_TYPE_LONGDOUBLE: + /* 128-bit long double is returned in memory, like a struct. */ + cif->flags = FFI_TYPE_STRUCT; + break; + default: cif->flags = FFI_TYPE_INT; break; @@ -57,6 +73,7 @@ ffi_prep_cif_machdep(ffi_cif *cif) return FFI_OK; } + void 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; ffi_type **arg_types; - FFI_ASSERT (cif->abi == FFI_OSF); - /* If the return value is a struct and we don't have a return value address then we need to make one. */ if (rvalue == NULL && cif->flags == FFI_TYPE_STRUCT) @@ -84,6 +99,8 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) while (i < avn) { + size_t size = (*arg_types)->size; + switch ((*arg_types)->type) { case FFI_TYPE_SINT8: @@ -129,6 +146,12 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) *(double *) argp = *(double *)(* avalue); 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: memcpy(argp, *avalue, (*arg_types)->size); break; @@ -137,7 +160,7 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) 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++; } @@ -154,8 +177,6 @@ ffi_prep_closure_loc (ffi_closure* closure, { unsigned int *tramp; - FFI_ASSERT (cif->abi == FFI_OSF); - tramp = (unsigned int *) &closure->tramp[0]; tramp[0] = 0x47fb0401; /* mov $27,$1 */ tramp[1] = 0xa77b0010; /* ldq $27,16($27) */ @@ -178,7 +199,8 @@ ffi_prep_closure_loc (ffi_closure* closure, return FFI_OK; } -int + +long FFI_HIDDEN ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp) { ffi_cif *cif; @@ -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. */ while (i < avn) { + size_t size = arg_types[i]->size; + switch (arg_types[i]->type) { case FFI_TYPE_SINT8: @@ -237,16 +261,22 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp) avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)]; 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: - 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++; } /* 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. */ return cif->rtype->type; diff --git a/libffi/src/alpha/ffitarget.h b/libffi/src/alpha/ffitarget.h index 00a121718d7..9ec82dab1c5 100644 --- a/libffi/src/alpha/ffitarget.h +++ b/libffi/src/alpha/ffitarget.h @@ -33,8 +33,8 @@ typedef signed long ffi_sarg; typedef enum ffi_abi { FFI_FIRST_ABI = 0, FFI_OSF, - FFI_DEFAULT_ABI = FFI_OSF, - FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_OSF } ffi_abi; #endif @@ -45,4 +45,3 @@ typedef enum ffi_abi { #define FFI_NATIVE_RAW_API 0 #endif - diff --git a/libffi/src/alpha/osf.S b/libffi/src/alpha/osf.S index 2f03d627aa2..aba6782e794 100644 --- a/libffi/src/alpha/osf.S +++ b/libffi/src/alpha/osf.S @@ -1,10 +1,8 @@ /* ----------------------------------------------------------------------- - osf.S - Copyright (c) 1998, 2001 Red Hat + osf.S - Copyright (c) 1998, 2001, 2007 Red Hat 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 a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including @@ -42,6 +40,8 @@ .align 3 .globl ffi_call_osf .ent ffi_call_osf + FFI_HIDDEN(ffi_call_osf) + ffi_call_osf: .frame $15, 32, $26, 0 .mask 0x4008000, -32 @@ -129,6 +129,8 @@ $LFE1: .align 3 .globl ffi_closure_osf .ent ffi_closure_osf + FFI_HIDDEN(ffi_closure_osf) + ffi_closure_osf: .frame $30, 16*8, $26, 0 .mask 0x4000000, -16*8 @@ -265,7 +267,7 @@ $load_table: .gprel32 $load_32 # FFI_TYPE_INT .gprel32 $load_float # FFI_TYPE_FLOAT .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_s8 # FFI_TYPE_SINT8 .gprel32 $load_u16 # FFI_TYPE_UINT16 diff --git a/libffi/src/types.c b/libffi/src/types.c index b65787359fe..6d3048870c8 100644 --- a/libffi/src/types.c +++ b/libffi/src/types.c @@ -23,6 +23,10 @@ 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 #include @@ -33,14 +37,14 @@ struct struct_align_##name { \ char c; \ type x; \ }; \ -ffi_type ffi_type_##name = { \ +const ffi_type ffi_type_##name = { \ sizeof(type), \ offsetof(struct struct_align_##name, x), \ id, NULL \ } /* 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 }; @@ -57,4 +61,16 @@ FFI_TYPEDEF(pointer, void*, FFI_TYPE_POINTER); FFI_TYPEDEF(float, float, FFI_TYPE_FLOAT); 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); +#endif diff --git a/libffi/testsuite/libffi.call/float4.c b/libffi/testsuite/libffi.call/float4.c index febad5eb917..0dd6d85e7aa 100644 --- a/libffi/testsuite/libffi.call/float4.c +++ b/libffi/testsuite/libffi.call/float4.c @@ -5,6 +5,8 @@ Originator: From the original ffitest.c */ /* { dg-do run } */ +/* { dg-options "-mieee" { target alpha*-*-* } } */ + #include "ffitest.h" #include "float.h"