mirror of
https://github.com/partic2/libffi
synced 2026-11-10 10:07:19 +00:00
Undo iOS ARM64 changes.
This commit is contained in:
+30
-33
@@ -77,19 +77,19 @@ static size_t ffi_put_arg(ffi_type **arg_type, void **arg, char *stack)
|
||||
case FFI_TYPE_SINT8:
|
||||
*(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
|
||||
break;
|
||||
|
||||
|
||||
case FFI_TYPE_UINT8:
|
||||
*(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
|
||||
break;
|
||||
|
||||
|
||||
case FFI_TYPE_SINT16:
|
||||
*(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
|
||||
break;
|
||||
|
||||
|
||||
case FFI_TYPE_UINT16:
|
||||
*(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
|
||||
break;
|
||||
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
memcpy(argp, *p_argv, (*p_arg)->size);
|
||||
break;
|
||||
@@ -117,12 +117,11 @@ static size_t ffi_put_arg(ffi_type **arg_type, void **arg, char *stack)
|
||||
}
|
||||
/* ffi_prep_args is called by the assembly routine once stack space
|
||||
has been allocated for the function's arguments
|
||||
|
||||
|
||||
The vfp_space parameter is the load area for VFP regs, the return
|
||||
value is cif->vfp_used (word bitset of VFP regs used for passing
|
||||
arguments). These are only used for the VFP hard-float ABI.
|
||||
*/
|
||||
int ffi_prep_args_SYSV(char *stack, extended_cif *ecif, float *vfp_space);
|
||||
int ffi_prep_args_SYSV(char *stack, extended_cif *ecif, float *vfp_space)
|
||||
{
|
||||
register unsigned int i;
|
||||
@@ -130,7 +129,7 @@ int ffi_prep_args_SYSV(char *stack, extended_cif *ecif, float *vfp_space)
|
||||
register char *argp;
|
||||
register ffi_type **p_arg;
|
||||
argp = stack;
|
||||
|
||||
|
||||
|
||||
if ( ecif->cif->flags == FFI_TYPE_STRUCT ) {
|
||||
*(void **) argp = ecif->rvalue;
|
||||
@@ -150,7 +149,6 @@ int ffi_prep_args_SYSV(char *stack, extended_cif *ecif, float *vfp_space)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space);
|
||||
int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space)
|
||||
{
|
||||
// make sure we are using FFI_VFP
|
||||
@@ -162,13 +160,13 @@ int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space)
|
||||
register ffi_type **p_arg;
|
||||
char stack_used = 0;
|
||||
char done_with_regs = 0;
|
||||
int is_vfp_type;
|
||||
char is_vfp_type;
|
||||
|
||||
/* the first 4 words on the stack are used for values passed in core
|
||||
* registers. */
|
||||
regp = stack;
|
||||
eo_regp = argp = regp + 16;
|
||||
|
||||
|
||||
|
||||
/* if the function returns an FFI_TYPE_STRUCT in memory, that address is
|
||||
* passed in r0 to the function */
|
||||
@@ -196,7 +194,7 @@ int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space)
|
||||
else if (!done_with_regs && !is_vfp_type)
|
||||
{
|
||||
char *tregp = ffi_align(p_arg, regp);
|
||||
size_t size = (*p_arg)->size;
|
||||
size_t size = (*p_arg)->size;
|
||||
size = (size < 4)? 4 : size; // pad
|
||||
/* Check if there is space left in the aligned register area to place
|
||||
* the argument */
|
||||
@@ -208,10 +206,10 @@ int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space)
|
||||
FFI_ASSERT(regp <= argp);
|
||||
continue;
|
||||
}
|
||||
/* In case there are no arguments in the stack area yet,
|
||||
/* In case there are no arguments in the stack area yet,
|
||||
the argument is passed in the remaining core registers and on the
|
||||
stack. */
|
||||
else if (!stack_used)
|
||||
else if (!stack_used)
|
||||
{
|
||||
stack_used = 1;
|
||||
done_with_regs = 1;
|
||||
@@ -233,7 +231,7 @@ int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space)
|
||||
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
{
|
||||
int type_code;
|
||||
/* Round the stack up to a multiple of 8 bytes. This isn't needed
|
||||
/* Round the stack up to a multiple of 8 bytes. This isn't needed
|
||||
everywhere, but it is on some platforms, and it doesn't harm anything
|
||||
when it isn't needed. */
|
||||
cif->bytes = (cif->bytes + 7) & ~7;
|
||||
@@ -304,7 +302,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
{
|
||||
extended_cif ecif;
|
||||
|
||||
int small_struct = (cif->flags == FFI_TYPE_INT
|
||||
int small_struct = (cif->flags == FFI_TYPE_INT
|
||||
&& cif->rtype->type == FFI_TYPE_STRUCT);
|
||||
int vfp_struct = (cif->flags == FFI_TYPE_STRUCT_VFP_FLOAT
|
||||
|| cif->flags == FFI_TYPE_STRUCT_VFP_DOUBLE);
|
||||
@@ -317,7 +315,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
/* If the return value is a struct and we don't have a return */
|
||||
/* value address then we need to make one */
|
||||
|
||||
if ((rvalue == NULL) &&
|
||||
if ((rvalue == NULL) &&
|
||||
(cif->flags == FFI_TYPE_STRUCT))
|
||||
{
|
||||
ecif.rvalue = alloca(cif->rtype->size);
|
||||
@@ -332,7 +330,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
else
|
||||
ecif.rvalue = rvalue;
|
||||
|
||||
switch (cif->abi)
|
||||
switch (cif->abi)
|
||||
{
|
||||
case FFI_SYSV:
|
||||
ffi_call_SYSV (fn, &ecif, cif->bytes, cif->flags, ecif.rvalue);
|
||||
@@ -348,9 +346,9 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
FFI_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
if (small_struct && rvalue != NULL)
|
||||
if (small_struct)
|
||||
memcpy (rvalue, &temp, cif->rtype->size);
|
||||
else if (vfp_struct && rvalue != NULL)
|
||||
else if (vfp_struct)
|
||||
memcpy (rvalue, ecif.rvalue, cif->rtype->size);
|
||||
}
|
||||
|
||||
@@ -368,7 +366,6 @@ void ffi_closure_VFP (ffi_closure *);
|
||||
|
||||
/* This function is jumped to by the trampoline */
|
||||
|
||||
unsigned int ffi_closure_inner (ffi_closure *closure, void **respp, void *args, void *vfp_args);
|
||||
unsigned int
|
||||
ffi_closure_inner (ffi_closure *closure,
|
||||
void **respp, void *args, void *vfp_args)
|
||||
@@ -378,10 +375,10 @@ ffi_closure_inner (ffi_closure *closure,
|
||||
void **arg_area;
|
||||
|
||||
cif = closure->cif;
|
||||
arg_area = (void**) alloca (cif->nargs * sizeof (void*));
|
||||
arg_area = (void**) alloca (cif->nargs * sizeof (void*));
|
||||
|
||||
/* this call will initialize ARG_AREA, such that each
|
||||
* element in that array points to the corresponding
|
||||
* element in that array points to the corresponding
|
||||
* value on the stack; and if the function returns
|
||||
* a structure, it will re-set RESP to point to the
|
||||
* structure return address. */
|
||||
@@ -396,7 +393,7 @@ ffi_closure_inner (ffi_closure *closure,
|
||||
}
|
||||
|
||||
/*@-exportheader@*/
|
||||
static void
|
||||
static void
|
||||
ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
|
||||
void **avalue, ffi_cif *cif,
|
||||
/* Used only under VFP hard-float ABI. */
|
||||
@@ -432,12 +429,12 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
|
||||
p_argv++;
|
||||
argp += z;
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*@-exportheader@*/
|
||||
static void
|
||||
static void
|
||||
ffi_prep_incoming_args_VFP(char *stack, void **rvalue,
|
||||
void **avalue, ffi_cif *cif,
|
||||
/* Used only under VFP hard-float ABI. */
|
||||
@@ -450,7 +447,7 @@ ffi_prep_incoming_args_VFP(char *stack, void **rvalue,
|
||||
register ffi_type **p_arg;
|
||||
char done_with_regs = 0;
|
||||
char stack_used = 0;
|
||||
int is_vfp_type;
|
||||
char is_vfp_type;
|
||||
|
||||
FFI_ASSERT(cif->abi == FFI_VFP);
|
||||
regp = stack;
|
||||
@@ -466,7 +463,7 @@ ffi_prep_incoming_args_VFP(char *stack, void **rvalue,
|
||||
for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
|
||||
{
|
||||
size_t z;
|
||||
is_vfp_type = vfp_type_p (*p_arg);
|
||||
is_vfp_type = vfp_type_p (*p_arg);
|
||||
|
||||
if(vi < cif->vfp_nargs && is_vfp_type)
|
||||
{
|
||||
@@ -477,12 +474,12 @@ ffi_prep_incoming_args_VFP(char *stack, void **rvalue,
|
||||
{
|
||||
char* tregp = ffi_align(p_arg, regp);
|
||||
|
||||
z = (*p_arg)->size;
|
||||
z = (*p_arg)->size;
|
||||
z = (z < 4)? 4 : z; // pad
|
||||
|
||||
|
||||
/* if the arguments either fits into the registers or uses registers
|
||||
* and stack, while we haven't read other things from the stack */
|
||||
if(tregp + z <= eo_regp || !stack_used)
|
||||
if(tregp + z <= eo_regp || !stack_used)
|
||||
{
|
||||
/* because we're little endian, this is what it turns into. */
|
||||
*p_argv = (void*) tregp;
|
||||
@@ -521,7 +518,7 @@ ffi_prep_incoming_args_VFP(char *stack, void **rvalue,
|
||||
p_argv++;
|
||||
argp += z;
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -884,7 +881,7 @@ static int place_vfp_arg (ffi_cif *cif, ffi_type *t)
|
||||
}
|
||||
/* Found regs to allocate. */
|
||||
cif->vfp_used |= new_used;
|
||||
cif->vfp_args[cif->vfp_nargs++] = (typeof(*(cif->vfp_args)))reg;
|
||||
cif->vfp_args[cif->vfp_nargs++] = reg;
|
||||
|
||||
/* Update vfp_reg_free. */
|
||||
if (cif->vfp_used & (1 << cif->vfp_reg_free))
|
||||
@@ -892,7 +889,7 @@ static int place_vfp_arg (ffi_cif *cif, ffi_type *t)
|
||||
reg += nregs;
|
||||
while (cif->vfp_used & (1 << reg))
|
||||
reg += 1;
|
||||
cif->vfp_reg_free = (typeof(cif->vfp_reg_free))reg;
|
||||
cif->vfp_reg_free = reg;
|
||||
}
|
||||
return 0;
|
||||
next_reg: ;
|
||||
|
||||
+61
-38
@@ -1,8 +1,8 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
sysv.S - Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
|
||||
Copyright (c) 2011 Plausible Labs Cooperative, Inc.
|
||||
|
||||
ARM Foreign Function Interface
|
||||
|
||||
ARM Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
@@ -25,7 +25,7 @@
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#define LIBFFI_ASM
|
||||
#define LIBFFI_ASM
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
#ifdef HAVE_MACHINE_ASM_H
|
||||
@@ -59,7 +59,7 @@
|
||||
#define __SOFTFP__
|
||||
#endif
|
||||
|
||||
/* We need a better way of testing for this, but for now, this is all
|
||||
/* We need a better way of testing for this, but for now, this is all
|
||||
we can do. */
|
||||
@ This selects the minimum architecture level required.
|
||||
#define __ARM_ARCH__ 3
|
||||
@@ -68,7 +68,7 @@
|
||||
# undef __ARM_ARCH__
|
||||
# define __ARM_ARCH__ 4
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
|
||||
|| defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
|
||||
|| defined(__ARM_ARCH_5TEJ__)
|
||||
@@ -107,37 +107,60 @@
|
||||
#define UNWIND
|
||||
#else
|
||||
#define UNWIND @
|
||||
#endif
|
||||
|
||||
.syntax unified
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
|
||||
#define ARM_FUNC_START(name) \
|
||||
.text; \
|
||||
.align 2; \
|
||||
.thumb; \
|
||||
.thumb_func; \
|
||||
ENTRY(name); \
|
||||
bx pc; \
|
||||
nop; \
|
||||
.arm; \
|
||||
UNWIND .fnstart; \
|
||||
_L__##name:
|
||||
.macro ARM_FUNC_START name
|
||||
.text
|
||||
.align 0
|
||||
.thumb
|
||||
.thumb_func
|
||||
#ifdef __APPLE__
|
||||
ENTRY($0)
|
||||
#else
|
||||
#define ARM_FUNC_START(name) \
|
||||
.text; \
|
||||
.align 2; \
|
||||
.arm; \
|
||||
ENTRY(name); \
|
||||
ENTRY(\name)
|
||||
#endif
|
||||
bx pc
|
||||
nop
|
||||
.arm
|
||||
UNWIND .fnstart
|
||||
/* A hook to tell gdb that we've switched to ARM mode. Also used to call
|
||||
directly from other local arm routines. */
|
||||
#ifdef __APPLE__
|
||||
_L__$0:
|
||||
#else
|
||||
_L__\name:
|
||||
#endif
|
||||
.endm
|
||||
#else
|
||||
.macro ARM_FUNC_START name
|
||||
.text
|
||||
.align 0
|
||||
.arm
|
||||
#ifdef __APPLE__
|
||||
ENTRY($0)
|
||||
#else
|
||||
ENTRY(\name)
|
||||
#endif
|
||||
UNWIND .fnstart
|
||||
.endm
|
||||
#endif
|
||||
|
||||
.macro RETLDM
|
||||
.macro RETLDM regs=, cond=, dirn=ia
|
||||
#if defined (__INTERWORKING__)
|
||||
ldr lr, [sp], #4
|
||||
bx lr
|
||||
.ifc "\regs",""
|
||||
ldr\cond lr, [sp], #4
|
||||
.else
|
||||
ldm\cond\dirn sp!, {\regs, lr}
|
||||
.endif
|
||||
bx\cond lr
|
||||
#else
|
||||
ldr pc, [sp], #4
|
||||
.ifc "\regs",""
|
||||
ldr\cond pc, [sp], #4
|
||||
.else
|
||||
ldm\cond\dirn sp!, {\regs, pc}
|
||||
.endif
|
||||
#endif
|
||||
.endm
|
||||
|
||||
@@ -148,7 +171,7 @@ _L__##name:
|
||||
@ sp+0: ecif.rvalue
|
||||
|
||||
@ This assumes we are using gas.
|
||||
ARM_FUNC_START(ffi_call_SYSV)
|
||||
ARM_FUNC_START ffi_call_SYSV
|
||||
@ Save registers
|
||||
stmfd sp!, {r0-r3, fp, lr}
|
||||
UNWIND .save {r0-r3, fp, lr}
|
||||
@@ -178,14 +201,14 @@ ARM_FUNC_START(ffi_call_SYSV)
|
||||
|
||||
@ call (fn) (...)
|
||||
call_reg(ip)
|
||||
|
||||
|
||||
@ Remove the space we pushed for the args
|
||||
mov sp, fp
|
||||
|
||||
@ Load r2 with the pointer to storage for the return value
|
||||
ldr r2, [sp, #24]
|
||||
|
||||
@ Load r3 with the return type code
|
||||
@ Load r3 with the return type code
|
||||
ldr r3, [sp, #12]
|
||||
|
||||
@ If the return value pointer is NULL, assume no return value.
|
||||
@@ -205,7 +228,7 @@ ARM_FUNC_START(ffi_call_SYSV)
|
||||
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
|
||||
cmpne r3, #FFI_TYPE_DOUBLE
|
||||
#endif
|
||||
stmiaeq r2, {r0, r1}
|
||||
stmeqia r2, {r0, r1}
|
||||
|
||||
#if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
|
||||
beq LSYM(Lepilogue)
|
||||
@@ -243,7 +266,7 @@ LSYM(Lepilogue):
|
||||
void *args;
|
||||
*/
|
||||
|
||||
ARM_FUNC_START(ffi_closure_SYSV)
|
||||
ARM_FUNC_START ffi_closure_SYSV
|
||||
UNWIND .pad #16
|
||||
add ip, sp, #16
|
||||
stmfd sp!, {ip, lr}
|
||||
@@ -322,7 +345,7 @@ ARM_FUNC_START(ffi_closure_SYSV)
|
||||
@ r3: fig->flags
|
||||
@ sp+0: ecif.rvalue
|
||||
|
||||
ARM_FUNC_START(ffi_call_VFP)
|
||||
ARM_FUNC_START ffi_call_VFP
|
||||
@ Save registers
|
||||
stmfd sp!, {r0-r3, fp, lr}
|
||||
UNWIND .save {r0-r3, fp, lr}
|
||||
@@ -374,7 +397,7 @@ LSYM(Lbase_args):
|
||||
@ the return value
|
||||
ldr r2, [sp, #24]
|
||||
|
||||
@ Load r3 with the return type code
|
||||
@ Load r3 with the return type code
|
||||
ldr r3, [sp, #12]
|
||||
|
||||
@ If the return value pointer is NULL,
|
||||
@@ -393,7 +416,7 @@ LSYM(Lbase_args):
|
||||
cmp r3, #FFI_TYPE_FLOAT
|
||||
fstseq s0, [r2]
|
||||
beq LSYM(Lepilogue_vfp)
|
||||
|
||||
|
||||
cmp r3, #FFI_TYPE_DOUBLE
|
||||
fstdeq d0, [r2]
|
||||
beq LSYM(Lepilogue_vfp)
|
||||
@@ -410,7 +433,7 @@ LSYM(Lepilogue_vfp):
|
||||
.size CNAME(ffi_call_VFP),.ffi_call_VFP_end-CNAME(ffi_call_VFP)
|
||||
|
||||
|
||||
ARM_FUNC_START(ffi_closure_VFP)
|
||||
ARM_FUNC_START ffi_closure_VFP
|
||||
fstmfdd sp!, {d0-d7}
|
||||
@ r0-r3, then d0-d7
|
||||
UNWIND .pad #80
|
||||
@@ -443,7 +466,7 @@ ARM_FUNC_START(ffi_closure_VFP)
|
||||
|
||||
cmp r0, #FFI_TYPE_STRUCT_VFP_DOUBLE
|
||||
beq .Lretdouble_struct_vfp
|
||||
|
||||
|
||||
.Lclosure_epilogue_vfp:
|
||||
add sp, sp, #72
|
||||
ldmfd sp, {sp, pc}
|
||||
|
||||
Reference in New Issue
Block a user