Merge pull request #151 from amodra/master

powerpc: go closures for linux
This commit is contained in:
Anthony Green
2014-11-19 21:13:50 -05:00
9 changed files with 418 additions and 321 deletions
+36 -4
View File
@@ -70,8 +70,12 @@ ffi_prep_cif_machdep_var (ffi_cif *cif,
#endif #endif
} }
void static void
ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) 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 /* 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 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); ecif.rvalue = alloca (cif->rtype->size);
#ifdef POWERPC64 #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 #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 #endif
/* Check for a bounce-buffered return value */ /* 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_status
ffi_prep_closure_loc (ffi_closure *closure, 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); return ffi_prep_closure_loc_sysv (closure, cif, fun, user_data, codeloc);
#endif #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;
}
+13 -11
View File
@@ -667,7 +667,8 @@ flush_icache (char *wraddr, char *xaddr, int size)
} }
#endif #endif
ffi_status
ffi_status FFI_HIDDEN
ffi_prep_closure_loc_linux64 (ffi_closure *closure, ffi_prep_closure_loc_linux64 (ffi_closure *closure,
ffi_cif *cif, ffi_cif *cif,
void (*fun) (ffi_cif *, void *, void **, void *), void (*fun) (ffi_cif *, void *, void **, void *),
@@ -688,17 +689,17 @@ ffi_prep_closure_loc_linux64 (ffi_closure *closure,
/* 2: .quad context */ /* 2: .quad context */
*(void **) &tramp[4] = (void *) ffi_closure_LINUX64; *(void **) &tramp[4] = (void *) ffi_closure_LINUX64;
*(void **) &tramp[6] = codeloc; *(void **) &tramp[6] = codeloc;
flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE); flush_icache ((char *) tramp, (char *) codeloc, 4 * 4);
#else #else
void **tramp = (void **) &closure->tramp[0]; void **tramp = (void **) &closure->tramp[0];
if (cif->abi < FFI_LINUX || cif->abi >= FFI_LAST_ABI) if (cif->abi < FFI_LINUX || cif->abi >= FFI_LAST_ABI)
return FFI_BAD_ABI; return FFI_BAD_ABI;
/* Copy function address and TOC from ffi_closure_LINUX64. */ /* Copy function address and TOC from ffi_closure_LINUX64 OPD. */
memcpy (tramp, (char *) ffi_closure_LINUX64, 16); memcpy (&tramp[0], (void **) ffi_closure_LINUX64, sizeof (void *));
tramp[2] = tramp[1];
tramp[1] = codeloc; tramp[1] = codeloc;
memcpy (&tramp[2], (void **) ffi_closure_LINUX64 + 1, sizeof (void *));
#endif #endif
closure->cif = cif; closure->cif = cif;
@@ -710,8 +711,12 @@ ffi_prep_closure_loc_linux64 (ffi_closure *closure,
int FFI_HIDDEN int FFI_HIDDEN
ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue, ffi_closure_helper_LINUX64 (ffi_cif *cif,
unsigned long *pst, ffi_dblfl *pfr) 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 */ /* rvalue is the pointer to space for return value in closure assembly */
/* pst is the pointer to parameter save area /* pst is the pointer to parameter save area
@@ -721,11 +726,9 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
void **avalue; void **avalue;
ffi_type **arg_types; ffi_type **arg_types;
unsigned long i, avn, nfixedargs; unsigned long i, avn, nfixedargs;
ffi_cif *cif;
ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64; ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;
unsigned long align; unsigned long align;
cif = closure->cif;
avalue = alloca (cif->nargs * sizeof (void *)); avalue = alloca (cif->nargs * sizeof (void *));
/* Copy the caller's structure return value address so that the /* Copy the caller's structure return value address so that the
@@ -925,8 +928,7 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
i++; i++;
} }
(*fun) (cif, rvalue, avalue, user_data);
(closure->fun) (cif, rvalue, avalue, closure->user_data);
/* Tell ffi_closure_LINUX64 how to perform return type promotions. */ /* Tell ffi_closure_LINUX64 how to perform return type promotions. */
if ((cif->flags & FLAG_RETURNS_SMST) != 0) if ((cif->flags & FLAG_RETURNS_SMST) != 0)
+23 -6
View File
@@ -56,22 +56,39 @@ typedef union
} ffi_dblfl; } ffi_dblfl;
void FFI_HIDDEN ffi_closure_SYSV (void); void FFI_HIDDEN ffi_closure_SYSV (void);
void FFI_HIDDEN ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *, void FFI_HIDDEN ffi_go_closure_sysv (void);
void (*)(void)); void FFI_HIDDEN ffi_call_SYSV(extended_cif *, void (*)(void), void *,
unsigned, void *, int);
void FFI_HIDDEN ffi_prep_types_sysv (ffi_abi); void FFI_HIDDEN ffi_prep_types_sysv (ffi_abi);
ffi_status FFI_HIDDEN ffi_prep_cif_sysv (ffi_cif *); 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 *); ffi_dblfl *, unsigned long *);
void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long, unsigned long, void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, void (*) (void), void *,
unsigned long *, void (*)(void)); unsigned long, void *, long);
void FFI_HIDDEN ffi_closure_LINUX64 (void); void FFI_HIDDEN ffi_closure_LINUX64 (void);
void FFI_HIDDEN ffi_go_closure_linux64 (void);
void FFI_HIDDEN ffi_prep_types_linux64 (ffi_abi); 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 (ffi_cif *);
ffi_status FFI_HIDDEN ffi_prep_cif_linux64_var (ffi_cif *, unsigned int, ffi_status FFI_HIDDEN ffi_prep_cif_linux64_var (ffi_cif *, unsigned int,
unsigned int); unsigned int);
void FFI_HIDDEN ffi_prep_args64 (extended_cif *, unsigned long *const); 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 *); unsigned long *, ffi_dblfl *);
+18 -15
View File
@@ -36,7 +36,7 @@
/* About the SYSV ABI. */ /* About the SYSV ABI. */
#define ASM_NEEDS_REGISTERS 4 #define ASM_NEEDS_REGISTERS 6
#define NUM_GPR_ARG_REGISTERS 8 #define NUM_GPR_ARG_REGISTERS 8
#define NUM_FPR_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 = (unsigned int *) &closure->tramp[0];
tramp[0] = 0x7c0802a6; /* mflr r0 */ tramp[0] = 0x7c0802a6; /* mflr r0 */
tramp[1] = 0x4800000d; /* bl 10 <trampoline_initial+0x10> */ tramp[1] = 0x429f0005; /* bcl 20,31,.+4 */
tramp[4] = 0x7d6802a6; /* mflr r11 */ tramp[2] = 0x7d6802a6; /* mflr r11 */
tramp[5] = 0x7c0803a6; /* mtlr r0 */ tramp[3] = 0x7c0803a6; /* mtlr r0 */
tramp[6] = 0x800b0000; /* lwz r0,0(r11) */ tramp[4] = 0x800b0018; /* lwz r0,24(r11) */
tramp[7] = 0x816b0004; /* lwz r11,4(r11) */ tramp[5] = 0x816b001c; /* lwz r11,28(r11) */
tramp[8] = 0x7c0903a6; /* mtctr r0 */ tramp[6] = 0x7c0903a6; /* mtctr r0 */
tramp[9] = 0x4e800420; /* bctr */ tramp[7] = 0x4e800420; /* bctr */
*(void **) &tramp[2] = (void *) ffi_closure_SYSV; /* function */ *(void **) &tramp[8] = (void *) ffi_closure_SYSV; /* function */
*(void **) &tramp[3] = codeloc; /* context */ *(void **) &tramp[9] = codeloc; /* context */
/* Flush the icache. */ /* Flush the icache. */
flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE); flush_icache ((char *)tramp, (char *)codeloc, 8 * 4);
closure->cif = cif; closure->cif = cif;
closure->fun = fun; closure->fun = fun;
@@ -682,8 +682,12 @@ ffi_prep_closure_loc_sysv (ffi_closure *closure,
following helper function to do most of the work. */ following helper function to do most of the work. */
int int
ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, ffi_closure_helper_SYSV (ffi_cif *cif,
unsigned long *pgr, ffi_dblfl *pfr, void (*fun) (ffi_cif *, void *, void **, void *),
void *user_data,
void *rvalue,
unsigned long *pgr,
ffi_dblfl *pfr,
unsigned long *pst) unsigned long *pst)
{ {
/* rvalue is the pointer to space for return value in closure assembly */ /* 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 #endif
long ng = 0; /* number of general registers already used */ long ng = 0; /* number of general registers already used */
ffi_cif *cif = closure->cif;
unsigned size = cif->rtype->size; unsigned size = cif->rtype->size;
unsigned short rtypenum = cif->rtype->type; unsigned short rtypenum = cif->rtype->type;
@@ -915,7 +918,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue,
i++; 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. /* Tell ffi_closure_SYSV how to perform return type promotions.
Because the FFI_SYSV ABI returns the structures <= 8 bytes in Because the FFI_SYSV ABI returns the structures <= 8 bytes in
+19 -7
View File
@@ -138,23 +138,35 @@ typedef enum ffi_abi {
#define FFI_CLOSURES 1 #define FFI_CLOSURES 1
#define FFI_NATIVE_RAW_API 0 #define FFI_NATIVE_RAW_API 0
#if defined (POWERPC) || defined (POWERPC_FREEBSD) #if defined (POWERPC) || defined (POWERPC_FREEBSD)
# define FFI_GO_CLOSURES 1
# define FFI_TARGET_SPECIFIC_VARIADIC 1 # define FFI_TARGET_SPECIFIC_VARIADIC 1
# define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs # define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs
#endif #endif
/* For additional types like the below, take care about the order in /* ppc_closure.S and linux64_closure.S expect this. */
ppc_closures.S. They must follow after the FFI_TYPE_LAST. */ #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. */ /* 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. */ /* 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. */ /* Used by ELFv2 for homogenous structure returns. */
#define FFI_V2_TYPE_FLOAT_HOMOG (FFI_TYPE_LAST + 1) #define FFI_V2_TYPE_FLOAT_HOMOG (FFI_PPC_TYPE_LAST + 1)
#define FFI_V2_TYPE_DOUBLE_HOMOG (FFI_TYPE_LAST + 2) #define FFI_V2_TYPE_DOUBLE_HOMOG (FFI_PPC_TYPE_LAST + 2)
#define FFI_V2_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 3) #define FFI_V2_TYPE_SMALL_STRUCT (FFI_PPC_TYPE_LAST + 3)
#if _CALL_ELF == 2 #if _CALL_ELF == 2
# define FFI_TRAMPOLINE_SIZE 32 # define FFI_TRAMPOLINE_SIZE 32
+20 -53
View File
@@ -32,8 +32,9 @@
#ifdef POWERPC64 #ifdef POWERPC64
.hidden ffi_call_LINUX64 .hidden ffi_call_LINUX64
.globl ffi_call_LINUX64 .globl ffi_call_LINUX64
# if _CALL_ELF == 2
.text .text
.cfi_startproc
# if _CALL_ELF == 2
ffi_call_LINUX64: ffi_call_LINUX64:
addis %r2, %r12, .TOC.-ffi_call_LINUX64@ha addis %r2, %r12, .TOC.-ffi_call_LINUX64@ha
addi %r2, %r2, .TOC.-ffi_call_LINUX64@l addi %r2, %r2, .TOC.-ffi_call_LINUX64@l
@@ -57,20 +58,26 @@ ffi_call_LINUX64:
.ffi_call_LINUX64: .ffi_call_LINUX64:
# endif # endif
# endif # endif
.LFB1:
mflr %r0 mflr %r0
std %r28, -32(%r1) std %r28, -32(%r1)
std %r29, -24(%r1) std %r29, -24(%r1)
std %r30, -16(%r1) std %r30, -16(%r1)
std %r31, -8(%r1) std %r31, -8(%r1)
std %r7, 8(%r1) /* closure, saved in cr field. */
std %r0, 16(%r1) std %r0, 16(%r1)
mr %r28, %r1 /* our AP. */ mr %r28, %r1 /* our AP. */
.LCFI0: .cfi_def_cfa_register 28
stdux %r1, %r1, %r4 .cfi_offset 65, 16
mr %r31, %r5 /* flags, */ .cfi_offset 31, -8
mr %r30, %r6 /* rvalue, */ .cfi_offset 30, -16
mr %r29, %r7 /* function address. */ .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 /* Save toc pointer, not for the ffi_prep_args64 call, but for the later
bctrl function call. */ bctrl function call. */
# if _CALL_ELF == 2 # if _CALL_ELF == 2
@@ -92,7 +99,6 @@ ffi_call_LINUX64:
# else # else
ld %r12, 0(%r29) ld %r12, 0(%r29)
ld %r2, 8(%r29) ld %r2, 8(%r29)
ld %r11, 16(%r29)
# endif # endif
/* Now do the call. */ /* Now do the call. */
/* Set up cr1 with bits 4-7 of the flags. */ /* Set up cr1 with bits 4-7 of the flags. */
@@ -130,6 +136,7 @@ ffi_call_LINUX64:
2: 2:
/* Make the call. */ /* Make the call. */
ld %r11, 8(%r28)
bctrl bctrl
/* This must follow the call immediately, the unwinder /* This must follow the call immediately, the unwinder
@@ -151,6 +158,7 @@ ffi_call_LINUX64:
.Ldone_return_value: .Ldone_return_value:
/* Restore the registers we used and return. */ /* Restore the registers we used and return. */
mr %r1, %r28 mr %r1, %r28
.cfi_def_cfa_register 1
ld %r0, 16(%r28) ld %r0, 16(%r28)
ld %r28, -32(%r28) ld %r28, -32(%r28)
mtlr %r0 mtlr %r0
@@ -160,6 +168,7 @@ ffi_call_LINUX64:
blr blr
.Lfp_return_value: .Lfp_return_value:
.cfi_def_cfa_register 28
bf 28, .Lfloat_return_value bf 28, .Lfloat_return_value
stfd %f1, 0(%r30) stfd %f1, 0(%r30)
mtcrf 0x02, %r31 /* cr6 */ mtcrf 0x02, %r31 /* cr6 */
@@ -199,61 +208,19 @@ ffi_call_LINUX64:
std %r4, 8(%r30) std %r4, 8(%r30)
b .Ldone_return_value b .Ldone_return_value
.LFE1: .cfi_endproc
.long 0
.byte 0,12,0,1,128,4,0,0
# if _CALL_ELF == 2 # if _CALL_ELF == 2
.size ffi_call_LINUX64,.-ffi_call_LINUX64 .size ffi_call_LINUX64,.-ffi_call_LINUX64
# else # else
# ifdef _CALL_LINUX # ifdef _CALL_LINUX
.size ffi_call_LINUX64,.-.L.ffi_call_LINUX64 .size ffi_call_LINUX64,.-.L.ffi_call_LINUX64
# else # else
.long 0
.byte 0,12,0,1,128,4,0,0
.size .ffi_call_LINUX64,.-.ffi_call_LINUX64 .size .ffi_call_LINUX64,.-.ffi_call_LINUX64
# endif # endif
# 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 #endif
#if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2 #if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2
+148 -52
View File
@@ -33,8 +33,9 @@
#ifdef POWERPC64 #ifdef POWERPC64
FFI_HIDDEN (ffi_closure_LINUX64) FFI_HIDDEN (ffi_closure_LINUX64)
.globl ffi_closure_LINUX64 .globl ffi_closure_LINUX64
# if _CALL_ELF == 2
.text .text
.cfi_startproc
# if _CALL_ELF == 2
ffi_closure_LINUX64: ffi_closure_LINUX64:
addis %r2, %r12, .TOC.-ffi_closure_LINUX64@ha addis %r2, %r12, .TOC.-ffi_closure_LINUX64@ha
addi %r2, %r2, .TOC.-ffi_closure_LINUX64@l addi %r2, %r2, .TOC.-ffi_closure_LINUX64@l
@@ -73,20 +74,18 @@ ffi_closure_LINUX64:
# define RETVAL PARMSAVE+64 # define RETVAL PARMSAVE+64
# endif # endif
.LFB1:
# if _CALL_ELF == 2 # if _CALL_ELF == 2
ld %r12, FFI_TRAMPOLINE_SIZE(%r11) # closure->cif ld %r12, FFI_TRAMPOLINE_SIZE(%r11) # closure->cif
mflr %r0 mflr %r0
lwz %r12, 28(%r12) # cif->flags lwz %r12, 28(%r12) # cif->flags
mtcrf 0x40, %r12 mtcrf 0x40, %r12
addi %r12, %r1, PARMSAVE addi %r12, %r1, PARMSAVE
bt 7, .Lparmsave bt 7, 0f
# Our caller has not allocated a parameter save area. # Our caller has not allocated a parameter save area.
# We need to allocate one here and use it to pass gprs to # We need to allocate one here and use it to pass gprs to
# ffi_closure_helper_LINUX64. # ffi_closure_helper_LINUX64.
addi %r12, %r1, -STACKFRAME+PARMSAVE addi %r12, %r1, -STACKFRAME+PARMSAVE
.Lparmsave: 0:
std %r0, 16(%r1)
# Save general regs into parm save area # Save general regs into parm save area
std %r3, 0(%r12) std %r3, 0(%r12)
std %r4, 8(%r12) std %r4, 8(%r12)
@@ -98,11 +97,11 @@ ffi_closure_LINUX64:
std %r10, 56(%r12) std %r10, 56(%r12)
# load up the pointer to the parm save area # load up the pointer to the parm save area
mr %r5, %r12 mr %r7, %r12
# else # else
# copy r2 to r11 and load TOC into r2 # copy r2 to r11 and load TOC into r2
mr %r11, %r2 mr %r11, %r2
ld %r2, 16(%r11) ld %r2, 16(%r2)
mflr %r0 mflr %r0
# Save general regs into parm save area # Save general regs into parm save area
@@ -116,12 +115,19 @@ ffi_closure_LINUX64:
std %r9, PARMSAVE+48(%r1) std %r9, PARMSAVE+48(%r1)
std %r10, PARMSAVE+56(%r1) std %r10, PARMSAVE+56(%r1)
# load up the pointer to the parm save area
addi %r7, %r1, PARMSAVE
# endif
std %r0, 16(%r1) std %r0, 16(%r1)
# load up the pointer to the parm save area # closure->cif
addi %r5, %r1, PARMSAVE ld %r3, FFI_TRAMPOLINE_SIZE(%r11)
# endif # 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 # next save fpr 1 to fpr 13
stfd %f1, -104+(0*8)(%r1) stfd %f1, -104+(0*8)(%r1)
stfd %f2, -104+(1*8)(%r1) stfd %f2, -104+(1*8)(%r1)
@@ -138,16 +144,14 @@ ffi_closure_LINUX64:
stfd %f13, -104+(12*8)(%r1) stfd %f13, -104+(12*8)(%r1)
# load up the pointer to the saved fpr registers */ # 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 # load up the pointer to the result storage
addi %r4, %r1, -STACKFRAME+RETVAL addi %r6, %r1, -STACKFRAME+RETVAL
stdu %r1, -STACKFRAME(%r1) stdu %r1, -STACKFRAME(%r1)
.LCFI0: .cfi_def_cfa_offset STACKFRAME
.cfi_offset 65, 16
# get the context pointer from the trampoline
mr %r3, %r11
# make the call # make the call
# if defined _CALL_LINUX || _CALL_ELF == 2 # if defined _CALL_LINUX || _CALL_ELF == 2
@@ -182,7 +186,9 @@ ffi_closure_LINUX64:
# case FFI_TYPE_VOID # case FFI_TYPE_VOID
mtlr %r0 mtlr %r0
addi %r1, %r1, STACKFRAME addi %r1, %r1, STACKFRAME
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset STACKFRAME
nop nop
# case FFI_TYPE_INT # case FFI_TYPE_INT
# ifdef __LITTLE_ENDIAN__ # ifdef __LITTLE_ENDIAN__
@@ -192,17 +198,23 @@ ffi_closure_LINUX64:
# endif # endif
mtlr %r0 mtlr %r0
addi %r1, %r1, STACKFRAME addi %r1, %r1, STACKFRAME
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset STACKFRAME
# case FFI_TYPE_FLOAT # case FFI_TYPE_FLOAT
lfs %f1, RETVAL+0(%r1) lfs %f1, RETVAL+0(%r1)
mtlr %r0 mtlr %r0
addi %r1, %r1, STACKFRAME addi %r1, %r1, STACKFRAME
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset STACKFRAME
# case FFI_TYPE_DOUBLE # case FFI_TYPE_DOUBLE
lfd %f1, RETVAL+0(%r1) lfd %f1, RETVAL+0(%r1)
mtlr %r0 mtlr %r0
addi %r1, %r1, STACKFRAME addi %r1, %r1, STACKFRAME
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset STACKFRAME
# case FFI_TYPE_LONGDOUBLE # case FFI_TYPE_LONGDOUBLE
lfd %f1, RETVAL+0(%r1) lfd %f1, RETVAL+0(%r1)
mtlr %r0 mtlr %r0
@@ -216,7 +228,9 @@ ffi_closure_LINUX64:
# endif # endif
mtlr %r0 mtlr %r0
addi %r1, %r1, STACKFRAME addi %r1, %r1, STACKFRAME
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset STACKFRAME
# case FFI_TYPE_SINT8 # case FFI_TYPE_SINT8
# ifdef __LITTLE_ENDIAN__ # ifdef __LITTLE_ENDIAN__
lbz %r3, RETVAL+0(%r1) lbz %r3, RETVAL+0(%r1)
@@ -235,7 +249,9 @@ ffi_closure_LINUX64:
mtlr %r0 mtlr %r0
.Lfinish: .Lfinish:
addi %r1, %r1, STACKFRAME addi %r1, %r1, STACKFRAME
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset STACKFRAME
# case FFI_TYPE_SINT16 # case FFI_TYPE_SINT16
# ifdef __LITTLE_ENDIAN__ # ifdef __LITTLE_ENDIAN__
lha %r3, RETVAL+0(%r1) lha %r3, RETVAL+0(%r1)
@@ -244,7 +260,9 @@ ffi_closure_LINUX64:
# endif # endif
mtlr %r0 mtlr %r0
addi %r1, %r1, STACKFRAME addi %r1, %r1, STACKFRAME
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset STACKFRAME
# case FFI_TYPE_UINT32 # case FFI_TYPE_UINT32
# ifdef __LITTLE_ENDIAN__ # ifdef __LITTLE_ENDIAN__
lwz %r3, RETVAL+0(%r1) lwz %r3, RETVAL+0(%r1)
@@ -253,7 +271,9 @@ ffi_closure_LINUX64:
# endif # endif
mtlr %r0 mtlr %r0
addi %r1, %r1, STACKFRAME addi %r1, %r1, STACKFRAME
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset STACKFRAME
# case FFI_TYPE_SINT32 # case FFI_TYPE_SINT32
# ifdef __LITTLE_ENDIAN__ # ifdef __LITTLE_ENDIAN__
lwa %r3, RETVAL+0(%r1) lwa %r3, RETVAL+0(%r1)
@@ -262,27 +282,37 @@ ffi_closure_LINUX64:
# endif # endif
mtlr %r0 mtlr %r0
addi %r1, %r1, STACKFRAME addi %r1, %r1, STACKFRAME
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset STACKFRAME
# case FFI_TYPE_UINT64 # case FFI_TYPE_UINT64
ld %r3, RETVAL+0(%r1) ld %r3, RETVAL+0(%r1)
mtlr %r0 mtlr %r0
addi %r1, %r1, STACKFRAME addi %r1, %r1, STACKFRAME
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset STACKFRAME
# case FFI_TYPE_SINT64 # case FFI_TYPE_SINT64
ld %r3, RETVAL+0(%r1) ld %r3, RETVAL+0(%r1)
mtlr %r0 mtlr %r0
addi %r1, %r1, STACKFRAME addi %r1, %r1, STACKFRAME
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset STACKFRAME
# case FFI_TYPE_STRUCT # case FFI_TYPE_STRUCT
mtlr %r0 mtlr %r0
addi %r1, %r1, STACKFRAME addi %r1, %r1, STACKFRAME
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset STACKFRAME
nop nop
# case FFI_TYPE_POINTER # case FFI_TYPE_POINTER
ld %r3, RETVAL+0(%r1) ld %r3, RETVAL+0(%r1)
mtlr %r0 mtlr %r0
addi %r1, %r1, STACKFRAME addi %r1, %r1, STACKFRAME
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset STACKFRAME
# case FFI_V2_TYPE_FLOAT_HOMOG # case FFI_V2_TYPE_FLOAT_HOMOG
lfs %f1, RETVAL+0(%r1) lfs %f1, RETVAL+0(%r1)
lfs %f2, RETVAL+4(%r1) lfs %f2, RETVAL+4(%r1)
@@ -299,7 +329,9 @@ ffi_closure_LINUX64:
lfd %f7, RETVAL+48(%r1) lfd %f7, RETVAL+48(%r1)
lfd %f8, RETVAL+56(%r1) lfd %f8, RETVAL+56(%r1)
addi %r1, %r1, STACKFRAME addi %r1, %r1, STACKFRAME
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset STACKFRAME
.Lmorefloat: .Lmorefloat:
lfs %f4, RETVAL+12(%r1) lfs %f4, RETVAL+12(%r1)
mtlr %r0 mtlr %r0
@@ -308,13 +340,16 @@ ffi_closure_LINUX64:
lfs %f7, RETVAL+24(%r1) lfs %f7, RETVAL+24(%r1)
lfs %f8, RETVAL+28(%r1) lfs %f8, RETVAL+28(%r1)
addi %r1, %r1, STACKFRAME addi %r1, %r1, STACKFRAME
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset STACKFRAME
.Lsmall: .Lsmall:
# ifdef __LITTLE_ENDIAN__ # ifdef __LITTLE_ENDIAN__
ld %r3,RETVAL+0(%r1) ld %r3,RETVAL+0(%r1)
mtlr %r0 mtlr %r0
ld %r4,RETVAL+8(%r1) ld %r4,RETVAL+8(%r1)
addi %r1, %r1, STACKFRAME addi %r1, %r1, STACKFRAME
.cfi_def_cfa_offset 0
blr blr
# else # else
# A struct smaller than a dword is returned in the low bits of r3 # A struct smaller than a dword is returned in the low bits of r3
@@ -328,63 +363,124 @@ ffi_closure_LINUX64:
mtlr %r0 mtlr %r0
ld %r4,RETVAL+8(%r1) ld %r4,RETVAL+8(%r1)
addi %r1, %r1, STACKFRAME addi %r1, %r1, STACKFRAME
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset STACKFRAME
.Lsmalldown: .Lsmalldown:
addi %r5, %r5, FFI_V2_TYPE_SMALL_STRUCT + 7 addi %r5, %r5, FFI_V2_TYPE_SMALL_STRUCT + 7
mtlr %r0 mtlr %r0
sldi %r5, %r5, 3 sldi %r5, %r5, 3
addi %r1, %r1, STACKFRAME addi %r1, %r1, STACKFRAME
.cfi_def_cfa_offset 0
srd %r3, %r3, %r5 srd %r3, %r3, %r5
blr blr
# endif # endif
.LFE1: .cfi_endproc
.long 0
.byte 0,12,0,1,128,0,0,0
# if _CALL_ELF == 2 # if _CALL_ELF == 2
.size ffi_closure_LINUX64,.-ffi_closure_LINUX64 .size ffi_closure_LINUX64,.-ffi_closure_LINUX64
# else # else
# ifdef _CALL_LINUX # ifdef _CALL_LINUX
.size ffi_closure_LINUX64,.-.L.ffi_closure_LINUX64 .size ffi_closure_LINUX64,.-.L.ffi_closure_LINUX64
# else # else
.long 0
.byte 0,12,0,1,128,0,0,0
.size .ffi_closure_LINUX64,.-.ffi_closure_LINUX64 .size .ffi_closure_LINUX64,.-.ffi_closure_LINUX64
# endif # endif
# 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 #endif
#if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2 #if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2
+89 -76
View File
@@ -33,13 +33,14 @@
#ifndef POWERPC64 #ifndef POWERPC64
FFI_HIDDEN(ffi_closure_SYSV)
ENTRY(ffi_closure_SYSV) ENTRY(ffi_closure_SYSV)
.LFB1: .cfi_startproc
stwu %r1,-144(%r1) stwu %r1,-144(%r1)
.LCFI0: .cfi_def_cfa_offset 144
mflr %r0 mflr %r0
.LCFI1:
stw %r0,148(%r1) stw %r0,148(%r1)
.cfi_offset 65, 4
# we want to build up an areas for the parameters passed # we want to build up an areas for the parameters passed
# in registers (both floating point and integer) # in registers (both floating point and integer)
@@ -48,6 +49,17 @@ ENTRY(ffi_closure_SYSV)
stw %r3, 16(%r1) stw %r3, 16(%r1)
stw %r4, 20(%r1) stw %r4, 20(%r1)
stw %r5, 24(%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 %r6, 28(%r1)
stw %r7, 32(%r1) stw %r7, 32(%r1)
stw %r8, 36(%r1) stw %r8, 36(%r1)
@@ -66,23 +78,18 @@ ENTRY(ffi_closure_SYSV)
stfd %f8, 104(%r1) stfd %f8, 104(%r1)
#endif #endif
# set up registers for the routine that actually does the work # pointer to the result storage
# get the context pointer from the trampoline addi %r6,%r1,112
mr %r3,%r11
# now load up the pointer to the result storage # pointer to the saved gpr registers
addi %r4,%r1,112 addi %r7,%r1,16
# now load up the pointer to the saved gpr registers # pointer to the saved fpr registers
addi %r5,%r1,16 addi %r8,%r1,48
# now load up the pointer to the saved fpr registers */ # pointer to the outgoing parameter save area in the previous frame
addi %r6,%r1,48
# now load up the pointer to the outgoing parameter
# stack in the previous frame
# i.e. the previous frame pointer + 8 # i.e. the previous frame pointer + 8
addi %r7,%r1,152 addi %r9,%r1,152
# make the call # make the call
bl ffi_closure_helper_SYSV@local 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 add %r3,%r3,%r4 # add contents of table to table address
mtctr %r3 mtctr %r3
bctr # jump to it bctr # jump to it
.LFE1:
# Each of the ret_typeX code fragments has to be exactly 16 bytes long # 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 # (4 instructions). For cache effectiveness we align to a 16 byte boundary
@@ -111,7 +117,9 @@ ENTRY(ffi_closure_SYSV)
.Lret_type0: .Lret_type0:
mtlr %r0 mtlr %r0
addi %r1,%r1,144 addi %r1,%r1,144
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset 144
nop nop
# case FFI_TYPE_INT # case FFI_TYPE_INT
@@ -119,31 +127,33 @@ ENTRY(ffi_closure_SYSV)
mtlr %r0 mtlr %r0
.Lfinish: .Lfinish:
addi %r1,%r1,144 addi %r1,%r1,144
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset 144
# case FFI_TYPE_FLOAT # case FFI_TYPE_FLOAT
#ifndef __NO_FPRS__ #ifndef __NO_FPRS__
lfs %f1,112+0(%r1) lfs %f1,112+0(%r1)
mtlr %r0
addi %r1,%r1,144
#else #else
nop nop
nop
nop
#endif #endif
mtlr %r0
addi %r1,%r1,144
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset 144
# case FFI_TYPE_DOUBLE # case FFI_TYPE_DOUBLE
#ifndef __NO_FPRS__ #ifndef __NO_FPRS__
lfd %f1,112+0(%r1) lfd %f1,112+0(%r1)
mtlr %r0
addi %r1,%r1,144
#else #else
nop nop
nop
nop
#endif #endif
mtlr %r0
addi %r1,%r1,144
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset 144
# case FFI_TYPE_LONGDOUBLE # case FFI_TYPE_LONGDOUBLE
#ifndef __NO_FPRS__ #ifndef __NO_FPRS__
@@ -152,10 +162,12 @@ ENTRY(ffi_closure_SYSV)
mtlr %r0 mtlr %r0
b .Lfinish b .Lfinish
#else #else
nop mtlr %r0
nop addi %r1,%r1,144
nop .cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset 144
nop
#endif #endif
# case FFI_TYPE_UINT8 # case FFI_TYPE_UINT8
@@ -166,7 +178,9 @@ ENTRY(ffi_closure_SYSV)
#endif #endif
mtlr %r0 mtlr %r0
addi %r1,%r1,144 addi %r1,%r1,144
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset 144
# case FFI_TYPE_SINT8 # case FFI_TYPE_SINT8
#ifdef __LITTLE_ENDIAN__ #ifdef __LITTLE_ENDIAN__
@@ -186,7 +200,9 @@ ENTRY(ffi_closure_SYSV)
#endif #endif
mtlr %r0 mtlr %r0
addi %r1,%r1,144 addi %r1,%r1,144
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset 144
# case FFI_TYPE_SINT16 # case FFI_TYPE_SINT16
#ifdef __LITTLE_ENDIAN__ #ifdef __LITTLE_ENDIAN__
@@ -196,19 +212,25 @@ ENTRY(ffi_closure_SYSV)
#endif #endif
mtlr %r0 mtlr %r0
addi %r1,%r1,144 addi %r1,%r1,144
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset 144
# case FFI_TYPE_UINT32 # case FFI_TYPE_UINT32
lwz %r3,112+0(%r1) lwz %r3,112+0(%r1)
mtlr %r0 mtlr %r0
addi %r1,%r1,144 addi %r1,%r1,144
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset 144
# case FFI_TYPE_SINT32 # case FFI_TYPE_SINT32
lwz %r3,112+0(%r1) lwz %r3,112+0(%r1)
mtlr %r0 mtlr %r0
addi %r1,%r1,144 addi %r1,%r1,144
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset 144
# case FFI_TYPE_UINT64 # case FFI_TYPE_UINT64
lwz %r3,112+0(%r1) lwz %r3,112+0(%r1)
@@ -225,14 +247,18 @@ ENTRY(ffi_closure_SYSV)
# case FFI_TYPE_STRUCT # case FFI_TYPE_STRUCT
mtlr %r0 mtlr %r0
addi %r1,%r1,144 addi %r1,%r1,144
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset 144
nop nop
# case FFI_TYPE_POINTER # case FFI_TYPE_POINTER
lwz %r3,112+0(%r1) lwz %r3,112+0(%r1)
mtlr %r0 mtlr %r0
addi %r1,%r1,144 addi %r1,%r1,144
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset 144
# case FFI_TYPE_UINT128 # case FFI_TYPE_UINT128
lwz %r3,112+0(%r1) lwz %r3,112+0(%r1)
@@ -245,20 +271,26 @@ ENTRY(ffi_closure_SYSV)
lbz %r3,112+0(%r1) lbz %r3,112+0(%r1)
mtlr %r0 mtlr %r0
addi %r1,%r1,144 addi %r1,%r1,144
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset 144
# case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct. # case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct.
lhz %r3,112+0(%r1) lhz %r3,112+0(%r1)
mtlr %r0 mtlr %r0
addi %r1,%r1,144 addi %r1,%r1,144
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset 144
# case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct. # case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct.
lwz %r3,112+0(%r1) lwz %r3,112+0(%r1)
#ifdef __LITTLE_ENDIAN__ #ifdef __LITTLE_ENDIAN__
mtlr %r0 mtlr %r0
addi %r1,%r1,144 addi %r1,%r1,144
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset 144
#else #else
srwi %r3,%r3,8 srwi %r3,%r3,8
mtlr %r0 mtlr %r0
@@ -269,7 +301,9 @@ ENTRY(ffi_closure_SYSV)
lwz %r3,112+0(%r1) lwz %r3,112+0(%r1)
mtlr %r0 mtlr %r0
addi %r1,%r1,144 addi %r1,%r1,144
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset 144
# case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct. # case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct.
lwz %r3,112+0(%r1) lwz %r3,112+0(%r1)
@@ -319,64 +353,43 @@ ENTRY(ffi_closure_SYSV)
or %r4,%r6,%r4 or %r4,%r6,%r4
mtlr %r0 mtlr %r0
addi %r1,%r1,144 addi %r1,%r1,144
.cfi_def_cfa_offset 0
blr blr
.cfi_def_cfa_offset 144
#endif #endif
.Luint128: .Luint128:
lwz %r6,112+12(%r1) lwz %r6,112+12(%r1)
mtlr %r0 mtlr %r0
addi %r1,%r1,144 addi %r1,%r1,144
.cfi_def_cfa_offset 0
blr blr
.cfi_endproc
END(ffi_closure_SYSV) END(ffi_closure_SYSV)
.section ".eh_frame",EH_FRAME_FLAGS,@progbits
.Lframe1: FFI_HIDDEN(ffi_go_closure_sysv)
.4byte .LECIE1-.LSCIE1 # Length of Common Information Entry ENTRY(ffi_go_closure_sysv)
.LSCIE1: .cfi_startproc
.4byte 0x0 # CIE Identifier Tag stwu %r1,-144(%r1)
.byte 0x1 # CIE Version .cfi_def_cfa_offset 144
#if defined _RELOCATABLE || defined __PIC__ mflr %r0
.ascii "zR\0" # CIE Augmentation stw %r0,148(%r1)
#else .cfi_offset 65, 4
.ascii "\0" # CIE Augmentation
#endif stw %r3, 16(%r1)
.uleb128 0x1 # CIE Code Alignment Factor stw %r4, 20(%r1)
.sleb128 -4 # CIE Data Alignment Factor stw %r5, 24(%r1)
.byte 0x41 # CIE RA Column
#if defined _RELOCATABLE || defined __PIC__ # closure->cif
.uleb128 0x1 # Augmentation size lwz %r3,4(%r11)
.byte 0x1b # FDE Encoding (pcrel sdata4) # closure->fun
#endif lwz %r4,8(%r11)
.byte 0xc # DW_CFA_def_cfa # user_data
.uleb128 0x1 mr %r5,%r11
.uleb128 0x0 b .Ldoclosure
.align 2 .cfi_endproc
.LECIE1: END(ffi_go_closure_sysv)
.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:
#if defined __ELF__ && defined __linux__ #if defined __ELF__ && defined __linux__
.section .note.GNU-stack,"",@progbits .section .note.GNU-stack,"",@progbits
+52 -97
View File
@@ -31,34 +31,35 @@
#include <powerpc/asm.h> #include <powerpc/asm.h>
#ifndef POWERPC64 #ifndef POWERPC64
.globl ffi_prep_args_SYSV FFI_HIDDEN(ffi_call_SYSV)
ENTRY(ffi_call_SYSV) ENTRY(ffi_call_SYSV)
.LFB1: .cfi_startproc
/* Save the old stack pointer as AP. */ /* 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. */ /* Allocate the stack space we need. */
stwux %r1,%r1,%r4 stwux %r1,%r1,%r8
/* Save registers we use. */ /* Save registers we use. */
mflr %r9 mflr %r9
stw %r28,-16(%r8) stw %r28,-16(%r10)
.LCFI1: stw %r29,-12(%r10)
stw %r29,-12(%r8) stw %r30, -8(%r10)
.LCFI2: stw %r31, -4(%r10)
stw %r30, -8(%r8) stw %r9, 4(%r10)
.LCFI3: .cfi_offset 65, 4
stw %r31, -4(%r8) .cfi_offset 31, -4
.LCFI4: .cfi_offset 30, -8
stw %r9, 4(%r8) .cfi_offset 29, -12
.LCFI5: .cfi_offset 28, -16
/* Save arguments over call... */ /* Save arguments over call... */
mr %r31,%r5 /* flags, */ stw %r7, -20(%r10) /* closure, */
mr %r30,%r6 /* rvalue, */ mr %r31,%r6 /* flags, */
mr %r29,%r7 /* function address, */ mr %r30,%r5 /* rvalue, */
mr %r28,%r8 /* our AP. */ mr %r29,%r4 /* function address, */
.LCFI6: mr %r28,%r10 /* our AP. */
.cfi_def_cfa_register 28
/* Call ffi_prep_args_SYSV. */ /* Call ffi_prep_args_SYSV. */
mr %r4,%r1 mr %r4,%r1
@@ -70,35 +71,36 @@ ENTRY(ffi_call_SYSV)
/* Get the address to call into CTR. */ /* Get the address to call into CTR. */
mtctr %r29 mtctr %r29
/* Load all those argument registers. */ /* Load all those argument registers. */
lwz %r3,-16-(8*4)(%r28) lwz %r3,-24-(8*4)(%r28)
lwz %r4,-16-(7*4)(%r28) lwz %r4,-24-(7*4)(%r28)
lwz %r5,-16-(6*4)(%r28) lwz %r5,-24-(6*4)(%r28)
lwz %r6,-16-(5*4)(%r28) lwz %r6,-24-(5*4)(%r28)
bf- 5,1f bf- 5,1f
nop nop
lwz %r7,-16-(4*4)(%r28) lwz %r7,-24-(4*4)(%r28)
lwz %r8,-16-(3*4)(%r28) lwz %r8,-24-(3*4)(%r28)
lwz %r9,-16-(2*4)(%r28) lwz %r9,-24-(2*4)(%r28)
lwz %r10,-16-(1*4)(%r28) lwz %r10,-24-(1*4)(%r28)
nop nop
1: 1:
#ifndef __NO_FPRS__ #ifndef __NO_FPRS__
/* Load all the FP registers. */ /* Load all the FP registers. */
bf- 6,2f bf- 6,2f
lfd %f1,-16-(8*4)-(8*8)(%r28) lfd %f1,-24-(8*4)-(8*8)(%r28)
lfd %f2,-16-(8*4)-(7*8)(%r28) lfd %f2,-24-(8*4)-(7*8)(%r28)
lfd %f3,-16-(8*4)-(6*8)(%r28) lfd %f3,-24-(8*4)-(6*8)(%r28)
lfd %f4,-16-(8*4)-(5*8)(%r28) lfd %f4,-24-(8*4)-(5*8)(%r28)
nop nop
lfd %f5,-16-(8*4)-(4*8)(%r28) lfd %f5,-24-(8*4)-(4*8)(%r28)
lfd %f6,-16-(8*4)-(3*8)(%r28) lfd %f6,-24-(8*4)-(3*8)(%r28)
lfd %f7,-16-(8*4)-(2*8)(%r28) lfd %f7,-24-(8*4)-(2*8)(%r28)
lfd %f8,-16-(8*4)-(1*8)(%r28) lfd %f8,-24-(8*4)-(1*8)(%r28)
#endif #endif
2: 2:
/* Make the call. */ /* Make the call. */
lwz %r11, -20(%r28)
bctrl bctrl
/* Now, deal with the return value. */ /* Now, deal with the return value. */
@@ -125,11 +127,24 @@ L(done_return_value):
lwz %r30, -8(%r28) lwz %r30, -8(%r28)
lwz %r29,-12(%r28) lwz %r29,-12(%r28)
lwz %r28,-16(%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) lwz %r1,0(%r1)
.cfi_same_value 1
blr blr
#ifndef __NO_FPRS__ #ifndef __NO_FPRS__
L(fp_return_value): L(fp_return_value):
.cfi_restore_state
bf 28,L(float_return_value) bf 28,L(float_return_value)
stfd %f1,0(%r30) stfd %f1,0(%r30)
mtcrf 0x02,%r31 /* cr6 */ mtcrf 0x02,%r31 /* cr6 */
@@ -150,70 +165,10 @@ L(small_struct_return_value):
stw %r3, 0(%r30) stw %r3, 0(%r30)
stw %r4, 4(%r30) stw %r4, 4(%r30)
b L(done_return_value) b L(done_return_value)
.cfi_endproc
.LFE1:
END(ffi_call_SYSV) 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__ #if defined __ELF__ && defined __linux__
.section .note.GNU-stack,"",@progbits .section .note.GNU-stack,"",@progbits
#endif #endif