summaryrefslogtreecommitdiffstats
path: root/package/libffi/libffi-arc-01-Add-ARC-support.patch
diff options
context:
space:
mode:
authorPeter Korsgaard <peter@korsgaard.com>2014-06-01 09:58:54 +0200
committerPeter Korsgaard <peter@korsgaard.com>2014-06-01 09:58:54 +0200
commit27a5414804f7b8ab41101aad219ebef02d364bde (patch)
treec9535dfed260314855b3ba1fe2c75652fdf60a1a /package/libffi/libffi-arc-01-Add-ARC-support.patch
parentf6162290fb6800fecffb86eed42069aa0f813f87 (diff)
parentfc90fa9417d8b99b5d1c77aaa9e4c9ac4c8c7c58 (diff)
downloadbuildroot-27a5414804f7b8ab41101aad219ebef02d364bde.tar.gz
buildroot-27a5414804f7b8ab41101aad219ebef02d364bde.zip
Merge branch 'next'
Conflicts: package/gdb/Config.in.host Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
Diffstat (limited to 'package/libffi/libffi-arc-01-Add-ARC-support.patch')
-rw-r--r--package/libffi/libffi-arc-01-Add-ARC-support.patch560
1 files changed, 560 insertions, 0 deletions
diff --git a/package/libffi/libffi-arc-01-Add-ARC-support.patch b/package/libffi/libffi-arc-01-Add-ARC-support.patch
new file mode 100644
index 0000000000..c39a3e70de
--- /dev/null
+++ b/package/libffi/libffi-arc-01-Add-ARC-support.patch
@@ -0,0 +1,560 @@
+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
+
OpenPOWER on IntegriCloud