diff options
Diffstat (limited to 'libffi/src/sh')
-rw-r--r-- | libffi/src/sh/ffi.c | 722 | ||||
-rw-r--r-- | libffi/src/sh/ffitarget.h | 48 | ||||
-rw-r--r-- | libffi/src/sh/sysv.S | 775 |
3 files changed, 0 insertions, 1545 deletions
diff --git a/libffi/src/sh/ffi.c b/libffi/src/sh/ffi.c deleted file mode 100644 index 8aa96a1..0000000 --- a/libffi/src/sh/ffi.c +++ /dev/null @@ -1,722 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 2002, 2003 Kaz Kojima - - SuperH 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 CYGNUS SOLUTIONS 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> - -#define NGREGARG 4 -#if defined(__SH4__) -#define NFREGARG 8 -#endif - -#if defined(__HITACHI__) -#define STRUCT_VALUE_ADDRESS_WITH_ARG 1 -#else -#define STRUCT_VALUE_ADDRESS_WITH_ARG 0 -#endif - -/* If the structure has essentialy an unique element, return its type. */ -static int -simple_type (ffi_type *arg) -{ - if (arg->type != FFI_TYPE_STRUCT) - return arg->type; - else if (arg->elements[1]) - return FFI_TYPE_STRUCT; - - return simple_type (arg->elements[0]); -} - -static int -return_type (ffi_type *arg) -{ - unsigned short type; - - if (arg->type != FFI_TYPE_STRUCT) - return arg->type; - - type = simple_type (arg->elements[0]); - if (! arg->elements[1]) - { - switch (type) - { - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT32: - return FFI_TYPE_INT; - - default: - return type; - } - } - - /* gcc uses r0/r1 pair for some kind of structures. */ - if (arg->size <= 2 * sizeof (int)) - { - int i = 0; - ffi_type *e; - - while ((e = arg->elements[i++])) - { - type = simple_type (e); - switch (type) - { - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT32: - case FFI_TYPE_INT: - case FFI_TYPE_FLOAT: - return FFI_TYPE_UINT64; - - default: - break; - } - } - } - - return FFI_TYPE_STRUCT; -} - -/* ffi_prep_args is called by the assembly routine once stack space - has been allocated for the function's arguments */ - -/*@-exportheader@*/ -void ffi_prep_args(char *stack, extended_cif *ecif) -/*@=exportheader@*/ -{ - register unsigned int i; - register int tmp; - register unsigned int avn; - register void **p_argv; - register char *argp; - register ffi_type **p_arg; - int greg, ireg; -#if defined(__SH4__) - int freg = 0; -#endif - - tmp = 0; - argp = stack; - - if (return_type (ecif->cif->rtype) == FFI_TYPE_STRUCT) - { - *(void **) argp = ecif->rvalue; - argp += 4; - ireg = STRUCT_VALUE_ADDRESS_WITH_ARG ? 1 : 0; - } - else - ireg = 0; - - /* Set arguments for registers. */ - greg = ireg; - avn = ecif->cif->nargs; - p_argv = ecif->avalue; - - for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++) - { - size_t z; - - z = (*p_arg)->size; - if (z < sizeof(int)) - { - if (greg++ >= NGREGARG) - continue; - - 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: - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); - break; - - default: - FFI_ASSERT(0); - } - argp += z; - } - else if (z == sizeof(int)) - { -#if defined(__SH4__) - if ((*p_arg)->type == FFI_TYPE_FLOAT) - { - if (freg++ >= NFREGARG) - continue; - } - else -#endif - { - if (greg++ >= NGREGARG) - continue; - } - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); - argp += z; - } -#if defined(__SH4__) - else if ((*p_arg)->type == FFI_TYPE_DOUBLE) - { - if (freg + 1 >= NFREGARG) - continue; - freg = (freg + 1) & ~1; - freg += 2; - memcpy (argp, *p_argv, z); - argp += z; - } -#endif - else - { - int n = (z + sizeof (int) - 1) / sizeof (int); -#if defined(__SH4__) - if (greg + n - 1 >= NGREGARG) - continue; - greg += n; -#else - if (greg >= NGREGARG) - continue; - else if (greg + n - 1 >= NGREGARG) - greg = NGREGARG; - else - greg += n; -#endif - memcpy (argp, *p_argv, z); - argp += n * sizeof (int); - } - } - - /* Set arguments on stack. */ - greg = ireg; -#if defined(__SH4__) - freg = 0; -#endif - p_argv = ecif->avalue; - - for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++) - { - size_t z; - - z = (*p_arg)->size; - if (z < sizeof(int)) - { - if (greg++ < NGREGARG) - continue; - - 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: - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); - break; - - default: - FFI_ASSERT(0); - } - argp += z; - } - else if (z == sizeof(int)) - { -#if defined(__SH4__) - if ((*p_arg)->type == FFI_TYPE_FLOAT) - { - if (freg++ < NFREGARG) - continue; - } - else -#endif - { - if (greg++ < NGREGARG) - continue; - } - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); - argp += z; - } -#if defined(__SH4__) - else if ((*p_arg)->type == FFI_TYPE_DOUBLE) - { - if (freg + 1 < NFREGARG) - { - freg = (freg + 1) & ~1; - freg += 2; - continue; - } - memcpy (argp, *p_argv, z); - argp += z; - } -#endif - else - { - int n = (z + sizeof (int) - 1) / sizeof (int); - if (greg + n - 1 < NGREGARG) - { - greg += n; - continue; - } -#if (! defined(__SH4__)) - else if (greg < NGREGARG) - { - greg = NGREGARG; - continue; - } -#endif - memcpy (argp, *p_argv, z); - argp += n * sizeof (int); - } - } - - return; -} - -/* Perform machine dependent cif processing */ -ffi_status ffi_prep_cif_machdep(ffi_cif *cif) -{ - int i, j; - int size, type; - int n, m; - int greg; -#if defined(__SH4__) - int freg = 0; -#endif - - cif->flags = 0; - - greg = ((return_type (cif->rtype) == FFI_TYPE_STRUCT) && - STRUCT_VALUE_ADDRESS_WITH_ARG) ? 1 : 0; - -#if defined(__SH4__) - for (i = j = 0; i < cif->nargs && j < 12; i++) - { - type = (cif->arg_types)[i]->type; - switch (type) - { - case FFI_TYPE_FLOAT: - if (freg >= NFREGARG) - continue; - freg++; - cif->flags += ((cif->arg_types)[i]->type) << (2 * j); - j++; - break; - - case FFI_TYPE_DOUBLE: - if ((freg + 1) >= NFREGARG) - continue; - freg = (freg + 1) & ~1; - freg += 2; - cif->flags += ((cif->arg_types)[i]->type) << (2 * j); - j++; - break; - - default: - size = (cif->arg_types)[i]->size; - n = (size + sizeof (int) - 1) / sizeof (int); - if (greg + n - 1 >= NGREGARG) - continue; - greg += n; - for (m = 0; m < n; m++) - cif->flags += FFI_TYPE_INT << (2 * j++); - break; - } - } -#else - for (i = j = 0; i < cif->nargs && j < 4; i++) - { - size = (cif->arg_types)[i]->size; - n = (size + sizeof (int) - 1) / sizeof (int); - if (greg >= NGREGARG) - continue; - else if (greg + n - 1 >= NGREGARG) - greg = NGREGARG; - else - greg += n; - for (m = 0; m < n; m++) - cif->flags += FFI_TYPE_INT << (2 * j++); - } -#endif - - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_STRUCT: - cif->flags += (unsigned) (return_type (cif->rtype)) << 24; - break; - - case FFI_TYPE_VOID: - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - cif->flags += (unsigned) cif->rtype->type << 24; - break; - - default: - cif->flags += FFI_TYPE_INT << 24; - break; - } - - return FFI_OK; -} - -/*@-declundef@*/ -/*@-exportheader@*/ -extern void ffi_call_SYSV(void (*)(char *, extended_cif *), - /*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, - void (*fn)()); -/*@=declundef@*/ -/*@=exportheader@*/ - -void ffi_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ void **avalue) -{ - extended_cif ecif; - - ecif.cif = cif; - ecif.avalue = avalue; - - /* If the return value is a struct and we don't have a return */ - /* value address then we need to make one */ - - if ((rvalue == NULL) && - (cif->rtype->type == FFI_TYPE_STRUCT)) - { - /*@-sysunrecog@*/ - ecif.rvalue = alloca(cif->rtype->size); - /*@=sysunrecog@*/ - } - else - ecif.rvalue = rvalue; - - - switch (cif->abi) - { - case FFI_SYSV: - /*@-usedef@*/ - ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ - break; - default: - FFI_ASSERT(0); - break; - } -} - -extern void ffi_closure_SYSV (void); -#if defined(__SH4__) -extern void __ic_invalidate (void *line); -#endif - -ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*, void*, void**, void*), - void *user_data) -{ - unsigned int *tramp; - - FFI_ASSERT (cif->abi == FFI_GCC_SYSV); - - tramp = (unsigned int *) &closure->tramp[0]; -#ifdef __LITTLE_ENDIAN__ - tramp[0] = 0xd301d202; - tramp[1] = 0x0009422b; -#else - tramp[0] = 0xd202d301; - tramp[1] = 0x422b0009; -#endif - *(void **) &tramp[2] = (void *)closure; /* ctx */ - *(void **) &tramp[3] = (void *)ffi_closure_SYSV; /* funaddr */ - - closure->cif = cif; - closure->fun = fun; - closure->user_data = user_data; - -#if defined(__SH4__) - /* Flush the icache. */ - __ic_invalidate(&closure->tramp[0]); -#endif - - return FFI_OK; -} - -/* Basically the trampoline invokes ffi_closure_SYSV, and on - * entry, r3 holds the address of the closure. - * After storing the registers that could possibly contain - * parameters to be passed into the stack frame and setting - * up space for a return value, ffi_closure_SYSV invokes the - * following helper function to do most of the work. - */ - -#ifdef __LITTLE_ENDIAN__ -#define OFS_INT8 0 -#define OFS_INT16 0 -#else -#define OFS_INT8 3 -#define OFS_INT16 2 -#endif - -int -ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, - unsigned long *pgr, unsigned long *pfr, - unsigned long *pst) -{ - void **avalue; - ffi_type **p_arg; - int i, avn; - int ireg, greg = 0; -#if defined(__SH4__) - int freg = 0; -#endif - ffi_cif *cif; - double temp; - - cif = closure->cif; - avalue = alloca(cif->nargs * sizeof(void *)); - - /* Copy the caller's structure return value address so that the closure - returns the data directly to the caller. */ - if (cif->rtype->type == FFI_TYPE_STRUCT && STRUCT_VALUE_ADDRESS_WITH_ARG) - { - rvalue = *pgr++; - ireg = 1; - } - else - ireg = 0; - - cif = closure->cif; - greg = ireg; - avn = cif->nargs; - - /* Grab the addresses of the arguments from the stack frame. */ - for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++) - { - size_t z; - - z = (*p_arg)->size; - if (z < sizeof(int)) - { - if (greg++ >= NGREGARG) - continue; - - z = sizeof(int); - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT8: - avalue[i] = (((char *)pgr) + OFS_INT8); - break; - - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT16: - avalue[i] = (((char *)pgr) + OFS_INT16); - break; - - case FFI_TYPE_STRUCT: - avalue[i] = pgr; - break; - - default: - FFI_ASSERT(0); - } - pgr++; - } - else if (z == sizeof(int)) - { -#if defined(__SH4__) - if ((*p_arg)->type == FFI_TYPE_FLOAT) - { - if (freg++ >= NFREGARG) - continue; - avalue[i] = pfr; - pfr++; - } - else -#endif - { - if (greg++ >= NGREGARG) - continue; - avalue[i] = pgr; - pgr++; - } - } -#if defined(__SH4__) - else if ((*p_arg)->type == FFI_TYPE_DOUBLE) - { - if (freg + 1 >= NFREGARG) - continue; - freg = (freg + 1) & ~1; - freg += 2; - avalue[i] = pfr; - pfr += 2; - } -#endif - else - { - int n = (z + sizeof (int) - 1) / sizeof (int); -#if defined(__SH4__) - if (greg + n - 1 >= NGREGARG) - continue; - greg += n; -#else - if (greg >= NGREGARG) - continue; - else if (greg + n - 1 >= NGREGARG) - greg = NGREGARG; - else - greg += n; -#endif - avalue[i] = pgr; - pgr += n; - } - } - - greg = ireg; -#if defined(__SH4__) - freg = 0; -#endif - - for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++) - { - size_t z; - - z = (*p_arg)->size; - if (z < sizeof(int)) - { - if (greg++ < NGREGARG) - continue; - - z = sizeof(int); - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT8: - avalue[i] = (((char *)pst) + OFS_INT8); - break; - - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT16: - avalue[i] = (((char *)pst) + OFS_INT16); - break; - - case FFI_TYPE_STRUCT: - avalue[i] = pst; - break; - - default: - FFI_ASSERT(0); - } - pst++; - } - else if (z == sizeof(int)) - { -#if defined(__SH4__) - if ((*p_arg)->type == FFI_TYPE_FLOAT) - { - if (freg++ < NFREGARG) - continue; - } - else -#endif - { - if (greg++ < NGREGARG) - continue; - } - avalue[i] = pst; - pst++; - } -#if defined(__SH4__) - else if ((*p_arg)->type == FFI_TYPE_DOUBLE) - { - if (freg + 1 < NFREGARG) - { - freg = (freg + 1) & ~1; - freg += 2; - continue; - } - avalue[i] = pst; - pst += 2; - } -#endif - else - { - int n = (z + sizeof (int) - 1) / sizeof (int); - if (greg + n - 1 < NGREGARG) - { - greg += n; - continue; - } -#if (! defined(__SH4__)) - else if (greg < NGREGARG) - { - greg = NGREGARG; - continue; - } -#endif - avalue[i] = pst; - pst += n; - } - } - - (closure->fun) (cif, rvalue, avalue, closure->user_data); - - /* Tell ffi_closure_SYSV how to perform return type promotions. */ - return return_type (cif->rtype); -} diff --git a/libffi/src/sh/ffitarget.h b/libffi/src/sh/ffitarget.h deleted file mode 100644 index f8492a1..0000000 --- a/libffi/src/sh/ffitarget.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -----------------------------------------------------------------*-C-*- - ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. - Target configuration macros for SuperH. - - 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 CYGNUS SOLUTIONS 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 - -/* ---- Generic type definitions ----------------------------------------- */ - -#ifndef LIBFFI_ASM -typedef unsigned long ffi_arg; -typedef signed long ffi_sarg; - -typedef enum ffi_abi { - FFI_FIRST_ABI = 0, - FFI_SYSV, - FFI_DEFAULT_ABI = FFI_SYSV, - FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 -} ffi_abi; -#endif - -#define FFI_CLOSURES 1 -#define FFI_TRAMPOLINE_SIZE 16 -#define FFI_NATIVE_RAW_API 0 - -#endif - diff --git a/libffi/src/sh/sysv.S b/libffi/src/sh/sysv.S deleted file mode 100644 index a7121c5..0000000 --- a/libffi/src/sh/sysv.S +++ /dev/null @@ -1,775 +0,0 @@ -/* ----------------------------------------------------------------------- - sysv.S - Copyright (c) 2002, 2003 Kaz Kojima - - SuperH 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 CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM -#include <fficonfig.h> -#include <ffi.h> -#ifdef HAVE_MACHINE_ASM_H -#include <machine/asm.h> -#else -/* XXX these lose for some platforms, I'm sure. */ -#define CNAME(x) x -#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x): -#endif - -#if defined(__HITACHI__) -#define STRUCT_VALUE_ADDRESS_WITH_ARG 1 -#else -#define STRUCT_VALUE_ADDRESS_WITH_ARG 0 -#endif - -.text - - # r4: ffi_prep_args - # r5: &ecif - # r6: bytes - # r7: flags - # sp+0: rvalue - # sp+4: fn - - # This assumes we are using gas. -ENTRY(ffi_call_SYSV) - # Save registers -.LFB1: - mov.l r8,@-r15 -.LCFI0: - mov.l r9,@-r15 -.LCFI1: - mov.l r10,@-r15 -.LCFI2: - mov.l r12,@-r15 -.LCFI3: - mov.l r14,@-r15 -.LCFI4: - sts.l pr,@-r15 -.LCFI5: - mov r15,r14 -.LCFI6: -#if defined(__SH4__) - mov r6,r8 - mov r7,r9 - - sub r6,r15 - add #-16,r15 - mov #~7,r0 - and r0,r15 - - mov r4,r0 - jsr @r0 - mov r15,r4 - - mov r9,r1 - shlr8 r9 - shlr8 r9 - shlr8 r9 - - mov #FFI_TYPE_STRUCT,r2 - cmp/eq r2,r9 - bf 1f -#if STRUCT_VALUE_ADDRESS_WITH_ARG - mov.l @r15+,r4 - bra 2f - mov #5,r2 -#else - mov.l @r15+,r10 -#endif -1: - mov #4,r2 -2: - mov #4,r3 - -L_pass: - cmp/pl r8 - bf L_call_it - - mov r1,r0 - and #3,r0 - -L_pass_d: - cmp/eq #FFI_TYPE_DOUBLE,r0 - bf L_pass_f - - mov r3,r0 - and #1,r0 - tst r0,r0 - bt 1f - add #1,r3 -1: - mov r15,r0 - and #7,r0 - tst r0,r0 - bt 2f - add #4,r15 -2: - mov #12,r0 - cmp/hs r0,r3 - bt/s 3f - shlr2 r1 - bsr L_pop_d - nop -3: - add #2,r3 - bra L_pass - add #-8,r8 - -L_pop_d: - mov r3,r0 - add r0,r0 - add r3,r0 - add #-12,r0 - braf r0 - nop -#ifdef __LITTLE_ENDIAN__ - fmov.s @r15+,fr5 - rts - fmov.s @r15+,fr4 - fmov.s @r15+,fr7 - rts - fmov.s @r15+,fr6 - fmov.s @r15+,fr9 - rts - fmov.s @r15+,fr8 - fmov.s @r15+,fr11 - rts - fmov.s @r15+,fr10 -#else - fmov.s @r15+,fr4 - rts - fmov.s @r15+,fr5 - fmov.s @r15+,fr6 - rts - fmov.s @r15+,fr7 - fmov.s @r15+,fr8 - rts - fmov.s @r15+,fr9 - fmov.s @r15+,fr10 - rts - fmov.s @r15+,fr11 -#endif - -L_pass_f: - cmp/eq #FFI_TYPE_FLOAT,r0 - bf L_pass_i - - mov #12,r0 - cmp/hs r0,r3 - bt/s 2f - shlr2 r1 - bsr L_pop_f - nop -2: - add #1,r3 - bra L_pass - add #-4,r8 - -L_pop_f: - mov r3,r0 - shll2 r0 - add #-16,r0 - braf r0 - nop -#ifdef __LITTLE_ENDIAN__ - rts - fmov.s @r15+,fr5 - rts - fmov.s @r15+,fr4 - rts - fmov.s @r15+,fr7 - rts - fmov.s @r15+,fr6 - rts - fmov.s @r15+,fr9 - rts - fmov.s @r15+,fr8 - rts - fmov.s @r15+,fr11 - rts - fmov.s @r15+,fr10 -#else - rts - fmov.s @r15+,fr4 - rts - fmov.s @r15+,fr5 - rts - fmov.s @r15+,fr6 - rts - fmov.s @r15+,fr7 - rts - fmov.s @r15+,fr8 - rts - fmov.s @r15+,fr9 - rts - fmov.s @r15+,fr10 - rts - fmov.s @r15+,fr11 -#endif - -L_pass_i: - cmp/eq #FFI_TYPE_INT,r0 - bf L_call_it - - mov #8,r0 - cmp/hs r0,r2 - bt/s 2f - shlr2 r1 - bsr L_pop_i - nop -2: - add #1,r2 - bra L_pass - add #-4,r8 - -L_pop_i: - mov r2,r0 - shll2 r0 - add #-16,r0 - braf r0 - nop - rts - mov.l @r15+,r4 - rts - mov.l @r15+,r5 - rts - mov.l @r15+,r6 - rts - mov.l @r15+,r7 - -L_call_it: - # call function -#if (! STRUCT_VALUE_ADDRESS_WITH_ARG) - mov r10, r2 -#endif - mov.l @(28,r14),r1 - jsr @r1 - nop - -L_ret_d: - mov #FFI_TYPE_DOUBLE,r2 - cmp/eq r2,r9 - bf L_ret_ll - - mov.l @(24,r14),r1 -#ifdef __LITTLE_ENDIAN__ - fmov.s fr1,@r1 - add #4,r1 - bra L_epilogue - fmov.s fr0,@r1 -#else - fmov.s fr0,@r1 - add #4,r1 - bra L_epilogue - fmov.s fr1,@r1 -#endif - -L_ret_ll: - mov #FFI_TYPE_SINT64,r2 - cmp/eq r2,r9 - bt/s 1f - mov #FFI_TYPE_UINT64,r2 - cmp/eq r2,r9 - bf L_ret_f - -1: - mov.l @(24,r14),r2 - mov.l r0,@r2 - bra L_epilogue - mov.l r1,@(4,r2) - -L_ret_f: - mov #FFI_TYPE_FLOAT,r2 - cmp/eq r2,r9 - bf L_ret_i - - mov.l @(24,r14),r1 - bra L_epilogue - fmov.s fr0,@r1 - -L_ret_i: - mov #FFI_TYPE_INT,r2 - cmp/eq r2,r9 - bf L_epilogue - - mov.l @(24,r14),r1 - bra L_epilogue - mov.l r0,@r1 - -L_epilogue: - # Remove the space we pushed for the args - mov r14,r15 - - lds.l @r15+,pr - mov.l @r15+,r14 - mov.l @r15+,r12 - mov.l @r15+,r10 - mov.l @r15+,r9 - rts - mov.l @r15+,r8 -#else - mov r6,r8 - mov r7,r9 - - sub r6,r15 - add #-16,r15 - mov #~7,r0 - and r0,r15 - - mov r4,r0 - jsr @r0 - mov r15,r4 - - mov r9,r3 - shlr8 r9 - shlr8 r9 - shlr8 r9 - - mov #FFI_TYPE_STRUCT,r2 - cmp/eq r2,r9 - bf 1f -#if STRUCT_VALUE_ADDRESS_WITH_ARG - mov.l @r15+,r4 - bra 2f - mov #5,r2 -#else - mov.l @r15+,r10 -#endif -1: - mov #4,r2 -2: - -L_pass: - cmp/pl r8 - bf L_call_it - - mov r3,r0 - and #3,r0 - -L_pass_d: - cmp/eq #FFI_TYPE_DOUBLE,r0 - bf L_pass_i - - mov r15,r0 - and #7,r0 - tst r0,r0 - bt 1f - add #4,r15 -1: - mov #8,r0 - cmp/hs r0,r2 - bt/s 2f - shlr2 r3 - bsr L_pop_d - nop -2: - add #2,r2 - bra L_pass - add #-8,r8 - -L_pop_d: - mov r2,r0 - add r0,r0 - add r2,r0 - add #-12,r0 - add r0,r0 - braf r0 - nop - mov.l @r15+,r4 - rts - mov.l @r15+,r5 - mov.l @r15+,r5 - rts - mov.l @r15+,r6 - mov.l @r15+,r6 - rts - mov.l @r15+,r7 - rts - mov.l @r15+,r7 - -L_pass_i: - mov #8,r0 - cmp/hs r0,r2 - bt/s 2f - shlr2 r3 - bsr L_pop_i - nop -2: - add #1,r2 - bra L_pass - add #-4,r8 - -L_pop_i: - mov r2,r0 - shll2 r0 - add #-16,r0 - braf r0 - nop - rts - mov.l @r15+,r4 - rts - mov.l @r15+,r5 - rts - mov.l @r15+,r6 - rts - mov.l @r15+,r7 - -L_call_it: - # call function -#if (! STRUCT_VALUE_ADDRESS_WITH_ARG) - mov r10, r2 -#endif - mov.l @(28,r14),r1 - jsr @r1 - nop - -L_ret_d: - mov #FFI_TYPE_DOUBLE,r2 - cmp/eq r2,r9 - bf L_ret_ll - - mov.l @(24,r14),r2 - mov.l r0,@r2 - bra L_epilogue - mov.l r1,@(4,r2) - -L_ret_ll: - mov #FFI_TYPE_SINT64,r2 - cmp/eq r2,r9 - bt/s 1f - mov #FFI_TYPE_UINT64,r2 - cmp/eq r2,r9 - bf L_ret_i - -1: - mov.l @(24,r14),r2 - mov.l r0,@r2 - bra L_epilogue - mov.l r1,@(4,r2) - -L_ret_i: - mov #FFI_TYPE_FLOAT,r2 - cmp/eq r2,r9 - bt 1f - mov #FFI_TYPE_INT,r2 - cmp/eq r2,r9 - bf L_epilogue -1: - mov.l @(24,r14),r1 - bra L_epilogue - mov.l r0,@r1 - -L_epilogue: - # Remove the space we pushed for the args - mov r14,r15 - - lds.l @r15+,pr - mov.l @r15+,r14 - mov.l @r15+,r12 - mov.l @r15+,r10 - mov.l @r15+,r9 - rts - mov.l @r15+,r8 -#endif -.LFE1: -.ffi_call_SYSV_end: - .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV) - -.globl ffi_closure_helper_SYSV - -ENTRY(ffi_closure_SYSV) -.LFB2: - mov.l r14,@-r15 -.LCFI7: - sts.l pr,@-r15 - - /* Stack layout: - ... - 32 bytes (floating register parameters, SH-4 only) - 16 bytes (register parameters) - 8 bytes (result) - 4 bytes (pad) - 4 bytes (5th arg) - <- new stack pointer - */ -.LCFI8: -#if defined(__SH4__) - add #-64,r15 -#else - add #-32,r15 -#endif -.LCFI9: - mov r15,r14 -.LCFIA: - mov r14,r1 - add #32,r1 - mov.l r7,@-r1 - mov.l r6,@-r1 - mov.l r5,@-r1 - mov.l r4,@-r1 - mov r1,r6 - -#if defined(__SH4__) - mov r14,r1 - add #64,r1 -#ifdef __LITTLE_ENDIAN__ - fmov.s fr10,@-r1 - fmov.s fr11,@-r1 - fmov.s fr8,@-r1 - fmov.s fr9,@-r1 - fmov.s fr6,@-r1 - fmov.s fr7,@-r1 - fmov.s fr4,@-r1 - fmov.s fr5,@-r1 -#else - fmov.s fr11,@-r1 - fmov.s fr10,@-r1 - fmov.s fr9,@-r1 - fmov.s fr8,@-r1 - fmov.s fr7,@-r1 - fmov.s fr6,@-r1 - fmov.s fr5,@-r1 - fmov.s fr4,@-r1 -#endif - mov r1,r7 -#endif - - mov r14,r1 - add #8,r1 - mov r1,r5 - - mov r14,r1 -#if defined(__SH4__) - add #72,r1 -#else - add #40,r1 -#endif - mov.l r1,@r14 - - mov.l L_helper,r0 - jsr @r0 - mov r3,r4 - - shll r0 - mov r0,r1 - mova L_table,r0 - add r1,r0 - mov.w @r0,r0 - mov r14,r2 - braf r0 - add #8,r2 -0: - .align 2 -L_helper: - .long ffi_closure_helper_SYSV -L_table: - .short L_case_v - 0b /* FFI_TYPE_VOID */ - .short L_case_i - 0b /* FFI_TYPE_INT */ -#if defined(__SH4__) - .short L_case_f - 0b /* FFI_TYPE_FLOAT */ - .short L_case_d - 0b /* FFI_TYPE_DOUBLE */ - .short L_case_d - 0b /* FFI_TYPE_LONGDOUBLE */ -#else - .short L_case_i - 0b /* FFI_TYPE_FLOAT */ - .short L_case_ll - 0b /* FFI_TYPE_DOUBLE */ - .short L_case_ll - 0b /* FFI_TYPE_LONGDOUBLE */ -#endif - .short L_case_uq - 0b /* FFI_TYPE_UINT8 */ - .short L_case_q - 0b /* FFI_TYPE_SINT8 */ - .short L_case_uh - 0b /* FFI_TYPE_UINT16 */ - .short L_case_h - 0b /* FFI_TYPE_SINT16 */ - .short L_case_i - 0b /* FFI_TYPE_UINT32 */ - .short L_case_i - 0b /* FFI_TYPE_SINT32 */ - .short L_case_ll - 0b /* FFI_TYPE_UINT64 */ - .short L_case_ll - 0b /* FFI_TYPE_SINT64 */ - .short L_case_v - 0b /* FFI_TYPE_STRUCT */ - .short L_case_i - 0b /* FFI_TYPE_POINTER */ - -#if defined(__SH4__) -L_case_d: -#ifdef __LITTLE_ENDIAN__ - fmov.s @r2+,fr1 - bra L_case_v - fmov.s @r2,fr0 -#else - fmov.s @r2+,fr0 - bra L_case_v - fmov.s @r2,fr1 -#endif - -L_case_f: - bra L_case_v - fmov.s @r2,fr0 -#endif - -L_case_ll: - mov.l @r2+,r0 - bra L_case_v - mov.l @r2,r1 - -L_case_i: - bra L_case_v - mov.l @r2,r0 - -L_case_q: -#ifdef __LITTLE_ENDIAN__ -#else - add #3,r2 -#endif - bra L_case_v - mov.b @r2,r0 - -L_case_uq: -#ifdef __LITTLE_ENDIAN__ -#else - add #3,r2 -#endif - mov.b @r2,r0 - bra L_case_v - extu.b r0,r0 - -L_case_h: -#ifdef __LITTLE_ENDIAN__ -#else - add #2,r2 -#endif - bra L_case_v - mov.w @r2,r0 - -L_case_uh: -#ifdef __LITTLE_ENDIAN__ -#else - add #2,r2 -#endif - mov.w @r2,r0 - extu.w r0,r0 - /* fall through */ - -L_case_v: -#if defined(__SH4__) - add #64,r15 -#else - add #32,r15 -#endif - lds.l @r15+,pr - rts - mov.l @r15+,r14 -.LFE2: -.ffi_closure_SYSV_end: - .size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV) - - .section ".eh_frame","aw",@progbits -__FRAME_BEGIN__: - .4byte .LECIE1-.LSCIE1 /* Length of Common Information Entry */ -.LSCIE1: - .4byte 0x0 /* CIE Identifier Tag */ - .byte 0x1 /* CIE Version */ - .byte 0x0 /* CIE Augmentation */ - .byte 0x1 /* uleb128 0x1; CIE Code Alignment Factor */ - .byte 0x7c /* sleb128 -4; CIE Data Alignment Factor */ - .byte 0x11 /* CIE RA Column */ - .byte 0xc /* DW_CFA_def_cfa */ - .byte 0xf /* uleb128 0xf */ - .byte 0x0 /* uleb128 0x0 */ - .align 2 -.LECIE1: -.LSFDE1: - .4byte .LEFDE1-.LASFDE1 /* FDE Length */ -.LASFDE1: - .4byte .LASFDE1-__FRAME_BEGIN__ /* FDE CIE offset */ - .4byte .LFB1 /* FDE initial location */ - .4byte .LFE1-.LFB1 /* FDE address range */ - .byte 0x4 /* DW_CFA_advance_loc4 */ - .4byte .LCFI0-.LFB1 - .byte 0xe /* DW_CFA_def_cfa_offset */ - .byte 0x4 /* uleb128 0x4 */ - .byte 0x4 /* DW_CFA_advance_loc4 */ - .4byte .LCFI1-.LCFI0 - .byte 0xe /* DW_CFA_def_cfa_offset */ - .byte 0x8 /* uleb128 0x4 */ - .byte 0x4 /* DW_CFA_advance_loc4 */ - .4byte .LCFI2-.LCFI1 - .byte 0xe /* DW_CFA_def_cfa_offset */ - .byte 0xc /* uleb128 0x4 */ - .byte 0x4 /* DW_CFA_advance_loc4 */ - .4byte .LCFI3-.LCFI2 - .byte 0xe /* DW_CFA_def_cfa_offset */ - .byte 0x10 /* uleb128 0x4 */ - .byte 0x4 /* DW_CFA_advance_loc4 */ - .4byte .LCFI4-.LCFI3 - .byte 0xe /* DW_CFA_def_cfa_offset */ - .byte 0x14 /* uleb128 0x4 */ - .byte 0x4 /* DW_CFA_advance_loc4 */ - .4byte .LCFI5-.LCFI4 - .byte 0xe /* DW_CFA_def_cfa_offset */ - .byte 0x18 /* uleb128 0x4 */ - .byte 0x91 /* DW_CFA_offset, column 0x11 */ - .byte 0x6 /* uleb128 0x6 */ - .byte 0x8e /* DW_CFA_offset, column 0xe */ - .byte 0x5 /* uleb128 0x5 */ - .byte 0x8c /* DW_CFA_offset, column 0xc */ - .byte 0x4 /* uleb128 0x4 */ - .byte 0x8a /* DW_CFA_offset, column 0xa */ - .byte 0x3 /* uleb128 0x3 */ - .byte 0x89 /* DW_CFA_offset, column 0x9 */ - .byte 0x2 /* uleb128 0x2 */ - .byte 0x88 /* DW_CFA_offset, column 0x8 */ - .byte 0x1 /* uleb128 0x1 */ - .byte 0x4 /* DW_CFA_advance_loc4 */ - .4byte .LCFI6-.LCFI5 - .byte 0xd /* DW_CFA_def_cfa_register */ - .byte 0xe /* uleb128 0xe */ - .align 2 -.LEFDE1: - -.LSFDE3: - .4byte .LEFDE3-.LASFDE3 /* FDE Length */ -.LASFDE3: - .4byte .LASFDE3-__FRAME_BEGIN__ /* FDE CIE offset */ - .4byte .LFB2 /* FDE initial location */ - .4byte .LFE2-.LFB2 /* FDE address range */ - .byte 0x4 /* DW_CFA_advance_loc4 */ - .4byte .LCFI7-.LFB2 - .byte 0xe /* DW_CFA_def_cfa_offset */ - .byte 0x4 /* uleb128 0x4 */ - .byte 0x4 /* DW_CFA_advance_loc4 */ - .4byte .LCFI8-.LCFI7 - .byte 0xe /* DW_CFA_def_cfa_offset */ - .byte 0x8 /* uleb128 0x8 */ - .byte 0x4 /* DW_CFA_advance_loc4 */ - .4byte .LCFI9-.LCFI8 - .byte 0xe /* DW_CFA_def_cfa_offset */ -#if defined(__SH4__) - .byte 8+64 /* uleb128 8+64 */ -#else - .byte 8+32 /* uleb128 8+32 */ -#endif - .byte 0x91 /* DW_CFA_offset, column 0x11 */ - .byte 0x2 - .byte 0x8e /* DW_CFA_offset, column 0xe */ - .byte 0x1 - .byte 0x4 /* DW_CFA_advance_loc4 */ - .4byte .LCFIA-.LCFI9 - .byte 0xd /* DW_CFA_def_cfa_register */ - .byte 0xe /* uleb128 0xe */ - .align 2 -.LEFDE3: |