Commit bfb7d2dd authored by Neal Norwitz's avatar Neal Norwitz

Update to newer version of ffi. Fixes crashes and test failures of longdouble

parent 28d0aff3
...@@ -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 (*)(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 (*)(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), void *rvalue, void **avalue) ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{ {
...@@ -64,8 +81,6 @@ ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) ...@@ -64,8 +81,6 @@ ffi_call(ffi_cif *cif, void (*fn)(void), 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), void *rvalue, void **avalue) ...@@ -84,6 +99,8 @@ ffi_call(ffi_cif *cif, void (*fn)(void), 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), void *rvalue, void **avalue) ...@@ -129,6 +146,12 @@ ffi_call(ffi_cif *cif, void (*fn)(void), 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), void *rvalue, void **avalue) ...@@ -137,7 +160,7 @@ ffi_call(ffi_cif *cif, void (*fn)(void), 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++;
} }
...@@ -153,8 +176,6 @@ ffi_prep_closure (ffi_closure* closure, ...@@ -153,8 +176,6 @@ ffi_prep_closure (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) */
...@@ -177,7 +198,8 @@ ffi_prep_closure (ffi_closure* closure, ...@@ -177,7 +198,8 @@ ffi_prep_closure (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;
...@@ -205,6 +227,8 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp) ...@@ -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. */ /* 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:
...@@ -236,16 +260,22 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp) ...@@ -236,16 +260,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;
......
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
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.2 2006/03/03 20:24:26 theller 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
......
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