diff options
Diffstat (limited to 'libffi/src/powerpc')
-rw-r--r-- | libffi/src/powerpc/aix.S | 12 | ||||
-rw-r--r-- | libffi/src/powerpc/darwin.S | 9 | ||||
-rw-r--r-- | libffi/src/powerpc/darwin_closure.S | 35 | ||||
-rw-r--r-- | libffi/src/powerpc/ffi.c | 40 | ||||
-rw-r--r-- | libffi/src/powerpc/ffi_darwin.c | 10 | ||||
-rw-r--r-- | libffi/src/powerpc/ffi_linux64.c | 25 | ||||
-rw-r--r-- | libffi/src/powerpc/ffi_powerpc.h | 29 | ||||
-rw-r--r-- | libffi/src/powerpc/ffi_sysv.c | 33 | ||||
-rw-r--r-- | libffi/src/powerpc/ffitarget.h | 26 | ||||
-rw-r--r-- | libffi/src/powerpc/linux64.S | 73 | ||||
-rw-r--r-- | libffi/src/powerpc/linux64_closure.S | 202 | ||||
-rw-r--r-- | libffi/src/powerpc/ppc_closure.S | 165 | ||||
-rw-r--r-- | libffi/src/powerpc/sysv.S | 149 |
13 files changed, 450 insertions, 358 deletions
diff --git a/libffi/src/powerpc/aix.S b/libffi/src/powerpc/aix.S index 213f2db39de..349e78c266e 100644 --- a/libffi/src/powerpc/aix.S +++ b/libffi/src/powerpc/aix.S @@ -137,7 +137,7 @@ ffi_call_AIX: mtcrf 0x40, r31 mtctr r0 /* Load all those argument registers. */ - // We have set up a nice stack frame, just load it into registers. + /* We have set up a nice stack frame, just load it into registers. */ ld r3, 40+(1*8)(r1) ld r4, 40+(2*8)(r1) ld r5, 40+(3*8)(r1) @@ -150,7 +150,7 @@ ffi_call_AIX: L1: /* Load all the FP registers. */ - bf 6,L2 // 2f + 0x18 + bf 6,L2 /* 2f + 0x18 */ lfd f1,-32-(13*8)(r28) lfd f2,-32-(12*8)(r28) lfd f3,-32-(11*8)(r28) @@ -239,7 +239,7 @@ L(float_return_value): mtcrf 0x40, r31 mtctr r0 /* Load all those argument registers. */ - // We have set up a nice stack frame, just load it into registers. + /* We have set up a nice stack frame, just load it into registers. */ lwz r3, 20+(1*4)(r1) lwz r4, 20+(2*4)(r1) lwz r5, 20+(3*4)(r1) @@ -252,7 +252,7 @@ L(float_return_value): L1: /* Load all the FP registers. */ - bf 6,L2 // 2f + 0x18 + bf 6,L2 /* 2f + 0x18 */ lfd f1,-16-(13*8)(r28) lfd f2,-16-(12*8)(r28) lfd f3,-16-(11*8)(r28) @@ -307,7 +307,7 @@ L(float_return_value): #endif .long 0 .byte 0,0,0,1,128,4,0,0 -//END(ffi_call_AIX) +/* END(ffi_call_AIX) */ .csect .text[PR] .align 2 @@ -325,4 +325,4 @@ ffi_call_DARWIN: blr .long 0 .byte 0,0,0,0,0,0,0,0 -//END(ffi_call_DARWIN) +/* END(ffi_call_DARWIN) */ diff --git a/libffi/src/powerpc/darwin.S b/libffi/src/powerpc/darwin.S index 4f987dc7482..066eb82efe9 100644 --- a/libffi/src/powerpc/darwin.S +++ b/libffi/src/powerpc/darwin.S @@ -318,11 +318,6 @@ _ffi_call_AIX: #define EH_DATA_ALIGN_FACT MODE_CHOICE(0x7c,0x78) - .static_data - .align LOG2_GPR_BYTES -LLFB0$non_lazy_ptr: - .g_long Lstartcode - .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support EH_frame1: .set L$set$0,LECIE1-LSCIE1 @@ -335,7 +330,7 @@ LSCIE1: .byte EH_DATA_ALIGN_FACT ; sleb128 -4; CIE Data Alignment Factor .byte 0x41 ; CIE RA Column .byte 0x1 ; uleb128 0x1; Augmentation size - .byte 0x10 ; FDE Encoding (indirect pcrel) + .byte 0x10 ; FDE Encoding (pcrel) .byte 0xc ; DW_CFA_def_cfa .byte 0x1 ; uleb128 0x1 .byte 0x0 ; uleb128 0x0 @@ -349,7 +344,7 @@ LSFDE1: .long L$set$1 ; FDE Length LASFDE1: .long LASFDE1-EH_frame1 ; FDE CIE offset - .g_long LLFB0$non_lazy_ptr-. ; FDE initial location + .g_long Lstartcode-. ; FDE initial location .set L$set$3,LFE1-Lstartcode .g_long L$set$3 ; FDE address range .byte 0x0 ; uleb128 0x0; Augmentation size diff --git a/libffi/src/powerpc/darwin_closure.S b/libffi/src/powerpc/darwin_closure.S index 3f6790f6bb3..c7734d41986 100644 --- a/libffi/src/powerpc/darwin_closure.S +++ b/libffi/src/powerpc/darwin_closure.S @@ -192,7 +192,7 @@ LCFI1: lg r0,0(r3) ; size => r0 lhz r3,FFI_TYPE_TYPE(r3) ; type => r3 - /* The helper will have intercepted struture returns and inserted + /* The helper will have intercepted structure returns and inserted the caller`s destination address for structs returned by ref. */ /* r3 contains the return type so use it to look up in a table @@ -467,11 +467,6 @@ Lendcode: #define EH_FRAME_OFFSETA MODE_CHOICE(176,0x90) #define EH_FRAME_OFFSETB MODE_CHOICE(1,3) - .static_data - .align LOG2_GPR_BYTES -LLFB1$non_lazy_ptr: - .g_long Lstartcode - .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support EH_frame1: .set L$set$0,LECIE1-LSCIE1 @@ -484,7 +479,7 @@ LSCIE1: .byte EH_DATA_ALIGN_FACT ; sleb128 -4; CIE Data Alignment Factor .byte 0x41 ; CIE RA Column .byte 0x1 ; uleb128 0x1; Augmentation size - .byte 0x10 ; FDE Encoding (indirect pcrel) + .byte 0x10 ; FDE Encoding (pcrel) .byte 0xc ; DW_CFA_def_cfa .byte 0x1 ; uleb128 0x1 .byte 0x0 ; uleb128 0x0 @@ -498,7 +493,7 @@ LSFDE1: LASFDE1: .long LASFDE1-EH_frame1 ; FDE CIE offset - .g_long LLFB1$non_lazy_ptr-. ; FDE initial location + .g_long Lstartcode-. ; FDE initial location .set L$set$3,LFE1-Lstartcode .g_long L$set$3 ; FDE address range .byte 0x0 ; uleb128 0x0; Augmentation size @@ -523,12 +518,12 @@ LEFDE1: L_ffi_closure_helper_DARWIN$stub: .indirect_symbol _ffi_closure_helper_DARWIN mflr r0 - bcl 20,31,"L00000000001$spb" -"L00000000001$spb": + bcl 20,31,"L1$spb" +"L1$spb": mflr r11 - addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L00000000001$spb") + addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L1$spb") mtlr r0 - lwzu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L00000000001$spb")(r11) + lwzu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L1$spb")(r11) mtctr r12 bctr .lazy_symbol_pointer @@ -542,12 +537,12 @@ L_ffi_closure_helper_DARWIN$lazy_ptr: L_darwin64_struct_ret_by_value_p$stub: .indirect_symbol _darwin64_struct_ret_by_value_p mflr r0 - bcl 20,31,"L00000000002$spb" -"L00000000002$spb": + bcl 20,31,"L2$spb" +"L2$spb": mflr r11 - addis r11,r11,ha16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L00000000002$spb") + addis r11,r11,ha16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L2$spb") mtlr r0 - lwzu r12,lo16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L00000000002$spb")(r11) + lwzu r12,lo16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L2$spb")(r11) mtctr r12 bctr .lazy_symbol_pointer @@ -560,12 +555,12 @@ L_darwin64_struct_ret_by_value_p$lazy_ptr: L_darwin64_pass_struct_floats$stub: .indirect_symbol _darwin64_pass_struct_floats mflr r0 - bcl 20,31,"L00000000003$spb" -"L00000000003$spb": + bcl 20,31,"L3$spb" +"L3$spb": mflr r11 - addis r11,r11,ha16(L_darwin64_pass_struct_floats$lazy_ptr-"L00000000003$spb") + addis r11,r11,ha16(L_darwin64_pass_struct_floats$lazy_ptr-"L3$spb") mtlr r0 - lwzu r12,lo16(L_darwin64_pass_struct_floats$lazy_ptr-"L00000000003$spb")(r11) + lwzu r12,lo16(L_darwin64_pass_struct_floats$lazy_ptr-"L3$spb")(r11) mtctr r12 bctr .lazy_symbol_pointer diff --git a/libffi/src/powerpc/ffi.c b/libffi/src/powerpc/ffi.c index efb441bbfc0..7eb543e4b3b 100644 --- a/libffi/src/powerpc/ffi.c +++ b/libffi/src/powerpc/ffi.c @@ -70,8 +70,12 @@ ffi_prep_cif_machdep_var (ffi_cif *cif, #endif } -void -ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +static void +ffi_call_int (ffi_cif *cif, + void (*fn) (void), + void *rvalue, + void **avalue, + void *closure) { /* The final SYSV ABI says that structures smaller or equal 8 bytes are returned in r3/r4. A draft ABI used by linux instead returns @@ -97,9 +101,10 @@ ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) ecif.rvalue = alloca (cif->rtype->size); #ifdef POWERPC64 - ffi_call_LINUX64 (&ecif, -(long) cif->bytes, cif->flags, ecif.rvalue, fn); + ffi_call_LINUX64 (&ecif, fn, ecif.rvalue, cif->flags, closure, + -(long) cif->bytes); #else - ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn); + ffi_call_SYSV (&ecif, fn, ecif.rvalue, cif->flags, closure, -cif->bytes); #endif /* Check for a bounce-buffered return value */ @@ -125,6 +130,18 @@ ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) } } +void +ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue) +{ + ffi_call_int (cif, fn, rvalue, avalue, NULL); +} + +void +ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue, + void *closure) +{ + ffi_call_int (cif, fn, rvalue, avalue, closure); +} ffi_status ffi_prep_closure_loc (ffi_closure *closure, @@ -139,3 +156,18 @@ ffi_prep_closure_loc (ffi_closure *closure, return ffi_prep_closure_loc_sysv (closure, cif, fun, user_data, codeloc); #endif } + +ffi_status +ffi_prep_go_closure (ffi_go_closure *closure, + ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *)) +{ +#ifdef POWERPC64 + closure->tramp = ffi_go_closure_linux64; +#else + closure->tramp = ffi_go_closure_sysv; +#endif + closure->cif = cif; + closure->fun = fun; + return FFI_OK; +} diff --git a/libffi/src/powerpc/ffi_darwin.c b/libffi/src/powerpc/ffi_darwin.c index dd897f4c631..cf6fb6d4b7c 100644 --- a/libffi/src/powerpc/ffi_darwin.c +++ b/libffi/src/powerpc/ffi_darwin.c @@ -302,10 +302,10 @@ ffi_prep_args (extended_cif *ecif, unsigned long *const stack) } /* Check that we didn't overrun the stack... */ - //FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS); - //FFI_ASSERT((unsigned *)fpr_base - // <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS); - //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4); + /* FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS); + FFI_ASSERT((unsigned *)fpr_base + <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS); + FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4); */ } #if defined(POWERPC_DARWIN64) @@ -593,7 +593,7 @@ darwin_adjust_aggregate_sizes (ffi_type *s) /* Natural alignment for all items. */ align = p->alignment; #else - /* Natrual alignment for the first item... */ + /* Natural alignment for the first item... */ if (i == 0) align = p->alignment; else if (p->alignment == 16 || p->alignment < 4) diff --git a/libffi/src/powerpc/ffi_linux64.c b/libffi/src/powerpc/ffi_linux64.c index 33f24b327b6..b84b91fb237 100644 --- a/libffi/src/powerpc/ffi_linux64.c +++ b/libffi/src/powerpc/ffi_linux64.c @@ -667,7 +667,8 @@ flush_icache (char *wraddr, char *xaddr, int size) } #endif -ffi_status + +ffi_status FFI_HIDDEN ffi_prep_closure_loc_linux64 (ffi_closure *closure, ffi_cif *cif, void (*fun) (ffi_cif *, void *, void **, void *), @@ -688,16 +689,17 @@ ffi_prep_closure_loc_linux64 (ffi_closure *closure, /* 2: .quad context */ *(void **) &tramp[4] = (void *) ffi_closure_LINUX64; *(void **) &tramp[6] = codeloc; - flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE); + flush_icache ((char *) tramp, (char *) codeloc, 4 * 4); #else void **tramp = (void **) &closure->tramp[0]; if (cif->abi < FFI_LINUX || cif->abi >= FFI_LAST_ABI) return FFI_BAD_ABI; - /* Copy function address and TOC from ffi_closure_LINUX64. */ - memcpy (tramp, (char *) ffi_closure_LINUX64, 16); - tramp[2] = codeloc; + /* Copy function address and TOC from ffi_closure_LINUX64 OPD. */ + memcpy (&tramp[0], (void **) ffi_closure_LINUX64, sizeof (void *)); + tramp[1] = codeloc; + memcpy (&tramp[2], (void **) ffi_closure_LINUX64 + 1, sizeof (void *)); #endif closure->cif = cif; @@ -709,8 +711,12 @@ ffi_prep_closure_loc_linux64 (ffi_closure *closure, int FFI_HIDDEN -ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue, - unsigned long *pst, ffi_dblfl *pfr) +ffi_closure_helper_LINUX64 (ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, + void *rvalue, + unsigned long *pst, + ffi_dblfl *pfr) { /* rvalue is the pointer to space for return value in closure assembly */ /* pst is the pointer to parameter save area @@ -720,11 +726,9 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue, void **avalue; ffi_type **arg_types; unsigned long i, avn, nfixedargs; - ffi_cif *cif; ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64; unsigned long align; - cif = closure->cif; avalue = alloca (cif->nargs * sizeof (void *)); /* Copy the caller's structure return value address so that the @@ -924,8 +928,7 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue, i++; } - - (closure->fun) (cif, rvalue, avalue, closure->user_data); + (*fun) (cif, rvalue, avalue, user_data); /* Tell ffi_closure_LINUX64 how to perform return type promotions. */ if ((cif->flags & FLAG_RETURNS_SMST) != 0) diff --git a/libffi/src/powerpc/ffi_powerpc.h b/libffi/src/powerpc/ffi_powerpc.h index 2e61653d1a7..3dcd6b57175 100644 --- a/libffi/src/powerpc/ffi_powerpc.h +++ b/libffi/src/powerpc/ffi_powerpc.h @@ -56,22 +56,39 @@ typedef union } ffi_dblfl; void FFI_HIDDEN ffi_closure_SYSV (void); -void FFI_HIDDEN ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *, - void (*)(void)); +void FFI_HIDDEN ffi_go_closure_sysv (void); +void FFI_HIDDEN ffi_call_SYSV(extended_cif *, void (*)(void), void *, + unsigned, void *, int); void FFI_HIDDEN ffi_prep_types_sysv (ffi_abi); ffi_status FFI_HIDDEN ffi_prep_cif_sysv (ffi_cif *); -int FFI_HIDDEN ffi_closure_helper_SYSV (ffi_closure *, void *, unsigned long *, +ffi_status FFI_HIDDEN ffi_prep_closure_loc_sysv (ffi_closure *, + ffi_cif *, + void (*) (ffi_cif *, void *, + void **, void *), + void *, void *); +int FFI_HIDDEN ffi_closure_helper_SYSV (ffi_cif *, + void (*) (ffi_cif *, void *, + void **, void *), + void *, void *, unsigned long *, ffi_dblfl *, unsigned long *); -void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long, unsigned long, - unsigned long *, void (*)(void)); +void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, void (*) (void), void *, + unsigned long, void *, long); void FFI_HIDDEN ffi_closure_LINUX64 (void); +void FFI_HIDDEN ffi_go_closure_linux64 (void); void FFI_HIDDEN ffi_prep_types_linux64 (ffi_abi); ffi_status FFI_HIDDEN ffi_prep_cif_linux64 (ffi_cif *); ffi_status FFI_HIDDEN ffi_prep_cif_linux64_var (ffi_cif *, unsigned int, unsigned int); void FFI_HIDDEN ffi_prep_args64 (extended_cif *, unsigned long *const); -int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *, +ffi_status FFI_HIDDEN ffi_prep_closure_loc_linux64 (ffi_closure *, ffi_cif *, + void (*) (ffi_cif *, void *, + void **, void *), + void *, void *); +int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_cif *, + void (*) (ffi_cif *, void *, + void **, void *), + void *, void *, unsigned long *, ffi_dblfl *); diff --git a/libffi/src/powerpc/ffi_sysv.c b/libffi/src/powerpc/ffi_sysv.c index fbe85fe9140..646c340d5ad 100644 --- a/libffi/src/powerpc/ffi_sysv.c +++ b/libffi/src/powerpc/ffi_sysv.c @@ -36,7 +36,7 @@ /* About the SYSV ABI. */ -#define ASM_NEEDS_REGISTERS 4 +#define ASM_NEEDS_REGISTERS 6 #define NUM_GPR_ARG_REGISTERS 8 #define NUM_FPR_ARG_REGISTERS 8 @@ -654,18 +654,18 @@ ffi_prep_closure_loc_sysv (ffi_closure *closure, tramp = (unsigned int *) &closure->tramp[0]; tramp[0] = 0x7c0802a6; /* mflr r0 */ - tramp[1] = 0x4800000d; /* bl 10 <trampoline_initial+0x10> */ - tramp[4] = 0x7d6802a6; /* mflr r11 */ - tramp[5] = 0x7c0803a6; /* mtlr r0 */ - tramp[6] = 0x800b0000; /* lwz r0,0(r11) */ - tramp[7] = 0x816b0004; /* lwz r11,4(r11) */ - tramp[8] = 0x7c0903a6; /* mtctr r0 */ - tramp[9] = 0x4e800420; /* bctr */ - *(void **) &tramp[2] = (void *) ffi_closure_SYSV; /* function */ - *(void **) &tramp[3] = codeloc; /* context */ + tramp[1] = 0x429f0005; /* bcl 20,31,.+4 */ + tramp[2] = 0x7d6802a6; /* mflr r11 */ + tramp[3] = 0x7c0803a6; /* mtlr r0 */ + tramp[4] = 0x800b0018; /* lwz r0,24(r11) */ + tramp[5] = 0x816b001c; /* lwz r11,28(r11) */ + tramp[6] = 0x7c0903a6; /* mtctr r0 */ + tramp[7] = 0x4e800420; /* bctr */ + *(void **) &tramp[8] = (void *) ffi_closure_SYSV; /* function */ + *(void **) &tramp[9] = codeloc; /* context */ /* Flush the icache. */ - flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE); + flush_icache ((char *)tramp, (char *)codeloc, 8 * 4); closure->cif = cif; closure->fun = fun; @@ -682,8 +682,12 @@ ffi_prep_closure_loc_sysv (ffi_closure *closure, following helper function to do most of the work. */ int -ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, - unsigned long *pgr, ffi_dblfl *pfr, +ffi_closure_helper_SYSV (ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, + void *rvalue, + unsigned long *pgr, + ffi_dblfl *pfr, unsigned long *pst) { /* rvalue is the pointer to space for return value in closure assembly */ @@ -699,7 +703,6 @@ ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, #endif long ng = 0; /* number of general registers already used */ - ffi_cif *cif = closure->cif; unsigned size = cif->rtype->size; unsigned short rtypenum = cif->rtype->type; @@ -915,7 +918,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, i++; } - (closure->fun) (cif, rvalue, avalue, closure->user_data); + (*fun) (cif, rvalue, avalue, user_data); /* Tell ffi_closure_SYSV how to perform return type promotions. Because the FFI_SYSV ABI returns the structures <= 8 bytes in diff --git a/libffi/src/powerpc/ffitarget.h b/libffi/src/powerpc/ffitarget.h index b47b0f5d3a2..0f66d319c77 100644 --- a/libffi/src/powerpc/ffitarget.h +++ b/libffi/src/powerpc/ffitarget.h @@ -138,23 +138,35 @@ typedef enum ffi_abi { #define FFI_CLOSURES 1 #define FFI_NATIVE_RAW_API 0 #if defined (POWERPC) || defined (POWERPC_FREEBSD) +# define FFI_GO_CLOSURES 1 # define FFI_TARGET_SPECIFIC_VARIADIC 1 # define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs #endif -/* For additional types like the below, take care about the order in - ppc_closures.S. They must follow after the FFI_TYPE_LAST. */ +/* ppc_closure.S and linux64_closure.S expect this. */ +#define FFI_PPC_TYPE_LAST FFI_TYPE_POINTER + +/* We define additional types below. If generic types are added that + must be supported by powerpc libffi then it is likely that + FFI_PPC_TYPE_LAST needs increasing *and* the jump tables in + ppc_closure.S and linux64_closure.S be extended. */ + +#if !(FFI_TYPE_LAST == FFI_PPC_TYPE_LAST \ + || (FFI_TYPE_LAST == FFI_TYPE_COMPLEX \ + && !defined FFI_TARGET_HAS_COMPLEX_TYPE)) +# error "You likely have a broken powerpc libffi" +#endif /* Needed for soft-float long-double-128 support. */ -#define FFI_TYPE_UINT128 (FFI_TYPE_LAST + 1) +#define FFI_TYPE_UINT128 (FFI_PPC_TYPE_LAST + 1) /* Needed for FFI_SYSV small structure returns. */ -#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 2) +#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_PPC_TYPE_LAST + 2) /* Used by ELFv2 for homogenous structure returns. */ -#define FFI_V2_TYPE_FLOAT_HOMOG (FFI_TYPE_LAST + 1) -#define FFI_V2_TYPE_DOUBLE_HOMOG (FFI_TYPE_LAST + 2) -#define FFI_V2_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 3) +#define FFI_V2_TYPE_FLOAT_HOMOG (FFI_PPC_TYPE_LAST + 1) +#define FFI_V2_TYPE_DOUBLE_HOMOG (FFI_PPC_TYPE_LAST + 2) +#define FFI_V2_TYPE_SMALL_STRUCT (FFI_PPC_TYPE_LAST + 3) #if _CALL_ELF == 2 # define FFI_TRAMPOLINE_SIZE 32 diff --git a/libffi/src/powerpc/linux64.S b/libffi/src/powerpc/linux64.S index d2acb7007b0..b2ae60ead6e 100644 --- a/libffi/src/powerpc/linux64.S +++ b/libffi/src/powerpc/linux64.S @@ -32,8 +32,9 @@ #ifdef POWERPC64 .hidden ffi_call_LINUX64 .globl ffi_call_LINUX64 -# if _CALL_ELF == 2 .text + .cfi_startproc +# if _CALL_ELF == 2 ffi_call_LINUX64: addis %r2, %r12, .TOC.-ffi_call_LINUX64@ha addi %r2, %r2, .TOC.-ffi_call_LINUX64@l @@ -57,20 +58,26 @@ ffi_call_LINUX64: .ffi_call_LINUX64: # endif # endif -.LFB1: mflr %r0 std %r28, -32(%r1) std %r29, -24(%r1) std %r30, -16(%r1) std %r31, -8(%r1) + std %r7, 8(%r1) /* closure, saved in cr field. */ std %r0, 16(%r1) mr %r28, %r1 /* our AP. */ -.LCFI0: - stdux %r1, %r1, %r4 - mr %r31, %r5 /* flags, */ - mr %r30, %r6 /* rvalue, */ - mr %r29, %r7 /* function address. */ + .cfi_def_cfa_register 28 + .cfi_offset 65, 16 + .cfi_offset 31, -8 + .cfi_offset 30, -16 + .cfi_offset 29, -24 + .cfi_offset 28, -32 + + stdux %r1, %r1, %r8 + mr %r31, %r6 /* flags, */ + mr %r30, %r5 /* rvalue, */ + mr %r29, %r4 /* function address. */ /* Save toc pointer, not for the ffi_prep_args64 call, but for the later bctrl function call. */ # if _CALL_ELF == 2 @@ -92,7 +99,6 @@ ffi_call_LINUX64: # else ld %r12, 0(%r29) ld %r2, 8(%r29) - ld %r11, 16(%r29) # endif /* Now do the call. */ /* Set up cr1 with bits 4-7 of the flags. */ @@ -130,6 +136,7 @@ ffi_call_LINUX64: 2: /* Make the call. */ + ld %r11, 8(%r28) bctrl /* This must follow the call immediately, the unwinder @@ -151,6 +158,7 @@ ffi_call_LINUX64: .Ldone_return_value: /* Restore the registers we used and return. */ mr %r1, %r28 + .cfi_def_cfa_register 1 ld %r0, 16(%r28) ld %r28, -32(%r28) mtlr %r0 @@ -160,6 +168,7 @@ ffi_call_LINUX64: blr .Lfp_return_value: + .cfi_def_cfa_register 28 bf 28, .Lfloat_return_value stfd %f1, 0(%r30) mtcrf 0x02, %r31 /* cr6 */ @@ -199,61 +208,19 @@ ffi_call_LINUX64: std %r4, 8(%r30) b .Ldone_return_value -.LFE1: - .long 0 - .byte 0,12,0,1,128,4,0,0 + .cfi_endproc # if _CALL_ELF == 2 .size ffi_call_LINUX64,.-ffi_call_LINUX64 # else # ifdef _CALL_LINUX .size ffi_call_LINUX64,.-.L.ffi_call_LINUX64 # else + .long 0 + .byte 0,12,0,1,128,4,0,0 .size .ffi_call_LINUX64,.-.ffi_call_LINUX64 # endif # endif - .section .eh_frame,EH_FRAME_FLAGS,@progbits -.Lframe1: - .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry -.LSCIE1: - .4byte 0x0 # CIE Identifier Tag - .byte 0x1 # CIE Version - .ascii "zR\0" # CIE Augmentation - .uleb128 0x1 # CIE Code Alignment Factor - .sleb128 -8 # CIE Data Alignment Factor - .byte 0x41 # CIE RA Column - .uleb128 0x1 # Augmentation size - .byte 0x14 # FDE Encoding (pcrel udata8) - .byte 0xc # DW_CFA_def_cfa - .uleb128 0x1 - .uleb128 0x0 - .align 3 -.LECIE1: -.LSFDE1: - .4byte .LEFDE1-.LASFDE1 # FDE Length -.LASFDE1: - .4byte .LASFDE1-.Lframe1 # FDE CIE offset - .8byte .LFB1-. # FDE initial location - .8byte .LFE1-.LFB1 # FDE address range - .uleb128 0x0 # Augmentation size - .byte 0x2 # DW_CFA_advance_loc1 - .byte .LCFI0-.LFB1 - .byte 0xd # DW_CFA_def_cfa_register - .uleb128 0x1c - .byte 0x11 # DW_CFA_offset_extended_sf - .uleb128 0x41 - .sleb128 -2 - .byte 0x9f # DW_CFA_offset, column 0x1f - .uleb128 0x1 - .byte 0x9e # DW_CFA_offset, column 0x1e - .uleb128 0x2 - .byte 0x9d # DW_CFA_offset, column 0x1d - .uleb128 0x3 - .byte 0x9c # DW_CFA_offset, column 0x1c - .uleb128 0x4 - .align 3 -.LEFDE1: - #endif #if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2 diff --git a/libffi/src/powerpc/linux64_closure.S b/libffi/src/powerpc/linux64_closure.S index 1d80a39490b..6487d2a2970 100644 --- a/libffi/src/powerpc/linux64_closure.S +++ b/libffi/src/powerpc/linux64_closure.S @@ -33,8 +33,9 @@ #ifdef POWERPC64 FFI_HIDDEN (ffi_closure_LINUX64) .globl ffi_closure_LINUX64 -# if _CALL_ELF == 2 .text + .cfi_startproc +# if _CALL_ELF == 2 ffi_closure_LINUX64: addis %r2, %r12, .TOC.-ffi_closure_LINUX64@ha addi %r2, %r2, .TOC.-ffi_closure_LINUX64@l @@ -73,20 +74,18 @@ ffi_closure_LINUX64: # define RETVAL PARMSAVE+64 # endif -.LFB1: # if _CALL_ELF == 2 ld %r12, FFI_TRAMPOLINE_SIZE(%r11) # closure->cif mflr %r0 lwz %r12, 28(%r12) # cif->flags mtcrf 0x40, %r12 addi %r12, %r1, PARMSAVE - bt 7, .Lparmsave + bt 7, 0f # Our caller has not allocated a parameter save area. # We need to allocate one here and use it to pass gprs to # ffi_closure_helper_LINUX64. addi %r12, %r1, -STACKFRAME+PARMSAVE -.Lparmsave: - std %r0, 16(%r1) +0: # Save general regs into parm save area std %r3, 0(%r12) std %r4, 8(%r12) @@ -98,8 +97,12 @@ ffi_closure_LINUX64: std %r10, 56(%r12) # load up the pointer to the parm save area - mr %r5, %r12 + mr %r7, %r12 # else + # copy r2 to r11 and load TOC into r2 + mr %r11, %r2 + ld %r2, 16(%r2) + mflr %r0 # Save general regs into parm save area # This is the parameter save area set up by our caller. @@ -112,12 +115,19 @@ ffi_closure_LINUX64: std %r9, PARMSAVE+48(%r1) std %r10, PARMSAVE+56(%r1) - std %r0, 16(%r1) - # load up the pointer to the parm save area - addi %r5, %r1, PARMSAVE + addi %r7, %r1, PARMSAVE # endif + std %r0, 16(%r1) + # closure->cif + ld %r3, FFI_TRAMPOLINE_SIZE(%r11) + # closure->fun + ld %r4, FFI_TRAMPOLINE_SIZE+8(%r11) + # closure->user_data + ld %r5, FFI_TRAMPOLINE_SIZE+16(%r11) + +.Ldoclosure: # next save fpr 1 to fpr 13 stfd %f1, -104+(0*8)(%r1) stfd %f2, -104+(1*8)(%r1) @@ -134,16 +144,14 @@ ffi_closure_LINUX64: stfd %f13, -104+(12*8)(%r1) # load up the pointer to the saved fpr registers */ - addi %r6, %r1, -104 + addi %r8, %r1, -104 # load up the pointer to the result storage - addi %r4, %r1, -STACKFRAME+RETVAL + addi %r6, %r1, -STACKFRAME+RETVAL stdu %r1, -STACKFRAME(%r1) -.LCFI0: - - # get the context pointer from the trampoline - mr %r3, %r11 + .cfi_def_cfa_offset STACKFRAME + .cfi_offset 65, 16 # make the call # if defined _CALL_LINUX || _CALL_ELF == 2 @@ -178,7 +186,9 @@ ffi_closure_LINUX64: # case FFI_TYPE_VOID mtlr %r0 addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset STACKFRAME nop # case FFI_TYPE_INT # ifdef __LITTLE_ENDIAN__ @@ -188,17 +198,23 @@ ffi_closure_LINUX64: # endif mtlr %r0 addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset STACKFRAME # case FFI_TYPE_FLOAT lfs %f1, RETVAL+0(%r1) mtlr %r0 addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset STACKFRAME # case FFI_TYPE_DOUBLE lfd %f1, RETVAL+0(%r1) mtlr %r0 addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset STACKFRAME # case FFI_TYPE_LONGDOUBLE lfd %f1, RETVAL+0(%r1) mtlr %r0 @@ -212,7 +228,9 @@ ffi_closure_LINUX64: # endif mtlr %r0 addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset STACKFRAME # case FFI_TYPE_SINT8 # ifdef __LITTLE_ENDIAN__ lbz %r3, RETVAL+0(%r1) @@ -231,7 +249,9 @@ ffi_closure_LINUX64: mtlr %r0 .Lfinish: addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset STACKFRAME # case FFI_TYPE_SINT16 # ifdef __LITTLE_ENDIAN__ lha %r3, RETVAL+0(%r1) @@ -240,7 +260,9 @@ ffi_closure_LINUX64: # endif mtlr %r0 addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset STACKFRAME # case FFI_TYPE_UINT32 # ifdef __LITTLE_ENDIAN__ lwz %r3, RETVAL+0(%r1) @@ -249,7 +271,9 @@ ffi_closure_LINUX64: # endif mtlr %r0 addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset STACKFRAME # case FFI_TYPE_SINT32 # ifdef __LITTLE_ENDIAN__ lwa %r3, RETVAL+0(%r1) @@ -258,27 +282,37 @@ ffi_closure_LINUX64: # endif mtlr %r0 addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset STACKFRAME # case FFI_TYPE_UINT64 ld %r3, RETVAL+0(%r1) mtlr %r0 addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset STACKFRAME # case FFI_TYPE_SINT64 ld %r3, RETVAL+0(%r1) mtlr %r0 addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset STACKFRAME # case FFI_TYPE_STRUCT mtlr %r0 addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset STACKFRAME nop # case FFI_TYPE_POINTER ld %r3, RETVAL+0(%r1) mtlr %r0 addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset STACKFRAME # case FFI_V2_TYPE_FLOAT_HOMOG lfs %f1, RETVAL+0(%r1) lfs %f2, RETVAL+4(%r1) @@ -295,7 +329,9 @@ ffi_closure_LINUX64: lfd %f7, RETVAL+48(%r1) lfd %f8, RETVAL+56(%r1) addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset STACKFRAME .Lmorefloat: lfs %f4, RETVAL+12(%r1) mtlr %r0 @@ -304,13 +340,16 @@ ffi_closure_LINUX64: lfs %f7, RETVAL+24(%r1) lfs %f8, RETVAL+28(%r1) addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset STACKFRAME .Lsmall: # ifdef __LITTLE_ENDIAN__ ld %r3,RETVAL+0(%r1) mtlr %r0 ld %r4,RETVAL+8(%r1) addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 blr # else # A struct smaller than a dword is returned in the low bits of r3 @@ -324,63 +363,124 @@ ffi_closure_LINUX64: mtlr %r0 ld %r4,RETVAL+8(%r1) addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset STACKFRAME .Lsmalldown: addi %r5, %r5, FFI_V2_TYPE_SMALL_STRUCT + 7 mtlr %r0 sldi %r5, %r5, 3 addi %r1, %r1, STACKFRAME + .cfi_def_cfa_offset 0 srd %r3, %r3, %r5 blr # endif -.LFE1: - .long 0 - .byte 0,12,0,1,128,0,0,0 + .cfi_endproc # if _CALL_ELF == 2 .size ffi_closure_LINUX64,.-ffi_closure_LINUX64 # else # ifdef _CALL_LINUX .size ffi_closure_LINUX64,.-.L.ffi_closure_LINUX64 # else + .long 0 + .byte 0,12,0,1,128,0,0,0 .size .ffi_closure_LINUX64,.-.ffi_closure_LINUX64 # endif # endif - .section .eh_frame,EH_FRAME_FLAGS,@progbits -.Lframe1: - .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry -.LSCIE1: - .4byte 0x0 # CIE Identifier Tag - .byte 0x1 # CIE Version - .ascii "zR\0" # CIE Augmentation - .uleb128 0x1 # CIE Code Alignment Factor - .sleb128 -8 # CIE Data Alignment Factor - .byte 0x41 # CIE RA Column - .uleb128 0x1 # Augmentation size - .byte 0x14 # FDE Encoding (pcrel udata8) - .byte 0xc # DW_CFA_def_cfa - .uleb128 0x1 - .uleb128 0x0 - .align 3 -.LECIE1: -.LSFDE1: - .4byte .LEFDE1-.LASFDE1 # FDE Length -.LASFDE1: - .4byte .LASFDE1-.Lframe1 # FDE CIE offset - .8byte .LFB1-. # FDE initial location - .8byte .LFE1-.LFB1 # FDE address range - .uleb128 0x0 # Augmentation size - .byte 0x2 # DW_CFA_advance_loc1 - .byte .LCFI0-.LFB1 - .byte 0xe # DW_CFA_def_cfa_offset - .uleb128 STACKFRAME - .byte 0x11 # DW_CFA_offset_extended_sf - .uleb128 0x41 - .sleb128 -2 - .align 3 -.LEFDE1: + FFI_HIDDEN (ffi_go_closure_linux64) + .globl ffi_go_closure_linux64 + .text + .cfi_startproc +# if _CALL_ELF == 2 +ffi_go_closure_linux64: + addis %r2, %r12, .TOC.-ffi_go_closure_linux64@ha + addi %r2, %r2, .TOC.-ffi_go_closure_linux64@l + .localentry ffi_go_closure_linux64, . - ffi_go_closure_linux64 +# else + .section ".opd","aw" + .align 3 +ffi_go_closure_linux64: +# ifdef _CALL_LINUX + .quad .L.ffi_go_closure_linux64,.TOC.@tocbase,0 + .type ffi_go_closure_linux64,@function + .text +.L.ffi_go_closure_linux64: +# else + FFI_HIDDEN (.ffi_go_closure_linux64) + .globl .ffi_go_closure_linux64 + .quad .ffi_go_closure_linux64,.TOC.@tocbase,0 + .size ffi_go_closure_linux64,24 + .type .ffi_go_closure_linux64,@function + .text +.ffi_go_closure_linux64: +# endif +# endif + +# if _CALL_ELF == 2 + ld %r12, 8(%r11) # closure->cif + mflr %r0 + lwz %r12, 28(%r12) # cif->flags + mtcrf 0x40, %r12 + addi %r12, %r1, PARMSAVE + bt 7, 0f + # Our caller has not allocated a parameter save area. + # We need to allocate one here and use it to pass gprs to + # ffi_closure_helper_LINUX64. + addi %r12, %r1, -STACKFRAME+PARMSAVE +0: + # Save general regs into parm save area + std %r3, 0(%r12) + std %r4, 8(%r12) + std %r5, 16(%r12) + std %r6, 24(%r12) + std %r7, 32(%r12) + std %r8, 40(%r12) + std %r9, 48(%r12) + std %r10, 56(%r12) + + # load up the pointer to the parm save area + mr %r7, %r12 +# else + mflr %r0 + # Save general regs into parm save area + # This is the parameter save area set up by our caller. + std %r3, PARMSAVE+0(%r1) + std %r4, PARMSAVE+8(%r1) + std %r5, PARMSAVE+16(%r1) + std %r6, PARMSAVE+24(%r1) + std %r7, PARMSAVE+32(%r1) + std %r8, PARMSAVE+40(%r1) + std %r9, PARMSAVE+48(%r1) + std %r10, PARMSAVE+56(%r1) + + # load up the pointer to the parm save area + addi %r7, %r1, PARMSAVE +# endif + std %r0, 16(%r1) + + # closure->cif + ld %r3, 8(%r11) + # closure->fun + ld %r4, 16(%r11) + # user_data + mr %r5, %r11 + b .Ldoclosure + + .cfi_endproc +# if _CALL_ELF == 2 + .size ffi_go_closure_linux64,.-ffi_go_closure_linux64 +# else +# ifdef _CALL_LINUX + .size ffi_go_closure_linux64,.-.L.ffi_go_closure_linux64 +# else + .long 0 + .byte 0,12,0,1,128,0,0,0 + .size .ffi_go_closure_linux64,.-.ffi_go_closure_linux64 +# endif +# endif #endif #if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2 diff --git a/libffi/src/powerpc/ppc_closure.S b/libffi/src/powerpc/ppc_closure.S index 0507128501e..b6d209de863 100644 --- a/libffi/src/powerpc/ppc_closure.S +++ b/libffi/src/powerpc/ppc_closure.S @@ -33,13 +33,14 @@ #ifndef POWERPC64 +FFI_HIDDEN(ffi_closure_SYSV) ENTRY(ffi_closure_SYSV) -.LFB1: + .cfi_startproc stwu %r1,-144(%r1) -.LCFI0: + .cfi_def_cfa_offset 144 mflr %r0 -.LCFI1: stw %r0,148(%r1) + .cfi_offset 65, 4 # we want to build up an areas for the parameters passed # in registers (both floating point and integer) @@ -48,6 +49,17 @@ ENTRY(ffi_closure_SYSV) stw %r3, 16(%r1) stw %r4, 20(%r1) stw %r5, 24(%r1) + + # set up registers for the routine that does the work + + # closure->cif + lwz %r3,FFI_TRAMPOLINE_SIZE(%r11) + # closure->fun + lwz %r4,FFI_TRAMPOLINE_SIZE+4(%r11) + # closure->user_data + lwz %r5,FFI_TRAMPOLINE_SIZE+8(%r11) + +.Ldoclosure: stw %r6, 28(%r1) stw %r7, 32(%r1) stw %r8, 36(%r1) @@ -66,23 +78,18 @@ ENTRY(ffi_closure_SYSV) stfd %f8, 104(%r1) #endif - # set up registers for the routine that actually does the work - # get the context pointer from the trampoline - mr %r3,%r11 + # pointer to the result storage + addi %r6,%r1,112 - # now load up the pointer to the result storage - addi %r4,%r1,112 + # pointer to the saved gpr registers + addi %r7,%r1,16 - # now load up the pointer to the saved gpr registers - addi %r5,%r1,16 + # pointer to the saved fpr registers + addi %r8,%r1,48 - # now load up the pointer to the saved fpr registers */ - addi %r6,%r1,48 - - # now load up the pointer to the outgoing parameter - # stack in the previous frame + # pointer to the outgoing parameter save area in the previous frame # i.e. the previous frame pointer + 8 - addi %r7,%r1,152 + addi %r9,%r1,152 # make the call bl ffi_closure_helper_SYSV@local @@ -101,7 +108,6 @@ ENTRY(ffi_closure_SYSV) add %r3,%r3,%r4 # add contents of table to table address mtctr %r3 bctr # jump to it -.LFE1: # Each of the ret_typeX code fragments has to be exactly 16 bytes long # (4 instructions). For cache effectiveness we align to a 16 byte boundary @@ -111,7 +117,9 @@ ENTRY(ffi_closure_SYSV) .Lret_type0: mtlr %r0 addi %r1,%r1,144 + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset 144 nop # case FFI_TYPE_INT @@ -119,31 +127,33 @@ ENTRY(ffi_closure_SYSV) mtlr %r0 .Lfinish: addi %r1,%r1,144 + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset 144 # case FFI_TYPE_FLOAT #ifndef __NO_FPRS__ lfs %f1,112+0(%r1) - mtlr %r0 - addi %r1,%r1,144 #else nop - nop - nop #endif + mtlr %r0 + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset 144 # case FFI_TYPE_DOUBLE #ifndef __NO_FPRS__ lfd %f1,112+0(%r1) - mtlr %r0 - addi %r1,%r1,144 #else nop - nop - nop #endif + mtlr %r0 + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset 144 # case FFI_TYPE_LONGDOUBLE #ifndef __NO_FPRS__ @@ -152,10 +162,12 @@ ENTRY(ffi_closure_SYSV) mtlr %r0 b .Lfinish #else - nop - nop - nop + mtlr %r0 + addi %r1,%r1,144 + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset 144 + nop #endif # case FFI_TYPE_UINT8 @@ -166,7 +178,9 @@ ENTRY(ffi_closure_SYSV) #endif mtlr %r0 addi %r1,%r1,144 + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset 144 # case FFI_TYPE_SINT8 #ifdef __LITTLE_ENDIAN__ @@ -186,7 +200,9 @@ ENTRY(ffi_closure_SYSV) #endif mtlr %r0 addi %r1,%r1,144 + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset 144 # case FFI_TYPE_SINT16 #ifdef __LITTLE_ENDIAN__ @@ -196,19 +212,25 @@ ENTRY(ffi_closure_SYSV) #endif mtlr %r0 addi %r1,%r1,144 + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset 144 # case FFI_TYPE_UINT32 lwz %r3,112+0(%r1) mtlr %r0 addi %r1,%r1,144 + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset 144 # case FFI_TYPE_SINT32 lwz %r3,112+0(%r1) mtlr %r0 addi %r1,%r1,144 + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset 144 # case FFI_TYPE_UINT64 lwz %r3,112+0(%r1) @@ -225,14 +247,18 @@ ENTRY(ffi_closure_SYSV) # case FFI_TYPE_STRUCT mtlr %r0 addi %r1,%r1,144 + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset 144 nop # case FFI_TYPE_POINTER lwz %r3,112+0(%r1) mtlr %r0 addi %r1,%r1,144 + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset 144 # case FFI_TYPE_UINT128 lwz %r3,112+0(%r1) @@ -245,20 +271,26 @@ ENTRY(ffi_closure_SYSV) lbz %r3,112+0(%r1) mtlr %r0 addi %r1,%r1,144 + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset 144 # case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct. lhz %r3,112+0(%r1) mtlr %r0 addi %r1,%r1,144 + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset 144 # case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct. lwz %r3,112+0(%r1) #ifdef __LITTLE_ENDIAN__ mtlr %r0 addi %r1,%r1,144 + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset 144 #else srwi %r3,%r3,8 mtlr %r0 @@ -269,7 +301,9 @@ ENTRY(ffi_closure_SYSV) lwz %r3,112+0(%r1) mtlr %r0 addi %r1,%r1,144 + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset 144 # case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct. lwz %r3,112+0(%r1) @@ -319,64 +353,43 @@ ENTRY(ffi_closure_SYSV) or %r4,%r6,%r4 mtlr %r0 addi %r1,%r1,144 + .cfi_def_cfa_offset 0 blr + .cfi_def_cfa_offset 144 #endif .Luint128: lwz %r6,112+12(%r1) mtlr %r0 addi %r1,%r1,144 + .cfi_def_cfa_offset 0 blr - + .cfi_endproc END(ffi_closure_SYSV) - .section ".eh_frame",EH_FRAME_FLAGS,@progbits -.Lframe1: - .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry -.LSCIE1: - .4byte 0x0 # CIE Identifier Tag - .byte 0x1 # CIE Version -#if defined _RELOCATABLE || defined __PIC__ - .ascii "zR\0" # CIE Augmentation -#else - .ascii "\0" # CIE Augmentation -#endif - .uleb128 0x1 # CIE Code Alignment Factor - .sleb128 -4 # CIE Data Alignment Factor - .byte 0x41 # CIE RA Column -#if defined _RELOCATABLE || defined __PIC__ - .uleb128 0x1 # Augmentation size - .byte 0x1b # FDE Encoding (pcrel sdata4) -#endif - .byte 0xc # DW_CFA_def_cfa - .uleb128 0x1 - .uleb128 0x0 - .align 2 -.LECIE1: -.LSFDE1: - .4byte .LEFDE1-.LASFDE1 # FDE Length -.LASFDE1: - .4byte .LASFDE1-.Lframe1 # FDE CIE offset -#if defined _RELOCATABLE || defined __PIC__ - .4byte .LFB1-. # FDE initial location -#else - .4byte .LFB1 # FDE initial location -#endif - .4byte .LFE1-.LFB1 # FDE address range -#if defined _RELOCATABLE || defined __PIC__ - .uleb128 0x0 # Augmentation size -#endif - .byte 0x4 # DW_CFA_advance_loc4 - .4byte .LCFI0-.LFB1 - .byte 0xe # DW_CFA_def_cfa_offset - .uleb128 144 - .byte 0x4 # DW_CFA_advance_loc4 - .4byte .LCFI1-.LCFI0 - .byte 0x11 # DW_CFA_offset_extended_sf - .uleb128 0x41 - .sleb128 -1 - .align 2 -.LEFDE1: + +FFI_HIDDEN(ffi_go_closure_sysv) +ENTRY(ffi_go_closure_sysv) + .cfi_startproc + stwu %r1,-144(%r1) + .cfi_def_cfa_offset 144 + mflr %r0 + stw %r0,148(%r1) + .cfi_offset 65, 4 + + stw %r3, 16(%r1) + stw %r4, 20(%r1) + stw %r5, 24(%r1) + + # closure->cif + lwz %r3,4(%r11) + # closure->fun + lwz %r4,8(%r11) + # user_data + mr %r5,%r11 + b .Ldoclosure + .cfi_endproc +END(ffi_go_closure_sysv) #if defined __ELF__ && defined __linux__ .section .note.GNU-stack,"",@progbits diff --git a/libffi/src/powerpc/sysv.S b/libffi/src/powerpc/sysv.S index fed2380c9fa..1474ce702b3 100644 --- a/libffi/src/powerpc/sysv.S +++ b/libffi/src/powerpc/sysv.S @@ -31,34 +31,35 @@ #include <powerpc/asm.h> #ifndef POWERPC64 - .globl ffi_prep_args_SYSV +FFI_HIDDEN(ffi_call_SYSV) ENTRY(ffi_call_SYSV) -.LFB1: + .cfi_startproc /* Save the old stack pointer as AP. */ - mr %r8,%r1 + mr %r10,%r1 + .cfi_def_cfa_register 10 -.LCFI0: /* Allocate the stack space we need. */ - stwux %r1,%r1,%r4 + stwux %r1,%r1,%r8 /* Save registers we use. */ mflr %r9 - stw %r28,-16(%r8) -.LCFI1: - stw %r29,-12(%r8) -.LCFI2: - stw %r30, -8(%r8) -.LCFI3: - stw %r31, -4(%r8) -.LCFI4: - stw %r9, 4(%r8) -.LCFI5: + stw %r28,-16(%r10) + stw %r29,-12(%r10) + stw %r30, -8(%r10) + stw %r31, -4(%r10) + stw %r9, 4(%r10) + .cfi_offset 65, 4 + .cfi_offset 31, -4 + .cfi_offset 30, -8 + .cfi_offset 29, -12 + .cfi_offset 28, -16 /* Save arguments over call... */ - mr %r31,%r5 /* flags, */ - mr %r30,%r6 /* rvalue, */ - mr %r29,%r7 /* function address, */ - mr %r28,%r8 /* our AP. */ -.LCFI6: + stw %r7, -20(%r10) /* closure, */ + mr %r31,%r6 /* flags, */ + mr %r30,%r5 /* rvalue, */ + mr %r29,%r4 /* function address, */ + mr %r28,%r10 /* our AP. */ + .cfi_def_cfa_register 28 /* Call ffi_prep_args_SYSV. */ mr %r4,%r1 @@ -70,35 +71,36 @@ ENTRY(ffi_call_SYSV) /* Get the address to call into CTR. */ mtctr %r29 /* Load all those argument registers. */ - lwz %r3,-16-(8*4)(%r28) - lwz %r4,-16-(7*4)(%r28) - lwz %r5,-16-(6*4)(%r28) - lwz %r6,-16-(5*4)(%r28) + lwz %r3,-24-(8*4)(%r28) + lwz %r4,-24-(7*4)(%r28) + lwz %r5,-24-(6*4)(%r28) + lwz %r6,-24-(5*4)(%r28) bf- 5,1f nop - lwz %r7,-16-(4*4)(%r28) - lwz %r8,-16-(3*4)(%r28) - lwz %r9,-16-(2*4)(%r28) - lwz %r10,-16-(1*4)(%r28) + lwz %r7,-24-(4*4)(%r28) + lwz %r8,-24-(3*4)(%r28) + lwz %r9,-24-(2*4)(%r28) + lwz %r10,-24-(1*4)(%r28) nop 1: #ifndef __NO_FPRS__ /* Load all the FP registers. */ bf- 6,2f - lfd %f1,-16-(8*4)-(8*8)(%r28) - lfd %f2,-16-(8*4)-(7*8)(%r28) - lfd %f3,-16-(8*4)-(6*8)(%r28) - lfd %f4,-16-(8*4)-(5*8)(%r28) + lfd %f1,-24-(8*4)-(8*8)(%r28) + lfd %f2,-24-(8*4)-(7*8)(%r28) + lfd %f3,-24-(8*4)-(6*8)(%r28) + lfd %f4,-24-(8*4)-(5*8)(%r28) nop - lfd %f5,-16-(8*4)-(4*8)(%r28) - lfd %f6,-16-(8*4)-(3*8)(%r28) - lfd %f7,-16-(8*4)-(2*8)(%r28) - lfd %f8,-16-(8*4)-(1*8)(%r28) + lfd %f5,-24-(8*4)-(4*8)(%r28) + lfd %f6,-24-(8*4)-(3*8)(%r28) + lfd %f7,-24-(8*4)-(2*8)(%r28) + lfd %f8,-24-(8*4)-(1*8)(%r28) #endif 2: /* Make the call. */ + lwz %r11, -20(%r28) bctrl /* Now, deal with the return value. */ @@ -125,11 +127,24 @@ L(done_return_value): lwz %r30, -8(%r28) lwz %r29,-12(%r28) lwz %r28,-16(%r28) + .cfi_remember_state + /* At this point we don't have a cfa register. Say all our + saved regs have been restored. */ + .cfi_same_value 65 + .cfi_same_value 31 + .cfi_same_value 30 + .cfi_same_value 29 + .cfi_same_value 28 + /* Hopefully this works.. */ + .cfi_def_cfa_register 1 + .cfi_offset 1, 0 lwz %r1,0(%r1) + .cfi_same_value 1 blr #ifndef __NO_FPRS__ L(fp_return_value): + .cfi_restore_state bf 28,L(float_return_value) stfd %f1,0(%r30) mtcrf 0x02,%r31 /* cr6 */ @@ -150,70 +165,10 @@ L(small_struct_return_value): stw %r3, 0(%r30) stw %r4, 4(%r30) b L(done_return_value) + .cfi_endproc -.LFE1: END(ffi_call_SYSV) - .section ".eh_frame",EH_FRAME_FLAGS,@progbits -.Lframe1: - .4byte .LECIE1-.LSCIE1 /* Length of Common Information Entry */ -.LSCIE1: - .4byte 0x0 /* CIE Identifier Tag */ - .byte 0x1 /* CIE Version */ -#if defined _RELOCATABLE || defined __PIC__ - .ascii "zR\0" /* CIE Augmentation */ -#else - .ascii "\0" /* CIE Augmentation */ -#endif - .uleb128 0x1 /* CIE Code Alignment Factor */ - .sleb128 -4 /* CIE Data Alignment Factor */ - .byte 0x41 /* CIE RA Column */ -#if defined _RELOCATABLE || defined __PIC__ - .uleb128 0x1 /* Augmentation size */ - .byte 0x1b /* FDE Encoding (pcrel sdata4) */ -#endif - .byte 0xc /* DW_CFA_def_cfa */ - .uleb128 0x1 - .uleb128 0x0 - .align 2 -.LECIE1: -.LSFDE1: - .4byte .LEFDE1-.LASFDE1 /* FDE Length */ -.LASFDE1: - .4byte .LASFDE1-.Lframe1 /* FDE CIE offset */ -#if defined _RELOCATABLE || defined __PIC__ - .4byte .LFB1-. /* FDE initial location */ -#else - .4byte .LFB1 /* FDE initial location */ -#endif - .4byte .LFE1-.LFB1 /* FDE address range */ -#if defined _RELOCATABLE || defined __PIC__ - .uleb128 0x0 /* Augmentation size */ -#endif - .byte 0x4 /* DW_CFA_advance_loc4 */ - .4byte .LCFI0-.LFB1 - .byte 0xd /* DW_CFA_def_cfa_register */ - .uleb128 0x08 - .byte 0x4 /* DW_CFA_advance_loc4 */ - .4byte .LCFI5-.LCFI0 - .byte 0x11 /* DW_CFA_offset_extended_sf */ - .uleb128 0x41 - .sleb128 -1 - .byte 0x9f /* DW_CFA_offset, column 0x1f */ - .uleb128 0x1 - .byte 0x9e /* DW_CFA_offset, column 0x1e */ - .uleb128 0x2 - .byte 0x9d /* DW_CFA_offset, column 0x1d */ - .uleb128 0x3 - .byte 0x9c /* DW_CFA_offset, column 0x1c */ - .uleb128 0x4 - .byte 0x4 /* DW_CFA_advance_loc4 */ - .4byte .LCFI6-.LCFI5 - .byte 0xd /* DW_CFA_def_cfa_register */ - .uleb128 0x1c - .align 2 -.LEFDE1: - #if defined __ELF__ && defined __linux__ .section .note.GNU-stack,"",@progbits #endif |