configure.ac (alpha*-*-*): Define HAVE_LONG_DOUBLE.

* configure.ac (alpha*-*-*): Define HAVE_LONG_DOUBLE.
        * configure: Regenerate.
        * include/ffi.h.in (ffi_type_longdouble): Define as ffi_type_double
        if HAVE_LONG_DOUBLE is false.
        * src/alpha/ffi.c (ffi_prep_cif_machdep): Support the 128-bit
        long double type.
        (ffi_call_osf, ffi_closure_osf): Likewise.
        * src/alpha/osf.S (ffi_call_osf, ffi_closure_osf): Mark hidden.
        * src/types.c (ffi_type_longdouble): For alpha, always generate
        for the 128-bit long double type.

From-SVN: r124004
This commit is contained in:
Richard Henderson
2007-04-20 13:35:37 -07:00
committed by Richard Henderson
parent 3e8a9f09b6
commit 6ee3e65a4c
7 changed files with 102 additions and 28 deletions

View File

@@ -1,3 +1,16 @@
2007-04-20 Richard Henderson <rth@redhat.com>
* configure.ac (alpha*-*-*): Define HAVE_LONG_DOUBLE.
* configure: Regenerate.
* include/ffi.h.in (ffi_type_longdouble): Define as ffi_type_double
if HAVE_LONG_DOUBLE is false.
* src/alpha/ffi.c (ffi_prep_cif_machdep): Support the 128-bit
long double type.
(ffi_call_osf, ffi_closure_osf): Likewise.
* src/alpha/osf.S (ffi_call_osf, ffi_closure_osf): Mark hidden.
* src/types.c (ffi_type_longdouble): For alpha, always generate
for the 128-bit long double type.
2007-02-13 Andreas Krebbel <krebbel1@de.ibm.com>
* src/s390/ffi.c (ffi_prep_args, ffi_prep_cif_machdep,

16
libffi/configure vendored
View File

@@ -5401,7 +5401,11 @@ 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;;
alpha*-*-linux* | alpha*-*-osf* | alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu | alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu)
TARGET=ALPHA; TARGETDIR=alpha
# Support 128-bit long double, changable via command-line switch.
HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
;;
ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;;
m32r*-*-linux* ) TARGET=M32R; TARGETDIR=m32r;;
m68k-*-linux*) TARGET=M68K; TARGETDIR=m68k;;
@@ -7142,15 +7146,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

View File

@@ -59,7 +59,11 @@ 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;;
alpha*-*-linux* | alpha*-*-osf* | alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu | alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu)
TARGET=ALPHA; TARGETDIR=alpha
# Support 128-bit long double, changable via command-line switch.
HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
;;
ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;;
m32r*-*-linux* ) TARGET=M32R; TARGETDIR=m32r;;
m68k-*-linux*) TARGET=M68K; TARGETDIR=m68k;;
@@ -132,11 +136,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)

View File

@@ -153,9 +153,13 @@ 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
typedef enum {
FFI_OK = 0,

View File

@@ -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++;
}
@@ -153,8 +176,6 @@ ffi_prep_closure (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) */
@@ -177,7 +198,8 @@ ffi_prep_closure (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;
@@ -205,6 +227,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:
@@ -236,16 +260,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;

View File

@@ -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

View File

@@ -57,4 +57,17 @@ 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
# undef ffi_type_longdouble
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