diff options
author | Richard Henderson <rth@redhat.com> | 2007-04-06 09:24:16 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2007-04-06 09:24:16 -0700 |
commit | bf8da5fc773ea73ed3558f88ad3758ecf119d61f (patch) | |
tree | 430f3d3b8444386a212bcbe6f9a70261cfb97d01 /libffi/src/alpha/ffi.c | |
parent | 8fbba42a965310642c0c893c640b2a86f1b6dd9e (diff) | |
download | gcc-bf8da5fc773ea73ed3558f88ad3758ecf119d61f.zip gcc-bf8da5fc773ea73ed3558f88ad3758ecf119d61f.tar.gz gcc-bf8da5fc773ea73ed3558f88ad3758ecf119d61f.tar.bz2 |
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
Diffstat (limited to 'libffi/src/alpha/ffi.c')
-rw-r--r-- | libffi/src/alpha/ffi.c | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/libffi/src/alpha/ffi.c b/libffi/src/alpha/ffi.c index d139423..cfa7b69 100644 --- a/libffi/src/alpha/ffi.c +++ b/libffi/src/alpha/ffi.c @@ -25,11 +25,22 @@ #include <ffi.h> #include <ffi_common.h> - #include <stdlib.h> -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; |