561 lines
17 KiB
Diff
561 lines
17 KiB
Diff
|
From 5a2352c476b501ecbd3c7ef3ef3e02c24ce5a449 Mon Sep 17 00:00:00 2001
|
||
|
From: Mischa Jonker <mjonker@synopsys.com>
|
||
|
Date: Mon, 10 Jun 2013 16:19:33 +0200
|
||
|
Subject: [PATCH 1/3] Add ARC support
|
||
|
|
||
|
This adds support for the ARC architecture to libffi. DesignWare ARC
|
||
|
is a family of processors from Synopsys, Inc.
|
||
|
|
||
|
This patch has been tested on a little-endian system and passes
|
||
|
the testsuite.
|
||
|
|
||
|
Signed-off-by: Mischa Jonker <mjonker@synopsys.com>
|
||
|
---
|
||
|
Makefile.am | 6 +-
|
||
|
README | 1 +
|
||
|
configure.ac | 5 +
|
||
|
src/arc/arcompact.S | 135 ++++++++++++++++++++++++++
|
||
|
src/arc/ffi.c | 268 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
src/arc/ffitarget.h | 53 +++++++++++
|
||
|
6 files changed, 467 insertions(+), 1 deletion(-)
|
||
|
create mode 100644 src/arc/arcompact.S
|
||
|
create mode 100644 src/arc/ffi.c
|
||
|
create mode 100644 src/arc/ffitarget.h
|
||
|
|
||
|
diff --git a/Makefile.am b/Makefile.am
|
||
|
index bf0156f..b57b2a8 100644
|
||
|
--- a/Makefile.am
|
||
|
+++ b/Makefile.am
|
||
|
@@ -9,7 +9,8 @@ SUBDIRS = include testsuite man
|
||
|
EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
|
||
|
src/aarch64/ffi.c src/aarch64/ffitarget.h src/aarch64/sysv.S \
|
||
|
build-ios.sh src/alpha/ffi.c src/alpha/osf.S \
|
||
|
- src/alpha/ffitarget.h src/arm/ffi.c src/arm/sysv.S \
|
||
|
+ src/alpha/ffitarget.h src/arc/ffi.c src/arc/arcompact.S \
|
||
|
+ src/arc/ffitarget.h src/arm/ffi.c src/arm/sysv.S \
|
||
|
src/arm/ffitarget.h src/avr32/ffi.c src/avr32/sysv.S \
|
||
|
src/avr32/ffitarget.h src/cris/ffi.c src/cris/sysv.S \
|
||
|
src/cris/ffitarget.h src/ia64/ffi.c src/ia64/ffitarget.h \
|
||
|
@@ -170,6 +171,9 @@ endif
|
||
|
if AARCH64
|
||
|
nodist_libffi_la_SOURCES += src/aarch64/sysv.S src/aarch64/ffi.c
|
||
|
endif
|
||
|
+if ARC
|
||
|
+nodist_libffi_la_SOURCES += src/arc/sysv.S src/arc/ffi.c
|
||
|
+endif
|
||
|
if ARM
|
||
|
nodist_libffi_la_SOURCES += src/arm/sysv.S src/arm/ffi.c
|
||
|
if FFI_EXEC_TRAMPOLINE_TABLE
|
||
|
diff --git a/README b/README
|
||
|
index 19156fe..d8e4e9e 100644
|
||
|
--- a/README
|
||
|
+++ b/README
|
||
|
@@ -54,6 +54,7 @@ tested:
|
||
|
| AArch64 | Linux | GCC |
|
||
|
| Alpha | Linux | GCC |
|
||
|
| Alpha | Tru64 | GCC |
|
||
|
+| ARC | Linux | GCC |
|
||
|
| ARM | Linux | GCC |
|
||
|
| ARM | iOS | GCC |
|
||
|
| AVR32 | Linux | GCC |
|
||
|
diff --git a/configure.ac b/configure.ac
|
||
|
index 0dc0675..a26cb46 100644
|
||
|
--- a/configure.ac
|
||
|
+++ b/configure.ac
|
||
|
@@ -77,6 +77,10 @@ case "$host" in
|
||
|
HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
|
||
|
;;
|
||
|
|
||
|
+ arc*-*-*)
|
||
|
+ TARGET=ARC; TARGETDIR=arc
|
||
|
+ ;;
|
||
|
+
|
||
|
arm*-*-*)
|
||
|
TARGET=ARM; TARGETDIR=arm
|
||
|
;;
|
||
|
@@ -289,6 +293,7 @@ AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
|
||
|
AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
|
||
|
AM_CONDITIONAL(POWERPC_FREEBSD, test x$TARGET = xPOWERPC_FREEBSD)
|
||
|
AM_CONDITIONAL(AARCH64, test x$TARGET = xAARCH64)
|
||
|
+AM_CONDITIONAL(ARC, test x$TARGET = xARC)
|
||
|
AM_CONDITIONAL(ARM, test x$TARGET = xARM)
|
||
|
AM_CONDITIONAL(AVR32, test x$TARGET = xAVR32)
|
||
|
AM_CONDITIONAL(LIBFFI_CRIS, test x$TARGET = xLIBFFI_CRIS)
|
||
|
diff --git a/src/arc/arcompact.S b/src/arc/arcompact.S
|
||
|
new file mode 100644
|
||
|
index 0000000..03715fd
|
||
|
--- /dev/null
|
||
|
+++ b/src/arc/arcompact.S
|
||
|
@@ -0,0 +1,135 @@
|
||
|
+/* -----------------------------------------------------------------------
|
||
|
+ arcompact.S - Copyright (c) 2013 Synposys, Inc. (www.synopsys.com)
|
||
|
+
|
||
|
+ ARCompact Foreign Function Interface
|
||
|
+
|
||
|
+ Permission is hereby granted, free of charge, to any person obtaining
|
||
|
+ a copy of this software and associated documentation files (the
|
||
|
+ ``Software''), to deal in the Software without restriction, including
|
||
|
+ without limitation the rights to use, copy, modify, merge, publish,
|
||
|
+ distribute, sublicense, and/or sell copies of the Software, and to
|
||
|
+ permit persons to whom the Software is furnished to do so, subject to
|
||
|
+ the following conditions:
|
||
|
+
|
||
|
+ The above copyright notice and this permission notice shall be included
|
||
|
+ in all copies or substantial portions of the Software.
|
||
|
+
|
||
|
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
|
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
|
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||
|
+ IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||
|
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||
|
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||
|
+ OTHER DEALINGS IN THE SOFTWARE.
|
||
|
+ ----------------------------------------------------------------------- */
|
||
|
+
|
||
|
+#define LIBFFI_ASM
|
||
|
+#include <fficonfig.h>
|
||
|
+#include <ffi.h>
|
||
|
+#ifdef HAVE_MACHINE_ASM_H
|
||
|
+#include <machine/asm.h>
|
||
|
+#else
|
||
|
+#define CNAME(x) x
|
||
|
+#define ENTRY(x) .globl CNAME(x)` .type CNAME(x),%function` CNAME(x):
|
||
|
+#endif
|
||
|
+
|
||
|
+.text
|
||
|
+
|
||
|
+ /* R0: ffi_prep_args */
|
||
|
+ /* R1: &ecif */
|
||
|
+ /* R2: cif->bytes */
|
||
|
+ /* R3: fig->flags */
|
||
|
+ /* R4: ecif.rvalue */
|
||
|
+ /* R5: fn */
|
||
|
+ENTRY(ffi_call_ARCompact)
|
||
|
+ /* Save registers. */
|
||
|
+ st.a fp, [sp, -4] /* fp + 20, fp */
|
||
|
+ push_s blink /* fp + 16, blink */
|
||
|
+ st.a r4, [sp, -4] /* fp + 12, ecif.rvalue */
|
||
|
+ push_s r3 /* fp + 8, fig->flags */
|
||
|
+ st.a r5, [sp, -4] /* fp + 4, fn */
|
||
|
+ push_s r2 /* fp + 0, cif->bytes */
|
||
|
+ mov fp, sp
|
||
|
+
|
||
|
+ /* Make room for all of the new args. */
|
||
|
+ sub sp, sp, r2
|
||
|
+
|
||
|
+ /* Place all of the ffi_prep_args in position. */
|
||
|
+ /* ffi_prep_args(char *stack, extended_cif *ecif) */
|
||
|
+ /* R1 already set. */
|
||
|
+
|
||
|
+ /* And call. */
|
||
|
+ jl_s.d [r0]
|
||
|
+ mov_s r0, sp
|
||
|
+
|
||
|
+ ld.ab r12, [fp, 4] /* cif->bytes */
|
||
|
+ ld.ab r11, [fp, 4] /* fn */
|
||
|
+
|
||
|
+ /* Move first 8 parameters in registers... */
|
||
|
+ ld_s r0, [sp]
|
||
|
+ ld_s r1, [sp, 4]
|
||
|
+ ld_s r2, [sp, 8]
|
||
|
+ ld_s r3, [sp, 12]
|
||
|
+ ld r4, [sp, 16]
|
||
|
+ ld r5, [sp, 20]
|
||
|
+ ld r6, [sp, 24]
|
||
|
+ ld r7, [sp, 28]
|
||
|
+
|
||
|
+ /* ...and adjust the stack. */
|
||
|
+ min r12, r12, 32
|
||
|
+
|
||
|
+ /* Call the function. */
|
||
|
+ jl.d [r11]
|
||
|
+ add sp, sp, r12
|
||
|
+
|
||
|
+ mov sp, fp
|
||
|
+ pop_s r3 /* fig->flags, return type */
|
||
|
+ pop_s r2 /* ecif.rvalue, pointer for return value */
|
||
|
+
|
||
|
+ /* If the return value pointer is NULL, assume no return value. */
|
||
|
+ breq.d r2, 0, epilogue
|
||
|
+ pop_s blink
|
||
|
+
|
||
|
+ /* Return INT. */
|
||
|
+ brne r3, FFI_TYPE_INT, return_double
|
||
|
+ b.d epilogue
|
||
|
+ st_s r0, [r2]
|
||
|
+
|
||
|
+return_double:
|
||
|
+ brne r3, FFI_TYPE_DOUBLE, epilogue
|
||
|
+ st_s r0, [r2]
|
||
|
+ st_s r1, [r2,4]
|
||
|
+
|
||
|
+epilogue:
|
||
|
+ j_s.d [blink]
|
||
|
+ ld.ab fp, [sp, 4]
|
||
|
+
|
||
|
+ENTRY(ffi_closure_ARCompact)
|
||
|
+ st.a r0, [sp, -32]
|
||
|
+ st_s r1, [sp, 4]
|
||
|
+ st_s r2, [sp, 8]
|
||
|
+ st_s r3, [sp, 12]
|
||
|
+ st r4, [sp, 16]
|
||
|
+ st r5, [sp, 20]
|
||
|
+ st r6, [sp, 24]
|
||
|
+ st r7, [sp, 28]
|
||
|
+
|
||
|
+ /* pointer to arguments */
|
||
|
+ mov_s r2, sp
|
||
|
+
|
||
|
+ /* return value goes here */
|
||
|
+ sub sp, sp, 8
|
||
|
+ mov_s r1, sp
|
||
|
+
|
||
|
+ push_s blink
|
||
|
+
|
||
|
+ bl.d ffi_closure_inner_ARCompact
|
||
|
+ mov_s r0, r8 /* codeloc, set by trampoline */
|
||
|
+
|
||
|
+ pop_s blink
|
||
|
+
|
||
|
+ /* set return value to r1:r0 */
|
||
|
+ pop_s r0
|
||
|
+ pop_s r1
|
||
|
+ j_s.d [blink]
|
||
|
+ add_s sp, sp, 32
|
||
|
diff --git a/src/arc/ffi.c b/src/arc/ffi.c
|
||
|
new file mode 100644
|
||
|
index 0000000..32f82a7
|
||
|
--- /dev/null
|
||
|
+++ b/src/arc/ffi.c
|
||
|
@@ -0,0 +1,268 @@
|
||
|
+/* -----------------------------------------------------------------------
|
||
|
+ ffi.c - Copyright (c) 2013 Synopsys, Inc. (www.synopsys.com)
|
||
|
+
|
||
|
+ ARC Foreign Function Interface
|
||
|
+
|
||
|
+ Permission is hereby granted, free of charge, to any person obtaining
|
||
|
+ a copy of this software and associated documentation files (the
|
||
|
+ ``Software''), to deal in the Software without restriction, including
|
||
|
+ without limitation the rights to use, copy, modify, merge, publish,
|
||
|
+ distribute, sublicense, and/or sell copies of the Software, and to
|
||
|
+ permit persons to whom the Software is furnished to do so, subject to
|
||
|
+ the following conditions:
|
||
|
+
|
||
|
+ The above copyright notice and this permission notice shall be included
|
||
|
+ in all copies or substantial portions of the Software.
|
||
|
+
|
||
|
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
|
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
|
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||
|
+ IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||
|
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||
|
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||
|
+ OTHER DEALINGS IN THE SOFTWARE.
|
||
|
+ ----------------------------------------------------------------------- */
|
||
|
+
|
||
|
+#include <ffi.h>
|
||
|
+#include <ffi_common.h>
|
||
|
+
|
||
|
+#include <stdlib.h>
|
||
|
+#include <stdint.h>
|
||
|
+
|
||
|
+#include <sys/cachectl.h>
|
||
|
+
|
||
|
+/* for little endian ARC, the code is in fact stored as mixed endian for
|
||
|
+ performance reasons */
|
||
|
+#if __BIG_ENDIAN__
|
||
|
+#define CODE_ENDIAN(x) (x)
|
||
|
+#else
|
||
|
+#define CODE_ENDIAN(x) ( (((uint32_t) (x)) << 16) | (((uint32_t) (x)) >> 16))
|
||
|
+#endif
|
||
|
+
|
||
|
+/* ffi_prep_args is called by the assembly routine once stack
|
||
|
+ space has been allocated for the function's arguments. */
|
||
|
+
|
||
|
+void
|
||
|
+ffi_prep_args (char *stack, extended_cif * ecif)
|
||
|
+{
|
||
|
+ unsigned int i;
|
||
|
+ int tmp;
|
||
|
+ void **p_argv;
|
||
|
+ char *argp;
|
||
|
+ ffi_type **p_arg;
|
||
|
+
|
||
|
+ tmp = 0;
|
||
|
+ argp = stack;
|
||
|
+
|
||
|
+ if (ecif->cif->rtype->type == FFI_TYPE_STRUCT)
|
||
|
+ {
|
||
|
+ *(void **) argp = ecif->rvalue;
|
||
|
+ argp += 4;
|
||
|
+ }
|
||
|
+
|
||
|
+ p_argv = ecif->avalue;
|
||
|
+
|
||
|
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
|
||
|
+ (i != 0); i--, p_arg++)
|
||
|
+ {
|
||
|
+ size_t z;
|
||
|
+ int alignment;
|
||
|
+
|
||
|
+ /* align alignment to 4 */
|
||
|
+ alignment = (((*p_arg)->alignment - 1) | 3) + 1;
|
||
|
+
|
||
|
+ /* Align if necessary. */
|
||
|
+ if ((alignment - 1) & (unsigned) argp)
|
||
|
+ argp = (char *) ALIGN (argp, alignment);
|
||
|
+
|
||
|
+ z = (*p_arg)->size;
|
||
|
+ if (z < sizeof (int))
|
||
|
+ {
|
||
|
+ z = sizeof (int);
|
||
|
+
|
||
|
+ switch ((*p_arg)->type)
|
||
|
+ {
|
||
|
+ case FFI_TYPE_SINT8:
|
||
|
+ *(signed int *) argp = (signed int) *(SINT8 *) (*p_argv);
|
||
|
+ break;
|
||
|
+
|
||
|
+ case FFI_TYPE_UINT8:
|
||
|
+ *(unsigned int *) argp = (unsigned int) *(UINT8 *) (*p_argv);
|
||
|
+ break;
|
||
|
+
|
||
|
+ case FFI_TYPE_SINT16:
|
||
|
+ *(signed int *) argp = (signed int) *(SINT16 *) (*p_argv);
|
||
|
+ break;
|
||
|
+
|
||
|
+ case FFI_TYPE_UINT16:
|
||
|
+ *(unsigned int *) argp = (unsigned int) *(UINT16 *) (*p_argv);
|
||
|
+ break;
|
||
|
+
|
||
|
+ case FFI_TYPE_STRUCT:
|
||
|
+ memcpy (argp, *p_argv, (*p_arg)->size);
|
||
|
+ break;
|
||
|
+
|
||
|
+ default:
|
||
|
+ FFI_ASSERT (0);
|
||
|
+ }
|
||
|
+ }
|
||
|
+ else if (z == sizeof (int))
|
||
|
+ {
|
||
|
+ *(unsigned int *) argp = (unsigned int) *(UINT32 *) (*p_argv);
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ if ((*p_arg)->type == FFI_TYPE_STRUCT)
|
||
|
+ {
|
||
|
+ memcpy (argp, *p_argv, z);
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ /* Double or long long 64bit. */
|
||
|
+ memcpy (argp, *p_argv, z);
|
||
|
+ }
|
||
|
+ }
|
||
|
+ p_argv++;
|
||
|
+ argp += z;
|
||
|
+ }
|
||
|
+
|
||
|
+ return;
|
||
|
+}
|
||
|
+
|
||
|
+/* Perform machine dependent cif processing. */
|
||
|
+ffi_status
|
||
|
+ffi_prep_cif_machdep (ffi_cif * cif)
|
||
|
+{
|
||
|
+ /* Set the return type flag. */
|
||
|
+ switch (cif->rtype->type)
|
||
|
+ {
|
||
|
+ case FFI_TYPE_VOID:
|
||
|
+ cif->flags = (unsigned) cif->rtype->type;
|
||
|
+ break;
|
||
|
+
|
||
|
+ case FFI_TYPE_STRUCT:
|
||
|
+ cif->flags = (unsigned) cif->rtype->type;
|
||
|
+ break;
|
||
|
+
|
||
|
+ case FFI_TYPE_SINT64:
|
||
|
+ case FFI_TYPE_UINT64:
|
||
|
+ case FFI_TYPE_DOUBLE:
|
||
|
+ cif->flags = FFI_TYPE_DOUBLE;
|
||
|
+ break;
|
||
|
+
|
||
|
+ case FFI_TYPE_FLOAT:
|
||
|
+ default:
|
||
|
+ cif->flags = FFI_TYPE_INT;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+
|
||
|
+ return FFI_OK;
|
||
|
+}
|
||
|
+
|
||
|
+extern void ffi_call_ARCompact (void (*)(char *, extended_cif *),
|
||
|
+ extended_cif *, unsigned, unsigned,
|
||
|
+ unsigned *, void (*fn) (void));
|
||
|
+
|
||
|
+void
|
||
|
+ffi_call (ffi_cif * cif, void (*fn) (void), void *rvalue, void **avalue)
|
||
|
+{
|
||
|
+ extended_cif ecif;
|
||
|
+
|
||
|
+ ecif.cif = cif;
|
||
|
+ ecif.avalue = avalue;
|
||
|
+
|
||
|
+ /* If the return value is a struct and we don't have
|
||
|
+ a return value address then we need to make one. */
|
||
|
+ if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
|
||
|
+ {
|
||
|
+ ecif.rvalue = alloca (cif->rtype->size);
|
||
|
+ }
|
||
|
+ else
|
||
|
+ ecif.rvalue = rvalue;
|
||
|
+
|
||
|
+ switch (cif->abi)
|
||
|
+ {
|
||
|
+ case FFI_ARCOMPACT:
|
||
|
+ ffi_call_ARCompact (ffi_prep_args, &ecif, cif->bytes,
|
||
|
+ cif->flags, ecif.rvalue, fn);
|
||
|
+ break;
|
||
|
+
|
||
|
+ default:
|
||
|
+ FFI_ASSERT (0);
|
||
|
+ break;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+int
|
||
|
+ffi_closure_inner_ARCompact (ffi_closure * closure, void *rvalue,
|
||
|
+ ffi_arg * args)
|
||
|
+{
|
||
|
+ void **arg_area, **p_argv;
|
||
|
+ ffi_cif *cif = closure->cif;
|
||
|
+ char *argp = (char *) args;
|
||
|
+ ffi_type **p_argt;
|
||
|
+ int i;
|
||
|
+
|
||
|
+ arg_area = (void **) alloca (cif->nargs * sizeof (void *));
|
||
|
+
|
||
|
+ /* handle hidden argument */
|
||
|
+ if (cif->flags == FFI_TYPE_STRUCT)
|
||
|
+ {
|
||
|
+ rvalue = *(void **) argp;
|
||
|
+ argp += 4;
|
||
|
+ }
|
||
|
+
|
||
|
+ p_argv = arg_area;
|
||
|
+
|
||
|
+ for (i = 0, p_argt = cif->arg_types; i < cif->nargs;
|
||
|
+ i++, p_argt++, p_argv++)
|
||
|
+ {
|
||
|
+ size_t z;
|
||
|
+ int alignment;
|
||
|
+
|
||
|
+ /* align alignment to 4 */
|
||
|
+ alignment = (((*p_argt)->alignment - 1) | 3) + 1;
|
||
|
+
|
||
|
+ /* Align if necessary. */
|
||
|
+ if ((alignment - 1) & (unsigned) argp)
|
||
|
+ argp = (char *) ALIGN (argp, alignment);
|
||
|
+
|
||
|
+ z = (*p_argt)->size;
|
||
|
+ *p_argv = (void *) argp;
|
||
|
+ argp += z;
|
||
|
+ }
|
||
|
+
|
||
|
+ (closure->fun) (cif, rvalue, arg_area, closure->user_data);
|
||
|
+
|
||
|
+ return cif->flags;
|
||
|
+}
|
||
|
+
|
||
|
+extern void ffi_closure_ARCompact (void);
|
||
|
+
|
||
|
+ffi_status
|
||
|
+ffi_prep_closure_loc (ffi_closure * closure, ffi_cif * cif,
|
||
|
+ void (*fun) (ffi_cif *, void *, void **, void *),
|
||
|
+ void *user_data, void *codeloc)
|
||
|
+{
|
||
|
+ uint32_t *tramp = (uint32_t *) & (closure->tramp[0]);
|
||
|
+
|
||
|
+ switch (cif->abi)
|
||
|
+ {
|
||
|
+ case FFI_ARCOMPACT:
|
||
|
+ FFI_ASSERT (tramp == codeloc);
|
||
|
+ tramp[0] = CODE_ENDIAN (0x200a1fc0); /* mov r8, pcl */
|
||
|
+ tramp[1] = CODE_ENDIAN (0x20200f80); /* j [long imm] */
|
||
|
+ tramp[2] = CODE_ENDIAN (ffi_closure_ARCompact);
|
||
|
+ break;
|
||
|
+
|
||
|
+ default:
|
||
|
+ return FFI_BAD_ABI;
|
||
|
+ }
|
||
|
+
|
||
|
+ closure->cif = cif;
|
||
|
+ closure->fun = fun;
|
||
|
+ closure->user_data = user_data;
|
||
|
+ cacheflush (codeloc, FFI_TRAMPOLINE_SIZE, BCACHE);
|
||
|
+
|
||
|
+ return FFI_OK;
|
||
|
+}
|
||
|
diff --git a/src/arc/ffitarget.h b/src/arc/ffitarget.h
|
||
|
new file mode 100644
|
||
|
index 0000000..bf8311b
|
||
|
--- /dev/null
|
||
|
+++ b/src/arc/ffitarget.h
|
||
|
@@ -0,0 +1,53 @@
|
||
|
+/* -----------------------------------------------------------------------
|
||
|
+ ffitarget.h - Copyright (c) 2012 Anthony Green
|
||
|
+ Copyright (c) 2013 Synopsys, Inc. (www.synopsys.com)
|
||
|
+ Target configuration macros for ARC.
|
||
|
+
|
||
|
+ Permission is hereby granted, free of charge, to any person obtaining
|
||
|
+ a copy of this software and associated documentation files (the
|
||
|
+ ``Software''), to deal in the Software without restriction, including
|
||
|
+ without limitation the rights to use, copy, modify, merge, publish,
|
||
|
+ distribute, sublicense, and/or sell copies of the Software, and to
|
||
|
+ permit persons to whom the Software is furnished to do so, subject to
|
||
|
+ the following conditions:
|
||
|
+
|
||
|
+ The above copyright notice and this permission notice shall be included
|
||
|
+ in all copies or substantial portions of the Software.
|
||
|
+
|
||
|
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
|
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
|
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||
|
+ IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||
|
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||
|
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||
|
+ OTHER DEALINGS IN THE SOFTWARE.
|
||
|
+
|
||
|
+ ----------------------------------------------------------------------- */
|
||
|
+
|
||
|
+#ifndef LIBFFI_TARGET_H
|
||
|
+#define LIBFFI_TARGET_H
|
||
|
+
|
||
|
+#ifndef LIBFFI_H
|
||
|
+#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
|
||
|
+#endif
|
||
|
+
|
||
|
+/* ---- Generic type definitions ----------------------------------------- */
|
||
|
+
|
||
|
+#ifndef LIBFFI_ASM
|
||
|
+typedef unsigned long ffi_arg;
|
||
|
+typedef signed long ffi_sarg;
|
||
|
+
|
||
|
+typedef enum ffi_abi
|
||
|
+{
|
||
|
+ FFI_FIRST_ABI = 0,
|
||
|
+ FFI_ARCOMPACT,
|
||
|
+ FFI_LAST_ABI,
|
||
|
+ FFI_DEFAULT_ABI = FFI_ARCOMPACT
|
||
|
+} ffi_abi;
|
||
|
+#endif
|
||
|
+
|
||
|
+#define FFI_CLOSURES 1
|
||
|
+#define FFI_TRAMPOLINE_SIZE 12
|
||
|
+#define FFI_NATIVE_RAW_API 0
|
||
|
+
|
||
|
+#endif
|
||
|
--
|
||
|
1.9.0
|
||
|
|