s390: Go closure support
This commit is contained in:
committed by
Richard Henderson
parent
75b2199f26
commit
02b7c89967
@@ -64,21 +64,6 @@
|
|||||||
|
|
||||||
/*===================== End of Defines ===============================*/
|
/*===================== End of Defines ===============================*/
|
||||||
|
|
||||||
/*====================================================================*/
|
|
||||||
/* Prototypes */
|
|
||||||
/* ---------- */
|
|
||||||
/*====================================================================*/
|
|
||||||
|
|
||||||
static void ffi_prep_args (unsigned char *, extended_cif *);
|
|
||||||
void
|
|
||||||
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
|
|
||||||
__attribute__ ((visibility ("hidden")))
|
|
||||||
#endif
|
|
||||||
ffi_closure_helper_SYSV (ffi_closure *, unsigned long *,
|
|
||||||
unsigned long long *, unsigned long *);
|
|
||||||
|
|
||||||
/*====================== End of Prototypes ===========================*/
|
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
/* Externals */
|
/* Externals */
|
||||||
/* --------- */
|
/* --------- */
|
||||||
@@ -89,9 +74,10 @@ extern void ffi_call_SYSV(unsigned,
|
|||||||
void (*)(unsigned char *, extended_cif *),
|
void (*)(unsigned char *, extended_cif *),
|
||||||
unsigned,
|
unsigned,
|
||||||
void *,
|
void *,
|
||||||
void (*fn)(void));
|
void (*fn)(void), void *);
|
||||||
|
|
||||||
extern void ffi_closure_SYSV(void);
|
extern void ffi_closure_SYSV(void);
|
||||||
|
extern void ffi_go_closure_SYSV(void);
|
||||||
|
|
||||||
/*====================== End of Externals ============================*/
|
/*====================== End of Externals ============================*/
|
||||||
|
|
||||||
@@ -504,11 +490,12 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
|||||||
/* */
|
/* */
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
void
|
static void
|
||||||
ffi_call(ffi_cif *cif,
|
ffi_call_int(ffi_cif *cif,
|
||||||
void (*fn)(void),
|
void (*fn)(void),
|
||||||
void *rvalue,
|
void *rvalue,
|
||||||
void **avalue)
|
void **avalue,
|
||||||
|
void *closure)
|
||||||
{
|
{
|
||||||
int ret_type = cif->flags;
|
int ret_type = cif->flags;
|
||||||
extended_cif ecif;
|
extended_cif ecif;
|
||||||
@@ -530,7 +517,7 @@ ffi_call(ffi_cif *cif,
|
|||||||
{
|
{
|
||||||
case FFI_SYSV:
|
case FFI_SYSV:
|
||||||
ffi_call_SYSV (cif->bytes, &ecif, ffi_prep_args,
|
ffi_call_SYSV (cif->bytes, &ecif, ffi_prep_args,
|
||||||
ret_type, ecif.rvalue, fn);
|
ret_type, ecif.rvalue, fn, closure);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -538,6 +525,19 @@ ffi_call(ffi_cif *cif,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
/*======================== End of Routine ============================*/
|
/*======================== End of Routine ============================*/
|
||||||
|
|
||||||
@@ -548,9 +548,12 @@ ffi_call(ffi_cif *cif,
|
|||||||
/* Function - Call a FFI closure target function. */
|
/* Function - Call a FFI closure target function. */
|
||||||
/* */
|
/* */
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
|
FFI_HIDDEN
|
||||||
void
|
void
|
||||||
ffi_closure_helper_SYSV (ffi_closure *closure,
|
ffi_closure_helper_SYSV (ffi_cif *cif,
|
||||||
|
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||||
|
void *user_data,
|
||||||
unsigned long *p_gpr,
|
unsigned long *p_gpr,
|
||||||
unsigned long long *p_fpr,
|
unsigned long long *p_fpr,
|
||||||
unsigned long *p_ov)
|
unsigned long *p_ov)
|
||||||
@@ -570,20 +573,18 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
|
|||||||
|
|
||||||
/* Allocate buffer for argument list pointers. */
|
/* Allocate buffer for argument list pointers. */
|
||||||
|
|
||||||
p_arg = avalue = alloca (closure->cif->nargs * sizeof (void *));
|
p_arg = avalue = alloca (cif->nargs * sizeof (void *));
|
||||||
|
|
||||||
/* If we returning a structure, pass the structure address
|
/* If we returning a structure, pass the structure address
|
||||||
directly to the target function. Otherwise, have the target
|
directly to the target function. Otherwise, have the target
|
||||||
function store the return value to the GPR save area. */
|
function store the return value to the GPR save area. */
|
||||||
|
|
||||||
if (closure->cif->flags == FFI390_RET_STRUCT)
|
if (cif->flags == FFI390_RET_STRUCT)
|
||||||
rvalue = (void *) p_gpr[n_gpr++];
|
rvalue = (void *) p_gpr[n_gpr++];
|
||||||
|
|
||||||
/* Now for the arguments. */
|
/* Now for the arguments. */
|
||||||
|
|
||||||
for (ptr = closure->cif->arg_types, i = closure->cif->nargs;
|
for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, p_arg++, ptr++)
|
||||||
i > 0;
|
|
||||||
i--, p_arg++, ptr++)
|
|
||||||
{
|
{
|
||||||
int deref_struct_pointer = 0;
|
int deref_struct_pointer = 0;
|
||||||
int type = (*ptr)->type;
|
int type = (*ptr)->type;
|
||||||
@@ -689,10 +690,10 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
|
|||||||
|
|
||||||
|
|
||||||
/* Call the target function. */
|
/* Call the target function. */
|
||||||
(closure->fun) (closure->cif, rvalue, avalue, closure->user_data);
|
(fun) (cif, rvalue, avalue, user_data);
|
||||||
|
|
||||||
/* Convert the return value. */
|
/* Convert the return value. */
|
||||||
switch (closure->cif->rtype->type)
|
switch (cif->rtype->type)
|
||||||
{
|
{
|
||||||
/* Void is easy, and so is struct. */
|
/* Void is easy, and so is struct. */
|
||||||
case FFI_TYPE_VOID:
|
case FFI_TYPE_VOID:
|
||||||
@@ -790,3 +791,18 @@ ffi_prep_closure_loc (ffi_closure *closure,
|
|||||||
|
|
||||||
/*======================== End of Routine ============================*/
|
/*======================== End of Routine ============================*/
|
||||||
|
|
||||||
|
/* Build a Go language closure. */
|
||||||
|
|
||||||
|
ffi_status
|
||||||
|
ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,
|
||||||
|
void (*fun)(ffi_cif*,void*,void**,void*))
|
||||||
|
{
|
||||||
|
if (cif->abi != FFI_SYSV)
|
||||||
|
return FFI_BAD_ABI;
|
||||||
|
|
||||||
|
closure->tramp = ffi_go_closure_SYSV;
|
||||||
|
closure->cif = cif;
|
||||||
|
closure->fun = fun;
|
||||||
|
|
||||||
|
return FFI_OK;
|
||||||
|
}
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ typedef enum ffi_abi {
|
|||||||
/* ---- Definitions for closures ----------------------------------------- */
|
/* ---- Definitions for closures ----------------------------------------- */
|
||||||
|
|
||||||
#define FFI_CLOSURES 1
|
#define FFI_CLOSURES 1
|
||||||
|
#define FFI_GO_CLOSURES 1
|
||||||
#ifdef S390X
|
#ifdef S390X
|
||||||
#define FFI_TRAMPOLINE_SIZE 32
|
#define FFI_TRAMPOLINE_SIZE 32
|
||||||
#else
|
#else
|
||||||
|
|||||||
457
src/s390/sysv.S
457
src/s390/sysv.S
@@ -39,18 +39,29 @@
|
|||||||
# r5: ret_type
|
# r5: ret_type
|
||||||
# r6: ecif.rvalue
|
# r6: ecif.rvalue
|
||||||
# ov: fn
|
# ov: fn
|
||||||
|
# ov+8: closure
|
||||||
|
|
||||||
# This assumes we are using gas.
|
# This assumes we are using gas.
|
||||||
.globl ffi_call_SYSV
|
.globl ffi_call_SYSV
|
||||||
|
FFI_HIDDEN(ffi_call_SYSV)
|
||||||
.type ffi_call_SYSV,%function
|
.type ffi_call_SYSV,%function
|
||||||
ffi_call_SYSV:
|
ffi_call_SYSV:
|
||||||
.LFB1:
|
.cfi_startproc
|
||||||
stm %r6,%r15,24(%r15) # Save registers
|
stm %r6,%r15,24(%r15) # Save registers
|
||||||
.LCFI0:
|
.cfi_offset r6, -72
|
||||||
|
.cfi_offset r7, -68
|
||||||
|
.cfi_offset r8, -64
|
||||||
|
.cfi_offset r9, -60
|
||||||
|
.cfi_offset r10, -56
|
||||||
|
.cfi_offset r11, -52
|
||||||
|
.cfi_offset r12, -48
|
||||||
|
.cfi_offset r13, -44
|
||||||
|
.cfi_offset r14, -40
|
||||||
|
.cfi_offset r15, -36
|
||||||
basr %r13,0 # Set up base register
|
basr %r13,0 # Set up base register
|
||||||
.Lbase:
|
.Lbase:
|
||||||
lr %r11,%r15 # Set up frame pointer
|
lr %r11,%r15 # Set up frame pointer
|
||||||
.LCFI1:
|
.cfi_def_cfa_register r11
|
||||||
sr %r15,%r2
|
sr %r15,%r2
|
||||||
ahi %r15,-96-48 # Allocate stack
|
ahi %r15,-96-48 # Allocate stack
|
||||||
lr %r8,%r6 # Save ecif.rvalue
|
lr %r8,%r6 # Save ecif.rvalue
|
||||||
@@ -59,12 +70,13 @@ ffi_call_SYSV:
|
|||||||
l %r7,96(%r11) # Load function address
|
l %r7,96(%r11) # Load function address
|
||||||
st %r11,0(%r15) # Set up back chain
|
st %r11,0(%r15) # Set up back chain
|
||||||
ahi %r11,-48 # Register save area
|
ahi %r11,-48 # Register save area
|
||||||
.LCFI2:
|
.cfi_adjust_cfa_offset 48
|
||||||
|
|
||||||
la %r2,96(%r15) # Save area
|
la %r2,96(%r15) # Save area
|
||||||
# r3 already holds &ecif
|
# r3 already holds &ecif
|
||||||
basr %r14,%r4 # Call ffi_prep_args
|
basr %r14,%r4 # Call ffi_prep_args
|
||||||
|
|
||||||
|
l %r0,96+48+4(%r11) # Go closure -> static chain
|
||||||
lm %r2,%r6,0(%r11) # Load arguments
|
lm %r2,%r6,0(%r11) # Load arguments
|
||||||
ld %f0,32(%r11)
|
ld %f0,32(%r11)
|
||||||
ld %f2,40(%r11)
|
ld %f2,40(%r11)
|
||||||
@@ -74,31 +86,106 @@ ffi_call_SYSV:
|
|||||||
.LretNone: # Return void
|
.LretNone: # Return void
|
||||||
l %r4,48+56(%r11)
|
l %r4,48+56(%r11)
|
||||||
lm %r6,%r15,48+24(%r11)
|
lm %r6,%r15,48+24(%r11)
|
||||||
|
.cfi_remember_state
|
||||||
|
.cfi_restore 15
|
||||||
|
.cfi_restore 14
|
||||||
|
.cfi_restore 13
|
||||||
|
.cfi_restore 12
|
||||||
|
.cfi_restore 11
|
||||||
|
.cfi_restore 10
|
||||||
|
.cfi_restore 9
|
||||||
|
.cfi_restore 8
|
||||||
|
.cfi_restore 7
|
||||||
|
.cfi_restore 6
|
||||||
|
.cfi_def_cfa r15, 96
|
||||||
br %r4
|
br %r4
|
||||||
|
.cfi_restore_state
|
||||||
|
# This nopr is necessary so that the .cfi instructions between the br
|
||||||
|
# above and the label below get executed. See execute_cfa_program() in
|
||||||
|
# the Gcc source code, libgcc/unwind-dw2.c.
|
||||||
|
nopr
|
||||||
|
|
||||||
.LretFloat:
|
.LretFloat:
|
||||||
l %r4,48+56(%r11)
|
l %r4,48+56(%r11)
|
||||||
ste %f0,0(%r8) # Return float
|
ste %f0,0(%r8) # Return float
|
||||||
lm %r6,%r15,48+24(%r11)
|
lm %r6,%r15,48+24(%r11)
|
||||||
|
.cfi_remember_state
|
||||||
|
.cfi_restore 15
|
||||||
|
.cfi_restore 14
|
||||||
|
.cfi_restore 13
|
||||||
|
.cfi_restore 12
|
||||||
|
.cfi_restore 11
|
||||||
|
.cfi_restore 10
|
||||||
|
.cfi_restore 9
|
||||||
|
.cfi_restore 8
|
||||||
|
.cfi_restore 7
|
||||||
|
.cfi_restore 6
|
||||||
|
.cfi_def_cfa r15, 96
|
||||||
br %r4
|
br %r4
|
||||||
|
.cfi_restore_state
|
||||||
|
# See comment on the nopr above.
|
||||||
|
nopr
|
||||||
|
|
||||||
.LretDouble:
|
.LretDouble:
|
||||||
l %r4,48+56(%r11)
|
l %r4,48+56(%r11)
|
||||||
std %f0,0(%r8) # Return double
|
std %f0,0(%r8) # Return double
|
||||||
lm %r6,%r15,48+24(%r11)
|
lm %r6,%r15,48+24(%r11)
|
||||||
|
.cfi_remember_state
|
||||||
|
.cfi_restore 15
|
||||||
|
.cfi_restore 14
|
||||||
|
.cfi_restore 13
|
||||||
|
.cfi_restore 12
|
||||||
|
.cfi_restore 11
|
||||||
|
.cfi_restore 10
|
||||||
|
.cfi_restore 9
|
||||||
|
.cfi_restore 8
|
||||||
|
.cfi_restore 7
|
||||||
|
.cfi_restore 6
|
||||||
|
.cfi_def_cfa r15, 96
|
||||||
br %r4
|
br %r4
|
||||||
|
.cfi_restore_state
|
||||||
|
# See comment on the nopr above.
|
||||||
|
nopr
|
||||||
|
|
||||||
.LretInt32:
|
.LretInt32:
|
||||||
l %r4,48+56(%r11)
|
l %r4,48+56(%r11)
|
||||||
st %r2,0(%r8) # Return int
|
st %r2,0(%r8) # Return int
|
||||||
lm %r6,%r15,48+24(%r11)
|
lm %r6,%r15,48+24(%r11)
|
||||||
|
.cfi_remember_state
|
||||||
|
.cfi_restore 15
|
||||||
|
.cfi_restore 14
|
||||||
|
.cfi_restore 13
|
||||||
|
.cfi_restore 12
|
||||||
|
.cfi_restore 11
|
||||||
|
.cfi_restore 10
|
||||||
|
.cfi_restore 9
|
||||||
|
.cfi_restore 8
|
||||||
|
.cfi_restore 7
|
||||||
|
.cfi_restore 6
|
||||||
|
.cfi_def_cfa r15, 96
|
||||||
br %r4
|
br %r4
|
||||||
|
.cfi_restore_state
|
||||||
|
# See comment on the nopr above.
|
||||||
|
nopr
|
||||||
|
|
||||||
.LretInt64:
|
.LretInt64:
|
||||||
l %r4,48+56(%r11)
|
l %r4,48+56(%r11)
|
||||||
stm %r2,%r3,0(%r8) # Return long long
|
stm %r2,%r3,0(%r8) # Return long long
|
||||||
lm %r6,%r15,48+24(%r11)
|
lm %r6,%r15,48+24(%r11)
|
||||||
|
.cfi_remember_state
|
||||||
|
.cfi_restore 15
|
||||||
|
.cfi_restore 14
|
||||||
|
.cfi_restore 13
|
||||||
|
.cfi_restore 12
|
||||||
|
.cfi_restore 11
|
||||||
|
.cfi_restore 10
|
||||||
|
.cfi_restore 9
|
||||||
|
.cfi_restore 8
|
||||||
|
.cfi_restore 7
|
||||||
|
.cfi_restore 6
|
||||||
|
.cfi_def_cfa r15, 96
|
||||||
br %r4
|
br %r4
|
||||||
|
.cfi_endproc
|
||||||
|
|
||||||
.Ltable:
|
.Ltable:
|
||||||
.byte .LretNone-.Lbase # FFI390_RET_VOID
|
.byte .LretNone-.Lbase # FFI390_RET_VOID
|
||||||
@@ -108,129 +195,78 @@ ffi_call_SYSV:
|
|||||||
.byte .LretInt32-.Lbase # FFI390_RET_INT32
|
.byte .LretInt32-.Lbase # FFI390_RET_INT32
|
||||||
.byte .LretInt64-.Lbase # FFI390_RET_INT64
|
.byte .LretInt64-.Lbase # FFI390_RET_INT64
|
||||||
|
|
||||||
.LFE1:
|
|
||||||
.ffi_call_SYSV_end:
|
.ffi_call_SYSV_end:
|
||||||
.size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
|
.size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
|
||||||
|
|
||||||
|
|
||||||
.globl ffi_closure_SYSV
|
.globl ffi_closure_SYSV
|
||||||
|
FFI_HIDDEN(ffi_closure_SYSV)
|
||||||
.type ffi_closure_SYSV,%function
|
.type ffi_closure_SYSV,%function
|
||||||
ffi_closure_SYSV:
|
ffi_closure_SYSV:
|
||||||
.LFB2:
|
.cfi_startproc
|
||||||
|
stm %r2,%r6,8(%r15) # Save arguments
|
||||||
|
.cfi_offset r6, -72
|
||||||
|
lr %r4,%r0 # Closure
|
||||||
|
l %r2,16(%r4) # ->cif
|
||||||
|
l %r3,20(%r4) # ->fun
|
||||||
|
l %r4,24(%r4) # ->user_data
|
||||||
|
.Ldoclosure:
|
||||||
stm %r12,%r15,48(%r15) # Save registers
|
stm %r12,%r15,48(%r15) # Save registers
|
||||||
.LCFI10:
|
.cfi_offset r12, -48
|
||||||
|
.cfi_offset r13, -44
|
||||||
|
.cfi_offset r14, -40
|
||||||
|
.cfi_offset r15, -36
|
||||||
basr %r13,0 # Set up base register
|
basr %r13,0 # Set up base register
|
||||||
.Lcbase:
|
.Lcbase:
|
||||||
stm %r2,%r6,8(%r15) # Save arguments
|
|
||||||
std %f0,64(%r15)
|
std %f0,64(%r15)
|
||||||
std %f2,72(%r15)
|
std %f2,72(%r15)
|
||||||
lr %r1,%r15 # Set up stack frame
|
lr %r1,%r15 # Set up stack frame
|
||||||
ahi %r15,-96
|
ahi %r15,-104
|
||||||
.LCFI11:
|
.cfi_adjust_cfa_offset 104
|
||||||
l %r12,.Lchelper-.Lcbase(%r13) # Get helper function
|
l %r12,.Lchelper-.Lcbase(%r13) # Get helper function
|
||||||
lr %r2,%r0 # Closure
|
la %r5,96(%r1)
|
||||||
la %r3,8(%r1) # GPRs
|
st %r5,96(%r15) # Overflow
|
||||||
la %r4,64(%r1) # FPRs
|
la %r5,8(%r1) # GPRs
|
||||||
la %r5,96(%r1) # Overflow
|
la %r6,64(%r1) # FPRs
|
||||||
st %r1,0(%r15) # Set up back chain
|
st %r1,0(%r15) # Set up back chain
|
||||||
|
|
||||||
bas %r14,0(%r12,%r13) # Call helper
|
bas %r14,0(%r12,%r13) # Call helper
|
||||||
|
|
||||||
l %r4,96+56(%r15)
|
l %r4,104+56(%r15)
|
||||||
ld %f0,96+64(%r15) # Load return registers
|
ld %f0,104+64(%r15) # Load return registers
|
||||||
lm %r2,%r3,96+8(%r15)
|
lm %r2,%r3,104+8(%r15)
|
||||||
lm %r12,%r15,96+48(%r15)
|
l %r6,104+24(%r15) # Restore saved registers
|
||||||
|
.cfi_restore r6
|
||||||
|
lm %r12,%r15,104+48(%r15)
|
||||||
|
.cfi_adjust_cfa_offset -104
|
||||||
|
.cfi_restore r12
|
||||||
|
.cfi_restore r13
|
||||||
|
.cfi_restore r14
|
||||||
|
.cfi_restore r15
|
||||||
br %r4
|
br %r4
|
||||||
|
.cfi_endproc
|
||||||
|
|
||||||
.align 4
|
.align 4
|
||||||
.Lchelper:
|
.Lchelper:
|
||||||
.long ffi_closure_helper_SYSV-.Lcbase
|
.long ffi_closure_helper_SYSV-.Lcbase
|
||||||
|
|
||||||
.LFE2:
|
|
||||||
|
|
||||||
.ffi_closure_SYSV_end:
|
.ffi_closure_SYSV_end:
|
||||||
.size ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
|
.size ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
|
||||||
|
|
||||||
|
|
||||||
.section .eh_frame,EH_FRAME_FLAGS,@progbits
|
.globl ffi_go_closure_SYSV
|
||||||
.Lframe1:
|
FFI_HIDDEN(ffi_go_closure_SYSV)
|
||||||
.4byte .LECIE1-.LSCIE1 # Length of Common Information Entry
|
.type ffi_go_closure_SYSV,%function
|
||||||
.LSCIE1:
|
ffi_go_closure_SYSV:
|
||||||
.4byte 0x0 # CIE Identifier Tag
|
.cfi_startproc
|
||||||
.byte 0x1 # CIE Version
|
stm %r2,%r6,8(%r15) # Save arguments
|
||||||
.ascii "zR\0" # CIE Augmentation
|
.cfi_offset r6, -72
|
||||||
.uleb128 0x1 # CIE Code Alignment Factor
|
lr %r4,%r0 # Load closure -> user_data
|
||||||
.sleb128 -4 # CIE Data Alignment Factor
|
l %r2,4(%r4) # ->cif
|
||||||
.byte 0xe # CIE RA Column
|
l %r3,8(%r4) # ->fun
|
||||||
.uleb128 0x1 # Augmentation size
|
j .Ldoclosure
|
||||||
.byte 0x1b # FDE Encoding (pcrel sdata4)
|
.cfi_endproc
|
||||||
.byte 0xc # DW_CFA_def_cfa
|
|
||||||
.uleb128 0xf
|
|
||||||
.uleb128 0x60
|
|
||||||
.align 4
|
|
||||||
.LECIE1:
|
|
||||||
.LSFDE1:
|
|
||||||
.4byte .LEFDE1-.LASFDE1 # FDE Length
|
|
||||||
.LASFDE1:
|
|
||||||
.4byte .LASFDE1-.Lframe1 # FDE CIE offset
|
|
||||||
.4byte .LFB1-. # FDE initial location
|
|
||||||
.4byte .LFE1-.LFB1 # FDE address range
|
|
||||||
.uleb128 0x0 # Augmentation size
|
|
||||||
.byte 0x4 # DW_CFA_advance_loc4
|
|
||||||
.4byte .LCFI0-.LFB1
|
|
||||||
.byte 0x8f # DW_CFA_offset, column 0xf
|
|
||||||
.uleb128 0x9
|
|
||||||
.byte 0x8e # DW_CFA_offset, column 0xe
|
|
||||||
.uleb128 0xa
|
|
||||||
.byte 0x8d # DW_CFA_offset, column 0xd
|
|
||||||
.uleb128 0xb
|
|
||||||
.byte 0x8c # DW_CFA_offset, column 0xc
|
|
||||||
.uleb128 0xc
|
|
||||||
.byte 0x8b # DW_CFA_offset, column 0xb
|
|
||||||
.uleb128 0xd
|
|
||||||
.byte 0x8a # DW_CFA_offset, column 0xa
|
|
||||||
.uleb128 0xe
|
|
||||||
.byte 0x89 # DW_CFA_offset, column 0x9
|
|
||||||
.uleb128 0xf
|
|
||||||
.byte 0x88 # DW_CFA_offset, column 0x8
|
|
||||||
.uleb128 0x10
|
|
||||||
.byte 0x87 # DW_CFA_offset, column 0x7
|
|
||||||
.uleb128 0x11
|
|
||||||
.byte 0x86 # DW_CFA_offset, column 0x6
|
|
||||||
.uleb128 0x12
|
|
||||||
.byte 0x4 # DW_CFA_advance_loc4
|
|
||||||
.4byte .LCFI1-.LCFI0
|
|
||||||
.byte 0xd # DW_CFA_def_cfa_register
|
|
||||||
.uleb128 0xb
|
|
||||||
.byte 0x4 # DW_CFA_advance_loc4
|
|
||||||
.4byte .LCFI2-.LCFI1
|
|
||||||
.byte 0xe # DW_CFA_def_cfa_offset
|
|
||||||
.uleb128 0x90
|
|
||||||
.align 4
|
|
||||||
.LEFDE1:
|
|
||||||
.LSFDE2:
|
|
||||||
.4byte .LEFDE2-.LASFDE2 # FDE Length
|
|
||||||
.LASFDE2:
|
|
||||||
.4byte .LASFDE2-.Lframe1 # FDE CIE offset
|
|
||||||
.4byte .LFB2-. # FDE initial location
|
|
||||||
.4byte .LFE2-.LFB2 # FDE address range
|
|
||||||
.uleb128 0x0 # Augmentation size
|
|
||||||
.byte 0x4 # DW_CFA_advance_loc4
|
|
||||||
.4byte .LCFI10-.LFB2
|
|
||||||
.byte 0x8f # DW_CFA_offset, column 0xf
|
|
||||||
.uleb128 0x9
|
|
||||||
.byte 0x8e # DW_CFA_offset, column 0xe
|
|
||||||
.uleb128 0xa
|
|
||||||
.byte 0x8d # DW_CFA_offset, column 0xd
|
|
||||||
.uleb128 0xb
|
|
||||||
.byte 0x8c # DW_CFA_offset, column 0xc
|
|
||||||
.uleb128 0xc
|
|
||||||
.byte 0x4 # DW_CFA_advance_loc4
|
|
||||||
.4byte .LCFI11-.LCFI10
|
|
||||||
.byte 0xe # DW_CFA_def_cfa_offset
|
|
||||||
.uleb128 0xc0
|
|
||||||
.align 4
|
|
||||||
.LEFDE2:
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -242,17 +278,28 @@ ffi_closure_SYSV:
|
|||||||
# r5: ret_type
|
# r5: ret_type
|
||||||
# r6: ecif.rvalue
|
# r6: ecif.rvalue
|
||||||
# ov: fn
|
# ov: fn
|
||||||
|
# ov+8: closure
|
||||||
|
|
||||||
# This assumes we are using gas.
|
# This assumes we are using gas.
|
||||||
.globl ffi_call_SYSV
|
.globl ffi_call_SYSV
|
||||||
|
FFI_HIDDEN(ffi_call_SYSV)
|
||||||
.type ffi_call_SYSV,%function
|
.type ffi_call_SYSV,%function
|
||||||
ffi_call_SYSV:
|
ffi_call_SYSV:
|
||||||
.LFB1:
|
.cfi_startproc
|
||||||
stmg %r6,%r15,48(%r15) # Save registers
|
stmg %r6,%r15,48(%r15) # Save registers
|
||||||
.LCFI0:
|
.cfi_offset r6, -112
|
||||||
|
.cfi_offset r7, -104
|
||||||
|
.cfi_offset r8, -96
|
||||||
|
.cfi_offset r9, -88
|
||||||
|
.cfi_offset r10, -80
|
||||||
|
.cfi_offset r11, -72
|
||||||
|
.cfi_offset r12, -64
|
||||||
|
.cfi_offset r13, -56
|
||||||
|
.cfi_offset r14, -48
|
||||||
|
.cfi_offset r15, -40
|
||||||
larl %r13,.Lbase # Set up base register
|
larl %r13,.Lbase # Set up base register
|
||||||
lgr %r11,%r15 # Set up frame pointer
|
lgr %r11,%r15 # Set up frame pointer
|
||||||
.LCFI1:
|
.cfi_def_cfa_register r11
|
||||||
sgr %r15,%r2
|
sgr %r15,%r2
|
||||||
aghi %r15,-160-80 # Allocate stack
|
aghi %r15,-160-80 # Allocate stack
|
||||||
lgr %r8,%r6 # Save ecif.rvalue
|
lgr %r8,%r6 # Save ecif.rvalue
|
||||||
@@ -260,12 +307,13 @@ ffi_call_SYSV:
|
|||||||
lg %r7,160(%r11) # Load function address
|
lg %r7,160(%r11) # Load function address
|
||||||
stg %r11,0(%r15) # Set up back chain
|
stg %r11,0(%r15) # Set up back chain
|
||||||
aghi %r11,-80 # Register save area
|
aghi %r11,-80 # Register save area
|
||||||
.LCFI2:
|
.cfi_adjust_cfa_offset 80
|
||||||
|
|
||||||
la %r2,160(%r15) # Save area
|
la %r2,160(%r15) # Save area
|
||||||
# r3 already holds &ecif
|
# r3 already holds &ecif
|
||||||
basr %r14,%r4 # Call ffi_prep_args
|
basr %r14,%r4 # Call ffi_prep_args
|
||||||
|
|
||||||
|
lg %r0,160+80+8(%r11) # Go closure -> static chain
|
||||||
lmg %r2,%r6,0(%r11) # Load arguments
|
lmg %r2,%r6,0(%r11) # Load arguments
|
||||||
ld %f0,48(%r11)
|
ld %f0,48(%r11)
|
||||||
ld %f2,56(%r11)
|
ld %f2,56(%r11)
|
||||||
@@ -278,154 +326,157 @@ ffi_call_SYSV:
|
|||||||
.LretNone: # Return void
|
.LretNone: # Return void
|
||||||
lg %r4,80+112(%r11)
|
lg %r4,80+112(%r11)
|
||||||
lmg %r6,%r15,80+48(%r11)
|
lmg %r6,%r15,80+48(%r11)
|
||||||
|
.cfi_remember_state
|
||||||
|
.cfi_restore r15
|
||||||
|
.cfi_restore r14
|
||||||
|
.cfi_restore r13
|
||||||
|
.cfi_restore r12
|
||||||
|
.cfi_restore r11
|
||||||
|
.cfi_restore r10
|
||||||
|
.cfi_restore r9
|
||||||
|
.cfi_restore r8
|
||||||
|
.cfi_restore r7
|
||||||
|
.cfi_restore r6
|
||||||
|
.cfi_def_cfa r15, 160
|
||||||
br %r4
|
br %r4
|
||||||
|
.cfi_restore_state
|
||||||
|
# This nopr is necessary so that the .cfi instructions between the br
|
||||||
|
# above and the label below get executed. See execute_cfa_program() in
|
||||||
|
# the Gcc source code, libgcc/unwind-dw2.c.
|
||||||
|
nopr
|
||||||
|
|
||||||
.LretFloat:
|
.LretFloat:
|
||||||
lg %r4,80+112(%r11)
|
lg %r4,80+112(%r11)
|
||||||
ste %f0,0(%r8) # Return float
|
ste %f0,0(%r8) # Return float
|
||||||
lmg %r6,%r15,80+48(%r11)
|
lmg %r6,%r15,80+48(%r11)
|
||||||
|
.cfi_remember_state
|
||||||
|
.cfi_restore r6
|
||||||
|
.cfi_restore r7
|
||||||
|
.cfi_restore r8
|
||||||
|
.cfi_restore r9
|
||||||
|
.cfi_restore r10
|
||||||
|
.cfi_restore r11
|
||||||
|
.cfi_restore r12
|
||||||
|
.cfi_restore r13
|
||||||
|
.cfi_restore r14
|
||||||
|
.cfi_restore r15
|
||||||
|
.cfi_def_cfa r15, 160
|
||||||
br %r4
|
br %r4
|
||||||
|
.cfi_restore_state
|
||||||
|
# See comment on the nopr above.
|
||||||
|
nopr
|
||||||
|
|
||||||
.LretDouble:
|
.LretDouble:
|
||||||
lg %r4,80+112(%r11)
|
lg %r4,80+112(%r11)
|
||||||
std %f0,0(%r8) # Return double
|
std %f0,0(%r8) # Return double
|
||||||
lmg %r6,%r15,80+48(%r11)
|
lmg %r6,%r15,80+48(%r11)
|
||||||
|
.cfi_remember_state
|
||||||
|
.cfi_restore r15
|
||||||
|
.cfi_restore r14
|
||||||
|
.cfi_restore r13
|
||||||
|
.cfi_restore r12
|
||||||
|
.cfi_restore r11
|
||||||
|
.cfi_restore r10
|
||||||
|
.cfi_restore r9
|
||||||
|
.cfi_restore r8
|
||||||
|
.cfi_restore r7
|
||||||
|
.cfi_restore r6
|
||||||
|
.cfi_def_cfa r15, 160
|
||||||
br %r4
|
br %r4
|
||||||
|
.cfi_restore_state
|
||||||
|
# See comment on the nopr above.
|
||||||
|
nopr
|
||||||
|
|
||||||
.LretInt32:
|
|
||||||
lg %r4,80+112(%r11)
|
|
||||||
st %r2,0(%r8) # Return int
|
|
||||||
lmg %r6,%r15,80+48(%r11)
|
|
||||||
br %r4
|
|
||||||
|
|
||||||
.LretInt64:
|
.LretInt64:
|
||||||
lg %r4,80+112(%r11)
|
lg %r4,80+112(%r11)
|
||||||
stg %r2,0(%r8) # Return long
|
stg %r2,0(%r8) # Return long
|
||||||
lmg %r6,%r15,80+48(%r11)
|
lmg %r6,%r15,80+48(%r11)
|
||||||
|
.cfi_restore r15
|
||||||
|
.cfi_restore r14
|
||||||
|
.cfi_restore r13
|
||||||
|
.cfi_restore r12
|
||||||
|
.cfi_restore r11
|
||||||
|
.cfi_restore r10
|
||||||
|
.cfi_restore r9
|
||||||
|
.cfi_restore r8
|
||||||
|
.cfi_restore r7
|
||||||
|
.cfi_restore r6
|
||||||
|
.cfi_def_cfa r15, 160
|
||||||
br %r4
|
br %r4
|
||||||
|
.cfi_endproc
|
||||||
|
|
||||||
.Ltable:
|
.Ltable:
|
||||||
.byte .LretNone-.Lbase # FFI390_RET_VOID
|
.byte .LretNone-.Lbase # FFI390_RET_VOID
|
||||||
.byte .LretNone-.Lbase # FFI390_RET_STRUCT
|
.byte .LretNone-.Lbase # FFI390_RET_STRUCT
|
||||||
.byte .LretFloat-.Lbase # FFI390_RET_FLOAT
|
.byte .LretFloat-.Lbase # FFI390_RET_FLOAT
|
||||||
.byte .LretDouble-.Lbase # FFI390_RET_DOUBLE
|
.byte .LretDouble-.Lbase # FFI390_RET_DOUBLE
|
||||||
.byte .LretInt32-.Lbase # FFI390_RET_INT32
|
.byte 0 # int32 retval not supported
|
||||||
.byte .LretInt64-.Lbase # FFI390_RET_INT64
|
.byte .LretInt64-.Lbase # FFI390_RET_INT64
|
||||||
|
|
||||||
.LFE1:
|
|
||||||
.ffi_call_SYSV_end:
|
.ffi_call_SYSV_end:
|
||||||
.size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
|
.size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
|
||||||
|
|
||||||
|
|
||||||
.globl ffi_closure_SYSV
|
.globl ffi_closure_SYSV
|
||||||
|
FFI_HIDDEN(ffi_closure_SYSV)
|
||||||
.type ffi_closure_SYSV,%function
|
.type ffi_closure_SYSV,%function
|
||||||
ffi_closure_SYSV:
|
ffi_closure_SYSV:
|
||||||
.LFB2:
|
.cfi_startproc
|
||||||
stmg %r14,%r15,112(%r15) # Save registers
|
|
||||||
.LCFI10:
|
|
||||||
stmg %r2,%r6,16(%r15) # Save arguments
|
stmg %r2,%r6,16(%r15) # Save arguments
|
||||||
std %f0,128(%r15)
|
.cfi_offset r6, -112
|
||||||
|
lgr %r4,%r0 # Load closure
|
||||||
|
lg %r2,32(%r4) # ->cif
|
||||||
|
lg %r3,40(%r4) # ->fun
|
||||||
|
lg %r4,48(%r4) # ->user_data
|
||||||
|
.Ldoclosure:
|
||||||
|
stmg %r14,%r15,112(%r15) # Save registers
|
||||||
|
.cfi_offset r14, -48
|
||||||
|
.cfi_offset r15, -40
|
||||||
|
std %f0,128(%r15) # Save arguments
|
||||||
std %f2,136(%r15)
|
std %f2,136(%r15)
|
||||||
std %f4,144(%r15)
|
std %f4,144(%r15)
|
||||||
std %f6,152(%r15)
|
std %f6,152(%r15)
|
||||||
lgr %r1,%r15 # Set up stack frame
|
lgr %r1,%r15 # Set up stack frame
|
||||||
aghi %r15,-160
|
aghi %r15,-168
|
||||||
.LCFI11:
|
.cfi_adjust_cfa_offset 168
|
||||||
lgr %r2,%r0 # Closure
|
la %r5,160(%r1)
|
||||||
la %r3,16(%r1) # GPRs
|
stg %r5,160(%r15) # Overflow
|
||||||
la %r4,128(%r1) # FPRs
|
la %r5,16(%r1) # GPRs
|
||||||
la %r5,160(%r1) # Overflow
|
la %r6,128(%r1) # FPRs
|
||||||
stg %r1,0(%r15) # Set up back chain
|
stg %r1,0(%r15) # Set up back chain
|
||||||
|
|
||||||
brasl %r14,ffi_closure_helper_SYSV # Call helper
|
brasl %r14,ffi_closure_helper_SYSV # Call helper
|
||||||
|
|
||||||
lg %r14,160+112(%r15)
|
ld %f0,168+128(%r15) # Load return registers
|
||||||
ld %f0,160+128(%r15) # Load return registers
|
lg %r2,168+16(%r15)
|
||||||
lg %r2,160+16(%r15)
|
lg %r6,168+48(%r15) # Restore saved registers
|
||||||
la %r15,160(%r15)
|
.cfi_restore r6
|
||||||
|
lmg %r14,%r15,168+112(%r15)
|
||||||
|
.cfi_restore r14
|
||||||
|
.cfi_restore r15
|
||||||
|
.cfi_adjust_cfa_offset -168
|
||||||
br %r14
|
br %r14
|
||||||
.LFE2:
|
.cfi_endproc
|
||||||
|
|
||||||
.ffi_closure_SYSV_end:
|
.ffi_closure_SYSV_end:
|
||||||
.size ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
|
.size ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
|
||||||
|
|
||||||
|
|
||||||
|
.globl ffi_go_closure_SYSV
|
||||||
|
FFI_HIDDEN(ffi_go_closure_SYSV)
|
||||||
|
.type ffi_go_closure_SYSV,%function
|
||||||
|
ffi_go_closure_SYSV:
|
||||||
|
.cfi_startproc
|
||||||
|
stmg %r2,%r6,16(%r15) # Save arguments
|
||||||
|
.cfi_offset r6, -112
|
||||||
|
lgr %r4,%r0 # Load closure -> user_data
|
||||||
|
lg %r2,8(%r4) # ->cif
|
||||||
|
lg %r3,16(%r4) # ->fun
|
||||||
|
j .Ldoclosure
|
||||||
|
.cfi_endproc
|
||||||
|
|
||||||
|
.ffi_go_closure_SYSV_end:
|
||||||
.section .eh_frame,EH_FRAME_FLAGS,@progbits
|
.size ffi_go_closure_SYSV,.ffi_go_closure_SYSV_end-ffi_go_closure_SYSV
|
||||||
.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 0xe # CIE RA Column
|
|
||||||
.uleb128 0x1 # Augmentation size
|
|
||||||
.byte 0x1b # FDE Encoding (pcrel sdata4)
|
|
||||||
.byte 0xc # DW_CFA_def_cfa
|
|
||||||
.uleb128 0xf
|
|
||||||
.uleb128 0xa0
|
|
||||||
.align 8
|
|
||||||
.LECIE1:
|
|
||||||
.LSFDE1:
|
|
||||||
.4byte .LEFDE1-.LASFDE1 # FDE Length
|
|
||||||
.LASFDE1:
|
|
||||||
.4byte .LASFDE1-.Lframe1 # FDE CIE offset
|
|
||||||
.4byte .LFB1-. # FDE initial location
|
|
||||||
.4byte .LFE1-.LFB1 # FDE address range
|
|
||||||
.uleb128 0x0 # Augmentation size
|
|
||||||
.byte 0x4 # DW_CFA_advance_loc4
|
|
||||||
.4byte .LCFI0-.LFB1
|
|
||||||
.byte 0x8f # DW_CFA_offset, column 0xf
|
|
||||||
.uleb128 0x5
|
|
||||||
.byte 0x8e # DW_CFA_offset, column 0xe
|
|
||||||
.uleb128 0x6
|
|
||||||
.byte 0x8d # DW_CFA_offset, column 0xd
|
|
||||||
.uleb128 0x7
|
|
||||||
.byte 0x8c # DW_CFA_offset, column 0xc
|
|
||||||
.uleb128 0x8
|
|
||||||
.byte 0x8b # DW_CFA_offset, column 0xb
|
|
||||||
.uleb128 0x9
|
|
||||||
.byte 0x8a # DW_CFA_offset, column 0xa
|
|
||||||
.uleb128 0xa
|
|
||||||
.byte 0x89 # DW_CFA_offset, column 0x9
|
|
||||||
.uleb128 0xb
|
|
||||||
.byte 0x88 # DW_CFA_offset, column 0x8
|
|
||||||
.uleb128 0xc
|
|
||||||
.byte 0x87 # DW_CFA_offset, column 0x7
|
|
||||||
.uleb128 0xd
|
|
||||||
.byte 0x86 # DW_CFA_offset, column 0x6
|
|
||||||
.uleb128 0xe
|
|
||||||
.byte 0x4 # DW_CFA_advance_loc4
|
|
||||||
.4byte .LCFI1-.LCFI0
|
|
||||||
.byte 0xd # DW_CFA_def_cfa_register
|
|
||||||
.uleb128 0xb
|
|
||||||
.byte 0x4 # DW_CFA_advance_loc4
|
|
||||||
.4byte .LCFI2-.LCFI1
|
|
||||||
.byte 0xe # DW_CFA_def_cfa_offset
|
|
||||||
.uleb128 0xf0
|
|
||||||
.align 8
|
|
||||||
.LEFDE1:
|
|
||||||
.LSFDE2:
|
|
||||||
.4byte .LEFDE2-.LASFDE2 # FDE Length
|
|
||||||
.LASFDE2:
|
|
||||||
.4byte .LASFDE2-.Lframe1 # FDE CIE offset
|
|
||||||
.4byte .LFB2-. # FDE initial location
|
|
||||||
.4byte .LFE2-.LFB2 # FDE address range
|
|
||||||
.uleb128 0x0 # Augmentation size
|
|
||||||
.byte 0x4 # DW_CFA_advance_loc4
|
|
||||||
.4byte .LCFI10-.LFB2
|
|
||||||
.byte 0x8f # DW_CFA_offset, column 0xf
|
|
||||||
.uleb128 0x5
|
|
||||||
.byte 0x8e # DW_CFA_offset, column 0xe
|
|
||||||
.uleb128 0x6
|
|
||||||
.byte 0x4 # DW_CFA_advance_loc4
|
|
||||||
.4byte .LCFI11-.LCFI10
|
|
||||||
.byte 0xe # DW_CFA_def_cfa_offset
|
|
||||||
.uleb128 0x140
|
|
||||||
.align 8
|
|
||||||
.LEFDE2:
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user