ffi.c (ffi_prep_incoming_args_SYSV, [...]): New, add closure support.

* src/m68k/ffi.c (ffi_prep_incoming_args_SYSV,
	ffi_closure_SYSV_inner,ffi_prep_closure): New, add closure support.
	* src/m68k/sysv.S(ffi_closure_SYSV,ffi_closure_struct_SYSV): Likewise.
	* src/m68k/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise.
	(FFI_CLOSURES): Enable closure support.

From-SVN: r124601
This commit is contained in:
Roman Zippel 2007-05-10 21:29:04 +00:00 committed by Roman Zippel
parent e6fbf387cf
commit 5635c26e57
4 changed files with 184 additions and 1 deletions

View File

@ -1,3 +1,11 @@
2007-05-10 Roman Zippel <zippel@linux-m68k.org>
* src/m68k/ffi.c (ffi_prep_incoming_args_SYSV,
ffi_closure_SYSV_inner,ffi_prep_closure): New, add closure support.
* src/m68k/sysv.S(ffi_closure_SYSV,ffi_closure_struct_SYSV): Likewise.
* src/m68k/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise.
(FFI_CLOSURES): Enable closure support.
2007-05-10 Roman Zippel <zippel@linux-m68k.org> 2007-05-10 Roman Zippel <zippel@linux-m68k.org>
* configure.ac (HAVE_AS_CFI_PSEUDO_OP): New test. * configure.ac (HAVE_AS_CFI_PSEUDO_OP): New test.

View File

@ -8,11 +8,18 @@
#include <ffi_common.h> #include <ffi_common.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <asm/cachectl.h>
void ffi_call_SYSV (extended_cif *, void ffi_call_SYSV (extended_cif *,
unsigned, unsigned, unsigned, unsigned,
void *, void (*fn) ()); void *, void (*fn) ());
void *ffi_prep_args (void *stack, extended_cif *ecif); void *ffi_prep_args (void *stack, extended_cif *ecif);
void ffi_closure_SYSV (ffi_closure *);
void ffi_closure_struct_SYSV (ffi_closure *);
unsigned int ffi_closure_SYSV_inner (ffi_closure *closure,
void *resp, void *args);
/* ffi_prep_args is called by the assembly routine once stack space has /* ffi_prep_args is called by the assembly routine once stack space has
been allocated for the function's arguments. */ been allocated for the function's arguments. */
@ -188,3 +195,84 @@ ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue)
break; break;
} }
} }
static void
ffi_prep_incoming_args_SYSV (char *stack, void **avalue, ffi_cif *cif)
{
unsigned int i;
void **p_argv;
char *argp;
ffi_type **p_arg;
argp = stack;
p_argv = avalue;
for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
{
size_t z;
z = (*p_arg)->size;
if (z <= 4)
{
*p_argv = (void *) (argp + 4 - z);
z = 4;
}
else
{
*p_argv = (void *) argp;
/* Align if necessary */
if ((sizeof(int) - 1) & z)
z = ALIGN(z, sizeof(int));
}
p_argv++;
argp += z;
}
}
unsigned int
ffi_closure_SYSV_inner (ffi_closure *closure, void *resp, void *args)
{
ffi_cif *cif;
void **arg_area;
cif = closure->cif;
arg_area = (void**) alloca (cif->nargs * sizeof (void *));
ffi_prep_incoming_args_SYSV(args, arg_area, cif);
(closure->fun) (cif, resp, arg_area, closure->user_data);
return cif->flags;
}
ffi_status
ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data,
void *codeloc)
{
FFI_ASSERT (cif->abi == FFI_SYSV);
*(unsigned short *)closure->tramp = 0x207c;
*(void **)(closure->tramp + 2) = codeloc;
*(unsigned short *)(closure->tramp + 6) = 0x4ef9;
if (cif->rtype->type == FFI_TYPE_STRUCT
&& !cif->flags)
*(void **)(closure->tramp + 8) = ffi_closure_struct_SYSV;
else
*(void **)(closure->tramp + 8) = ffi_closure_SYSV;
syscall(SYS_cacheflush, codeloc, FLUSH_SCOPE_LINE,
FLUSH_CACHE_BOTH, FFI_TRAMPOLINE_SIZE);
closure->cif = cif;
closure->user_data = user_data;
closure->fun = fun;
return FFI_OK;
}

View File

@ -40,7 +40,8 @@ typedef enum ffi_abi {
/* ---- Definitions for closures ----------------------------------------- */ /* ---- Definitions for closures ----------------------------------------- */
#define FFI_CLOSURES 0 #define FFI_CLOSURES 1
#define FFI_TRAMPOLINE_SIZE 16
#define FFI_NATIVE_RAW_API 0 #define FFI_NATIVE_RAW_API 0
#endif #endif

View File

@ -121,3 +121,89 @@ epilogue:
rts rts
CFI_ENDPROC() CFI_ENDPROC()
.size ffi_call_SYSV,.-ffi_call_SYSV .size ffi_call_SYSV,.-ffi_call_SYSV
.globl ffi_closure_SYSV
.type ffi_closure_SYSV, @function
.align 4
ffi_closure_SYSV:
CFI_STARTPROC()
link %fp,#-12
CFI_OFFSET(14,-8)
CFI_DEF_CFA(14,8)
move.l %sp,-12(%fp)
pea 8(%fp)
pea -12(%fp)
move.l %a0,-(%sp)
#if !defined __PIC__
jsr ffi_closure_SYSV_inner
#else
bsr.l ffi_closure_SYSV_inner@PLTPC
#endif
lsr.l #1,%d0
jne 1f
jcc .Lcls_epilogue
move.l -12(%fp),%d0
.Lcls_epilogue:
unlk %fp
rts
1:
lea -12(%fp),%a0
lsr.l #2,%d0
jne 1f
jcs .Lcls_ret_float
move.l (%a0)+,%d0
move.l (%a0),%d1
jra .Lcls_epilogue
.Lcls_ret_float:
fmove.s (%a0),%fp0
jra .Lcls_epilogue
1:
lsr.l #2,%d0
jne 1f
jcs .Lcls_ret_ldouble
fmove.d (%a0),%fp0
jra .Lcls_epilogue
.Lcls_ret_ldouble:
fmove.x (%a0),%fp0
jra .Lcls_epilogue
1:
lsr.l #2,%d0
jne .Lcls_ret_struct2
jcs .Lcls_ret_struct1
move.l (%a0),%a0
move.l %a0,%d0
jra .Lcls_epilogue
.Lcls_ret_struct1:
move.b (%a0),%d0
jra .Lcls_epilogue
.Lcls_ret_struct2:
move.w (%a0),%d0
jra .Lcls_epilogue
CFI_ENDPROC()
.size ffi_closure_SYSV,.-ffi_closure_SYSV
.globl ffi_closure_struct_SYSV
.type ffi_closure_struct_SYSV, @function
.align 4
ffi_closure_struct_SYSV:
CFI_STARTPROC()
link %fp,#0
CFI_OFFSET(14,-8)
CFI_DEF_CFA(14,8)
move.l %sp,-12(%fp)
pea 8(%fp)
move.l %a1,-(%sp)
move.l %a0,-(%sp)
#if !defined __PIC__
jsr ffi_closure_SYSV_inner
#else
bsr.l ffi_closure_SYSV_inner@PLTPC
#endif
unlk %fp
rts
CFI_ENDPROC()
.size ffi_closure_struct_SYSV,.-ffi_closure_struct_SYSV