diff options
author | Anthony Green <green@moxielogic.com> | 2013-12-05 16:23:25 -0500 |
---|---|---|
committer | Anthony Green <green@moxielogic.com> | 2013-12-05 16:23:25 -0500 |
commit | 3dc3f32c35db5ab995a835225f6815369735ceb7 (patch) | |
tree | 3ed261655ba53cd2269dba583d6f3bf561adb34d /src/arm | |
parent | 356b2cbc304bfe5bdc28b8d1c68d1ff084e9ec37 (diff) | |
download | libffi-3dc3f32c35db5ab995a835225f6815369735ceb7.tar.gz |
Undo iOS ARM64 changes.
Diffstat (limited to 'src/arm')
-rw-r--r-- | src/arm/ffi.c | 63 | ||||
-rw-r--r-- | src/arm/sysv.S | 99 |
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} |