ffi.c (ffi_struct_type): Put type declaration on separate line.
* src/pa/ffi.c (ffi_struct_type): Put type declaration on separate line. (ffi_prep_args_pa32): Likewise. (ffi_size_stack_pa32): Likewise. (ffi_prep_cif_machdep): Likewise. (ffi_call): Likewise. Rename to ffi_call_int. Add closure argument and update call to ffi_call_pa32. (ffi_call, ffi_call_go, ffi_prep_go_closure): New. (ffi_closure_inner_pa32): Update to handle go closures. * src/pa/ffitarget.h (FFI_GO_CLOSURES): Define. * src/pa/hpux32.S (ffi_call_pa32): Pass go closure argument in static chain register (%ret1). (ffi_closure_pa32): Set closure type argument to zero. (ffi_go_closure_pa32): New function. Add unwind data for it. * src/pa/linux.S: Likewise. Use cfi directives for unwind data. * testsuite/libffi.go/static-chain.h (STATIC_CHAIN_REG): Define for hppa. From-SVN: r239978
This commit is contained in:
parent
d6598cf719
commit
5961d13d27
|
@ -1,3 +1,22 @@
|
||||||
|
2016-09-04 John David Anglin <danglin@gcc.gnu.org>
|
||||||
|
|
||||||
|
* src/pa/ffi.c (ffi_struct_type): Put type declaration on separate line.
|
||||||
|
(ffi_prep_args_pa32): Likewise.
|
||||||
|
(ffi_size_stack_pa32): Likewise.
|
||||||
|
(ffi_prep_cif_machdep): Likewise.
|
||||||
|
(ffi_call): Likewise. Rename to ffi_call_int. Add closure argument
|
||||||
|
and update call to ffi_call_pa32.
|
||||||
|
(ffi_call, ffi_call_go, ffi_prep_go_closure): New.
|
||||||
|
(ffi_closure_inner_pa32): Update to handle go closures.
|
||||||
|
* src/pa/ffitarget.h (FFI_GO_CLOSURES): Define.
|
||||||
|
* src/pa/hpux32.S (ffi_call_pa32): Pass go closure argument in static
|
||||||
|
chain register (%ret1).
|
||||||
|
(ffi_closure_pa32): Set closure type argument to zero.
|
||||||
|
(ffi_go_closure_pa32): New function. Add unwind data for it.
|
||||||
|
* src/pa/linux.S: Likewise. Use cfi directives for unwind data.
|
||||||
|
* testsuite/libffi.go/static-chain.h (STATIC_CHAIN_REG): Define for
|
||||||
|
hppa.
|
||||||
|
|
||||||
2016-05-23 Thomas Schwinge <thomas@codesourcery.com>
|
2016-05-23 Thomas Schwinge <thomas@codesourcery.com>
|
||||||
|
|
||||||
PR libffi/65567
|
PR libffi/65567
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* -----------------------------------------------------------------------
|
/* -----------------------------------------------------------------------
|
||||||
ffi.c - (c) 2011 Anthony Green
|
ffi.c - (c) 2016 John David Anglin
|
||||||
|
(c) 2011 Anthony Green
|
||||||
(c) 2008 Red Hat, Inc.
|
(c) 2008 Red Hat, Inc.
|
||||||
(c) 2006 Free Software Foundation, Inc.
|
(c) 2006 Free Software Foundation, Inc.
|
||||||
(c) 2003-2004 Randolph Chung <tausq@debian.org>
|
(c) 2003-2004 Randolph Chung <tausq@debian.org>
|
||||||
|
@ -51,7 +52,8 @@
|
||||||
|
|
||||||
#define debug(lvl, x...) do { if (lvl <= DEBUG_LEVEL) { printf(x); } } while (0)
|
#define debug(lvl, x...) do { if (lvl <= DEBUG_LEVEL) { printf(x); } } while (0)
|
||||||
|
|
||||||
static inline int ffi_struct_type(ffi_type *t)
|
static inline int
|
||||||
|
ffi_struct_type (ffi_type *t)
|
||||||
{
|
{
|
||||||
size_t sz = t->size;
|
size_t sz = t->size;
|
||||||
|
|
||||||
|
@ -139,7 +141,8 @@ static inline int ffi_struct_type(ffi_type *t)
|
||||||
NOTE: We load floating point args in this function... that means we
|
NOTE: We load floating point args in this function... that means we
|
||||||
assume gcc will not mess with fp regs in here. */
|
assume gcc will not mess with fp regs in here. */
|
||||||
|
|
||||||
void ffi_prep_args_pa32(UINT32 *stack, extended_cif *ecif, unsigned bytes)
|
void
|
||||||
|
ffi_prep_args_pa32 (UINT32 *stack, extended_cif *ecif, unsigned bytes)
|
||||||
{
|
{
|
||||||
register unsigned int i;
|
register unsigned int i;
|
||||||
register ffi_type **p_arg;
|
register ffi_type **p_arg;
|
||||||
|
@ -275,7 +278,8 @@ void ffi_prep_args_pa32(UINT32 *stack, extended_cif *ecif, unsigned bytes)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ffi_size_stack_pa32(ffi_cif *cif)
|
static void
|
||||||
|
ffi_size_stack_pa32 (ffi_cif *cif)
|
||||||
{
|
{
|
||||||
ffi_type **ptr;
|
ffi_type **ptr;
|
||||||
int i;
|
int i;
|
||||||
|
@ -316,7 +320,8 @@ static void ffi_size_stack_pa32(ffi_cif *cif)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform machine dependent cif processing. */
|
/* Perform machine dependent cif processing. */
|
||||||
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
ffi_status
|
||||||
|
ffi_prep_cif_machdep (ffi_cif *cif)
|
||||||
{
|
{
|
||||||
/* Set the return type flag */
|
/* Set the return type flag */
|
||||||
switch (cif->rtype->type)
|
switch (cif->rtype->type)
|
||||||
|
@ -369,11 +374,13 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||||
return FFI_OK;
|
return FFI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void ffi_call_pa32(void (*)(UINT32 *, extended_cif *, unsigned),
|
extern void ffi_call_pa32 (void (*)(UINT32 *, extended_cif *, unsigned),
|
||||||
extended_cif *, unsigned, unsigned, unsigned *,
|
extended_cif *, unsigned, unsigned, unsigned *,
|
||||||
void (*fn)(void));
|
void (*fn)(void), void *closure);
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
extended_cif ecif;
|
extended_cif ecif;
|
||||||
|
|
||||||
|
@ -401,8 +408,8 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||||
{
|
{
|
||||||
case FFI_PA32:
|
case FFI_PA32:
|
||||||
debug(3, "Calling ffi_call_pa32: ecif=%p, bytes=%u, flags=%u, rvalue=%p, fn=%p\n", &ecif, cif->bytes, cif->flags, ecif.rvalue, (void *)fn);
|
debug(3, "Calling ffi_call_pa32: ecif=%p, bytes=%u, flags=%u, rvalue=%p, fn=%p\n", &ecif, cif->bytes, cif->flags, ecif.rvalue, (void *)fn);
|
||||||
ffi_call_pa32(ffi_prep_args_pa32, &ecif, cif->bytes,
|
ffi_call_pa32 (ffi_prep_args_pa32, &ecif, cif->bytes,
|
||||||
cif->flags, ecif.rvalue, fn);
|
cif->flags, ecif.rvalue, fn, closure);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -411,14 +418,30 @@ void 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);
|
||||||
|
}
|
||||||
|
|
||||||
#if FFI_CLOSURES
|
#if FFI_CLOSURES
|
||||||
/* This is more-or-less an inverse of ffi_call -- we have arguments on
|
/* This is more-or-less an inverse of ffi_call -- we have arguments on
|
||||||
the stack, and we need to fill them into a cif structure and invoke
|
the stack, and we need to fill them into a cif structure and invoke
|
||||||
the user function. This really ought to be in asm to make sure
|
the user function. This really ought to be in asm to make sure
|
||||||
the compiler doesn't do things we don't expect. */
|
the compiler doesn't do things we don't expect. */
|
||||||
ffi_status ffi_closure_inner_pa32(ffi_closure *closure, UINT32 *stack)
|
ffi_status
|
||||||
|
ffi_closure_inner_pa32 (void *closure, UINT32 *stack, int closure_type)
|
||||||
{
|
{
|
||||||
ffi_cif *cif;
|
ffi_cif *cif;
|
||||||
|
void (*fun)(ffi_cif *,void *,void **,void *);
|
||||||
|
void *user_data;
|
||||||
void **avalue;
|
void **avalue;
|
||||||
void *rvalue;
|
void *rvalue;
|
||||||
UINT32 ret[2]; /* function can return up to 64-bits in registers */
|
UINT32 ret[2]; /* function can return up to 64-bits in registers */
|
||||||
|
@ -428,7 +451,19 @@ ffi_status ffi_closure_inner_pa32(ffi_closure *closure, UINT32 *stack)
|
||||||
unsigned int slot = FIRST_ARG_SLOT;
|
unsigned int slot = FIRST_ARG_SLOT;
|
||||||
register UINT32 r28 asm("r28");
|
register UINT32 r28 asm("r28");
|
||||||
|
|
||||||
cif = closure->cif;
|
/* A non-zero closure type indicates a go closure. */
|
||||||
|
if (closure_type)
|
||||||
|
{
|
||||||
|
cif = ((ffi_go_closure *)closure)->cif;
|
||||||
|
fun = ((ffi_go_closure *)closure)->fun;
|
||||||
|
user_data = closure;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cif = ((ffi_closure *)closure)->cif;
|
||||||
|
fun = ((ffi_closure *)closure)->fun;
|
||||||
|
user_data = ((ffi_closure *)closure)->user_data;
|
||||||
|
}
|
||||||
|
|
||||||
/* If returning via structure, callee will write to our pointer. */
|
/* If returning via structure, callee will write to our pointer. */
|
||||||
if (cif->flags == FFI_TYPE_STRUCT)
|
if (cif->flags == FFI_TYPE_STRUCT)
|
||||||
|
@ -436,7 +471,7 @@ ffi_status ffi_closure_inner_pa32(ffi_closure *closure, UINT32 *stack)
|
||||||
else
|
else
|
||||||
rvalue = &ret[0];
|
rvalue = &ret[0];
|
||||||
|
|
||||||
avalue = (void **)alloca(cif->nargs * FFI_SIZEOF_ARG);
|
avalue = (void **) alloca (cif->nargs * FFI_SIZEOF_ARG);
|
||||||
avn = cif->nargs;
|
avn = cif->nargs;
|
||||||
p_arg = cif->arg_types;
|
p_arg = cif->arg_types;
|
||||||
|
|
||||||
|
@ -529,7 +564,7 @@ ffi_status ffi_closure_inner_pa32(ffi_closure *closure, UINT32 *stack)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Invoke the closure. */
|
/* Invoke the closure. */
|
||||||
(closure->fun) (cif, rvalue, avalue, closure->user_data);
|
fun (cif, rvalue, avalue, user_data);
|
||||||
|
|
||||||
debug(3, "after calling function, ret[0] = %08x, ret[1] = %08x\n", ret[0],
|
debug(3, "after calling function, ret[0] = %08x, ret[1] = %08x\n", ret[0],
|
||||||
ret[1]);
|
ret[1]);
|
||||||
|
@ -621,6 +656,7 @@ ffi_status ffi_closure_inner_pa32(ffi_closure *closure, UINT32 *stack)
|
||||||
cif specifies the argument and result types for fun.
|
cif specifies the argument and result types for fun.
|
||||||
The cif must already be prep'ed. */
|
The cif must already be prep'ed. */
|
||||||
|
|
||||||
|
extern void ffi_go_closure_pa32(void);
|
||||||
extern void ffi_closure_pa32(void);
|
extern void ffi_closure_pa32(void);
|
||||||
|
|
||||||
ffi_status
|
ffi_status
|
||||||
|
@ -716,4 +752,21 @@ ffi_prep_closure_loc (ffi_closure* closure,
|
||||||
|
|
||||||
return FFI_OK;
|
return FFI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef FFI_GO_CLOSURES
|
||||||
|
ffi_status
|
||||||
|
ffi_prep_go_closure (ffi_go_closure *closure,
|
||||||
|
ffi_cif *cif,
|
||||||
|
void (*fun)(ffi_cif *, void *, void **, void *))
|
||||||
|
{
|
||||||
|
if (cif->abi != FFI_PA32)
|
||||||
|
return FFI_BAD_ABI;
|
||||||
|
|
||||||
|
closure->tramp = &ffi_go_closure_pa32;
|
||||||
|
closure->cif = cif;
|
||||||
|
closure->fun = fun;
|
||||||
|
|
||||||
|
return FFI_OK;
|
||||||
|
}
|
||||||
|
#endif /* FFI_GO_CLOSURES */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* -----------------------------------------------------------------*-C-*-
|
/* -----------------------------------------------------------------*-C-*-
|
||||||
ffitarget.h - Copyright (c) 2012 Anthony Green
|
ffitarget.h - Copyright (c) 2016 John David Anglin
|
||||||
|
Copyright (c) 2012 Anthony Green
|
||||||
Copyright (c) 1996-2003 Red Hat, Inc.
|
Copyright (c) 1996-2003 Red Hat, Inc.
|
||||||
Target configuration macros for hppa.
|
Target configuration macros for hppa.
|
||||||
|
|
||||||
|
@ -67,6 +68,7 @@ typedef enum ffi_abi {
|
||||||
/* ---- Definitions for closures ----------------------------------------- */
|
/* ---- Definitions for closures ----------------------------------------- */
|
||||||
|
|
||||||
#define FFI_CLOSURES 1
|
#define FFI_CLOSURES 1
|
||||||
|
#define FFI_GO_CLOSURES 1
|
||||||
#define FFI_NATIVE_RAW_API 0
|
#define FFI_NATIVE_RAW_API 0
|
||||||
|
|
||||||
#ifdef PA_LINUX
|
#ifdef PA_LINUX
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* -----------------------------------------------------------------------
|
/* -----------------------------------------------------------------------
|
||||||
hpux32.S - Copyright (c) 2006 Free Software Foundation, Inc.
|
hpux32.S - Copyright (c) 2006 Free Software Foundation, Inc.
|
||||||
(c) 2008 Red Hat, Inc.
|
(c) 2008 Red Hat, Inc.
|
||||||
|
(c) 2016 John David Anglin
|
||||||
based on src/pa/linux.S
|
based on src/pa/linux.S
|
||||||
|
|
||||||
HP-UX PA Foreign Function Interface
|
HP-UX PA Foreign Function Interface
|
||||||
|
@ -41,7 +42,8 @@
|
||||||
unsigned bytes,
|
unsigned bytes,
|
||||||
unsigned flags,
|
unsigned flags,
|
||||||
unsigned *rvalue,
|
unsigned *rvalue,
|
||||||
void (*fn)(void));
|
void (*fn)(void),
|
||||||
|
ffi_go_closure *closure);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.export ffi_call_pa32,ENTRY,PRIV_LEV=3
|
.export ffi_call_pa32,ENTRY,PRIV_LEV=3
|
||||||
|
@ -104,6 +106,7 @@ L$CFI13
|
||||||
we need to give it a place to put the result. */
|
we need to give it a place to put the result. */
|
||||||
ldw -52(%r3), %ret0 ; %ret0 <- rvalue
|
ldw -52(%r3), %ret0 ; %ret0 <- rvalue
|
||||||
ldw -56(%r3), %r22 ; %r22 <- function to call
|
ldw -56(%r3), %r22 ; %r22 <- function to call
|
||||||
|
ldw -60(%r3), %ret1 ; %ret1 <- closure
|
||||||
bl $$dyncall, %r31 ; Call the user function
|
bl $$dyncall, %r31 ; Call the user function
|
||||||
copy %r31, %rp
|
copy %r31, %rp
|
||||||
|
|
||||||
|
@ -285,7 +288,9 @@ L$CFI22
|
||||||
stw %arg2, -44(%r3)
|
stw %arg2, -44(%r3)
|
||||||
stw %arg3, -48(%r3)
|
stw %arg3, -48(%r3)
|
||||||
|
|
||||||
|
/* Closure type 0. */
|
||||||
copy %r21, %arg0
|
copy %r21, %arg0
|
||||||
|
copy %r0, %arg2
|
||||||
bl ffi_closure_inner_pa32, %r2
|
bl ffi_closure_inner_pa32, %r2
|
||||||
copy %r3, %arg1
|
copy %r3, %arg1
|
||||||
ldwm -64(%sp), %r3
|
ldwm -64(%sp), %r3
|
||||||
|
@ -297,6 +302,47 @@ L$CFI22
|
||||||
.procend
|
.procend
|
||||||
L$FE2:
|
L$FE2:
|
||||||
|
|
||||||
|
/* void ffi_go_closure_pa32(void);
|
||||||
|
Called with closure argument in %ret1 */
|
||||||
|
|
||||||
|
.SPACE $TEXT$
|
||||||
|
.SUBSPA $CODE$
|
||||||
|
.export ffi_go_closure_pa32,ENTRY,PRIV_LEV=3,RTNVAL=GR
|
||||||
|
.import ffi_closure_inner_pa32,CODE
|
||||||
|
.align 4
|
||||||
|
L$FB3
|
||||||
|
ffi_go_closure_pa32
|
||||||
|
.proc
|
||||||
|
.callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
|
||||||
|
.entry
|
||||||
|
|
||||||
|
stw %rp, -20(%sp)
|
||||||
|
copy %r3, %r1
|
||||||
|
L$CFI31
|
||||||
|
copy %sp, %r3
|
||||||
|
L$CFI32
|
||||||
|
stwm %r1, 64(%sp)
|
||||||
|
|
||||||
|
/* Put arguments onto the stack and call ffi_closure_inner. */
|
||||||
|
stw %arg0, -36(%r3)
|
||||||
|
stw %arg1, -40(%r3)
|
||||||
|
stw %arg2, -44(%r3)
|
||||||
|
stw %arg3, -48(%r3)
|
||||||
|
|
||||||
|
/* Closure type 1. */
|
||||||
|
copy %ret1, %arg0
|
||||||
|
ldi 1, %arg2
|
||||||
|
bl ffi_closure_inner_pa32, %r2
|
||||||
|
copy %r3, %arg1
|
||||||
|
ldwm -64(%sp), %r3
|
||||||
|
ldw -20(%sp), %rp
|
||||||
|
ldw -36(%sp), %ret0
|
||||||
|
bv %r0(%rp)
|
||||||
|
ldw -40(%sp), %ret1
|
||||||
|
.exit
|
||||||
|
.procend
|
||||||
|
L$FE3:
|
||||||
|
|
||||||
.SPACE $PRIVATE$
|
.SPACE $PRIVATE$
|
||||||
.SUBSPA $DATA$
|
.SUBSPA $DATA$
|
||||||
|
|
||||||
|
@ -366,3 +412,25 @@ L$ASFDE2:
|
||||||
|
|
||||||
.align 4
|
.align 4
|
||||||
L$EFDE2:
|
L$EFDE2:
|
||||||
|
|
||||||
|
L$SFDE3:
|
||||||
|
.word L$EFDE3-L$ASFDE3 ;# FDE Length
|
||||||
|
L$ASFDE3:
|
||||||
|
.word L$ASFDE3-L$frame1 ;# FDE CIE offset
|
||||||
|
.word L$FB3 ;# FDE initial location
|
||||||
|
.word L$FE3-L$FB3 ;# FDE address range
|
||||||
|
.byte 0x4 ;# DW_CFA_advance_loc4
|
||||||
|
.word L$CFI31-L$FB3
|
||||||
|
.byte 0x83 ;# DW_CFA_offset, column 0x3
|
||||||
|
.uleb128 0x0
|
||||||
|
.byte 0x11 ;# DW_CFA_offset_extended_sf
|
||||||
|
.uleb128 0x2
|
||||||
|
.sleb128 -5
|
||||||
|
|
||||||
|
.byte 0x4 ;# DW_CFA_advance_loc4
|
||||||
|
.word L$CFI32-L$CFI31
|
||||||
|
.byte 0xd ;# DW_CFA_def_cfa_register = r3
|
||||||
|
.uleb128 0x3
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
L$EFDE3:
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* -----------------------------------------------------------------------
|
/* -----------------------------------------------------------------------
|
||||||
linux.S - (c) 2003-2004 Randolph Chung <tausq@debian.org>
|
linux.S - (c) 2003-2004 Randolph Chung <tausq@debian.org>
|
||||||
(c) 2008 Red Hat, Inc.
|
(c) 2008 Red Hat, Inc.
|
||||||
|
(c) 2016 John David Anglin
|
||||||
|
|
||||||
HPPA Foreign Function Interface
|
HPPA Foreign Function Interface
|
||||||
|
|
||||||
|
@ -37,24 +38,26 @@
|
||||||
unsigned bytes,
|
unsigned bytes,
|
||||||
unsigned flags,
|
unsigned flags,
|
||||||
unsigned *rvalue,
|
unsigned *rvalue,
|
||||||
void (*fn)(void));
|
void (*fn)(void),
|
||||||
|
ffi_go_closure *closure);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.export ffi_call_pa32,code
|
.export ffi_call_pa32,code
|
||||||
.import ffi_prep_args_pa32,code
|
.import ffi_prep_args_pa32,code
|
||||||
|
|
||||||
.type ffi_call_pa32, @function
|
.type ffi_call_pa32, @function
|
||||||
.LFB1:
|
.cfi_startproc
|
||||||
ffi_call_pa32:
|
ffi_call_pa32:
|
||||||
.proc
|
.proc
|
||||||
.callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=4
|
.callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=4
|
||||||
.entry
|
.entry
|
||||||
stw %rp, -20(%sp)
|
stw %rp, -20(%sp)
|
||||||
copy %r3, %r1
|
copy %r3, %r1
|
||||||
.LCFI11:
|
.cfi_offset 2, -20
|
||||||
|
.cfi_register 3, 1
|
||||||
|
|
||||||
copy %sp, %r3
|
copy %sp, %r3
|
||||||
.LCFI12:
|
.cfi_def_cfa_register 3
|
||||||
|
|
||||||
/* Setup the stack for calling prep_args...
|
/* Setup the stack for calling prep_args...
|
||||||
We want the stack to look like this:
|
We want the stack to look like this:
|
||||||
|
@ -70,8 +73,8 @@ ffi_call_pa32:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
stwm %r1, 64(%sp)
|
stwm %r1, 64(%sp)
|
||||||
|
.cfi_offset 3, 0
|
||||||
stw %r4, 12(%r3)
|
stw %r4, 12(%r3)
|
||||||
.LCFI13:
|
|
||||||
copy %sp, %r4
|
copy %sp, %r4
|
||||||
|
|
||||||
addl %arg2, %r4, %arg0 /* arg stack */
|
addl %arg2, %r4, %arg0 /* arg stack */
|
||||||
|
@ -98,6 +101,7 @@ ffi_call_pa32:
|
||||||
we need to give it a place to put the result. */
|
we need to give it a place to put the result. */
|
||||||
ldw -52(%r3), %ret0 /* %ret0 <- rvalue */
|
ldw -52(%r3), %ret0 /* %ret0 <- rvalue */
|
||||||
ldw -56(%r3), %r22 /* %r22 <- function to call */
|
ldw -56(%r3), %r22 /* %r22 <- function to call */
|
||||||
|
ldw -60(%r3), %ret1 /* %ret1 <- closure */
|
||||||
bl $$dyncall, %r31 /* Call the user function */
|
bl $$dyncall, %r31 /* Call the user function */
|
||||||
copy %r31, %rp
|
copy %r31, %rp
|
||||||
|
|
||||||
|
@ -249,27 +253,27 @@ ffi_call_pa32:
|
||||||
nop
|
nop
|
||||||
.exit
|
.exit
|
||||||
.procend
|
.procend
|
||||||
.LFE1:
|
.cfi_endproc
|
||||||
|
|
||||||
/* void ffi_closure_pa32(void);
|
/* void ffi_closure_pa32(void);
|
||||||
Called with closure argument in %r21 */
|
Called with ffi_closure argument in %r21. */
|
||||||
.export ffi_closure_pa32,code
|
.export ffi_closure_pa32,code
|
||||||
.import ffi_closure_inner_pa32,code
|
.import ffi_closure_inner_pa32,code
|
||||||
|
|
||||||
.type ffi_closure_pa32, @function
|
.type ffi_closure_pa32, @function
|
||||||
.LFB2:
|
.cfi_startproc
|
||||||
ffi_closure_pa32:
|
ffi_closure_pa32:
|
||||||
.proc
|
.proc
|
||||||
.callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
|
.callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
|
||||||
.entry
|
.entry
|
||||||
|
|
||||||
stw %rp, -20(%sp)
|
stw %rp, -20(%sp)
|
||||||
.LCFI20:
|
|
||||||
copy %r3, %r1
|
copy %r3, %r1
|
||||||
.LCFI21:
|
.cfi_offset 2, -20
|
||||||
|
.cfi_register 3, 1
|
||||||
copy %sp, %r3
|
copy %sp, %r3
|
||||||
.LCFI22:
|
.cfi_def_cfa_register 3
|
||||||
stwm %r1, 64(%sp)
|
stwm %r1, 64(%sp)
|
||||||
|
.cfi_offset 3, 0
|
||||||
|
|
||||||
/* Put arguments onto the stack and call ffi_closure_inner. */
|
/* Put arguments onto the stack and call ffi_closure_inner. */
|
||||||
stw %arg0, -36(%r3)
|
stw %arg0, -36(%r3)
|
||||||
|
@ -277,7 +281,9 @@ ffi_closure_pa32:
|
||||||
stw %arg2, -44(%r3)
|
stw %arg2, -44(%r3)
|
||||||
stw %arg3, -48(%r3)
|
stw %arg3, -48(%r3)
|
||||||
|
|
||||||
|
/* Closure type 0. */
|
||||||
copy %r21, %arg0
|
copy %r21, %arg0
|
||||||
|
copy %r0, %arg2
|
||||||
bl ffi_closure_inner_pa32, %r2
|
bl ffi_closure_inner_pa32, %r2
|
||||||
copy %r3, %arg1
|
copy %r3, %arg1
|
||||||
|
|
||||||
|
@ -289,69 +295,46 @@ ffi_closure_pa32:
|
||||||
|
|
||||||
.exit
|
.exit
|
||||||
.procend
|
.procend
|
||||||
.LFE2:
|
.cfi_endproc
|
||||||
|
|
||||||
.section ".eh_frame",EH_FRAME_FLAGS,@progbits
|
/* void ffi_go_closure_pa32(void);
|
||||||
.Lframe1:
|
Called with ffi_go_closure argument in %ret1. */
|
||||||
.word .LECIE1-.LSCIE1 ;# Length of Common Information Entry
|
.export ffi_go_closure_pa32,code
|
||||||
.LSCIE1:
|
.import ffi_closure_inner_pa32,code
|
||||||
.word 0x0 ;# CIE Identifier Tag
|
.type ffi_go_closure_pa32, @function
|
||||||
.byte 0x1 ;# CIE Version
|
.cfi_startproc
|
||||||
.ascii "\0" ;# CIE Augmentation
|
ffi_go_closure_pa32:
|
||||||
.uleb128 0x1 ;# CIE Code Alignment Factor
|
.proc
|
||||||
.sleb128 4 ;# CIE Data Alignment Factor
|
.callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
|
||||||
.byte 0x2 ;# CIE RA Column
|
.entry
|
||||||
.byte 0xc ;# DW_CFA_def_cfa
|
|
||||||
.uleb128 0x1e
|
|
||||||
.uleb128 0x0
|
|
||||||
.align 4
|
|
||||||
.LECIE1:
|
|
||||||
.LSFDE1:
|
|
||||||
.word .LEFDE1-.LASFDE1 ;# FDE Length
|
|
||||||
.LASFDE1:
|
|
||||||
.word .LASFDE1-.Lframe1 ;# FDE CIE offset
|
|
||||||
.word .LFB1 ;# FDE initial location
|
|
||||||
.word .LFE1-.LFB1 ;# FDE address range
|
|
||||||
|
|
||||||
.byte 0x4 ;# DW_CFA_advance_loc4
|
stw %rp, -20(%sp)
|
||||||
.word .LCFI11-.LFB1
|
copy %r3, %r1
|
||||||
.byte 0x83 ;# DW_CFA_offset, column 0x3
|
.cfi_offset 2, -20
|
||||||
.uleb128 0x0
|
.cfi_register 3, 1
|
||||||
.byte 0x11 ;# DW_CFA_offset_extended_sf; save r2 at [r30-20]
|
copy %sp, %r3
|
||||||
.uleb128 0x2
|
.cfi_def_cfa_register 3
|
||||||
.sleb128 -5
|
stwm %r1, 64(%sp)
|
||||||
|
.cfi_offset 3, 0
|
||||||
|
|
||||||
.byte 0x4 ;# DW_CFA_advance_loc4
|
/* Put arguments onto the stack and call ffi_closure_inner. */
|
||||||
.word .LCFI12-.LCFI11
|
stw %arg0, -36(%r3)
|
||||||
.byte 0xd ;# DW_CFA_def_cfa_register = r3
|
stw %arg1, -40(%r3)
|
||||||
.uleb128 0x3
|
stw %arg2, -44(%r3)
|
||||||
|
stw %arg3, -48(%r3)
|
||||||
|
|
||||||
.byte 0x4 ;# DW_CFA_advance_loc4
|
/* Closure type 1. */
|
||||||
.word .LCFI13-.LCFI12
|
copy %ret1, %arg0
|
||||||
.byte 0x84 ;# DW_CFA_offset, column 0x4
|
ldi 1, %arg2
|
||||||
.uleb128 0x3
|
bl ffi_closure_inner_pa32, %r2
|
||||||
|
copy %r3, %arg1
|
||||||
|
|
||||||
.align 4
|
ldwm -64(%sp), %r3
|
||||||
.LEFDE1:
|
ldw -20(%sp), %rp
|
||||||
|
ldw -36(%sp), %ret0
|
||||||
|
bv %r0(%r2)
|
||||||
|
ldw -40(%sp), %ret1
|
||||||
|
|
||||||
.LSFDE2:
|
.exit
|
||||||
.word .LEFDE2-.LASFDE2 ;# FDE Length
|
.procend
|
||||||
.LASFDE2:
|
.cfi_endproc
|
||||||
.word .LASFDE2-.Lframe1 ;# FDE CIE offset
|
|
||||||
.word .LFB2 ;# FDE initial location
|
|
||||||
.word .LFE2-.LFB2 ;# FDE address range
|
|
||||||
.byte 0x4 ;# DW_CFA_advance_loc4
|
|
||||||
.word .LCFI21-.LFB2
|
|
||||||
.byte 0x83 ;# DW_CFA_offset, column 0x3
|
|
||||||
.uleb128 0x0
|
|
||||||
.byte 0x11 ;# DW_CFA_offset_extended_sf
|
|
||||||
.uleb128 0x2
|
|
||||||
.sleb128 -5
|
|
||||||
|
|
||||||
.byte 0x4 ;# DW_CFA_advance_loc4
|
|
||||||
.word .LCFI22-.LCFI21
|
|
||||||
.byte 0xd ;# DW_CFA_def_cfa_register = r3
|
|
||||||
.uleb128 0x3
|
|
||||||
|
|
||||||
.align 4
|
|
||||||
.LEFDE2:
|
|
||||||
|
|
|
@ -4,6 +4,12 @@
|
||||||
# define STATIC_CHAIN_REG "$1"
|
# define STATIC_CHAIN_REG "$1"
|
||||||
#elif defined(__arm__)
|
#elif defined(__arm__)
|
||||||
# define STATIC_CHAIN_REG "ip"
|
# define STATIC_CHAIN_REG "ip"
|
||||||
|
#elif defined(__hppa__)
|
||||||
|
# if defined(__LP64)
|
||||||
|
# define define STATIC_CHAIN_REG "%r31"
|
||||||
|
# else
|
||||||
|
# define define STATIC_CHAIN_REG "%r29" /* %ret1 */
|
||||||
|
# endif
|
||||||
#elif defined(__sparc__)
|
#elif defined(__sparc__)
|
||||||
# if defined(__arch64__) || defined(__sparcv9)
|
# if defined(__arch64__) || defined(__sparcv9)
|
||||||
# define STATIC_CHAIN_REG "g5"
|
# define STATIC_CHAIN_REG "g5"
|
||||||
|
|
Loading…
Reference in New Issue