From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8914 invoked by alias); 8 Aug 2012 18:46:06 -0000 Received: (qmail 8897 invoked by uid 22791); 8 Aug 2012 18:46:02 -0000 X-SWARE-Spam-Status: No, hits=0.3 required=5.0 tests=AWL,BAYES_50,KHOP_THREADED,TW_BF,TW_BG,TW_CP,TW_EG,TW_GZ,TW_JR,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from usmamail.tilera.com (HELO USMAMAIL.TILERA.COM) (12.216.194.151) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 08 Aug 2012 18:45:44 +0000 Received: from [10.7.0.160] (10.9.0.23) by USMAExch2.tad.internal.tilera.com (10.3.0.33) with Microsoft SMTP Server (TLS) id 14.0.694.0; Wed, 8 Aug 2012 14:45:42 -0400 Message-ID: <5022B3D6.3040401@tilera.com> Date: Wed, 08 Aug 2012 18:46:00 -0000 From: Walter Lee User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20120614 Thunderbird/13.0.1 MIME-Version: 1.0 To: Walter Lee CC: Subject: Re: [PATCH] new port for TILE-Gx/TILEPro References: <201207102148.q6ALmm6S019170@farm-0039.internal.tilera.com> In-Reply-To: <201207102148.q6ALmm6S019170@farm-0039.internal.tilera.com> Content-Type: text/plain; charset="ISO-8859-1"; format=flowed Content-Transfer-Encoding: 7bit Mailing-List: contact libffi-discuss-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libffi-discuss-owner@sourceware.org X-SW-Source: 2012/txt/msg00225.txt.bz2 Ping? Is there something else I need to do? Thanks, Walter On 7/10/2012 5:48 PM, Walter Lee wrote: > On behalf of Tilera Corporation, I would like to contribute libffi > ports for the TILE-Gx and TILEPro architectures. The ports have been > in use for over two years, and they pass the test suite cleanly. The > ChangeLog entry and the patch are included below. Please let me know > if there is anything else I need to do. > > Thanks, > > Walter Lee > > 2012-07-10 Walter Lee > > * Makefile.am: Add TILE-Gx/TILEPro support. > * configure.ac: Likewise. > * Makefile.in: Regenerate. > * configure: Likewise. > * src/prep_cif.c (ffi_prep_cif_core): Handle TILE-Gx/TILEPro. > * src/tile: New directory. > * src/tile/ffi.c: New file. > * src/tile/ffitarget.h: Ditto. > * src/tile/tile.S: Ditto. > > ---------------------------------------------------------------- > > diff -ruP orig/libffi/Makefile.am libffi/Makefile.am > --- orig/libffi/Makefile.am 2012-07-10 17:17:21.879017000 -0400 > +++ libffi/Makefile.am 2012-07-10 17:24:59.475868000 -0400 > @@ -29,11 +29,12 @@ > src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S src/frv/ffi.c \ > src/bfin/ffi.c src/bfin/ffitarget.h src/bfin/sysv.S \ > src/frv/eabi.S src/frv/ffitarget.h src/dlmalloc.c \ > - src/moxie/ffi.c src/moxie/eabi.S libtool-version \ > - 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 generate-ios-source-and-headers.py \ > + src/moxie/ffi.c src/moxie/eabi.S src/tile/ffi.c \ > + src/tile/tile.S libtool-version 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 \ > + generate-ios-source-and-headers.py \ > generate-osx-source-and-headers.py \ > libffi.xcodeproj/project.pbxproj \ > src/arm/trampoline.S > @@ -187,6 +188,9 @@ > if PA_HPUX > nodist_libffi_la_SOURCES += src/pa/hpux32.S src/pa/ffi.c > endif > +if TILE > +nodist_libffi_la_SOURCES += src/tile/tile.S src/tile/ffi.c > +endif > > libffi_convenience_la_SOURCES = $(libffi_la_SOURCES) > nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES) > diff -ruP orig/libffi/Makefile.in libffi/Makefile.in > --- orig/libffi/Makefile.in 2012-07-10 17:17:21.881014000 -0400 > +++ libffi/Makefile.in 2012-07-10 17:31:20.642098000 -0400 > @@ -65,9 +65,10 @@ > @SH64_TRUE@am__append_27 = src/sh64/sysv.S src/sh64/ffi.c > @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 > # Build debug. Define FFI_DEBUG on the commandline so that, when building with > # MSVC, it can link against the debug CRT. > -@FFI_DEBUG_TRUE@am__append_30 = -DFFI_DEBUG > +@FFI_DEBUG_TRUE@am__append_31 = -DFFI_DEBUG > subdir = . > DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ > $(srcdir)/Makefile.in $(srcdir)/doc/stamp-vti \ > @@ -156,6 +157,7 @@ > @SH64_TRUE@am__objects_27 = src/sh64/sysv.lo src/sh64/ffi.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 > 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) \ > @@ -165,17 +167,18 @@ > $(am__objects_18) $(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_27) $(am__objects_28) $(am__objects_29) \ > + $(am__objects_30) > 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_30 = src/prep_cif.lo src/types.lo src/raw_api.lo \ > +am__objects_31 = 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_30) > -am__objects_31 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \ > +am_libffi_convenience_la_OBJECTS = $(am__objects_31) > +am__objects_32 = $(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) \ > @@ -184,8 +187,8 @@ > $(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) > -nodist_libffi_convenience_la_OBJECTS = $(am__objects_31) > + $(am__objects_28) $(am__objects_29) $(am__objects_30) > +nodist_libffi_convenience_la_OBJECTS = $(am__objects_32) > libffi_convenience_la_OBJECTS = $(am_libffi_convenience_la_OBJECTS) \ > $(nodist_libffi_convenience_la_OBJECTS) > DEFAULT_INCLUDES = -I.@am__isrc@ > @@ -434,11 +437,12 @@ > src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S src/frv/ffi.c \ > src/bfin/ffi.c src/bfin/ffitarget.h src/bfin/sysv.S \ > src/frv/eabi.S src/frv/ffitarget.h src/dlmalloc.c \ > - src/moxie/ffi.c src/moxie/eabi.S libtool-version \ > - 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 generate-ios-source-and-headers.py \ > + src/moxie/ffi.c src/moxie/eabi.S src/tile/ffi.c \ > + src/tile/tile.S libtool-version 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 \ > + generate-ios-source-and-headers.py \ > generate-osx-source-and-headers.py \ > libffi.xcodeproj/project.pbxproj \ > src/arm/trampoline.S > @@ -501,10 +505,11 @@ > $(am__append_18) $(am__append_19) $(am__append_20) \ > $(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_27) $(am__append_28) $(am__append_29) \ > + $(am__append_30) > libffi_convenience_la_SOURCES = $(libffi_la_SOURCES) > nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES) > -AM_CFLAGS = -g $(am__append_30) > +AM_CFLAGS = -g $(am__append_31) > libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS) > AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src -DFFI_BUILDING > AM_CCASFLAGS = $(AM_CPPFLAGS) -g > @@ -834,6 +839,16 @@ > src/pa/ffi.lo: src/pa/$(am__dirstamp) src/pa/$(DEPDIR)/$(am__dirstamp) > src/pa/hpux32.lo: src/pa/$(am__dirstamp) \ > src/pa/$(DEPDIR)/$(am__dirstamp) > +src/tile/$(am__dirstamp): > + @$(MKDIR_P) src/tile > + @: > src/tile/$(am__dirstamp) > +src/tile/$(DEPDIR)/$(am__dirstamp): > + @$(MKDIR_P) src/tile/$(DEPDIR) > + @: > src/tile/$(DEPDIR)/$(am__dirstamp) > +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) > libffi.la: $(libffi_la_OBJECTS) $(libffi_la_DEPENDENCIES) > $(libffi_la_LINK) -rpath $(libdir) $(libffi_la_OBJECTS) $(libffi_la_LIBADD) $(LIBS) > libffi_convenience.la: $(libffi_convenience_la_OBJECTS) $(libffi_convenience_la_DEPENDENCIES) > @@ -943,6 +958,10 @@ > -rm -f src/sparc/v8.lo > -rm -f src/sparc/v9.$(OBJEXT) > -rm -f src/sparc/v9.lo > + -rm -f src/tile/ffi.$(OBJEXT) > + -rm -f src/tile/ffi.lo > + -rm -f src/tile/tile.$(OBJEXT) > + -rm -f src/tile/tile.lo > -rm -f src/types.$(OBJEXT) > -rm -f src/types.lo > -rm -f src/x86/darwin.$(OBJEXT) > @@ -1019,6 +1038,8 @@ > @AMDEP_TRUE@@am__include@ @am__quote@src/sparc/$(DEPDIR)/ffi.Plo@am__quote@ > @AMDEP_TRUE@@am__include@ @am__quote@src/sparc/$(DEPDIR)/v8.Plo@am__quote@ > @AMDEP_TRUE@@am__include@ @am__quote@src/sparc/$(DEPDIR)/v9.Plo@am__quote@ > +@AMDEP_TRUE@@am__include@ @am__quote@src/tile/$(DEPDIR)/ffi.Plo@am__quote@ > +@AMDEP_TRUE@@am__include@ @am__quote@src/tile/$(DEPDIR)/tile.Plo@am__quote@ > @AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/darwin.Plo@am__quote@ > @AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/darwin64.Plo@am__quote@ > @AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/ffi.Plo@am__quote@ > @@ -1100,6 +1121,7 @@ > -rm -rf src/sh/.libs src/sh/_libs > -rm -rf src/sh64/.libs src/sh64/_libs > -rm -rf src/sparc/.libs src/sparc/_libs > + -rm -rf src/tile/.libs src/tile/_libs > -rm -rf src/x86/.libs src/x86/_libs > > distclean-libtool: > @@ -1669,6 +1691,8 @@ > -rm -f src/sh64/$(am__dirstamp) > -rm -f src/sparc/$(DEPDIR)/$(am__dirstamp) > -rm -f src/sparc/$(am__dirstamp) > + -rm -f src/tile/$(DEPDIR)/$(am__dirstamp) > + -rm -f src/tile/$(am__dirstamp) > -rm -f src/x86/$(DEPDIR)/$(am__dirstamp) > -rm -f src/x86/$(am__dirstamp) > > @@ -1682,7 +1706,7 @@ > > distclean: distclean-recursive > -rm -f $(am__CONFIG_DISTCLEAN_FILES) > - -rm -rf src/$(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/moxie/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/x86/$(DEPDIR) > + -rm -rf src/$(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/moxie/$(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 -f Makefile > distclean-am: clean-am distclean-compile distclean-generic \ > distclean-hdr distclean-libtool distclean-tags > @@ -1802,7 +1826,7 @@ > maintainer-clean: maintainer-clean-recursive > -rm -f $(am__CONFIG_DISTCLEAN_FILES) > -rm -rf $(top_srcdir)/autom4te.cache > - -rm -rf src/$(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/moxie/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/x86/$(DEPDIR) > + -rm -rf src/$(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/moxie/$(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 -f Makefile > maintainer-clean-am: distclean-am maintainer-clean-aminfo \ > maintainer-clean-generic maintainer-clean-vti > diff -ruP orig/libffi/configure libffi/configure > --- orig/libffi/configure 2012-07-10 17:17:21.903030000 -0400 > +++ libffi/configure 2012-07-10 17:31:30.250259000 -0400 > @@ -627,6 +627,8 @@ > sys_symbol_underscore > HAVE_LONG_DOUBLE > ALLOCA > +TILE_FALSE > +TILE_TRUE > PA64_HPUX_FALSE > PA64_HPUX_TRUE > PA_HPUX_FALSE > @@ -13266,6 +13268,10 @@ > TARGET=SPARC; TARGETDIR=sparc > ;; > > + tile*-*) > + TARGET=TILE; TARGETDIR=tile > + ;; > + > x86_64-*-darwin*) > TARGET=X86_DARWIN; TARGETDIR=x86 > ;; > @@ -13519,6 +13525,14 @@ > PA64_HPUX_FALSE= > fi > > + if test x$TARGET = xTILE; then > + TILE_TRUE= > + TILE_FALSE='#' > +else > + TILE_TRUE='#' > + TILE_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; } > @@ -14830,6 +14844,10 @@ > as_fn_error $? "conditional \"PA64_HPUX\" was never defined. > Usually this means the macro was only invoked conditionally." "$LINENO" 5 > fi > +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 "${FFI_EXEC_TRAMPOLINE_TABLE_TRUE}" && test -z "${FFI_EXEC_TRAMPOLINE_TABLE_FALSE}"; then > as_fn_error $? "conditional \"FFI_EXEC_TRAMPOLINE_TABLE\" was never defined. > diff -ruP orig/libffi/configure.ac libffi/configure.ac > --- orig/libffi/configure.ac 2012-07-10 17:17:21.904027000 -0400 > +++ libffi/configure.ac 2012-07-10 17:25:26.915450000 -0400 > @@ -187,6 +187,10 @@ > TARGET=SPARC; TARGETDIR=sparc > ;; > > + tile*-*) > + TARGET=TILE; TARGETDIR=tile > + ;; > + > x86_64-*-darwin*) > TARGET=X86_DARWIN; TARGETDIR=x86 > ;; > @@ -244,6 +248,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) > > AC_HEADER_STDC > AC_CHECK_FUNCS(memcpy) > diff -ruP orig/libffi/src/prep_cif.c libffi/src/prep_cif.c > --- orig/libffi/src/prep_cif.c 2012-07-10 17:17:22.421038000 -0400 > +++ libffi/src/prep_cif.c 2012-07-10 17:26:05.208271000 -0400 > @@ -140,6 +140,9 @@ > #ifdef SPARC > && (cif->abi != FFI_V9 || cif->rtype->size > 32) > #endif > +#ifdef TILE > + && (cif->rtype->size > 10 * FFI_SIZEOF_ARG) > +#endif > ) > bytes = STACK_ARG_SIZE(sizeof(void*)); > #endif > @@ -169,6 +172,16 @@ > if (((*ptr)->alignment - 1) & bytes) > bytes = ALIGN(bytes, (*ptr)->alignment); > > +#ifdef TILE > + if (bytes < 10 * FFI_SIZEOF_ARG && > + bytes + STACK_ARG_SIZE((*ptr)->size) > 10 * FFI_SIZEOF_ARG) > + { > + /* An argument is never split between the 10 parameter > + registers and the stack. */ > + bytes = 10 * FFI_SIZEOF_ARG; > + } > +#endif > + > bytes += STACK_ARG_SIZE((*ptr)->size); > } > #endif > diff -ruP orig/libffi/src/tile/ffi.c libffi/src/tile/ffi.c > --- orig/libffi/src/tile/ffi.c 1969-12-31 19:00:00.000000000 -0500 > +++ libffi/src/tile/ffi.c 2012-07-10 17:26:05.232280000 -0400 > @@ -0,0 +1,355 @@ > +/* ----------------------------------------------------------------------- > + ffi.c - Copyright (c) 2012 Tilera Corp. > + > + TILE 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 > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > + > +/* The first 10 registers are used to pass arguments and return values. */ > +#define NUM_ARG_REGS 10 > + > +/* Performs a raw function call with the given NUM_ARG_REGS register arguments > + and the specified additional stack arguments (if any). */ > +extern void ffi_call_tile(ffi_sarg reg_args[NUM_ARG_REGS], > + const ffi_sarg *stack_args, > + size_t stack_args_bytes, > + void (*fnaddr)(void)) > + FFI_HIDDEN; > + > +/* This handles the raw call from the closure stub, cleaning up the > + parameters and delegating to ffi_closure_tile_inner. */ > +extern void ffi_closure_tile(void) FFI_HIDDEN; > + > + > +ffi_status > +ffi_prep_cif_machdep(ffi_cif *cif) > +{ > + /* We always allocate room for all registers. Even if we don't > + use them as parameters, they get returned in the same array > + as struct return values so we need to make room. */ > + if (cif->bytes < NUM_ARG_REGS * FFI_SIZEOF_ARG) > + cif->bytes = NUM_ARG_REGS * FFI_SIZEOF_ARG; > + > + if (cif->rtype->size > NUM_ARG_REGS * FFI_SIZEOF_ARG) > + cif->flags = FFI_TYPE_STRUCT; > + else > + cif->flags = FFI_TYPE_INT; > + > + /* Nothing to do. */ > + return FFI_OK; > +} > + > + > +static long > +assign_to_ffi_arg(ffi_sarg *out, void *in, const ffi_type *type, > + int write_to_reg) > +{ > + switch (type->type) > + { > + case FFI_TYPE_SINT8: > + *out = *(SINT8 *)in; > + return 1; > + > + case FFI_TYPE_UINT8: > + *out = *(UINT8 *)in; > + return 1; > + > + case FFI_TYPE_SINT16: > + *out = *(SINT16 *)in; > + return 1; > + > + case FFI_TYPE_UINT16: > + *out = *(UINT16 *)in; > + return 1; > + > + case FFI_TYPE_SINT32: > + case FFI_TYPE_UINT32: > +#ifndef __LP64__ > + case FFI_TYPE_POINTER: > +#endif > + /* Note that even unsigned 32-bit quantities are sign extended > + on tilegx when stored in a register. */ > + *out = *(SINT32 *)in; > + return 1; > + > + case FFI_TYPE_FLOAT: > +#ifdef __tilegx__ > + if (write_to_reg) > + { > + /* Properly sign extend the value. */ > + union { float f; SINT32 s32; } val; > + val.f = *(float *)in; > + *out = val.s32; > + } > + else > +#endif > + { > + *(float *)out = *(float *)in; > + } > + return 1; > + > + case FFI_TYPE_SINT64: > + case FFI_TYPE_UINT64: > + case FFI_TYPE_DOUBLE: > +#ifdef __LP64__ > + case FFI_TYPE_POINTER: > +#endif > + *(UINT64 *)out = *(UINT64 *)in; > + return sizeof(UINT64) / FFI_SIZEOF_ARG; > + > + case FFI_TYPE_STRUCT: > + memcpy(out, in, type->size); > + return (type->size + FFI_SIZEOF_ARG - 1) / FFI_SIZEOF_ARG; > + > + case FFI_TYPE_VOID: > + /* Must be a return type. Nothing to do. */ > + return 0; > + > + default: > + FFI_ASSERT(0); > + return -1; > + } > +} > + > + > +void > +ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) > +{ > + ffi_sarg * const arg_mem = alloca(cif->bytes); > + ffi_sarg * const reg_args = arg_mem; > + ffi_sarg * const stack_args = ®_args[NUM_ARG_REGS]; > + ffi_sarg *argp = arg_mem; > + ffi_type ** const arg_types = cif->arg_types; > + const long num_args = cif->nargs; > + long i; > + > + if (cif->flags == FFI_TYPE_STRUCT) > + { > + /* Pass a hidden pointer to the return value. We make sure there > + is scratch space for the callee to store the return value even if > + our caller doesn't care about it. */ > + *argp++ = (intptr_t)(rvalue ? rvalue : alloca(cif->rtype->size)); > + > + /* No more work needed to return anything. */ > + rvalue = NULL; > + } > + > + for (i = 0; i < num_args; i++) > + { > + ffi_type *type = arg_types[i]; > + void * const arg_in = avalue[i]; > + ptrdiff_t arg_word = argp - arg_mem; > + > +#ifndef __tilegx__ > + /* Doubleword-aligned values are always in an even-number register > + pair, or doubleword-aligned stack slot if out of registers. */ > + long align = arg_word & (type->alignment > FFI_SIZEOF_ARG); > + argp += align; > + arg_word += align; > +#endif > + > + if (type->type == FFI_TYPE_STRUCT) > + { > + const size_t arg_size_in_words = > + (type->size + FFI_SIZEOF_ARG - 1) / FFI_SIZEOF_ARG; > + > + if (arg_word < NUM_ARG_REGS && > + arg_word + arg_size_in_words > NUM_ARG_REGS) > + { > + /* Args are not allowed to span registers and the stack. */ > + argp = stack_args; > + } > + > + memcpy(argp, arg_in, type->size); > + argp += arg_size_in_words; > + } > + else > + { > + argp += assign_to_ffi_arg(argp, arg_in, arg_types[i], 1); > + } > + } > + > + /* Actually do the call. */ > + ffi_call_tile(reg_args, stack_args, > + cif->bytes - (NUM_ARG_REGS * FFI_SIZEOF_ARG), fn); > + > + if (rvalue != NULL) > + assign_to_ffi_arg(rvalue, reg_args, cif->rtype, 0); > +} > + > + > +/* Template code for closure. */ > +extern const UINT64 ffi_template_tramp_tile[] FFI_HIDDEN; > + > + > +ffi_status > +ffi_prep_closure_loc (ffi_closure *closure, > + ffi_cif *cif, > + void (*fun)(ffi_cif*, void*, void**, void*), > + void *user_data, > + void *codeloc) > +{ > +#ifdef __tilegx__ > + /* TILE-Gx */ > + SINT64 c; > + SINT64 h; > + int s; > + UINT64 *out; > + > + if (cif->abi != FFI_UNIX) > + return FFI_BAD_ABI; > + > + out = (UINT64 *)closure->tramp; > + > + c = (intptr_t)closure; > + h = (intptr_t)ffi_closure_tile; > + s = 0; > + > + /* Find the smallest shift count that doesn't lose information > + (i.e. no need to explicitly insert high bits of the address that > + are just the sign extension of the low bits). */ > + while ((c >> s) != (SINT16)(c >> s) || (h >> s) != (SINT16)(h >> s)) > + s += 16; > + > +#define OPS(a, b, shift) \ > + (create_Imm16_X0((a) >> (shift)) | create_Imm16_X1((b) >> (shift))) > + > + /* Emit the moveli. */ > + *out++ = ffi_template_tramp_tile[0] | OPS(c, h, s); > + for (s -= 16; s >= 0; s -= 16) > + *out++ = ffi_template_tramp_tile[1] | OPS(c, h, s); > + > +#undef OPS > + > + *out++ = ffi_template_tramp_tile[2]; > + > +#else > + /* TILEPro */ > + UINT64 *out; > + intptr_t delta; > + > + if (cif->abi != FFI_UNIX) > + return FFI_BAD_ABI; > + > + out = (UINT64 *)closure->tramp; > + delta = (intptr_t)ffi_closure_tile - (intptr_t)codeloc; > + > + *out++ = ffi_template_tramp_tile[0] | create_JOffLong_X1(delta >> 3); > +#endif > + > + closure->cif = cif; > + closure->fun = fun; > + closure->user_data = user_data; > + > + invalidate_icache(closure->tramp, (char *)out - closure->tramp, > + getpagesize()); > + > + return FFI_OK; > +} > + > + > +/* This is called by the assembly wrapper for closures. This does > + all of the work. On entry reg_args[0] holds the values the registers > + had when the closure was invoked. On return reg_args[1] holds the register > + values to be returned to the caller (many of which may be garbage). */ > +void FFI_HIDDEN > +ffi_closure_tile_inner(ffi_closure *closure, > + ffi_sarg reg_args[2][NUM_ARG_REGS], > + ffi_sarg *stack_args) > +{ > + ffi_cif * const cif = closure->cif; > + void ** const avalue = alloca(cif->nargs * sizeof(void *)); > + void *rvalue; > + ffi_type ** const arg_types = cif->arg_types; > + ffi_sarg * const reg_args_in = reg_args[0]; > + ffi_sarg * const reg_args_out = reg_args[1]; > + ffi_sarg * argp; > + long i, arg_word, nargs = cif->nargs; > + /* Use a union to guarantee proper alignment for double. */ > + union { ffi_sarg arg[NUM_ARG_REGS]; double d; UINT64 u64; } closure_ret; > + > + /* Start out reading register arguments. */ > + argp = reg_args_in; > + > + /* Copy the caller's structure return address to that the closure > + returns the data directly to the caller. */ > + if (cif->flags == FFI_TYPE_STRUCT) > + { > + /* Return by reference via hidden pointer. */ > + rvalue = (void *)(intptr_t)*argp++; > + arg_word = 1; > + } > + else > + { > + /* Return the value in registers. */ > + rvalue = &closure_ret; > + arg_word = 0; > + } > + > + /* Grab the addresses of the arguments. */ > + for (i = 0; i < nargs; i++) > + { > + ffi_type * const type = arg_types[i]; > + const size_t arg_size_in_words = > + (type->size + FFI_SIZEOF_ARG - 1) / FFI_SIZEOF_ARG; > + > +#ifndef __tilegx__ > + /* Doubleword-aligned values are always in an even-number register > + pair, or doubleword-aligned stack slot if out of registers. */ > + long align = arg_word & (type->alignment > FFI_SIZEOF_ARG); > + argp += align; > + arg_word += align; > +#endif > + > + if (arg_word == NUM_ARG_REGS || > + (arg_word < NUM_ARG_REGS && > + arg_word + arg_size_in_words > NUM_ARG_REGS)) > + { > + /* Switch to reading arguments from the stack. */ > + argp = stack_args; > + arg_word = NUM_ARG_REGS; > + } > + > + avalue[i] = argp; > + argp += arg_size_in_words; > + arg_word += arg_size_in_words; > + } > + > + /* Invoke the closure. */ > + closure->fun(cif, rvalue, avalue, closure->user_data); > + > + if (cif->flags != FFI_TYPE_STRUCT) > + { > + /* Canonicalize for register representation. */ > + assign_to_ffi_arg(reg_args_out, &closure_ret, cif->rtype, 1); > + } > +} > diff -ruP orig/libffi/src/tile/ffitarget.h libffi/src/tile/ffitarget.h > --- orig/libffi/src/tile/ffitarget.h 1969-12-31 19:00:00.000000000 -0500 > +++ libffi/src/tile/ffitarget.h 2012-07-10 17:26:05.241297000 -0400 > @@ -0,0 +1,65 @@ > +/* -----------------------------------------------------------------*-C-*- > + ffitarget.h - Copyright (c) 2012 Tilera Corp. > + Target configuration macros for TILE. > + > + 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 > + > +#include > + > +typedef uint_reg_t ffi_arg; > +typedef int_reg_t ffi_sarg; > + > +typedef enum ffi_abi { > + FFI_FIRST_ABI = 0, > + FFI_UNIX, > + FFI_LAST_ABI, > + FFI_DEFAULT_ABI = FFI_UNIX > +} ffi_abi; > +#endif > + > +/* ---- Definitions for closures ----------------------------------------- */ > +#define FFI_CLOSURES 1 > + > +#ifdef __tilegx__ > +/* We always pass 8-byte values, even in -m32 mode. */ > +# define FFI_SIZEOF_ARG 8 > +# ifdef __LP64__ > +# define FFI_TRAMPOLINE_SIZE (8 * 5) /* 5 bundles */ > +# else > +# define FFI_TRAMPOLINE_SIZE (8 * 3) /* 3 bundles */ > +# endif > +#else > +# define FFI_SIZEOF_ARG 4 > +# define FFI_TRAMPOLINE_SIZE 8 /* 1 bundle */ > +#endif > +#define FFI_NATIVE_RAW_API 0 > + > +#endif > diff -ruP orig/libffi/src/tile/tile.S libffi/src/tile/tile.S > --- orig/libffi/src/tile/tile.S 1969-12-31 19:00:00.000000000 -0500 > +++ libffi/src/tile/tile.S 2012-07-10 17:26:05.246288000 -0400 > @@ -0,0 +1,360 @@ > +/* ----------------------------------------------------------------------- > + tile.S - Copyright (c) 2011 Tilera Corp. > + > + Tilera TILEPro and TILE-Gx 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 > +#include > + > +/* Number of bytes in a register. */ > +#define REG_SIZE FFI_SIZEOF_ARG > + > +/* Number of bytes in stack linkage area for backtracing. > + > + A note about the ABI: on entry to a procedure, sp points to a stack > + slot where it must spill the return address if it's not a leaf. > + REG_SIZE bytes beyond that is a slot owned by the caller which > + contains the sp value that the caller had when it was originally > + entered (i.e. the caller's frame pointer). */ > +#define LINKAGE_SIZE (2 * REG_SIZE) > + > +/* The first 10 registers are used to pass arguments and return values. */ > +#define NUM_ARG_REGS 10 > + > +#ifdef __tilegx__ > +#define SW st > +#define LW ld > +#define BGZT bgtzt > +#else > +#define SW sw > +#define LW lw > +#define BGZT bgzt > +#endif > + > + > +/* void ffi_call_tile (int_reg_t reg_args[NUM_ARG_REGS], > + const int_reg_t *stack_args, > + unsigned long stack_args_bytes, > + void (*fnaddr)(void)); > + > + On entry, REG_ARGS contain the outgoing register values, > + and STACK_ARGS containts STACK_ARG_BYTES of additional values > + to be passed on the stack. If STACK_ARG_BYTES is zero, then > + STACK_ARGS is ignored. > + > + When the invoked function returns, the values of r0-r9 are > + blindly stored back into REG_ARGS for the caller to examine. */ > + > + .section .text.ffi_call_tile, "ax", @progbits > + .align 8 > + .globl ffi_call_tile > + FFI_HIDDEN(ffi_call_tile) > +ffi_call_tile: > + > +/* Incoming arguments. */ > +#define REG_ARGS r0 > +#define INCOMING_STACK_ARGS r1 > +#define STACK_ARG_BYTES r2 > +#define ORIG_FNADDR r3 > + > +/* Temporary values. */ > +#define FRAME_SIZE r10 > +#define TMP r11 > +#define TMP2 r12 > +#define OUTGOING_STACK_ARGS r13 > +#define REG_ADDR_PTR r14 > +#define RETURN_REG_ADDR r15 > +#define FNADDR r16 > + > + .cfi_startproc > + { > + /* Save return address. */ > + SW sp, lr > + .cfi_offset lr, 0 > + /* Prepare to spill incoming r52. */ > + addi TMP, sp, -REG_SIZE > + /* Increase frame size to have room to spill r52 and REG_ARGS. > + The +7 is to round up mod 8. */ > + addi FRAME_SIZE, STACK_ARG_BYTES, \ > + REG_SIZE + REG_SIZE + LINKAGE_SIZE + 7 > + } > + { > + /* Round stack frame size to a multiple of 8 to satisfy ABI. */ > + andi FRAME_SIZE, FRAME_SIZE, -8 > + /* Compute where to spill REG_ARGS value. */ > + addi TMP2, sp, -(REG_SIZE * 2) > + } > + { > + /* Spill incoming r52. */ > + SW TMP, r52 > + .cfi_offset r52, -REG_SIZE > + /* Set up our frame pointer. */ > + move r52, sp > + .cfi_def_cfa_register r52 > + /* Push stack frame. */ > + sub sp, sp, FRAME_SIZE > + } > + { > + /* Prepare to set up stack linkage. */ > + addi TMP, sp, REG_SIZE > + /* Prepare to memcpy stack args. */ > + addi OUTGOING_STACK_ARGS, sp, LINKAGE_SIZE > + /* Save REG_ARGS which we will need after we call the subroutine. */ > + SW TMP2, REG_ARGS > + } > + { > + /* Set up linkage info to hold incoming stack pointer. */ > + SW TMP, r52 > + } > + { > + /* Skip stack args memcpy if we don't have any stack args (common). */ > + blezt STACK_ARG_BYTES, .Ldone_stack_args_memcpy > + } > + > +.Lmemcpy_stack_args: > + { > + /* Load incoming argument from stack_args. */ > + LW TMP, INCOMING_STACK_ARGS > + addi INCOMING_STACK_ARGS, INCOMING_STACK_ARGS, REG_SIZE > + } > + { > + /* Store stack argument into outgoing stack argument area. */ > + SW OUTGOING_STACK_ARGS, TMP > + addi OUTGOING_STACK_ARGS, OUTGOING_STACK_ARGS, REG_SIZE > + addi STACK_ARG_BYTES, STACK_ARG_BYTES, -REG_SIZE > + } > + { > + BGZT STACK_ARG_BYTES, .Lmemcpy_stack_args > + } > +.Ldone_stack_args_memcpy: > + > + { > + /* Copy aside ORIG_FNADDR so we can overwrite its register. */ > + move FNADDR, ORIG_FNADDR > + /* Prepare to load argument registers. */ > + addi REG_ADDR_PTR, r0, REG_SIZE > + /* Load outgoing r0. */ > + LW r0, r0 > + } > + > + /* Load up argument registers from the REG_ARGS array. */ > +#define LOAD_REG(REG, PTR) \ > + { \ > + LW REG, PTR ; \ > + addi PTR, PTR, REG_SIZE \ > + } > + > + LOAD_REG(r1, REG_ADDR_PTR) > + LOAD_REG(r2, REG_ADDR_PTR) > + LOAD_REG(r3, REG_ADDR_PTR) > + LOAD_REG(r4, REG_ADDR_PTR) > + LOAD_REG(r5, REG_ADDR_PTR) > + LOAD_REG(r6, REG_ADDR_PTR) > + LOAD_REG(r7, REG_ADDR_PTR) > + LOAD_REG(r8, REG_ADDR_PTR) > + LOAD_REG(r9, REG_ADDR_PTR) > + > + { > + /* Call the subroutine. */ > + jalr FNADDR > + } > + > + { > + /* Restore original lr. */ > + LW lr, r52 > + /* Prepare to recover ARGS, which we spilled earlier. */ > + addi TMP, r52, -(2 * REG_SIZE) > + } > + { > + /* Restore ARGS, so we can fill it in with the return regs r0-r9. */ > + LW RETURN_REG_ADDR, TMP > + /* Prepare to restore original r52. */ > + addi TMP, r52, -REG_SIZE > + } > + > + { > + /* Pop stack frame. */ > + move sp, r52 > + /* Restore original r52. */ > + LW r52, TMP > + } > + > +#define STORE_REG(REG, PTR) \ > + { \ > + SW PTR, REG ; \ > + addi PTR, PTR, REG_SIZE \ > + } > + > + /* Return all register values by reference. */ > + STORE_REG(r0, RETURN_REG_ADDR) > + STORE_REG(r1, RETURN_REG_ADDR) > + STORE_REG(r2, RETURN_REG_ADDR) > + STORE_REG(r3, RETURN_REG_ADDR) > + STORE_REG(r4, RETURN_REG_ADDR) > + STORE_REG(r5, RETURN_REG_ADDR) > + STORE_REG(r6, RETURN_REG_ADDR) > + STORE_REG(r7, RETURN_REG_ADDR) > + STORE_REG(r8, RETURN_REG_ADDR) > + STORE_REG(r9, RETURN_REG_ADDR) > + > + { > + jrp lr > + } > + > + .cfi_endproc > + .size ffi_call_tile, .-ffi_call_tile > + > +/* ffi_closure_tile(...) > + > + On entry, lr points to the closure plus 8 bytes, and r10 > + contains the actual return address. > + > + This function simply dumps all register parameters into a stack array > + and passes the closure, the registers array, and the stack arguments > + to C code that does all of the actual closure processing. */ > + > + .section .text.ffi_closure_tile, "ax", @progbits > + .align 8 > + .globl ffi_closure_tile > + FFI_HIDDEN(ffi_closure_tile) > + > + .cfi_startproc > +/* Room to spill all NUM_ARG_REGS incoming registers, plus frame linkage. */ > +#define CLOSURE_FRAME_SIZE (((NUM_ARG_REGS * REG_SIZE * 2 + LINKAGE_SIZE) + 7) & -8) > +ffi_closure_tile: > + { > +#ifdef __tilegx__ > + st sp, lr > + .cfi_offset lr, 0 > +#else > + /* Save return address (in r10 due to closure stub wrapper). */ > + SW sp, r10 > + .cfi_return_column r10 > + .cfi_offset r10, 0 > +#endif > + /* Compute address for stack frame linkage. */ > + addli r10, sp, -(CLOSURE_FRAME_SIZE - REG_SIZE) > + } > + { > + /* Save incoming stack pointer in linkage area. */ > + SW r10, sp > + .cfi_offset sp, -(CLOSURE_FRAME_SIZE - REG_SIZE) > + /* Push a new stack frame. */ > + addli sp, sp, -CLOSURE_FRAME_SIZE > + .cfi_adjust_cfa_offset CLOSURE_FRAME_SIZE > + } > + > + { > + /* Create pointer to where to start spilling registers. */ > + addi r10, sp, LINKAGE_SIZE > + } > + > + /* Spill all the incoming registers. */ > + STORE_REG(r0, r10) > + STORE_REG(r1, r10) > + STORE_REG(r2, r10) > + STORE_REG(r3, r10) > + STORE_REG(r4, r10) > + STORE_REG(r5, r10) > + STORE_REG(r6, r10) > + STORE_REG(r7, r10) > + STORE_REG(r8, r10) > + { > + /* Save r9. */ > + SW r10, r9 > +#ifdef __tilegx__ > + /* Pointer to closure is passed in r11. */ > + move r0, r11 > +#else > + /* Compute pointer to the closure object. Because the closure > + starts with a "jal ffi_closure_tile", we can just take the > + value of lr (a phony return address pointing into the closure) > + and subtract 8. */ > + addi r0, lr, -8 > +#endif > + /* Compute a pointer to the register arguments we just spilled. */ > + addi r1, sp, LINKAGE_SIZE > + } > + { > + /* Compute a pointer to the extra stack arguments (if any). */ > + addli r2, sp, CLOSURE_FRAME_SIZE + LINKAGE_SIZE > + /* Call C code to deal with all of the grotty details. */ > + jal ffi_closure_tile_inner > + } > + { > + addli r10, sp, CLOSURE_FRAME_SIZE > + } > + { > + /* Restore the return address. */ > + LW lr, r10 > + /* Compute pointer to registers array. */ > + addli r10, sp, LINKAGE_SIZE + (NUM_ARG_REGS * REG_SIZE) > + } > + /* Return all the register values, which C code may have set. */ > + LOAD_REG(r0, r10) > + LOAD_REG(r1, r10) > + LOAD_REG(r2, r10) > + LOAD_REG(r3, r10) > + LOAD_REG(r4, r10) > + LOAD_REG(r5, r10) > + LOAD_REG(r6, r10) > + LOAD_REG(r7, r10) > + LOAD_REG(r8, r10) > + LOAD_REG(r9, r10) > + { > + /* Pop the frame. */ > + addli sp, sp, CLOSURE_FRAME_SIZE > + jrp lr > + } > + > + .cfi_endproc > + .size ffi_closure_tile, . - ffi_closure_tile > + > + > +/* What follows are code template instructions that get copied to the > + closure trampoline by ffi_prep_closure_loc. The zeroed operands > + get replaced by their proper values at runtime. */ > + > + .section .text.ffi_template_tramp_tile, "ax", @progbits > + .align 8 > + .globl ffi_template_tramp_tile > + FFI_HIDDEN(ffi_template_tramp_tile) > +ffi_template_tramp_tile: > +#ifdef __tilegx__ > + { > + moveli r11, 0 /* backpatched to address of containing closure. */ > + moveli r10, 0 /* backpatched to ffi_closure_tile. */ > + } > + /* Note: the following bundle gets generated multiple times > + depending on the pointer value (esp. useful for -m32 mode). */ > + { shl16insli r11, r11, 0 ; shl16insli r10, r10, 0 } > + { info 2+8 /* for backtracer: -> pc in lr, frame size 0 */ ; jr r10 } > +#else > + /* 'jal .' yields a PC-relative offset of zero so we can OR in the > + right offset at runtime. */ > + { move r10, lr ; jal . /* ffi_closure_tile */ } > +#endif > + > + .size ffi_template_tramp_tile, . - ffi_template_tramp_tile