summaryrefslogtreecommitdiff
path: root/libffi/src/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'libffi/src/powerpc')
-rw-r--r--libffi/src/powerpc/aix.S12
-rw-r--r--libffi/src/powerpc/darwin.S9
-rw-r--r--libffi/src/powerpc/darwin_closure.S35
-rw-r--r--libffi/src/powerpc/ffi.c40
-rw-r--r--libffi/src/powerpc/ffi_darwin.c10
-rw-r--r--libffi/src/powerpc/ffi_linux64.c25
-rw-r--r--libffi/src/powerpc/ffi_powerpc.h29
-rw-r--r--libffi/src/powerpc/ffi_sysv.c33
-rw-r--r--libffi/src/powerpc/ffitarget.h26
-rw-r--r--libffi/src/powerpc/linux64.S73
-rw-r--r--libffi/src/powerpc/linux64_closure.S202
-rw-r--r--libffi/src/powerpc/ppc_closure.S165
-rw-r--r--libffi/src/powerpc/sysv.S149
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