diff options
author | Anthony Green <green@moxielogic.com> | 2018-03-11 08:50:01 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-11 08:50:01 -0400 |
commit | dca52b55bc2ac0213c20849d7e9e19fbc9202023 (patch) | |
tree | 0f149f28826bb14dd9fc7d777df7bea805066131 /src/ia64 | |
parent | 83d9aba3a44dff8426052312a9445a7ef52f1db1 (diff) | |
parent | 11de69ddb788e4d87ef653898878384116ac16c6 (diff) | |
download | libffi-dca52b55bc2ac0213c20849d7e9e19fbc9202023.tar.gz |
Merge pull request #406 from trofi/master
ia64: fix variadic function closures with FP arguments
Diffstat (limited to 'src/ia64')
-rw-r--r-- | src/ia64/ffi.c | 30 | ||||
-rw-r--r-- | src/ia64/ffitarget.h | 3 |
2 files changed, 26 insertions, 7 deletions
diff --git a/src/ia64/ffi.c b/src/ia64/ffi.c index b77a836..b1d04c3 100644 --- a/src/ia64/ffi.c +++ b/src/ia64/ffi.c @@ -220,8 +220,8 @@ hfa_element_type (ffi_type *type, int nested) /* Perform machine dependent cif processing. */ -ffi_status -ffi_prep_cif_machdep(ffi_cif *cif) +static ffi_status +ffi_prep_cif_machdep_core(ffi_cif *cif) { int flags; @@ -271,6 +271,22 @@ ffi_prep_cif_machdep(ffi_cif *cif) 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); void @@ -454,10 +470,11 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack, ffi_cif *cif; void **avalue; ffi_type **p_arg; - long i, avn, gpcount, fpcount; + long i, avn, gpcount, fpcount, nfixedargs; cif = closure->cif; avn = cif->nargs; + nfixedargs = cif->nfixedargs; avalue = alloca (avn * sizeof (void *)); /* 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; for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++) { + int named = i < nfixedargs; switch ((*p_arg)->type) { case FFI_TYPE_SINT8: @@ -491,7 +509,7 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack, break; case FFI_TYPE_FLOAT: - if (gpcount < 8 && fpcount < 8) + if (named && gpcount < 8 && fpcount < 8) { fpreg *addr = &stack->fp_regs[fpcount++]; float result; @@ -505,7 +523,7 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack, break; case FFI_TYPE_DOUBLE: - if (gpcount < 8 && fpcount < 8) + if (named && gpcount < 8 && fpcount < 8) { fpreg *addr = &stack->fp_regs[fpcount++]; double result; @@ -521,7 +539,7 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack, case FFI_TYPE_LONGDOUBLE: if (gpcount & 1) 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++]; __float80 result; diff --git a/src/ia64/ffitarget.h b/src/ia64/ffitarget.h index e68cea6..fd5b9a0 100644 --- a/src/ia64/ffitarget.h +++ b/src/ia64/ffitarget.h @@ -50,6 +50,7 @@ typedef enum ffi_abi { #define FFI_TRAMPOLINE_SIZE 24 /* Really the following struct, which */ /* can be interpreted as a C function */ /* descriptor: */ +#define FFI_TARGET_SPECIFIC_VARIADIC 1 +#define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs #endif - |