summaryrefslogtreecommitdiff
path: root/libffi
diff options
context:
space:
mode:
authorRoman Zippel <zippel@linux-m68k.org>2007-05-10 21:29:04 +0000
committerRoman Zippel <zippel@gcc.gnu.org>2007-05-10 21:29:04 +0000
commit5635c26e579161430860f8f85941949ccf586f1d (patch)
tree78cb2774ba34e95691b63ceefd517e55587b612b /libffi
parente6fbf387cfb88e498691e6bc48ef1566b2556fff (diff)
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
Diffstat (limited to 'libffi')
-rw-r--r--libffi/ChangeLog8
-rw-r--r--libffi/src/m68k/ffi.c88
-rw-r--r--libffi/src/m68k/ffitarget.h3
-rw-r--r--libffi/src/m68k/sysv.S86
4 files changed, 184 insertions, 1 deletions
diff --git a/libffi/ChangeLog b/libffi/ChangeLog
index 7512e8124c1..1f49a27e555 100644
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -1,5 +1,13 @@
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>
+
* configure.ac (HAVE_AS_CFI_PSEUDO_OP): New test.
* configure: Regenerate.
* fficonfig.h.in: Regenerate.
diff --git a/libffi/src/m68k/ffi.c b/libffi/src/m68k/ffi.c
index 5b9650e0ae5..600cf20527f 100644
--- a/libffi/src/m68k/ffi.c
+++ b/libffi/src/m68k/ffi.c
@@ -8,11 +8,18 @@
#include <ffi_common.h>
#include <stdlib.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <asm/cachectl.h>
void ffi_call_SYSV (extended_cif *,
unsigned, unsigned,
void *, void (*fn) ());
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
been allocated for the function's arguments. */
@@ -188,3 +195,84 @@ ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue)
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;
+}
+
diff --git a/libffi/src/m68k/ffitarget.h b/libffi/src/m68k/ffitarget.h
index aca7facc50a..9a072db404f 100644
--- a/libffi/src/m68k/ffitarget.h
+++ b/libffi/src/m68k/ffitarget.h
@@ -40,7 +40,8 @@ typedef enum ffi_abi {
/* ---- Definitions for closures ----------------------------------------- */
-#define FFI_CLOSURES 0
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 16
#define FFI_NATIVE_RAW_API 0
#endif
diff --git a/libffi/src/m68k/sysv.S b/libffi/src/m68k/sysv.S
index a3d9a4f7ff7..d2a4ff1c64a 100644
--- a/libffi/src/m68k/sysv.S
+++ b/libffi/src/m68k/sysv.S
@@ -121,3 +121,89 @@ epilogue:
rts
CFI_ENDPROC()
.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