create separated versions of ffi_prep_incoming_args_* for SYSV and VFP ABIs.

The different versions will be called depending on the value of cif->abi
This commit is contained in:
David Schneider
2013-03-27 16:38:35 +01:00
parent dd26f1f39c
commit b41120981e
2 changed files with 52 additions and 6 deletions

View File

@@ -357,6 +357,9 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
void** args, ffi_cif* cif, float *vfp_stack);
static void ffi_prep_incoming_args_VFP (char *stack, void **ret,
void** args, ffi_cif* cif, float *vfp_stack);
void ffi_closure_SYSV (ffi_closure *);
void ffi_closure_VFP (ffi_closure *);
@@ -364,7 +367,7 @@ void ffi_closure_VFP (ffi_closure *);
/* This function is jumped to by the trampoline */
unsigned int
ffi_closure_SYSV_inner (closure, respp, args, vfp_args)
ffi_closure_inner (closure, respp, args, vfp_args)
ffi_closure *closure;
void **respp;
void *args;
@@ -382,8 +385,10 @@ ffi_closure_SYSV_inner (closure, respp, args, vfp_args)
* value on the stack; and if the function returns
* a structure, it will re-set RESP to point to the
* structure return address. */
ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif, vfp_args);
if (cif->abi == FFI_VFP)
ffi_prep_incoming_args_VFP(args, respp, arg_area, cif, vfp_args);
else
ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif, vfp_args);
(closure->fun) (cif, *respp, arg_area, closure->user_data);
@@ -397,6 +402,47 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
/* Used only under VFP hard-float ABI. */
float *vfp_stack)
/*@=exportheader@*/
{
register unsigned int i;
register void **p_argv;
register char *argp;
register ffi_type **p_arg;
argp = stack;
if ( cif->flags == FFI_TYPE_STRUCT ) {
*rvalue = *(void **) argp;
argp += 4;
}
p_argv = avalue;
for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
{
size_t z;
argp = ffi_align(p_arg, argp);
z = (*p_arg)->size;
/* because we're little endian, this is what it turns into. */
*p_argv = (void*) argp;
p_argv++;
argp += z;
}
return;
}
/*@-exportheader@*/
static void
ffi_prep_incoming_args_VFP(char *stack, void **rvalue,
void **avalue, ffi_cif *cif,
/* Used only under VFP hard-float ABI. */
float *vfp_stack)
/*@=exportheader@*/
{
register unsigned int i, vi = 0;
register void **p_argv;

View File

@@ -260,7 +260,7 @@ LSYM(Lepilogue):
/*
unsigned int FFI_HIDDEN
ffi_closure_SYSV_inner (closure, respp, args)
ffi_closure_inner (closure, respp, args)
ffi_closure *closure;
void **respp;
void *args;
@@ -276,7 +276,7 @@ ARM_FUNC_START ffi_closure_SYSV
sub sp, sp, #16
str sp, [sp, #8]
add r1, sp, #8
bl CNAME(ffi_closure_SYSV_inner)
bl CNAME(ffi_closure_inner)
cmp r0, #FFI_TYPE_INT
beq .Lretint
@@ -446,7 +446,7 @@ ARM_FUNC_START ffi_closure_VFP
sub sp, sp, #72
str sp, [sp, #64]
add r1, sp, #64
bl CNAME(ffi_closure_SYSV_inner)
bl CNAME(ffi_closure_inner)
cmp r0, #FFI_TYPE_INT
beq .Lretint_vfp