From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-lj1-x243.google.com (mail-lj1-x243.google.com [IPv6:2a00:1450:4864:20::243]) by sourceware.org (Postfix) with ESMTPS id 94391385B834 for ; Tue, 24 Mar 2020 13:41:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 94391385B834 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=moxielogic.com Authentication-Results: sourceware.org; spf=none smtp.mailfrom=green@moxielogic.com Received: by mail-lj1-x243.google.com with SMTP id v16so11572550ljk.13 for ; Tue, 24 Mar 2020 06:41:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=moxielogic-com.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=Cz/MHqC2kIrMcg6SynThbHFtAo5TqXbBsRBynCn+6gY=; b=iB3ytUrQAVf4DPSYsz9h6az6lS7md/Sje6bHI3F1fe5Re9/Iq+8YcO2z+e5msFBaYe wCmAR9kabI0txTSgcOWqcy4a/dkBEKq1pJBWQhlSFxUQKkrMPC88s+DEq4Qsjg35bFMe DVmjrJ15kF3DHd7ujp29ss2K8Suios6FRLQJwjNlDRoSUdBCUKf9lwRPefPIk9w0jZXR fX/kjhig5/02smLC7T7g9w1kcDaoKxTlNIcjhwXfvzxE0gEoqhRu4GmMI3GkxMzNPkZj pVqSdwzsnH6+xrtahU50TwKmj1Xr8LFr2GLHOpNUBDDEv72piOAcOlX4j9ZNEls3ktmT xclQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=Cz/MHqC2kIrMcg6SynThbHFtAo5TqXbBsRBynCn+6gY=; b=c8VKkpCc1TunbCxLx/asIahO5u9BTjBUYHSv6IYDj2kdlANal5WaHs0wicxBPl0oa8 EfJ+YeYhY4zEg2NAUlDb++xNANHbUopYwSyPeCfU6F+DAM9a/5hf6jx0r8VS39p159wB PiH64YLgFGhQQrHVUqDCORx6wp1uW7wCTPsGJvBsd3EjkWLphxzwCKSmV52Z2Kvk0wOC 1wtacB893AgfKoxCKRwoK1IXmI03cYsY9YrTf+J2yQeOO5h20Ydbw/a+cMr5oo3cSICv 8QT6lUXBebYqRPfb3y5iGSo/ypGVKOd2T1Pfh6vjdS3e2hDAVeyIRA8PjbVhJnd0sONW xh5g== X-Gm-Message-State: ANhLgQ2bN3vUXIEEalyQqmDM2/zZSxtXzdwAdGFI7PwO2DcUI9LWn0oS a1KDy0pSbe2wF0SvUjN0XPaBmwyOyrtl8etHza5w8Q== X-Google-Smtp-Source: ADFU+vt+mvLCCdWVtjD8YbJWDEkG6LS0lArbCqlSZLe+xpBov8xpd2gYnfln7DMg1crqKt/1tU5NBrnHHQxaw1jrwvc= X-Received: by 2002:a2e:151e:: with SMTP id s30mr17635402ljd.92.1585057290243; Tue, 24 Mar 2020 06:41:30 -0700 (PDT) MIME-Version: 1.0 References: <1584264721-16318-1-git-send-email-majun258@linux.alibaba.com> In-Reply-To: <1584264721-16318-1-git-send-email-majun258@linux.alibaba.com> From: Anthony Green Date: Tue, 24 Mar 2020 09:41:19 -0400 Message-ID: Subject: Re: [PATCH] package/libffi: Add csky cpu support To: Ma Jun Cc: libffi-discuss , wenmeng_zhang@c-sky.com, linux-csky@vger.kernel.org X-Spam-Status: No, score=-15.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, HTML_MESSAGE, RCVD_IN_DNSWL_NONE, SCC_10_SHORT_WORD_LINES, SCC_5_SHORT_WORD_LINES, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org Content-Type: text/plain; charset="UTF-8" X-Content-Filtered-By: Mailman/MimeDel 2.1.29 X-BeenThere: libffi-discuss@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libffi-discuss mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Mar 2020 13:41:36 -0000 Thank you for this patch. I have merged it into a branch on github for now: https://github.com/libffi/libffi/commit/54b81a5167de713c7bba0cfde5ccea3398b69128 There's no opportunity to test the code without a compiler or simulator, but I'm willing to merge in the absence of those. Eventually we will need a simulator so we can test on travis-ci. The source files require a copyright notice. Would adding something like this work?... ffi.c - Copyright (C) 2020 Alibaba I would also like to adjust some of the spacing from 4-space tabs to 2-space tabs. I can make that change, or you can resubmit. Other than that, I'm ok with these changes. Thanks, AG On Mon, Mar 23, 2020 at 3:04 AM Ma Jun via Libffi-discuss < libffi-discuss@sourceware.org> wrote: > This patch added the support for csky cpu architecture > > Signed-off-by: Zhang Wenmeng > Signed-off-by: Ma Jun > --- > Makefile.am | 2 + > README.md | 1 + > configure.host | 5 + > src/csky/ffi.c | 395 +++++++++++++++++++++++++++++++++++++++++++ > src/csky/ffitarget.h | 63 +++++++ > src/csky/sysv.S | 371 ++++++++++++++++++++++++++++++++++++++++ > 6 files changed, 837 insertions(+) > create mode 100644 src/csky/ffi.c > create mode 100644 src/csky/ffitarget.h > create mode 100644 src/csky/sysv.S > > diff --git a/Makefile.am b/Makefile.am > index f83e444..e528ffd 100644 > --- a/Makefile.am > +++ b/Makefile.am > @@ -53,6 +53,7 @@ noinst_HEADERS = \ > src/avr32/ffitarget.h \ > src/bfin/ffitarget.h \ > src/cris/ffitarget.h \ > + src/csky/ffitarget.h \ > src/frv/ffitarget.h \ > src/ia64/ffitarget.h src/ia64/ia64_flags.h \ > src/m32r/ffitarget.h \ > @@ -85,6 +86,7 @@ EXTRA_libffi_la_SOURCES = \ > src/avr32/ffi.c src/avr32/sysv.S \ > src/bfin/ffi.c src/bfin/sysv.S \ > src/cris/ffi.c src/cris/sysv.S \ > + src/csky/ffi.c src/csky/sysv.S \ > src/frv/ffi.c src/frv/eabi.S \ > src/ia64/ffi.c src/ia64/unix.S \ > src/m32r/ffi.c src/m32r/sysv.S \ > diff --git a/README.md b/README.md > index 3caf2fa..bdfe880 100644 > --- a/README.md > +++ b/README.md > @@ -58,6 +58,7 @@ tested: > | ARM | iOS | GCC | > | AVR32 | Linux | GCC | > | Blackfin | uClinux | GCC | > +| CSKY | Linux | GCC | > | HPPA | HPUX | GCC | > | IA-64 | Linux | GCC | > | M68K | FreeMiNT | GCC | > diff --git a/configure.host b/configure.host > index 7634c3a..9201cd4 100644 > --- a/configure.host > +++ b/configure.host > @@ -43,6 +43,11 @@ case "${host}" in > SOURCES="ffi.c sysv.S" > ;; > > + csky-*-*) > + TARGET=CSKY; TARGETDIR=csky > + SOURCES="ffi.c sysv.S" > + ;; > + > frv-*-*) > TARGET=FRV; TARGETDIR=frv > SOURCES="ffi.c eabi.S" > diff --git a/src/csky/ffi.c b/src/csky/ffi.c > new file mode 100644 > index 0000000..eb53848 > --- /dev/null > +++ b/src/csky/ffi.c > @@ -0,0 +1,395 @@ > +/* ----------------------------------------------------------------------- > + ffi.c > + > + CSKY 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 > + > +/* 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) > +{ > + register unsigned int i; > + register void **p_argv; > + register char *argp; > + register ffi_type **p_arg; > + > + argp = stack; > + > + if ( ecif->cif->flags == 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; > + size_t alignment; > + > + /* Align if necessary */ > + alignment = (*p_arg)->alignment; > +#ifdef __CSKYABIV1__ > + /* > + * Adapt ABIV1 bug. > + * If struct's size is larger than 8 bytes, then it always > alignment as 4 bytes. > + */ > + if (((*p_arg)->type == FFI_TYPE_STRUCT) && ((*p_arg)->size > > 8) && (alignment == 8)) { > + alignment = 4; > + } > +#endif > + > + if ((alignment - 1) & (unsigned) argp) { > + argp = (char *) FFI_ALIGN(argp, alignment); > + } > + > + if ((*p_arg)->type == FFI_TYPE_STRUCT) > + argp = (char *) FFI_ALIGN(argp, 4); > + > + 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: > +#ifdef __CSKYBE__ > + memcpy((argp + 4 - (*p_arg)->size), > *p_argv, (*p_arg)->size); > +#else > + memcpy(argp, *p_argv, (*p_arg)->size); > +#endif > + break; > + > + default: > + FFI_ASSERT(0); > + } > + } > + else if (z == sizeof(int)) > + { > + *(unsigned int *) argp = (unsigned int)*(UINT32 > *)(* p_argv); > + } > + else > + { > + memcpy(argp, *p_argv, z); > + } > + p_argv++; > + argp += z; > + } > + > + return; > +} > + > +/* Perform machine dependent cif processing */ > +ffi_status ffi_prep_cif_machdep(ffi_cif *cif) > +{ > + /* Round the stack up to a multiple of 8 bytes. This isn't needed > + everywhere, but it is on some platforms, and it doesn't hcsky > anything > + when it isn't needed. */ > + cif->bytes = (cif->bytes + 7) & ~7; > + > + /* Set the return type flag */ > + switch (cif->rtype->type) > + { > + > + case FFI_TYPE_DOUBLE: > + case FFI_TYPE_SINT64: > + case FFI_TYPE_UINT64: > + cif->flags = (unsigned) FFI_TYPE_SINT64; > + break; > + > + case FFI_TYPE_STRUCT: > + if (cif->rtype->size <= 4) > + /* A Composite Type not larger than 4 bytes is returned in r0. */ > + cif->flags = (unsigned)FFI_TYPE_INT; > + else if (cif->rtype->size <= 8) > + /* A Composite Type not larger than 8 bytes is returned in r0, > r1. */ > + cif->flags = (unsigned)FFI_TYPE_SINT64; > + else > + /* A Composite Type larger than 8 bytes, or whose size cannot > + be determined statically ... is stored in memory at an > + address passed [in r0]. */ > + cif->flags = (unsigned)FFI_TYPE_STRUCT; > + break; > + > + default: > + cif->flags = FFI_TYPE_INT; > + break; > + } > + > + return FFI_OK; > +} > + > +/* Perform machine dependent cif processing for variadic calls */ > +ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif, > + unsigned int nfixedargs, > + unsigned int ntotalargs) > +{ > + return ffi_prep_cif_machdep(cif); > +} > + > +/* Prototypes for assembly functions, in sysv.S */ > +extern void ffi_call_SYSV (void (*fn)(void), extended_cif *, unsigned, > unsigned, unsigned *); > + > +void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) > +{ > + extended_cif ecif; > + > + int small_struct = (cif->flags == FFI_TYPE_INT > + && cif->rtype->type == FFI_TYPE_STRUCT); > + > + ecif.cif = cif; > + ecif.avalue = avalue; > + > + unsigned int temp; > + > + /* 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->flags == FFI_TYPE_STRUCT)) > + { > + ecif.rvalue = alloca(cif->rtype->size); > + } > + else if (small_struct) > + ecif.rvalue = &temp; > + else > + ecif.rvalue = rvalue; > + > + switch (cif->abi) > + { > + case FFI_SYSV: > + ffi_call_SYSV (fn, &ecif, cif->bytes, cif->flags, ecif.rvalue); > + break; > + > + default: > + FFI_ASSERT(0); > + break; > + } > + if (small_struct) > +#ifdef __CSKYBE__ > + memcpy (rvalue, ((unsigned char *)&temp + (4 - cif->rtype->size)), > cif->rtype->size); > +#else > + memcpy (rvalue, &temp, cif->rtype->size); > +#endif > +} > + > +/** private members **/ > + > +static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, > + void** args, ffi_cif* cif); > + > +void ffi_closure_SYSV (ffi_closure *); > + > +/* This function is jumped to by the trampoline */ > + > +unsigned int > +ffi_closure_SYSV_inner (closure, respp, args) > + ffi_closure *closure; > + void **respp; > + void *args; > +{ > + // our various things... > + ffi_cif *cif; > + void **arg_area; > + > + cif = closure->cif; > + arg_area = (void**) alloca (cif->nargs * sizeof (void*)); > + > + /* this call will initialize ARG_AREA, such that each > + * element in that array points to the corresponding > + * value on the stack; and if the function returns > + * a structure, it will re-set RESP to point to the > + * structure return address. */ > + > + ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif); > + > + (closure->fun) (cif, *respp, arg_area, closure->user_data); > + > +#ifdef __CSKYBE__ > + if (cif->flags == FFI_TYPE_INT && cif->rtype->type == FFI_TYPE_STRUCT) { > + unsigned int tmp = 0; > + tmp = *(unsigned int *)(*respp); > + *(unsigned int *)(*respp) = (tmp >> ((4 - cif->rtype->size) * 8)); > + } > +#endif > + > + return cif->flags; > +} > + > + > +static void > +ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, > + void **avalue, ffi_cif *cif) > +{ > + register unsigned int i; > + register void **p_argv; > + register char *argp; > + register ffi_type **p_arg; > + > + argp = stack; > + > + if ( cif->flags == FFI_TYPE_STRUCT ) { > + *rvalue = *(void **) argp; > + argp += 4; > + } > + > + p_argv = avalue; > + > + for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) > + { > + size_t z; > + size_t alignment; > + > + alignment = (*p_arg)->alignment; > + if (alignment < 4) > + alignment = 4; > + > +#ifdef __CSKYABIV1__ > + /* > + * Adapt ABIV1 bug. > + * If struct's size is larger than 8 bytes, then it always > alignment as 4 bytes. > + */ > + if (((*p_arg)->type == FFI_TYPE_STRUCT) && ((*p_arg)->size > 8) && > (alignment == 8)) { > + alignment = 4; > + } > +#endif > + > + /* Align if necessary */ > + if ((alignment - 1) & (unsigned) argp) { > + argp = (char *) FFI_ALIGN(argp, alignment); > + } > + > + z = (*p_arg)->size; > + > +#ifdef __CSKYBE__ > + unsigned int tmp = 0; > + if ((*p_arg)->size < 4) { > + tmp = *(unsigned int *)argp; > + memcpy(argp, ((unsigned char *)&tmp + (4 - (*p_arg)->size)), > (*p_arg)->size); > + } > +#else > + /* because we're little endian, this is what it turns into. */ > +#endif > + *p_argv = (void*) argp; > + > + p_argv++; > + argp += z; > + } > + > + return; > +} > + > +/* How to make a trampoline. */ > + > +extern unsigned char ffi_csky_trampoline[TRAMPOLINE_SIZE]; > + > +/* > + * Since there is no __clear_cache in libgcc in csky toolchain. > + * define ffi_csky_cacheflush in sysv.S. > + * void ffi_csky_cacheflush(uint32 start_addr, uint32 size, int cache) > + */ > +#define CACHEFLUSH_IN_FFI 1 > +#if CACHEFLUSH_IN_FFI > +extern void ffi_csky_cacheflush(unsigned char *__tramp, unsigned int k, > + int i); > +#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \ > +({ unsigned char *__tramp = (unsigned char*)(TRAMP); \ > + unsigned int __fun = (unsigned int)(FUN); \ > + unsigned int __ctx = (unsigned int)(CTX); \ > + unsigned char *insns = (unsigned char *)(CTX); \ > + memcpy (__tramp, ffi_csky_trampoline, TRAMPOLINE_SIZE); \ > + *(unsigned int*) &__tramp[TRAMPOLINE_SIZE] = __ctx; \ > + *(unsigned int*) &__tramp[TRAMPOLINE_SIZE + 4] = __fun; \ > + ffi_csky_cacheflush(&__tramp[0], TRAMPOLINE_SIZE, 3); /* Clear data > mapping. */ \ > + ffi_csky_cacheflush(insns, TRAMPOLINE_SIZE, 3); \ > + /* Clear instruction \ > + mapping. */ \ > + }) > +#else > +#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \ > +({ unsigned char *__tramp = (unsigned char*)(TRAMP); \ > + unsigned int __fun = (unsigned int)(FUN); \ > + unsigned int __ctx = (unsigned int)(CTX); \ > + unsigned char *insns = (unsigned char *)(CTX); \ > + memcpy (__tramp, ffi_csky_trampoline, TRAMPOLINE_SIZE); \ > + *(unsigned int*) &__tramp[TRAMPOLINE_SIZE] = __ctx; \ > + *(unsigned int*) &__tramp[TRAMPOLINE_SIZE + 4] = __fun; \ > + __clear_cache((&__tramp[0]), (&__tramp[TRAMPOLINE_SIZE-1])); /* Clear > data mapping. */ \ > + __clear_cache(insns, insns + TRAMPOLINE_SIZE); \ > + /* Clear instruction \ > + mapping. */ \ > + }) > +#endif > + > +/* the cif must already be prep'ed */ > + > +ffi_status > +ffi_prep_closure_loc (ffi_closure* closure, > + ffi_cif* cif, > + void (*fun)(ffi_cif*,void*,void**,void*), > + void *user_data, > + void *codeloc) > +{ > + void (*closure_func)(ffi_closure*) = NULL; > + > + if (cif->abi == FFI_SYSV) > + closure_func = &ffi_closure_SYSV; > + else > + return FFI_BAD_ABI; > + > + FFI_INIT_TRAMPOLINE (&closure->tramp[0], \ > + closure_func, \ > + codeloc); > + > + closure->cif = cif; > + closure->user_data = user_data; > + closure->fun = fun; > + > + return FFI_OK; > +} > + > + > diff --git a/src/csky/ffitarget.h b/src/csky/ffitarget.h > new file mode 100644 > index 0000000..f770aac > --- /dev/null > +++ b/src/csky/ffitarget.h > @@ -0,0 +1,63 @@ > +/* -----------------------------------------------------------------*-C-*- > + ffitarget.h - Copyright (c) 2012 Anthony Green > + Copyright (c) 2010 CodeSourcery > + Copyright (c) 1996-2003 Red Hat, Inc. > + > + Target configuration macros for CSKY. > + > + 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 > + > +#ifdef __CSKYABIV2__ > +#define FFI_ASM_ARGREG_SIZE 16 > +#define TRAMPOLINE_SIZE 16 > +#define FFI_TRAMPOLINE_SIZE 24 > +#else > +#define FFI_ASM_ARGREG_SIZE 24 > +#define TRAMPOLINE_SIZE 20 > +#define FFI_TRAMPOLINE_SIZE 28 > +#endif > + > +/* ---- Definitions for closures > ----------------------------------------- */ > + > +#define FFI_CLOSURES 1 > +#define FFI_NATIVE_RAW_API 0 > +#endif > diff --git a/src/csky/sysv.S b/src/csky/sysv.S > new file mode 100644 > index 0000000..962a796 > --- /dev/null > +++ b/src/csky/sysv.S > @@ -0,0 +1,371 @@ > +/* ----------------------------------------------------------------------- > + sysv.S > + > + CSKY 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 > + > +.macro CSKY_FUNC_START name > + .text > + .align 2 > + .globl \name > + .type \name, @function > + \name: > +.endm > + > +#ifdef __CSKYABIV2__ > + > + /* > + * a0: fn > + * a1: &ecif > + * a2: cif->bytes > + * a3: fig->flags > + * sp+0: ecif.rvalue > + */ > +CSKY_FUNC_START ffi_call_SYSV > + /* Save registers */ > + .cfi_startproc > + subi sp, 28 > + .cfi_def_cfa_offset 28 > + stw a0, (sp, 0x0) > + .cfi_offset 0, -28 > + stw a1, (sp, 0x4) > + .cfi_offset 1, -24 > + stw a2, (sp, 0x8) > + .cfi_offset 2, -20 > + stw a3, (sp, 0xC) > + .cfi_offset 3, -16 > + stw l0, (sp, 0x10) > + .cfi_offset 4, -12 > + stw l1, (sp, 0x14) > + .cfi_offset 5, -8 > + stw lr, (sp, 0x18) > + .cfi_offset 15, -4 > + > + mov l0, sp > + .cfi_def_cfa_register 4 > + > + /* Make room for all of the new args. */ > + subu sp, sp, a2 > + > + /* Place all of the ffi_prep_args in position */ > + mov a0, sp > + /* a1 already set */ > + > + /* Call ffi_prep_args(stack, &ecif) */ > + jsri ffi_prep_args > + > + /* move first 4 parameters in registers */ > + ldw a0, (sp, 0x0) > + ldw a1, (sp, 0x4) > + ldw a2, (sp, 0x8) > + ldw a3, (sp, 0xC) > + > + /* and adjust stack */ > + subu lr, l0, sp /* cif->bytes == l0 - sp */ > + cmphsi lr, 16 > + movi l1, 16 > + movt lr, l1 > + addu sp, sp, lr > + > + ldw l1, (l0, 0) /* load fn() in advance */ > + > + /* call (fn) (...) */ > + jsr l1 > + > + /* Remove the space we pushed for the args */ > + mov sp, l0 > + > + /* Load r2 with the pointer to storage for the return value */ > + ldw a2, (sp, 0x1C) > + > + /* Load r3 with the return type code */ > + ldw a3, (sp, 0xC) > + > + /* If the return value pointer is NULL, assume no return value. */ > + cmpnei a2, 0 > + bf .Lepilogue > + > + cmpnei a3, FFI_TYPE_STRUCT > + bf .Lepilogue > + > + /* return INT64 */ > + cmpnei a3, FFI_TYPE_SINT64 > + bt .Lretint > + /* stw a0, (a2, 0x0) at .Lretint */ > + stw a1, (a2, 0x4) > + > +.Lretint: > + /* return INT */ > + stw a0, (a2, 0x0) > + > +.Lepilogue: > + ldw a0, (sp, 0x0) > + ldw a1, (sp, 0x4) > + ldw a2, (sp, 0x8) > + ldw a3, (sp, 0xC) > + ldw l0, (sp, 0x10) > + ldw l1, (sp, 0x14) > + ldw lr, (sp, 0x18) > + addi sp, sp, 28 > + rts > + .cfi_endproc > + .size ffi_call_SYSV, .-ffi_call_SYSV > + > + > + /* > + * unsigned int FFI_HIDDEN > + * ffi_closure_SYSV_inner (closure, respp, args) > + * ffi_closure *closure; > + * void **respp; > + * void *args; > + */ > +CSKY_FUNC_START ffi_closure_SYSV > + .cfi_startproc > + mov a2, sp > + addi a1, sp, 16 > + subi sp, sp, 24 > + .cfi_def_cfa_offset 40 > + stw a1, (sp, 0x10) > + .cfi_offset 1, -24 > + stw lr, (sp, 0x14) > + .cfi_offset 15, -20 > + stw sp, (sp, 0x8) > + addi a1, sp, 8 > + jsri ffi_closure_SYSV_inner > + ldw a0, (sp, 0x0) > + /* > + * if FFI_TYPE_SINT64, need a1. > + * if FFI_TYPE_INT, ignore a1. > + */ > + ldw a1, (sp, 0x4) > + > + ldw lr, (sp, 0x14) > + addi sp, sp, 40 > + rts > + .cfi_endproc > + .size ffi_closure_SYSV, .-ffi_closure_SYSV > + > +CSKY_FUNC_START ffi_csky_trampoline > + subi sp, sp, 16 > + stw a0, (sp, 0x0) > + stw a1, (sp, 0x4) > + stw a2, (sp, 0x8) > + stw a3, (sp, 0xC) > + lrw a0, [.Lctx] > + lrw a1, [.Lfun] > + jmp a1 > +.Lctx: > + mov a0, a0 > + mov a0, a0 > +.Lfun: > + > + .size ffi_csky_trampoline, .-ffi_csky_trampoline > + > +CSKY_FUNC_START ffi_csky_cacheflush > + mov t0, r7 > + movi r7, 123 > + trap 0 > + mov r7, t0 > + rts > + > + .size ffi_csky_cacheflush, .-ffi_csky_cacheflush > + > +#else /* !__CSKYABIV2__ */ > + > + /* > + * a0: fn > + * a1: &ecif > + * a2: cif->bytes > + * a3: fig->flags > + * a4: ecif.rvalue > + */ > +CSKY_FUNC_START ffi_call_SYSV > + /* Save registers */ > + .cfi_startproc > + subi sp, 32 > + subi sp, 8 > + .cfi_def_cfa_offset 40 > + stw a0, (sp, 0x0) > + .cfi_offset 2, -40 > + stw a1, (sp, 0x4) > + .cfi_offset 3, -36 > + stw a2, (sp, 0x8) > + .cfi_offset 4, -32 > + stw a3, (sp, 0xC) > + .cfi_offset 5, -28 > + stw a4, (sp, 0x10) > + .cfi_offset 6, -24 > + stw a5, (sp, 0x14) > + .cfi_offset 7, -20 > + stw l0, (sp, 0x18) > + .cfi_offset 8, -16 > + stw l1, (sp, 0x1C) > + .cfi_offset 9, -12 > + stw lr, (sp, 0x20) > + .cfi_offset 15, -8 > + > + mov l0, sp > + .cfi_def_cfa_register 8 > + > + /* Make room for all of the new args. */ > + subu sp, sp, a2 > + > + /* Place all of the ffi_prep_args in position */ > + mov a0, sp > + /* a1 already set */ > + > + /* Call ffi_prep_args(stack, &ecif) */ > + jsri ffi_prep_args > + > + /* move first 4 parameters in registers */ > + ldw a0, (sp, 0x0) > + ldw a1, (sp, 0x4) > + ldw a2, (sp, 0x8) > + ldw a3, (sp, 0xC) > + ldw a4, (sp, 0x10) > + ldw a5, (sp, 0x14) > + > + /* and adjust stack */ > + mov lr, l0 > + subu lr, sp /* cif->bytes == l0 - sp */ > + movi l1, 24 > + cmphs lr, l1 > + movt lr, l1 > + addu sp, sp, lr > + > + ldw l1, (l0, 0) /* load fn() in advance */ > + > + /* call (fn) (...) */ > + jsr l1 > + > + /* Remove the space we pushed for the args */ > + mov sp, l0 > + > + /* Load r2 with the pointer to storage for the return value */ > + ldw a2, (sp, 0x10) > + > + /* Load r3 with the return type code */ > + ldw a3, (sp, 0xC) > + > + /* If the return value pointer is NULL, assume no return value. */ > + cmpnei a2, 0 > + bf .Lepilogue > + > + cmpnei a3, FFI_TYPE_STRUCT > + bf .Lepilogue > + > + /* return INT64 */ > + cmpnei a3, FFI_TYPE_SINT64 > + bt .Lretint > + /* stw a0, (a2, 0x0) at .Lretint */ > + stw a1, (a2, 0x4) > + > +.Lretint: > + /* return INT */ > + stw a0, (a2, 0x0) > + > +.Lepilogue: > + ldw a0, (sp, 0x0) > + ldw a1, (sp, 0x4) > + ldw a2, (sp, 0x8) > + ldw a3, (sp, 0xC) > + ldw a4, (sp, 0x10) > + ldw a5, (sp, 0x14) > + ldw l0, (sp, 0x18) > + ldw l1, (sp, 0x1C) > + ldw lr, (sp, 0x20) > + addi sp, sp, 32 > + addi sp, sp, 8 > + rts > + .cfi_endproc > + > + .size ffi_call_SYSV, .-ffi_call_SYSV > + > + > + /* > + * unsigned int FFI_HIDDEN > + * ffi_closure_SYSV_inner (closure, respp, args) > + * ffi_closure *closure; > + * void **respp; > + * void *args; > + */ > +CSKY_FUNC_START ffi_closure_SYSV > + .cfi_startproc > + mov a2, sp > + mov a1, sp > + addi a1, 24 > + subi sp, sp, 24 > + .cfi_def_cfa_offset 48 > + stw a1, (sp, 0x10) > + .cfi_offset 3, -32 > + stw lr, (sp, 0x14) > + .cfi_offset 15, -28 > + stw sp, (sp, 0x8) > + mov a1, sp > + addi a1, 8 > + jsri ffi_closure_SYSV_inner > + ldw a0, (sp, 0x0) > + /* > + * if FFI_TYPE_SINT64, need a1. > + * if FFI_TYPE_INT, ignore a1. > + */ > + ldw a1, (sp, 0x4) > + > + ldw lr, (sp, 0x14) > + addi sp, sp, 24 > + addi sp, sp, 24 > + rts > + .cfi_endproc > + > + .size ffi_closure_SYSV, .-ffi_closure_SYSV > + > +CSKY_FUNC_START ffi_csky_trampoline > + subi sp, 24 > + stw a0, (sp, 0x0) > + stw a1, (sp, 0x4) > + stw a2, (sp, 0x8) > + stw a3, (sp, 0xC) > + stw a4, (sp, 0x10) > + stw a5, (sp, 0x14) > + lrw a0, [.Lctx] > + lrw a1, [.Lfun] > + jmp a1 > +.Lctx: > + mov a0, a0 > + mov a0, a0 > +.Lfun: > + > + .size ffi_csky_trampoline, .-ffi_csky_trampoline > + > +CSKY_FUNC_START ffi_csky_cacheflush > + lrw r1, 123 > + trap 0 > + rts > + > + .size ffi_csky_cacheflush, .-ffi_csky_cacheflush > + > +#endif /* __CSKYABIV2__ */ > -- > 2.17.1 > >