Xtensa support
This commit is contained in:
13
ChangeLog
13
ChangeLog
@@ -1,3 +1,16 @@
|
||||
2013-01-21 Chris Zankel <chris@zankel.net>
|
||||
|
||||
* README: Add Xtensa support.
|
||||
* Makefile.am: Likewise.
|
||||
* configure.ac: Likewise.
|
||||
* Makefile.in Regenerate.
|
||||
* configure: Likewise.
|
||||
* src/prep_cif.c: Handle Xtensa.
|
||||
* src/xtensa: New directory.
|
||||
* src/xtensa/ffi.c: New file.
|
||||
* src/xtensa/ffitarget.h: Ditto.
|
||||
* src/xtensa/sysv.S: Ditto.
|
||||
|
||||
2013-01-11 Anthony Green <green@moxielogic.com>
|
||||
|
||||
* src/powerpc/ffi_darwin.c (ffi_prep_args): Replace // style
|
||||
|
||||
@@ -32,6 +32,7 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
|
||||
src/bfin/ffitarget.h src/bfin/sysv.S src/frv/eabi.S \
|
||||
src/frv/ffitarget.h src/dlmalloc.c src/tile/ffi.c \
|
||||
src/tile/ffitarget.h src/tile/tile.S libtool-version \
|
||||
src/xtensa/ffitarget.h src/xtensa/ffi.c src/xtensa/sysv.S \
|
||||
ChangeLog.libffi m4/libtool.m4 m4/lt~obsolete.m4 \
|
||||
m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 \
|
||||
m4/ltversion.m4 src/arm/gentramp.sh src/debug.c msvcc.sh \
|
||||
@@ -189,6 +190,9 @@ endif
|
||||
if TILE
|
||||
nodist_libffi_la_SOURCES += src/tile/tile.S src/tile/ffi.c
|
||||
endif
|
||||
if XTENSA
|
||||
nodist_libffi_la_SOURCES += src/xtensa/sysv.S src/xtensa/ffi.c
|
||||
endif
|
||||
|
||||
libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
|
||||
nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
|
||||
|
||||
39
Makefile.in
39
Makefile.in
@@ -81,6 +81,7 @@ target_triplet = @target@
|
||||
@PA_LINUX_TRUE@am__append_28 = src/pa/linux.S src/pa/ffi.c
|
||||
@PA_HPUX_TRUE@am__append_29 = src/pa/hpux32.S src/pa/ffi.c
|
||||
@TILE_TRUE@am__append_30 = src/tile/tile.S src/tile/ffi.c
|
||||
@XTENSA_TRUE@am__append_31 = src/xtensa/sysv.S src/xtensa/ffi.c
|
||||
subdir = .
|
||||
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
|
||||
$(srcdir)/Makefile.in $(srcdir)/doc/stamp-vti \
|
||||
@@ -187,6 +188,7 @@ am_libffi_la_OBJECTS = src/prep_cif.lo src/types.lo src/raw_api.lo \
|
||||
@PA_LINUX_TRUE@am__objects_28 = src/pa/linux.lo src/pa/ffi.lo
|
||||
@PA_HPUX_TRUE@am__objects_29 = src/pa/hpux32.lo src/pa/ffi.lo
|
||||
@TILE_TRUE@am__objects_30 = src/tile/tile.lo src/tile/ffi.lo
|
||||
@XTENSA_TRUE@am__objects_31 = src/xtensa/sysv.lo src/xtensa/ffi.lo
|
||||
nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
|
||||
$(am__objects_3) $(am__objects_4) $(am__objects_5) \
|
||||
$(am__objects_6) $(am__objects_7) $(am__objects_8) \
|
||||
@@ -197,17 +199,17 @@ nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
|
||||
$(am__objects_21) $(am__objects_22) $(am__objects_23) \
|
||||
$(am__objects_24) $(am__objects_25) $(am__objects_26) \
|
||||
$(am__objects_27) $(am__objects_28) $(am__objects_29) \
|
||||
$(am__objects_30)
|
||||
$(am__objects_30) $(am__objects_31)
|
||||
libffi_la_OBJECTS = $(am_libffi_la_OBJECTS) \
|
||||
$(nodist_libffi_la_OBJECTS)
|
||||
libffi_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
$(libffi_la_LDFLAGS) $(LDFLAGS) -o $@
|
||||
libffi_convenience_la_LIBADD =
|
||||
am__objects_31 = src/prep_cif.lo src/types.lo src/raw_api.lo \
|
||||
am__objects_32 = src/prep_cif.lo src/types.lo src/raw_api.lo \
|
||||
src/java_raw_api.lo src/closures.lo
|
||||
am_libffi_convenience_la_OBJECTS = $(am__objects_31)
|
||||
am__objects_32 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
|
||||
am_libffi_convenience_la_OBJECTS = $(am__objects_32)
|
||||
am__objects_33 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
|
||||
$(am__objects_4) $(am__objects_5) $(am__objects_6) \
|
||||
$(am__objects_7) $(am__objects_8) $(am__objects_9) \
|
||||
$(am__objects_10) $(am__objects_11) $(am__objects_12) \
|
||||
@@ -216,8 +218,9 @@ am__objects_32 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
|
||||
$(am__objects_19) $(am__objects_20) $(am__objects_21) \
|
||||
$(am__objects_22) $(am__objects_23) $(am__objects_24) \
|
||||
$(am__objects_25) $(am__objects_26) $(am__objects_27) \
|
||||
$(am__objects_28) $(am__objects_29) $(am__objects_30)
|
||||
nodist_libffi_convenience_la_OBJECTS = $(am__objects_32)
|
||||
$(am__objects_28) $(am__objects_29) $(am__objects_30) \
|
||||
$(am__objects_31)
|
||||
nodist_libffi_convenience_la_OBJECTS = $(am__objects_33)
|
||||
libffi_convenience_la_OBJECTS = $(am_libffi_convenience_la_OBJECTS) \
|
||||
$(nodist_libffi_convenience_la_OBJECTS)
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@
|
||||
@@ -480,6 +483,7 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
|
||||
src/bfin/ffitarget.h src/bfin/sysv.S src/frv/eabi.S \
|
||||
src/frv/ffitarget.h src/dlmalloc.c src/tile/ffi.c \
|
||||
src/tile/ffitarget.h src/tile/tile.S libtool-version \
|
||||
src/xtensa/ffitarget.h src/xtensa/ffi.c src/xtensa/sysv.S \
|
||||
ChangeLog.libffi m4/libtool.m4 m4/lt~obsolete.m4 \
|
||||
m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 \
|
||||
m4/ltversion.m4 src/arm/gentramp.sh src/debug.c msvcc.sh \
|
||||
@@ -546,7 +550,7 @@ nodist_libffi_la_SOURCES = $(am__append_1) $(am__append_2) \
|
||||
$(am__append_21) $(am__append_22) $(am__append_23) \
|
||||
$(am__append_24) $(am__append_25) $(am__append_26) \
|
||||
$(am__append_27) $(am__append_28) $(am__append_29) \
|
||||
$(am__append_30)
|
||||
$(am__append_30) $(am__append_31)
|
||||
libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
|
||||
nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
|
||||
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
|
||||
@@ -892,6 +896,16 @@ src/tile/tile.lo: src/tile/$(am__dirstamp) \
|
||||
src/tile/$(DEPDIR)/$(am__dirstamp)
|
||||
src/tile/ffi.lo: src/tile/$(am__dirstamp) \
|
||||
src/tile/$(DEPDIR)/$(am__dirstamp)
|
||||
src/xtensa/$(am__dirstamp):
|
||||
@$(MKDIR_P) src/xtensa
|
||||
@: > src/xtensa/$(am__dirstamp)
|
||||
src/xtensa/$(DEPDIR)/$(am__dirstamp):
|
||||
@$(MKDIR_P) src/xtensa/$(DEPDIR)
|
||||
@: > src/xtensa/$(DEPDIR)/$(am__dirstamp)
|
||||
src/xtensa/sysv.lo: src/xtensa/$(am__dirstamp) \
|
||||
src/xtensa/$(DEPDIR)/$(am__dirstamp)
|
||||
src/xtensa/ffi.lo: src/xtensa/$(am__dirstamp) \
|
||||
src/xtensa/$(DEPDIR)/$(am__dirstamp)
|
||||
libffi.la: $(libffi_la_OBJECTS) $(libffi_la_DEPENDENCIES) $(EXTRA_libffi_la_DEPENDENCIES)
|
||||
$(libffi_la_LINK) -rpath $(toolexeclibdir) $(libffi_la_OBJECTS) $(libffi_la_LIBADD) $(LIBS)
|
||||
libffi_convenience.la: $(libffi_convenience_la_OBJECTS) $(libffi_convenience_la_DEPENDENCIES) $(EXTRA_libffi_convenience_la_DEPENDENCIES)
|
||||
@@ -939,6 +953,8 @@ mostlyclean-compile:
|
||||
-rm -f src/tile/*.lo
|
||||
-rm -f src/x86/*.$(OBJEXT)
|
||||
-rm -f src/x86/*.lo
|
||||
-rm -f src/xtensa/*.$(OBJEXT)
|
||||
-rm -f src/xtensa/*.lo
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
@@ -1006,6 +1022,8 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/unix64.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/win32.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/win64.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/xtensa/$(DEPDIR)/ffi.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/xtensa/$(DEPDIR)/sysv.Plo@am__quote@
|
||||
|
||||
.S.o:
|
||||
@am__fastdepCCAS_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
|
||||
@@ -1080,6 +1098,7 @@ clean-libtool:
|
||||
-rm -rf src/sparc/.libs src/sparc/_libs
|
||||
-rm -rf src/tile/.libs src/tile/_libs
|
||||
-rm -rf src/x86/.libs src/x86/_libs
|
||||
-rm -rf src/xtensa/.libs src/xtensa/_libs
|
||||
|
||||
distclean-libtool:
|
||||
-rm -f libtool config.lt
|
||||
@@ -1642,6 +1661,8 @@ distclean-generic:
|
||||
-rm -f src/tile/$(am__dirstamp)
|
||||
-rm -f src/x86/$(DEPDIR)/$(am__dirstamp)
|
||||
-rm -f src/x86/$(am__dirstamp)
|
||||
-rm -f src/xtensa/$(DEPDIR)/$(am__dirstamp)
|
||||
-rm -f src/xtensa/$(am__dirstamp)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@@ -1654,7 +1675,7 @@ clean-am: clean-aminfo clean-generic clean-libtool \
|
||||
|
||||
distclean: distclean-recursive
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/mips/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/x86/$(DEPDIR)
|
||||
-rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/mips/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-hdr distclean-libtool distclean-tags
|
||||
@@ -1793,7 +1814,7 @@ installcheck-am:
|
||||
maintainer-clean: maintainer-clean-recursive
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -rf $(top_srcdir)/autom4te.cache
|
||||
-rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/mips/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/x86/$(DEPDIR)
|
||||
-rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/mips/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-aminfo \
|
||||
maintainer-clean-generic maintainer-clean-vti
|
||||
|
||||
3
README
3
README
@@ -99,6 +99,7 @@ tested:
|
||||
| X86-64 | OpenBSD | GCC |
|
||||
| X86-64 | Solaris | Oracle Solaris Studio C |
|
||||
| X86-64 | Windows/MingW | GCC |
|
||||
| Xtensa | Linux | GCC |
|
||||
|-----------------+------------------+-------------------------|
|
||||
|
||||
Please send additional platform test results to
|
||||
@@ -160,6 +161,7 @@ See the ChangeLog files for details.
|
||||
Add Blackfin support.
|
||||
Add TILE-Gx/TILEPro support.
|
||||
Add AArch64 support.
|
||||
Add Xtensa support.
|
||||
Add support for PaX enabled kernels with MPROTECT.
|
||||
Add support for native vendor compilers on
|
||||
Solaris and AIX.
|
||||
@@ -355,6 +357,7 @@ sparc Anthony Green, Gordon Irlam
|
||||
tile-gx/tilepro Walter Lee
|
||||
x86 Anthony Green, Jon Beniston
|
||||
x86-64 Bo Thorsen
|
||||
xtensa Chris Zankel
|
||||
|
||||
Jesper Skov and Andrew Haley both did more than their fair share of
|
||||
stepping through the code and tracking down bugs.
|
||||
|
||||
18
configure
vendored
18
configure
vendored
@@ -647,6 +647,8 @@ FFI_EXEC_TRAMPOLINE_TABLE_TRUE
|
||||
sys_symbol_underscore
|
||||
HAVE_LONG_DOUBLE
|
||||
ALLOCA
|
||||
XTENSA_FALSE
|
||||
XTENSA_TRUE
|
||||
TILE_FALSE
|
||||
TILE_TRUE
|
||||
PA64_HPUX_FALSE
|
||||
@@ -13452,6 +13454,10 @@ case "$host" in
|
||||
fi
|
||||
;;
|
||||
|
||||
xtensa*-*)
|
||||
TARGET=XTENSA; TARGETDIR=xtensa
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
|
||||
@@ -13701,6 +13707,14 @@ else
|
||||
TILE_FALSE=
|
||||
fi
|
||||
|
||||
if test x$TARGET = xXTENSA; then
|
||||
XTENSA_TRUE=
|
||||
XTENSA_FALSE='#'
|
||||
else
|
||||
XTENSA_TRUE='#'
|
||||
XTENSA_FALSE=
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
|
||||
$as_echo_n "checking for ANSI C header files... " >&6; }
|
||||
@@ -15071,6 +15085,10 @@ if test -z "${TILE_TRUE}" && test -z "${TILE_FALSE}"; then
|
||||
as_fn_error $? "conditional \"TILE\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
fi
|
||||
if test -z "${XTENSA_TRUE}" && test -z "${XTENSA_FALSE}"; then
|
||||
as_fn_error $? "conditional \"XTENSA\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
fi
|
||||
|
||||
if test -z "${FFI_EXEC_TRAMPOLINE_TABLE_TRUE}" && test -z "${FFI_EXEC_TRAMPOLINE_TABLE_FALSE}"; then
|
||||
as_fn_error $? "conditional \"FFI_EXEC_TRAMPOLINE_TABLE\" was never defined.
|
||||
|
||||
@@ -237,6 +237,10 @@ case "$host" in
|
||||
fi
|
||||
;;
|
||||
|
||||
xtensa*-*)
|
||||
TARGET=XTENSA; TARGETDIR=xtensa
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
AC_SUBST(AM_RUNTESTFLAGS)
|
||||
@@ -276,6 +280,7 @@ AM_CONDITIONAL(PA_LINUX, test x$TARGET = xPA_LINUX)
|
||||
AM_CONDITIONAL(PA_HPUX, test x$TARGET = xPA_HPUX)
|
||||
AM_CONDITIONAL(PA64_HPUX, test x$TARGET = xPA64_HPUX)
|
||||
AM_CONDITIONAL(TILE, test x$TARGET = xTILE)
|
||||
AM_CONDITIONAL(XTENSA, test x$TARGET = xXTENSA)
|
||||
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_FUNCS(memcpy)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@set UPDATED 14 February 2008
|
||||
@set UPDATED-MONTH February 2008
|
||||
@set EDITION 3.0.8
|
||||
@set VERSION 3.0.8
|
||||
@set UPDATED 23 December 2012
|
||||
@set UPDATED-MONTH December 2012
|
||||
@set EDITION 3.0.12-rc0
|
||||
@set VERSION 3.0.12-rc0
|
||||
|
||||
@@ -143,6 +143,10 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
|
||||
#ifdef TILE
|
||||
&& (cif->rtype->size > 10 * FFI_SIZEOF_ARG)
|
||||
#endif
|
||||
#ifdef XTENSA
|
||||
&& (cif->rtype->size > 16)
|
||||
#endif
|
||||
|
||||
)
|
||||
bytes = STACK_ARG_SIZE(sizeof(void*));
|
||||
#endif
|
||||
@@ -181,6 +185,10 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
|
||||
bytes = 10 * FFI_SIZEOF_ARG;
|
||||
}
|
||||
#endif
|
||||
#ifdef XTENSA
|
||||
if (bytes <= 6*4 && bytes + STACK_ARG_SIZE((*ptr)->size) > 6*4)
|
||||
bytes = 6*4;
|
||||
#endif
|
||||
|
||||
bytes += STACK_ARG_SIZE((*ptr)->size);
|
||||
}
|
||||
|
||||
298
src/xtensa/ffi.c
Normal file
298
src/xtensa/ffi.c
Normal file
@@ -0,0 +1,298 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffi.c - Copyright (c) 2013 Tensilica, Inc.
|
||||
|
||||
XTENSA 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 THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS 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>
|
||||
|
||||
/*
|
||||
|----------------------------------------|
|
||||
| |
|
||||
on entry to ffi_call ----> |----------------------------------------|
|
||||
| caller stack frame for registers a0-a3 |
|
||||
|----------------------------------------|
|
||||
| |
|
||||
| additional arguments |
|
||||
entry of the function ---> |----------------------------------------|
|
||||
| copy of function arguments a2-a7 |
|
||||
| - - - - - - - - - - - - - |
|
||||
| |
|
||||
|
||||
The area below the entry line becomes the new stack frame for the function.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#define FFI_TYPE_STRUCT_REGS FFI_TYPE_LAST
|
||||
|
||||
|
||||
extern void ffi_call_SYSV(void *rvalue, unsigned rsize, unsigned flags,
|
||||
void(*fn)(void), unsigned nbytes, extended_cif*);
|
||||
extern void ffi_closure_SYSV(void) FFI_HIDDEN;
|
||||
|
||||
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
{
|
||||
switch(cif->rtype->type) {
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_UINT16:
|
||||
cif->flags = cif->rtype->type;
|
||||
break;
|
||||
case FFI_TYPE_VOID:
|
||||
case FFI_TYPE_FLOAT:
|
||||
cif->flags = FFI_TYPE_UINT32;
|
||||
break;
|
||||
case FFI_TYPE_DOUBLE:
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_SINT64:
|
||||
cif->flags = FFI_TYPE_UINT64; // cif->rtype->type;
|
||||
break;
|
||||
case FFI_TYPE_STRUCT:
|
||||
cif->flags = FFI_TYPE_STRUCT; //_REGS;
|
||||
/* Up to 16 bytes are returned in registers */
|
||||
if (cif->rtype->size > 4 * 4) {
|
||||
/* returned structure is referenced by a register; use 8 bytes
|
||||
(including 4 bytes for potential additional alignment) */
|
||||
cif->flags = FFI_TYPE_STRUCT;
|
||||
cif->bytes += 8;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
cif->flags = FFI_TYPE_UINT32;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Round the stack up to a full 4 register frame, just in case
|
||||
(we use this size in movsp). This way, it's also a multiple of
|
||||
8 bytes for 64-bit arguments. */
|
||||
cif->bytes = ALIGN(cif->bytes, 16);
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
void ffi_prep_args(extended_cif *ecif, unsigned char* stack)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned long *addr;
|
||||
ffi_type **ptr;
|
||||
|
||||
union {
|
||||
void **v;
|
||||
char **c;
|
||||
signed char **sc;
|
||||
unsigned char **uc;
|
||||
signed short **ss;
|
||||
unsigned short **us;
|
||||
unsigned int **i;
|
||||
long long **ll;
|
||||
float **f;
|
||||
double **d;
|
||||
} p_argv;
|
||||
|
||||
/* Verify that everything is aligned up properly */
|
||||
FFI_ASSERT (((unsigned long) stack & 0x7) == 0);
|
||||
|
||||
p_argv.v = ecif->avalue;
|
||||
addr = (unsigned long*)stack;
|
||||
|
||||
/* structures with a size greater than 16 bytes are passed in memory */
|
||||
if (ecif->cif->rtype->type == FFI_TYPE_STRUCT && ecif->cif->rtype->size > 16)
|
||||
{
|
||||
*addr++ = (unsigned long)ecif->rvalue;
|
||||
}
|
||||
|
||||
for (i = ecif->cif->nargs, ptr = ecif->cif->arg_types;
|
||||
i > 0;
|
||||
i--, ptr++, p_argv.v++)
|
||||
{
|
||||
switch ((*ptr)->type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
*addr++ = **p_argv.sc;
|
||||
break;
|
||||
case FFI_TYPE_UINT8:
|
||||
*addr++ = **p_argv.uc;
|
||||
break;
|
||||
case FFI_TYPE_SINT16:
|
||||
*addr++ = **p_argv.ss;
|
||||
break;
|
||||
case FFI_TYPE_UINT16:
|
||||
*addr++ = **p_argv.us;
|
||||
break;
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_INT:
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_POINTER:
|
||||
*addr++ = **p_argv.i;
|
||||
break;
|
||||
case FFI_TYPE_DOUBLE:
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_SINT64:
|
||||
if (((unsigned long)addr & 4) != 0)
|
||||
addr++;
|
||||
*(unsigned long long*)addr = **p_argv.ll;
|
||||
addr += sizeof(unsigned long long) / sizeof (addr);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
{
|
||||
unsigned long offs;
|
||||
unsigned long size;
|
||||
|
||||
if (((unsigned long)addr & 4) != 0 && (*ptr)->alignment > 4)
|
||||
addr++;
|
||||
|
||||
offs = (unsigned long) addr - (unsigned long) stack;
|
||||
size = (*ptr)->size;
|
||||
|
||||
/* Entire structure must fit the argument registers or referenced */
|
||||
if (offs < FFI_REGISTER_NARGS * 4
|
||||
&& offs + size > FFI_REGISTER_NARGS * 4)
|
||||
addr = (unsigned long*) (stack + FFI_REGISTER_NARGS * 4);
|
||||
|
||||
memcpy((char*) addr, *p_argv.c, size);
|
||||
addr += (size + 3) / 4;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ffi_call(ffi_cif* cif, void(*fn)(void), void *rvalue, void **avalue)
|
||||
{
|
||||
extended_cif ecif;
|
||||
unsigned long rsize = cif->rtype->size;
|
||||
int flags = cif->flags;
|
||||
void *alloc = NULL;
|
||||
|
||||
ecif.cif = cif;
|
||||
ecif.avalue = avalue;
|
||||
|
||||
/* Note that for structures that are returned in registers (size <= 16 bytes)
|
||||
we allocate a temporary buffer and use memcpy to copy it to the final
|
||||
destination. The reason is that the target address might be misaligned or
|
||||
the length not a multiple of 4 bytes. Handling all those cases would be
|
||||
very complex. */
|
||||
|
||||
if (flags == FFI_TYPE_STRUCT && (rsize <= 16 || rvalue == NULL))
|
||||
{
|
||||
alloc = alloca(ALIGN(rsize, 4));
|
||||
ecif.rvalue = alloc;
|
||||
}
|
||||
else
|
||||
{
|
||||
ecif.rvalue = rvalue;
|
||||
}
|
||||
|
||||
if (cif->abi != FFI_SYSV)
|
||||
FFI_ASSERT(0);
|
||||
|
||||
ffi_call_SYSV (ecif.rvalue, rsize, cif->flags, fn, cif->bytes, &ecif);
|
||||
|
||||
if (alloc != NULL && rvalue != NULL)
|
||||
memcpy(rvalue, alloc, rsize);
|
||||
}
|
||||
|
||||
extern void ffi_trampoline();
|
||||
extern void ffi_cacheflush(void* start, void* end);
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure* closure,
|
||||
ffi_cif* cif,
|
||||
void (*fun)(ffi_cif*, void*, void**, void*),
|
||||
void *user_data,
|
||||
void *codeloc)
|
||||
{
|
||||
/* copye trampoline to stack and patch 'ffi_closure_SYSV' pointer */
|
||||
memcpy(closure->tramp, ffi_trampoline, FFI_TRAMPOLINE_SIZE);
|
||||
*(unsigned int*)(&closure->tramp[8]) = (unsigned int)ffi_closure_SYSV;
|
||||
|
||||
// Do we have this function?
|
||||
// __builtin___clear_cache(closer->tramp, closer->tramp + FFI_TRAMPOLINE_SIZE)
|
||||
ffi_cacheflush(closure->tramp, closure->tramp + FFI_TRAMPOLINE_SIZE);
|
||||
|
||||
closure->cif = cif;
|
||||
closure->fun = fun;
|
||||
closure->user_data = user_data;
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
|
||||
long FFI_HIDDEN
|
||||
ffi_closure_SYSV_inner(ffi_closure *closure, void **values, void *rvalue)
|
||||
{
|
||||
ffi_cif *cif;
|
||||
ffi_type **arg_types;
|
||||
void **avalue;
|
||||
int i, areg;
|
||||
|
||||
cif = closure->cif;
|
||||
if (cif->abi != FFI_SYSV)
|
||||
return FFI_BAD_ABI;
|
||||
|
||||
areg = 0;
|
||||
|
||||
int rtype = cif->rtype->type;
|
||||
if (rtype == FFI_TYPE_STRUCT && cif->rtype->size > 4 * 4)
|
||||
{
|
||||
rvalue = *values;
|
||||
areg++;
|
||||
}
|
||||
|
||||
cif = closure->cif;
|
||||
arg_types = cif->arg_types;
|
||||
avalue = alloca(cif->nargs * sizeof(void *));
|
||||
|
||||
for (i = 0; i < cif->nargs; i++)
|
||||
{
|
||||
if (arg_types[i]->alignment == 8 && (areg & 1) != 0)
|
||||
areg++;
|
||||
|
||||
// skip the entry 16,a1 framework, add 16 bytes (4 registers)
|
||||
if (areg == FFI_REGISTER_NARGS)
|
||||
areg += 4;
|
||||
|
||||
if (arg_types[i]->type == FFI_TYPE_STRUCT)
|
||||
{
|
||||
int numregs = ((arg_types[i]->size + 3) & ~3) / 4;
|
||||
if (areg < FFI_REGISTER_NARGS && areg + numregs > FFI_REGISTER_NARGS)
|
||||
areg = FFI_REGISTER_NARGS + 4;
|
||||
}
|
||||
|
||||
avalue[i] = &values[areg];
|
||||
areg += (arg_types[i]->size + 3) / 4;
|
||||
}
|
||||
|
||||
(closure->fun)(cif, rvalue, avalue, closure->user_data);
|
||||
|
||||
return rtype;
|
||||
}
|
||||
53
src/xtensa/ffitarget.h
Normal file
53
src/xtensa/ffitarget.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 2013 Tensilica, Inc.
|
||||
Target configuration macros for XTENSA.
|
||||
|
||||
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 THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS 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
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
FFI_SYSV,
|
||||
FFI_LAST_ABI,
|
||||
FFI_DEFAULT_ABI = FFI_SYSV
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
#define FFI_REGISTER_NARGS 6
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
#define FFI_TRAMPOLINE_SIZE 24
|
||||
|
||||
#endif
|
||||
253
src/xtensa/sysv.S
Normal file
253
src/xtensa/sysv.S
Normal file
@@ -0,0 +1,253 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
sysv.S - Copyright (c) 2013 Tensilica, Inc.
|
||||
|
||||
XTENSA 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 THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS 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>
|
||||
|
||||
#define ENTRY(name) .text; .globl name; .type name,@function; .align 4; name:
|
||||
#define END(name) .size name , . - name
|
||||
|
||||
/* Assert that the table below is in sync with ffi.h. */
|
||||
|
||||
#if FFI_TYPE_UINT8 != 5 \
|
||||
|| FFI_TYPE_SINT8 != 6 \
|
||||
|| FFI_TYPE_UINT16 != 7 \
|
||||
|| FFI_TYPE_SINT16 != 8 \
|
||||
|| FFI_TYPE_UINT32 != 9 \
|
||||
|| FFI_TYPE_SINT32 != 10 \
|
||||
|| FFI_TYPE_UINT64 != 11
|
||||
#error "xtensa/sysv.S out of sync with ffi.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* ffi_call_SYSV (rvalue, rbytes, flags, (*fnaddr)(), bytes, ecif)
|
||||
void *rvalue; a2
|
||||
unsigned long rbytes; a3
|
||||
unsigned flags; a4
|
||||
void (*fnaddr)(); a5
|
||||
unsigned long bytes; a6
|
||||
extended_cif* ecif) a7
|
||||
*/
|
||||
|
||||
ENTRY(ffi_call_SYSV)
|
||||
|
||||
entry a1, 32 # 32 byte frame for using call8 below
|
||||
|
||||
mov a10, a7 # a10(->arg0): ecif
|
||||
sub a11, a1, a6 # a11(->arg1): stack pointer
|
||||
mov a7, a1 # fp
|
||||
movsp a1, a11 # set new sp = old_sp - bytes
|
||||
|
||||
movi a8, ffi_prep_args
|
||||
callx8 a8 # ffi_prep_args(ecif, stack)
|
||||
|
||||
# prepare to move stack pointer back up to 6 arguments
|
||||
# note that 'bytes' is already aligned
|
||||
|
||||
movi a10, 6*4
|
||||
sub a11, a6, a10
|
||||
movgez a6, a10, a11
|
||||
add a6, a1, a6
|
||||
|
||||
|
||||
# we can pass up to 6 arguments in registers
|
||||
# for simplicity, just load 6 arguments
|
||||
# (the stack size is at least 32 bytes, so no risk to cross boundaries)
|
||||
|
||||
l32i a10, a1, 0
|
||||
l32i a11, a1, 4
|
||||
l32i a12, a1, 8
|
||||
l32i a13, a1, 12
|
||||
l32i a14, a1, 16
|
||||
l32i a15, a1, 20
|
||||
|
||||
# move stack pointer
|
||||
|
||||
movsp a1, a6
|
||||
|
||||
callx8 a5 # (*fn)(args...)
|
||||
|
||||
# Handle return value(s)
|
||||
|
||||
beqz a2, .Lexit
|
||||
|
||||
movi a5, FFI_TYPE_STRUCT
|
||||
bne a4, a5, .Lstore
|
||||
movi a5, 16
|
||||
blt a5, a3, .Lexit
|
||||
|
||||
s32i a10, a2, 0
|
||||
blti a3, 5, .Lexit
|
||||
addi a3, a3, -1
|
||||
s32i a11, a2, 4
|
||||
blti a3, 8, .Lexit
|
||||
s32i a12, a2, 8
|
||||
blti a3, 12, .Lexit
|
||||
s32i a13, a2, 12
|
||||
|
||||
.Lexit: retw
|
||||
|
||||
.Lstore:
|
||||
addi a4, a4, -FFI_TYPE_UINT8
|
||||
bgei a4, 7, .Lexit # should never happen
|
||||
movi a6, store_calls
|
||||
add a4, a4, a4
|
||||
addx4 a6, a4, a6 # store_table + idx * 8
|
||||
jx a6
|
||||
|
||||
.align 8
|
||||
store_calls:
|
||||
# UINT8
|
||||
s8i a10, a2, 0
|
||||
retw
|
||||
|
||||
# SINT8
|
||||
.align 8
|
||||
s8i a10, a2, 0
|
||||
retw
|
||||
|
||||
# UINT16
|
||||
.align 8
|
||||
s16i a10, a2, 0
|
||||
retw
|
||||
|
||||
# SINT16
|
||||
.align 8
|
||||
s16i a10, a2, 0
|
||||
retw
|
||||
|
||||
# UINT32
|
||||
.align 8
|
||||
s32i a10, a2, 0
|
||||
retw
|
||||
|
||||
# SINT32
|
||||
.align 8
|
||||
s32i a10, a2, 0
|
||||
retw
|
||||
|
||||
# UINT64
|
||||
.align 8
|
||||
s32i a10, a2, 0
|
||||
s32i a11, a2, 4
|
||||
retw
|
||||
|
||||
END(ffi_call_SYSV)
|
||||
|
||||
|
||||
/*
|
||||
* void ffi_cacheflush (unsigned long start, unsigned long end)
|
||||
*/
|
||||
|
||||
#define EXTRA_ARGS_SIZE 24
|
||||
|
||||
ENTRY(ffi_cacheflush)
|
||||
|
||||
entry a1, 16
|
||||
|
||||
1: dhwbi a2, 0
|
||||
ihi a2, 0
|
||||
addi a2, a2, 4
|
||||
blt a2, a3, 1b
|
||||
|
||||
retw
|
||||
|
||||
END(ffi_cacheflush)
|
||||
|
||||
/* ffi_trampoline is copied to the stack */
|
||||
|
||||
ENTRY(ffi_trampoline)
|
||||
|
||||
entry a1, 16 + (FFI_REGISTER_NARGS * 4) + (4 * 4) # [ 0]
|
||||
j 2f # [ 3]
|
||||
.align 4 # [ 6]
|
||||
1: .long 0 # [ 8]
|
||||
2: l32r a15, 1b # [12]
|
||||
_mov a14, a0 # [15]
|
||||
callx0 a15 # [18]
|
||||
# [21]
|
||||
END(ffi_trampoline)
|
||||
|
||||
/*
|
||||
* ffi_closure()
|
||||
*
|
||||
* a0: closure + 21
|
||||
* a14: return address (a0)
|
||||
*/
|
||||
|
||||
ENTRY(ffi_closure_SYSV)
|
||||
|
||||
/* intentionally omitting entry here */
|
||||
|
||||
# restore return address (a0) and move pointer to closure to a10
|
||||
addi a10, a0, -21
|
||||
mov a0, a14
|
||||
|
||||
# allow up to 4 arguments as return values
|
||||
addi a11, a1, 4 * 4
|
||||
|
||||
# save up to 6 arguments to stack (allocated by entry below)
|
||||
s32i a2, a11, 0
|
||||
s32i a3, a11, 4
|
||||
s32i a4, a11, 8
|
||||
s32i a5, a11, 12
|
||||
s32i a6, a11, 16
|
||||
s32i a7, a11, 20
|
||||
|
||||
movi a8, ffi_closure_SYSV_inner
|
||||
mov a12, a1
|
||||
callx8 a8 # .._inner(*closure, **avalue, *rvalue)
|
||||
|
||||
# load up to four return arguments
|
||||
l32i a2, a1, 0
|
||||
l32i a3, a1, 4
|
||||
l32i a4, a1, 8
|
||||
l32i a5, a1, 12
|
||||
|
||||
# (sign-)extend return value
|
||||
movi a11, FFI_TYPE_UINT8
|
||||
bne a10, a11, 1f
|
||||
extui a2, a2, 0, 8
|
||||
retw
|
||||
|
||||
1: movi a11, FFI_TYPE_SINT8
|
||||
bne a10, a11, 1f
|
||||
sext a2, a2, 7
|
||||
retw
|
||||
|
||||
1: movi a11, FFI_TYPE_UINT16
|
||||
bne a10, a11, 1f
|
||||
extui a2, a2, 0, 16
|
||||
retw
|
||||
|
||||
1: movi a11, FFI_TYPE_SINT16
|
||||
bne a10, a11, 1f
|
||||
sext a2, a2, 15
|
||||
|
||||
1: retw
|
||||
|
||||
END(ffi_closure_SYSV)
|
||||
Reference in New Issue
Block a user