summaryrefslogtreecommitdiff
path: root/src/arm
diff options
context:
space:
mode:
authorAnthony Green <green@moxielogic.com>2013-12-05 16:23:25 -0500
committerAnthony Green <green@moxielogic.com>2013-12-05 16:23:25 -0500
commit3dc3f32c35db5ab995a835225f6815369735ceb7 (patch)
tree3ed261655ba53cd2269dba583d6f3bf561adb34d /src/arm
parent356b2cbc304bfe5bdc28b8d1c68d1ff084e9ec37 (diff)
downloadlibffi-3dc3f32c35db5ab995a835225f6815369735ceb7.tar.gz
Undo iOS ARM64 changes.
Diffstat (limited to 'src/arm')
-rw-r--r--src/arm/ffi.c63
-rw-r--r--src/arm/sysv.S99
2 files changed, 91 insertions, 71 deletions
diff --git a/src/arm/ffi.c b/src/arm/ffi.c
index e2a8380..e452a6e 100644
--- a/src/arm/ffi.c
+++ b/src/arm/ffi.c
@@ -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: ;
diff --git a/src/arm/sysv.S b/src/arm/sysv.S
index ef33fc9..454dfc9 100644
--- a/src/arm/sysv.S
+++ b/src/arm/sysv.S
@@ -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}