123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878 |
- From 38e46503a1f78166e5f0730133f15bb3cb70f588 Mon Sep 17 00:00:00 2001
- From: tianshuliang <tian_shuliang@hoperun.com>
- Date: Sun, 25 Apr 2021 13:51:41 +0800
- Subject: [PATCH] append support for csky
- ---
- configure.host | 5 +
- src/csky/ffi.c | 395 +++++++++++++++++++++++++++++++++++++++++++
- src/csky/ffitarget.h | 63 +++++++
- src/csky/sysv.S | 371 ++++++++++++++++++++++++++++++++++++++++
- 4 files changed, 834 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/configure.host b/configure.host
- index 9a72cda..3deed6c 100644
- --- a/configure.host
- +++ b/configure.host
- @@ -214,6 +214,11 @@ case "${host}" in
- TARGET=RISCV; TARGETDIR=riscv
- SOURCES="ffi.c sysv.S"
- ;;
- +
- + csky*-*)
- + TARGET=CSKY; TARGETDIR=csky
- + SOURCES="ffi.c sysv.S"
- + ;;
-
- s390-*-* | s390x-*-*)
- TARGET=S390; TARGETDIR=s390
- 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 <ffi.h>
- +#include <ffi_common.h>
- +
- +#include <stdlib.h>
- +
- +/* 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 <fficonfig.h>
- +#include <ffi.h>
- +
- +.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__ */
|