Merge pull request #406 from trofi/master

ia64: fix variadic function closures with FP arguments
This commit is contained in:
Anthony Green
2018-03-11 08:50:01 -04:00
committed by GitHub
2 changed files with 26 additions and 7 deletions

View File

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

View File

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