This is a backport from upstream libffi so get it working on ARM with and without VFP -Khem Index: mozilla-central/js/src/ctypes/libffi/src/arm/sysv.S =================================================================== --- mozilla-central.orig/js/src/ctypes/libffi/src/arm/sysv.S +++ mozilla-central/js/src/ctypes/libffi/src/arm/sysv.S @@ -1,5 +1,6 @@ /* ----------------------------------------------------------------------- - sysv.S - Copyright (c) 1998, 2008 Red Hat, Inc. + sysv.S - Copyright (c) 1998, 2008, 2011 Red Hat, Inc. + Copyright (c) 2011 Plausible Labs Cooperative, Inc. ARM Foreign Function Interface @@ -39,7 +40,11 @@ #else #define CNAME(x) x #endif +#ifdef __APPLE__ +#define ENTRY(x) .globl CNAME(x); CNAME(x): +#else #define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x): +#endif /* __APPLE__ */ #endif #ifdef __ELF__ @@ -48,6 +53,12 @@ #define LSYM(x) x #endif +/* Use the SOFTFP return value ABI on Mac OS X, as per the iOS ABI + Function Call Guide */ +#ifdef __APPLE__ +#define __SOFTFP__ +#endif + /* 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. @@ -105,21 +116,33 @@ .align 0 .thumb .thumb_func +#ifdef __APPLE__ + ENTRY($0) +#else 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. */ -_L__\name: +#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 @@ -141,8 +164,7 @@ _L__\name: #endif .endm - - @ r0: fn + @ r0: ffi_prep_args @ r1: &ecif @ r2: cif->bytes @ r3: fig->flags @@ -222,12 +244,98 @@ ARM_FUNC_START ffi_call_SYSV #endif LSYM(Lepilogue): - RETLDM "r0-r3,fp" +#if defined (__INTERWORKING__) + ldmia sp!, {r0-r3,fp, lr} + bx lr +#else + ldmia sp!, {r0-r3,fp, pc} +#endif .ffi_call_SYSV_end: UNWIND .fnend +#ifdef __ELF__ .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV) +#endif + + +/* + unsigned int FFI_HIDDEN + ffi_closure_SYSV_inner (closure, respp, args) + ffi_closure *closure; + void **respp; + void *args; +*/ + +ARM_FUNC_START ffi_closure_SYSV + UNWIND .pad #16 + add ip, sp, #16 + stmfd sp!, {ip, lr} + UNWIND .save {r0, lr} + add r2, sp, #8 + UNWIND .pad #16 + sub sp, sp, #16 + str sp, [sp, #8] + add r1, sp, #8 + bl CNAME(ffi_closure_SYSV_inner) + cmp r0, #FFI_TYPE_INT + beq .Lretint + + cmp r0, #FFI_TYPE_FLOAT +#if defined(__SOFTFP__) || defined(__ARM_EABI__) + beq .Lretint +#else + beq .Lretfloat +#endif + + cmp r0, #FFI_TYPE_DOUBLE +#if defined(__SOFTFP__) || defined(__ARM_EABI__) + beq .Lretlonglong +#else + beq .Lretdouble +#endif + + cmp r0, #FFI_TYPE_LONGDOUBLE +#if defined(__SOFTFP__) || defined(__ARM_EABI__) + beq .Lretlonglong +#else + beq .Lretlongdouble +#endif + + cmp r0, #FFI_TYPE_SINT64 + beq .Lretlonglong +.Lclosure_epilogue: + add sp, sp, #16 + ldmfd sp, {sp, pc} +.Lretint: + ldr r0, [sp] + b .Lclosure_epilogue +.Lretlonglong: + ldr r0, [sp] + ldr r1, [sp, #4] + b .Lclosure_epilogue +#if !defined(__SOFTFP__) && !defined(__ARM_EABI__) +.Lretfloat: + ldfs f0, [sp] + b .Lclosure_epilogue +.Lretdouble: + ldfd f0, [sp] + b .Lclosure_epilogue +.Lretlongdouble: + ldfd f0, [sp] + b .Lclosure_epilogue +#endif + +.ffi_closure_SYSV_end: + UNWIND .fnend +#ifdef __ELF__ + .size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV) +#endif + + +/* Below are VFP hard-float ABI call and closure implementations. + Add VFP FPU directive here. */ + .fpu vfp @ r0: fn @ r1: &ecif @@ -294,7 +402,7 @@ LSYM(Lbase_args): @ assume no return value. cmp r2, #0 beq LSYM(Lepilogue_vfp) - + cmp r3, #FFI_TYPE_INT streq r0, [r2] beq LSYM(Lepilogue_vfp) @@ -321,79 +429,6 @@ LSYM(Lepilogue_vfp): .ffi_call_VFP_end: UNWIND .fnend .size CNAME(ffi_call_VFP),.ffi_call_VFP_end-CNAME(ffi_call_VFP) - - -/* - unsigned int FFI_HIDDEN - ffi_closure_SYSV_inner (closure, respp, args) - ffi_closure *closure; - void **respp; - void *args; -*/ - -ARM_FUNC_START ffi_closure_SYSV - UNWIND .pad #16 - add ip, sp, #16 - stmfd sp!, {ip, lr} - UNWIND .save {r0, lr} - add r2, sp, #8 - .pad #16 - sub sp, sp, #16 - str sp, [sp, #8] - add r1, sp, #8 - bl ffi_closure_SYSV_inner - cmp r0, #FFI_TYPE_INT - beq .Lretint - - cmp r0, #FFI_TYPE_FLOAT -#if defined(__SOFTFP__) || defined(__ARM_EABI__) - beq .Lretint -#else - beq .Lretfloat -#endif - - cmp r0, #FFI_TYPE_DOUBLE -#if defined(__SOFTFP__) || defined(__ARM_EABI__) - beq .Lretlonglong -#else - beq .Lretdouble -#endif - - cmp r0, #FFI_TYPE_LONGDOUBLE -#if defined(__SOFTFP__) || defined(__ARM_EABI__) - beq .Lretlonglong -#else - beq .Lretlongdouble -#endif - - cmp r0, #FFI_TYPE_SINT64 - beq .Lretlonglong -.Lclosure_epilogue: - add sp, sp, #16 - ldmfd sp, {sp, pc} -.Lretint: - ldr r0, [sp] - b .Lclosure_epilogue -.Lretlonglong: - ldr r0, [sp] - ldr r1, [sp, #4] - b .Lclosure_epilogue - -#if !defined(__SOFTFP__) && !defined(__ARM_EABI__) -.Lretfloat: - ldfs f0, [sp] - b .Lclosure_epilogue -.Lretdouble: - ldfd f0, [sp] - b .Lclosure_epilogue -.Lretlongdouble: - ldfd f0, [sp] - b .Lclosure_epilogue -#endif - -.ffi_closure_SYSV_end: - UNWIND .fnend - .size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV) ARM_FUNC_START ffi_closure_VFP @@ -405,7 +440,7 @@ ARM_FUNC_START ffi_closure_VFP UNWIND .save {r0, lr} add r2, sp, #72 add r3, sp, #8 - .pad #72 + UNWIND .pad #72 sub sp, sp, #72 str sp, [sp, #64] add r1, sp, #64 @@ -460,3 +495,4 @@ ARM_FUNC_START ffi_closure_VFP #if defined __ELF__ && defined __linux__ .section .note.GNU-stack,"",%progbits #endif +