Merge pull request #406 from trofi/master
ia64: fix variadic function closures with FP arguments
This commit is contained in:
@@ -220,8 +220,8 @@ hfa_element_type (ffi_type *type, int nested)
|
|||||||
|
|
||||||
/* Perform machine dependent cif processing. */
|
/* Perform machine dependent cif processing. */
|
||||||
|
|
||||||
ffi_status
|
static ffi_status
|
||||||
ffi_prep_cif_machdep(ffi_cif *cif)
|
ffi_prep_cif_machdep_core(ffi_cif *cif)
|
||||||
{
|
{
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
@@ -271,6 +271,22 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
|||||||
return FFI_OK;
|
return FFI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ffi_status
|
||||||
|
ffi_prep_cif_machdep(ffi_cif *cif)
|
||||||
|
{
|
||||||
|
cif->nfixedargs = cif->nargs;
|
||||||
|
return ffi_prep_cif_machdep_core(cif);
|
||||||
|
}
|
||||||
|
|
||||||
|
ffi_status
|
||||||
|
ffi_prep_cif_machdep_var(ffi_cif *cif,
|
||||||
|
unsigned int nfixedargs,
|
||||||
|
unsigned int ntotalargs MAYBE_UNUSED)
|
||||||
|
{
|
||||||
|
cif->nfixedargs = nfixedargs;
|
||||||
|
return ffi_prep_cif_machdep_core(cif);
|
||||||
|
}
|
||||||
|
|
||||||
extern int ffi_call_unix (struct ia64_args *, PTR64, void (*)(void), UINT64);
|
extern int ffi_call_unix (struct ia64_args *, PTR64, void (*)(void), UINT64);
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -454,10 +470,11 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack,
|
|||||||
ffi_cif *cif;
|
ffi_cif *cif;
|
||||||
void **avalue;
|
void **avalue;
|
||||||
ffi_type **p_arg;
|
ffi_type **p_arg;
|
||||||
long i, avn, gpcount, fpcount;
|
long i, avn, gpcount, fpcount, nfixedargs;
|
||||||
|
|
||||||
cif = closure->cif;
|
cif = closure->cif;
|
||||||
avn = cif->nargs;
|
avn = cif->nargs;
|
||||||
|
nfixedargs = cif->nfixedargs;
|
||||||
avalue = alloca (avn * sizeof (void *));
|
avalue = alloca (avn * sizeof (void *));
|
||||||
|
|
||||||
/* If the structure return value is passed in memory get that location
|
/* If the structure return value is passed in memory get that location
|
||||||
@@ -468,6 +485,7 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack,
|
|||||||
gpcount = fpcount = 0;
|
gpcount = fpcount = 0;
|
||||||
for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
|
for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
|
||||||
{
|
{
|
||||||
|
int named = i < nfixedargs;
|
||||||
switch ((*p_arg)->type)
|
switch ((*p_arg)->type)
|
||||||
{
|
{
|
||||||
case FFI_TYPE_SINT8:
|
case FFI_TYPE_SINT8:
|
||||||
@@ -491,7 +509,7 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case FFI_TYPE_FLOAT:
|
case FFI_TYPE_FLOAT:
|
||||||
if (gpcount < 8 && fpcount < 8)
|
if (named && gpcount < 8 && fpcount < 8)
|
||||||
{
|
{
|
||||||
fpreg *addr = &stack->fp_regs[fpcount++];
|
fpreg *addr = &stack->fp_regs[fpcount++];
|
||||||
float result;
|
float result;
|
||||||
@@ -505,7 +523,7 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case FFI_TYPE_DOUBLE:
|
case FFI_TYPE_DOUBLE:
|
||||||
if (gpcount < 8 && fpcount < 8)
|
if (named && gpcount < 8 && fpcount < 8)
|
||||||
{
|
{
|
||||||
fpreg *addr = &stack->fp_regs[fpcount++];
|
fpreg *addr = &stack->fp_regs[fpcount++];
|
||||||
double result;
|
double result;
|
||||||
@@ -521,7 +539,7 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack,
|
|||||||
case FFI_TYPE_LONGDOUBLE:
|
case FFI_TYPE_LONGDOUBLE:
|
||||||
if (gpcount & 1)
|
if (gpcount & 1)
|
||||||
gpcount++;
|
gpcount++;
|
||||||
if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8)
|
if (LDBL_MANT_DIG == 64 && named && gpcount < 8 && fpcount < 8)
|
||||||
{
|
{
|
||||||
fpreg *addr = &stack->fp_regs[fpcount++];
|
fpreg *addr = &stack->fp_regs[fpcount++];
|
||||||
__float80 result;
|
__float80 result;
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ typedef enum ffi_abi {
|
|||||||
#define FFI_TRAMPOLINE_SIZE 24 /* Really the following struct, which */
|
#define FFI_TRAMPOLINE_SIZE 24 /* Really the following struct, which */
|
||||||
/* can be interpreted as a C function */
|
/* can be interpreted as a C function */
|
||||||
/* descriptor: */
|
/* descriptor: */
|
||||||
|
#define FFI_TARGET_SPECIFIC_VARIADIC 1
|
||||||
|
#define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user