summaryrefslogtreecommitdiff
path: root/src/ia64
diff options
context:
space:
mode:
authorAnthony Green <green@moxielogic.com>2018-03-11 08:50:01 -0400
committerGitHub <noreply@github.com>2018-03-11 08:50:01 -0400
commitdca52b55bc2ac0213c20849d7e9e19fbc9202023 (patch)
tree0f149f28826bb14dd9fc7d777df7bea805066131 /src/ia64
parent83d9aba3a44dff8426052312a9445a7ef52f1db1 (diff)
parent11de69ddb788e4d87ef653898878384116ac16c6 (diff)
downloadlibffi-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.c30
-rw-r--r--src/ia64/ffitarget.h3
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
-