diff options
Diffstat (limited to 'libffi/src')
-rw-r--r-- | libffi/src/alpha/ffi.c | 199 | ||||
-rw-r--r-- | libffi/src/alpha/osf.S | 118 | ||||
-rw-r--r-- | libffi/src/arm/ffi.c | 185 | ||||
-rw-r--r-- | libffi/src/arm/sysv.S | 119 | ||||
-rw-r--r-- | libffi/src/debug.c | 67 | ||||
-rw-r--r-- | libffi/src/ffitest.c | 732 | ||||
-rw-r--r-- | libffi/src/ia64/ffi.c | 670 | ||||
-rw-r--r-- | libffi/src/ia64/ia64_flags.h | 62 | ||||
-rw-r--r-- | libffi/src/ia64/unix.S | 301 | ||||
-rw-r--r-- | libffi/src/java_raw_api.c | 271 | ||||
-rw-r--r-- | libffi/src/m68k/ffi.c | 184 | ||||
-rw-r--r-- | libffi/src/m68k/sysv.S | 96 | ||||
-rw-r--r-- | libffi/src/mips/ffi.c | 471 | ||||
-rw-r--r-- | libffi/src/mips/n32.S | 320 | ||||
-rw-r--r-- | libffi/src/mips/n32.s | 14 | ||||
-rw-r--r-- | libffi/src/mips/o32.S | 173 | ||||
-rw-r--r-- | libffi/src/mips/o32.s | 2 | ||||
-rw-r--r-- | libffi/src/powerpc/asm.h | 128 | ||||
-rw-r--r-- | libffi/src/powerpc/ffi.c | 423 | ||||
-rw-r--r-- | libffi/src/powerpc/sysv.S | 119 | ||||
-rw-r--r-- | libffi/src/prep_cif.c | 143 | ||||
-rw-r--r-- | libffi/src/raw_api.c | 242 | ||||
-rw-r--r-- | libffi/src/sparc/ffi.c | 216 | ||||
-rw-r--r-- | libffi/src/sparc/v8.S | 85 | ||||
-rw-r--r-- | libffi/src/types.c | 98 | ||||
-rw-r--r-- | libffi/src/x86/ffi.c | 510 | ||||
-rw-r--r-- | libffi/src/x86/sysv.S | 168 |
27 files changed, 0 insertions, 6116 deletions
diff --git a/libffi/src/alpha/ffi.c b/libffi/src/alpha/ffi.c deleted file mode 100644 index e3d807ab196..00000000000 --- a/libffi/src/alpha/ffi.c +++ /dev/null @@ -1,199 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1998 Cygnus Solutions - - Alpha Foreign Function Interface - - $Id: ffi.c,v 1.1.1.1 1998/11/29 16:48:16 green Exp $ - - 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> - -/* ffi_prep_args is called by the assembly routine once stack space - has been allocated for the function's arguments */ - -static void -ffi_prep_args(char *stack, extended_cif *ecif, int bytes, int flags) -{ - register long i, avn; - register void **p_argv; - register char *argp; - register ffi_type **p_arg; - - /* To streamline things in the assembly code, we always allocate 12 - words for loading up the int and fp argument registers. The layout - is as when processing varargs: the 6 fp args, the 6 int args, then - the incoming stack. ARGP points to the first int slot. */ - argp = stack + 6 * SIZEOF_ARG; - memset (stack, 0, 12 * SIZEOF_ARG); - - if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) - { - *(void **) argp = ecif->rvalue; - argp += sizeof(void *); - } - - i = 0; - avn = ecif->cif->nargs; - p_arg = ecif->cif->arg_types; - p_argv = ecif->avalue; - while (i < avn) - { - size_t z = ALIGN((*p_arg)->size, SIZEOF_ARG); - - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - *(SINT64 *) argp = *(SINT8 *)(* p_argv); - break; - - case FFI_TYPE_UINT8: - *(UINT64 *) argp = *(UINT8 *)(* p_argv); - break; - - case FFI_TYPE_SINT16: - *(SINT64 *) argp = *(SINT16 *)(* p_argv); - break; - - case FFI_TYPE_UINT16: - *(UINT64 *) argp = *(UINT16 *)(* p_argv); - break; - - case FFI_TYPE_SINT32: - *(SINT64 *) argp = *(SINT32 *)(* p_argv); - break; - - case FFI_TYPE_UINT32: - *(UINT64 *) argp = *(UINT32 *)(* p_argv); - break; - - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - case FFI_TYPE_POINTER: - *(UINT64 *) argp = *(UINT64 *)(* p_argv); - break; - - case FFI_TYPE_FLOAT: - if (argp - stack < 12 * SIZEOF_ARG) - { - /* Note the conversion -- all the fp regs are loaded as - doubles. The in-register format is the same. */ - *(double *) (argp - 6 * SIZEOF_ARG) = *(float *)(* p_argv); - } - else - *(float *) argp = *(float *)(* p_argv); - break; - - case FFI_TYPE_DOUBLE: - if (argp - stack < 12 * SIZEOF_ARG) - *(double *) (argp - 6 * SIZEOF_ARG) = *(double *)(* p_argv); - else - *(double *) argp = *(double *)(* p_argv); - break; - - case FFI_TYPE_STRUCT: - memcpy(argp, *p_argv, (*p_arg)->size); - break; - - default: - FFI_ASSERT(0); - } - - argp += z; - i++, p_arg++, p_argv++; - } -} - -/* Perform machine dependent cif processing */ -ffi_status -ffi_prep_cif_machdep(ffi_cif *cif) -{ - /* Adjust cif->bytes. to include 12 words for the temporary register - argument loading area. This will be removed before the call. */ - - cif->bytes += 6*SIZEOF_ARG; - if (cif->bytes < 12*SIZEOF_ARG) - cif->bytes = 12*SIZEOF_ARG; - - /* The stack must be double word aligned, so round bytes up - appropriately. */ - - cif->bytes = ALIGN(cif->bytes, 2*sizeof(void*)); - - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_VOID: - case FFI_TYPE_STRUCT: - cif->flags = cif->rtype->type; - break; - - case FFI_TYPE_FLOAT: - cif->flags = FFI_TYPE_FLOAT; - break; - - case FFI_TYPE_DOUBLE: - cif->flags = FFI_TYPE_DOUBLE; - break; - - default: - cif->flags = FFI_TYPE_INT; - break; - } - - return FFI_OK; -} - -extern int ffi_call_osf(void (*)(char *, extended_cif *, int, int), - extended_cif *, unsigned, - unsigned, unsigned *, void (*)()); - -void -ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, 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) - ecif.rvalue = alloca(cif->rtype->size); - else - ecif.rvalue = rvalue; - - switch (cif->abi) - { - case FFI_OSF: - ffi_call_osf(ffi_prep_args, &ecif, cif->bytes, - cif->flags, rvalue, fn); - break; - - default: - FFI_ASSERT(0); - break; - } -} diff --git a/libffi/src/alpha/osf.S b/libffi/src/alpha/osf.S deleted file mode 100644 index 2078683cfb3..00000000000 --- a/libffi/src/alpha/osf.S +++ /dev/null @@ -1,118 +0,0 @@ -/* ----------------------------------------------------------------------- - osf.S - Copyright (c) 1998 Cygnus Solutions - - Alpha/OSF Foreign Function Interface - - $Id: osf.S,v 1.1.1.1 1998/11/29 16:48:16 green Exp $ - - 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 <ffi.h> - -#define callback $16 -#define ecifp $17 -#define bytes $18 -#define flags $19 -#define raddr $20 -#define fn $21 - -#define flags_ofs 16 -#define raddr_ofs 24 -#define fn_ofs 32 - -#define SIZEOF_FRAME (6*8) - - .text - .align 4 - .globl ffi_call_osf - .ent ffi_call_osf - -ffi_call_osf: - lda $30, -SIZEOF_FRAME($30) - stq $26, 0($30) - stq $15, 8($30) - stq flags, flags_ofs($30) - stq raddr, raddr_ofs($30) - stq fn, fn_ofs($30) - mov $30, $15 - .frame $15, SIZEOF_FRAME, $26, 0 - .mask 0x4008000, -SIZEOF_FRAME - .prologue 0 - - mov callback, $27 # mov callback into place - subq $30, bytes, $30 # allocate stack space - - # Call ffi_prep_args; ecif, bytes and flags are already in place. - mov $30, $16 # push stack arg - jsr $26, ($27), 0 - - # Load up all of the (potential) argument registers. - ldt $f16, 0($30) - ldt $f17, 8($30) - ldt $f18, 16($30) - ldt $f19, 24($30) - ldt $f20, 32($30) - ldt $f21, 40($30) - ldq $16, 48($30) - ldq $17, 56($30) - ldq $18, 64($30) - ldq $19, 72($30) - ldq $20, 80($30) - ldq $21, 88($30) - - # Get rid of the arg reg temp space and call the function. - ldq $27, fn_ofs($15) - lda $30, 12*8($30) - jsr $26, ($27), 0 - - # If the return value pointer is NULL, assume no return value. - ldq raddr, raddr_ofs($15) - beq raddr, $noretval - - ldq flags, flags_ofs($15) - cmpeq flags, FFI_TYPE_INT, $1 - bne $1, $retint - cmpeq flags, FFI_TYPE_FLOAT, $2 - bne $2, $retfloat - cmpeq flags, FFI_TYPE_DOUBLE, $3 - bne $3, $retdouble - br $retstruct - - .align 3 -$retint: - stq $0, 0(raddr) - br $noretval -$retfloat: - sts $f0, 0(raddr) - br $noretval -$retdouble: - stt $f0, 0(raddr) - -$retstruct: -$noretval: - mov $15, $30 - ldq $26, 0($15) - ldq $15, 8($15) - lda $30, SIZEOF_FRAME($30) - ret - - .end ffi_call_osf diff --git a/libffi/src/arm/ffi.c b/libffi/src/arm/ffi.c deleted file mode 100644 index 5933c6bf9ff..00000000000 --- a/libffi/src/arm/ffi.c +++ /dev/null @@ -1,185 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1998 Cygnus Solutions - - ARM Foreign Function Interface - - $Id: ffi.c,v 1.1.1.1 1998/11/29 16:48:16 green Exp $ - - 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> - -/* 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; - - tmp = 0; - argp = stack; - - if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) { - *(void **) argp = ecif->rvalue; - argp += 4; - } - - avn = ecif->cif->nargs; - p_argv = ecif->avalue; - - for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; - (i != 0) && (avn != 0); - i--, p_arg++) - { - size_t z; - - /* Align if necessary */ - if (((*p_arg)->alignment - 1) & (unsigned) argp) { - argp = (char *) ALIGN(argp, (*p_arg)->alignment); - } - - if (avn != 0) - { - avn--; - 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: - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); - 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) -{ - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_VOID: - case FFI_TYPE_STRUCT: - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - cif->flags = (unsigned) cif->rtype->type; - break; - - default: - cif->flags = FFI_TYPE_INT; - 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; - } -} diff --git a/libffi/src/arm/sysv.S b/libffi/src/arm/sysv.S deleted file mode 100644 index 14230c4b25f..00000000000 --- a/libffi/src/arm/sysv.S +++ /dev/null @@ -1,119 +0,0 @@ -/* ----------------------------------------------------------------------- - sysv.S - Copyright (c) 1998 Cygnus Solutions - - ARM Foreign Function Interface - - $Id: sysv.S,v 1.1.1.1 1998/11/29 16:48:16 green Exp $ - - 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 <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 - -.text - - # a1: ffi_prep_args - # a2: &ecif - # a3: cif->bytes - # a4: fig->flags - # sp+0: ecif.rvalue - # sp+4: fn - - # This assumes we are using gas. -ENTRY(ffi_call_SYSV) - # Save registers - stmfd sp!, {a1-a4, fp, lr} - mov fp, sp - - # Make room for all of the new args. - sub sp, fp, a3 - - # Place all of the ffi_prep_args in position - mov ip, a1 - mov a1, sp - # a2 already set - - # And call - mov lr, pc - mov pc, ip - - # move first 4 parameters in registers - ldr a1, [sp, #0] - ldr a2, [sp, #4] - ldr a3, [sp, #8] - ldr a4, [sp, #12] - - # and adjust stack - ldr ip, [fp, #8] - cmp ip, #16 - movge ip, #16 - add sp, sp, ip - - # call function - mov lr, pc - ldr pc, [fp, #28] - - # Remove the space we pushed for the args - mov sp, fp - - # Load a3 with the pointer to storage for the return value - ldr a3, [sp, #24] - - # Load a4 with the return type code - ldr a4, [sp, #12] - - # If the return value pointer is NULL, assume no return value. - cmp a3, #0 - beq epilogue - -# return INT - cmp a4, #FFI_TYPE_INT - streq a1, [a3] - beq epilogue - -# return FLOAT - cmp a4, #FFI_TYPE_FLOAT - bne retdouble - stfs f0, [a3] - b epilogue - -# return DOUBLE or LONGDOUBLE -retdouble: - cmp a4, #FFI_TYPE_DOUBLE - bne epilogue - - stfs f0, [a3, #0] - stfs f1, [a3, #4] - b epilogue - -epilogue: - ldmfd sp!, {a1-a4, fp, pc} - -.ffi_call_SYSV_end: - .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV) - diff --git a/libffi/src/debug.c b/libffi/src/debug.c deleted file mode 100644 index bf925202131..00000000000 --- a/libffi/src/debug.c +++ /dev/null @@ -1,67 +0,0 @@ -/* ----------------------------------------------------------------------- - debug.c - Copyright (c) 1996 Cygnus Solutions - - $Id: debug.c,v 1.1.1.1 1998/11/29 16:48:16 green Exp $ - - 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> -#include <stdio.h> - -/* General debugging routines */ - -void ffi_stop_here(void) -{ - /* This function is only useful for debugging purposes. - Place a breakpoint on ffi_stop_here to be notified of - significant events. */ -} - -/* This function should only be called via the FFI_ASSERT() macro */ - -int ffi_assert(char *file, int line) -{ - fprintf(stderr, "ASSERTION FAILURE: %s line %d\n", file, line); - ffi_stop_here(); - abort(); - - /* This has to return something for the compiler not to complain */ - /*@notreached@*/ - return 0; -} - -/* Perform a sanity check on an ffi_type structure */ - -bool ffi_type_test(ffi_type *a) -{ - /*@-usedef@*/ - FFI_ASSERT(a->type <= FFI_TYPE_LAST); - FFI_ASSERT(a->type > FFI_TYPE_VOID ? a->size > 0 : 1); - FFI_ASSERT(a->type > FFI_TYPE_VOID ? a->alignment > 0 : 1); - FFI_ASSERT(a->type == FFI_TYPE_STRUCT ? a->elements != NULL : 1); - /*@=usedef@*/ - - /* This is a silly thing to return, but it keeps the compiler from - issuing warnings about "a" not being used in non-debug builds. */ - return (a != NULL); -} diff --git a/libffi/src/ffitest.c b/libffi/src/ffitest.c deleted file mode 100644 index 3dd0989783c..00000000000 --- a/libffi/src/ffitest.c +++ /dev/null @@ -1,732 +0,0 @@ -/* ----------------------------------------------------------------------- - ffitest.c - Copyright (c) 1996, 1997, 1998 Cygnus Solutions - - $Id: ffitest.c,v 1.1.1.1 1998/11/29 16:48:16 green Exp $ - - 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 <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <float.h> - -/* This is lame. Long double support is barely there under SunOS 4.x */ -#if defined(SPARC) && (SIZEOF_LONG_DOUBLE != 16) -#define BROKEN_LONG_DOUBLE -#endif - -#define CHECK(x) !(x) ? fail(__FILE__, __LINE__) : 0 - -static int fail(char *file, int line) -{ - fprintf(stderr, "Test failure: %s line %d\n", file, line); - exit(EXIT_FAILURE); - /*@notreached@*/ - return 0; -} - -#define MAX_ARGS 256 - -static size_t my_strlen(char *s) -{ - return (strlen(s)); -} - -static int promotion(signed char sc, signed short ss, - unsigned char uc, unsigned short us) -{ - int r = (int) sc + (int) ss + (int) uc + (int) us; - - return r; -} - -static signed char return_sc(signed char sc) -{ - return sc; -} - -static unsigned char return_uc(unsigned char uc) -{ - return uc; -} - -static long long return_ll(long long ll) -{ - return ll; -} - -static int floating(int a, float b, double c, long double d, int e) -{ - int i; - -#if 0 - /* This is ifdef'd out for now. long double support under SunOS/gcc - is pretty much non-existent. You'll get the odd bus error in library - routines like printf(). */ - printf("%d %f %f %Lf %d\n", a, (double)b, c, d, e); -#endif - - i = (int) ((float)a/b + ((float)c/(float)d)); - - return i; -} - -static float many(float f1, - float f2, - float f3, - float f4, - float f5, - float f6, - float f7, - float f8, - float f9, - float f10, - float f11, - float f12, - float f13) -{ -#if 0 - printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n", - (double) f1, (double) f2, (double) f3, (double) f4, (double) f5, - (double) f6, (double) f7, (double) f8, (double) f9, (double) f10, - (double) f11, (double) f12, (double) f13); -#endif - - return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13); -} - -static double dblit(float f) -{ - return f/3.0; -} - -static long double ldblit(float f) -{ - return (long double) (((long double) f)/ (long double) 3.0); -} - -typedef struct -{ - unsigned char uc; - double d; - unsigned int ui; -} test_structure_1; - -typedef struct -{ - double d1; - double d2; -} test_structure_2; - -typedef struct -{ - int si; -} test_structure_3; - -typedef struct -{ - unsigned ui1; - unsigned ui2; - unsigned ui3; -} test_structure_4; - -typedef struct -{ - char c1; - char c2; -} test_structure_5; - -static test_structure_1 struct1(test_structure_1 ts) -{ - /*@-type@*/ - ts.uc++; - /*@=type@*/ - ts.d--; - ts.ui++; - - return ts; -} - -static test_structure_2 struct2(test_structure_2 ts) -{ - ts.d1--; - ts.d2--; - - return ts; -} - -static test_structure_3 struct3(test_structure_3 ts) -{ - ts.si = -(ts.si*2); - - return ts; -} - -static test_structure_4 struct4(test_structure_4 ts) -{ - ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3; - - return ts; -} - -static test_structure_5 struct5(test_structure_5 ts1, test_structure_5 ts2) -{ - ts1.c1 += ts2.c1; - ts1.c2 -= ts2.c2; - - return ts1; -} - -/* Take an int and a float argument, together with int userdata, and */ -/* return the sum. */ -static void closure_test_fn(ffi_cif* cif,void* resp,void** args, void* userdata) -{ - *(int*)resp = - *(int *)args[0] + (int)(*(float *)args[1]) + (int)(long)userdata; -} - -typedef int (*closure_test_type)(int, float); - -int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[]) -{ - ffi_cif cif; - ffi_type *args[MAX_ARGS]; - void *values[MAX_ARGS]; - char *s; - signed char sc; - unsigned char uc; - signed short ss; - unsigned short us; - unsigned long ul; - long long ll; - float f; - double d; - long double ld; - signed int si1; - signed int si2; - -#if defined(ALPHA) || defined(IA64) || (defined(MIPS) && (_MIPS_SIM == _ABIN32)) - long long rint; -#else - int rint; -#endif - long long rlonglong; - - ffi_type ts1_type; - ffi_type ts2_type; - ffi_type ts3_type; - ffi_type ts4_type; - ffi_type ts5_type; - ffi_type *ts1_type_elements[4]; - ffi_type *ts2_type_elements[3]; - ffi_type *ts3_type_elements[2]; - ffi_type *ts4_type_elements[4]; - ffi_type *ts5_type_elements[3]; - - ts1_type.size = 0; - ts1_type.alignment = 0; - ts1_type.type = FFI_TYPE_STRUCT; - - ts2_type.size = 0; - ts2_type.alignment = 0; - ts2_type.type = FFI_TYPE_STRUCT; - - ts3_type.size = 0; - ts3_type.alignment = 0; - ts3_type.type = FFI_TYPE_STRUCT; - - ts4_type.size = 0; - ts4_type.alignment = 0; - ts4_type.type = FFI_TYPE_STRUCT; - - ts5_type.size = 0; - ts5_type.alignment = 0; - ts5_type.type = FFI_TYPE_STRUCT; - - /*@-immediatetrans@*/ - ts1_type.elements = ts1_type_elements; - ts2_type.elements = ts2_type_elements; - ts3_type.elements = ts3_type_elements; - ts4_type.elements = ts4_type_elements; - ts5_type.elements = ts5_type_elements; - /*@=immediatetrans@*/ - - ts1_type_elements[0] = &ffi_type_uchar; - ts1_type_elements[1] = &ffi_type_double; - ts1_type_elements[2] = &ffi_type_uint; - ts1_type_elements[3] = NULL; - - ts2_type_elements[0] = &ffi_type_double; - ts2_type_elements[1] = &ffi_type_double; - ts2_type_elements[2] = NULL; - - ts3_type_elements[0] = &ffi_type_sint; - ts3_type_elements[1] = NULL; - - ts4_type_elements[0] = &ffi_type_uint; - ts4_type_elements[1] = &ffi_type_uint; - ts4_type_elements[2] = &ffi_type_uint; - ts4_type_elements[3] = NULL; - - ts5_type_elements[0] = &ffi_type_schar; - ts5_type_elements[1] = &ffi_type_schar; - ts5_type_elements[2] = NULL; - - ul = 0; - - /* return value tests */ - { -#if defined(MIPS) || defined(SPARC) /* || defined(ARM) */ - puts ("long long tests not run. This is a known bug on this architecture."); -#else - args[0] = &ffi_type_sint64; - values[0] = ≪ - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_sint64, args) == FFI_OK); - - for (ll = 0LL; ll < 100LL; ll++) - { - ul++; - ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values); - CHECK(rlonglong == ll); - } - - for (ll = 55555555555000LL; ll < 55555555555100LL; ll++) - { - ul++; - ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values); - CHECK(rlonglong == ll); - } -#endif - - args[0] = &ffi_type_schar; - values[0] = ≻ - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_schar, args) == FFI_OK); - - for (sc = (signed char) -127; - sc < (signed char) 127; /*@-type@*/ sc++ /*@=type@*/) - { - ul++; - ffi_call(&cif, FFI_FN(return_sc), &rint, values); - CHECK(rint == (int) sc); - } - - args[0] = &ffi_type_uchar; - values[0] = &uc; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_uchar, args) == FFI_OK); - - for (uc = (unsigned char) '\x00'; - uc < (unsigned char) '\xff'; /*@-type@*/ uc++ /*@=type@*/) - { - ul++; - ffi_call(&cif, FFI_FN(return_uc), &rint, values); - CHECK(rint == (signed int) uc); - } - - printf("%lu return value tests run\n", ul); - } - -#ifdef BROKEN_LONG_DOUBLE - printf ("This architecture has broken `long double' support. No floating point\ntests have been run.\n"); -#else - /* float arg tests */ - { - args[0] = &ffi_type_float; - values[0] = &f; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_longdouble, args) == FFI_OK); - - f = 3.14159; - -#if 0 - /* This is ifdef'd out for now. long double support under SunOS/gcc - is pretty much non-existent. You'll get the odd bus error in library - routines like printf(). */ - printf ("%Lf\n", ldblit(f)); -#endif - ld = 666; - ffi_call(&cif, FFI_FN(ldblit), &ld, values); - -#if 0 - /* This is ifdef'd out for now. long double support under SunOS/gcc - is pretty much non-existent. You'll get the odd bus error in library - routines like printf(). */ - printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON); -#endif - - /* These are not always the same!! Check for a reasonable delta */ - /*@-realcompare@*/ - if (ld - ldblit(f) < LDBL_EPSILON) - /*@=realcompare@*/ - puts("long double return value tests ok!"); - else - CHECK(0); - } - - /* float arg tests */ - { - args[0] = &ffi_type_sint; - values[0] = &si1; - args[1] = &ffi_type_float; - values[1] = &f; - args[2] = &ffi_type_double; - values[2] = &d; - args[3] = &ffi_type_longdouble; - values[3] = &ld; - args[4] = &ffi_type_sint; - values[4] = &si2; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 5, - &ffi_type_sint, args) == FFI_OK); - - si1 = 6; - f = 3.14159; - d = (double)1.0/(double)3.0; - ld = 2.71828182846L; - si2 = 10; - - floating (si1, f, d, ld, si2); - - ffi_call(&cif, FFI_FN(floating), &rint, values); - - printf ("%d vs %d\n", rint, floating (si1, f, d, ld, si2)); - - CHECK(rint == floating(si1, f, d, ld, si2)); - - printf("float arg tests ok!\n"); - } -#endif - - /* strlen tests */ - { - args[0] = &ffi_type_pointer; - values[0] = (void*) &s; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_sint, args) == FFI_OK); - - s = "a"; - ffi_call(&cif, FFI_FN(my_strlen), &rint, values); - CHECK(rint == 1); - - s = "1234567"; - ffi_call(&cif, FFI_FN(my_strlen), &rint, values); - CHECK(rint == 7); - - s = "1234567890123456789012345"; - ffi_call(&cif, FFI_FN(my_strlen), &rint, values); - CHECK(rint == 25); - - printf("strlen tests passed\n"); - } - - /* float arg tests */ - { - args[0] = &ffi_type_float; - values[0] = &f; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_double, args) == FFI_OK); - - f = 3.14159; - - ffi_call(&cif, FFI_FN(dblit), &d, values); - - /* These are not always the same!! Check for a reasonable delta */ - /*@-realcompare@*/ - CHECK(d - dblit(f) < DBL_EPSILON); - /*@=realcompare@*/ - - printf("double return value tests ok!\n"); - } - - /* many arg tests */ - { - float ff; - float fa[13]; - - for (ul = 0; ul < 13; ul++) - { - args[ul] = &ffi_type_float; - values[ul] = &fa[ul]; - fa[ul] = (float) ul; - } - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, - &ffi_type_float, args) == FFI_OK); - - /*@-usedef@*/ - ff = many(fa[0], fa[1], - fa[2], fa[3], - fa[4], fa[5], - fa[6], fa[7], - fa[8], fa[9], - fa[10],fa[11],fa[12]); - /*@=usedef@*/ - - ffi_call(&cif, FFI_FN(many), &f, values); - - /*@-realcompare@*/ - if (f - ff < FLT_EPSILON) - /*@=realcompare@*/ - printf("many arg tests ok!\n"); - else -#ifdef POWERPC - printf("many arg tests failed! This is a gcc bug.\n"); -#else - CHECK(0); -#endif - } - - /* promotion tests */ - { - args[0] = &ffi_type_schar; - args[1] = &ffi_type_sshort; - args[2] = &ffi_type_uchar; - args[3] = &ffi_type_ushort; - values[0] = ≻ - values[1] = &ss; - values[2] = &uc; - values[3] = &us; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, - &ffi_type_sint, args) == FFI_OK); - - us = 0; - ul = 0; - - for (sc = (signed char) -127; - sc <= (signed char) 120; /*@-type@*/ sc += 1 /*@=type@*/) - for (ss = -30000; ss <= 30000; ss += 10000) - for (uc = (unsigned char) 0; - uc <= (unsigned char) 200; /*@-type@*/ uc += 20 /*@=type@*/) - for (us = 0; us <= 60000; us += 10000) - { - ul++; - ffi_call(&cif, FFI_FN(promotion), &rint, values); - CHECK(rint == (int) sc + (int) ss + (int) uc + (int) us); - } - printf("%lu promotion tests run\n", ul); - } - - /* struct tests */ - { - test_structure_1 ts1_arg; - /* This is a hack to get a properly aligned result buffer */ - test_structure_1 *ts1_result = - (test_structure_1 *) malloc (sizeof(test_structure_1)); - - args[0] = &ts1_type; - values[0] = &ts1_arg; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ts1_type, args) == FFI_OK); - - ts1_arg.uc = '\x01'; - ts1_arg.d = 3.14159; - ts1_arg.ui = 555; - - ffi_call(&cif, FFI_FN(struct1), ts1_result, values); - - CHECK(ts1_result->ui == 556); - CHECK(ts1_result->d == 3.14159 - 1); - - puts ("structure test 1 ok!\n"); - - free (ts1_result); - } - - /* struct tests */ - { - test_structure_2 ts2_arg; - - /* This is a hack to get a properly aligned result buffer */ - test_structure_2 *ts2_result = - (test_structure_2 *) malloc (sizeof(test_structure_2)); - - args[0] = &ts2_type; - values[0] = &ts2_arg; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ts2_type, args) == FFI_OK); - - ts2_arg.d1 = 5.55; - ts2_arg.d2 = 6.66; - - printf ("%g\n", ts2_result->d1); - printf ("%g\n", ts2_result->d2); - - ffi_call(&cif, FFI_FN(struct2), ts2_result, values); - - printf ("%g\n", ts2_result->d1); - printf ("%g\n", ts2_result->d2); - - CHECK(ts2_result->d1 == 5.55 - 1); - CHECK(ts2_result->d2 == 6.66 - 1); - - printf("structure test 2 ok!\n"); - - free (ts2_result); - } - - /* struct tests */ - { - int compare_value; - test_structure_3 ts3_arg; - test_structure_3 *ts3_result = - (test_structure_3 *) malloc (sizeof(test_structure_3)); - - args[0] = &ts3_type; - values[0] = &ts3_arg; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ts3_type, args) == FFI_OK); - - ts3_arg.si = -123; - compare_value = ts3_arg.si; - - ffi_call(&cif, FFI_FN(struct3), ts3_result, values); - - printf ("%d %d\n", ts3_result->si, -(compare_value*2)); - - if (ts3_result->si == -(ts3_arg.si*2)) - puts ("structure test 3 ok!"); - else - { - puts ("Structure test 3 found structure passing bug."); - puts (" Current versions of GCC are not 100% compliant with the"); - puts (" n32 ABI. There is a known problem related to passing"); - puts (" small structures. Send a bug report to the gcc maintainers."); - } - - free (ts3_result); - } - - /* struct tests */ - { - test_structure_4 ts4_arg; - - /* This is a hack to get a properly aligned result buffer */ - test_structure_4 *ts4_result = - (test_structure_4 *) malloc (sizeof(test_structure_4)); - - args[0] = &ts4_type; - values[0] = &ts4_arg; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ts4_type, args) == FFI_OK); - - ts4_arg.ui1 = 2; - ts4_arg.ui2 = 3; - ts4_arg.ui3 = 4; - - ffi_call (&cif, FFI_FN(struct4), ts4_result, values); - - if (ts4_result->ui3 == 2U * 3U * 4U) - puts ("structure test 4 ok!"); - else - puts ("Structure test 4 found GCC's structure passing bug."); - - free (ts4_result); - } - - /* struct tests */ - { - test_structure_5 ts5_arg1, ts5_arg2; - - /* This is a hack to get a properly aligned result buffer */ - test_structure_5 *ts5_result = - (test_structure_5 *) malloc (sizeof(test_structure_5)); - - args[0] = &ts5_type; - args[1] = &ts5_type; - values[0] = &ts5_arg1; - values[1] = &ts5_arg2; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, - &ts5_type, args) == FFI_OK); - - ts5_arg1.c1 = 2; - ts5_arg1.c2 = 6; - ts5_arg2.c1 = 5; - ts5_arg2.c2 = 3; - - ffi_call (&cif, FFI_FN(struct5), ts5_result, values); - - if (ts5_result->c1 == 7 - && ts5_result->c2 == 3) - puts ("structure test 5 ok!"); - else - puts ("Structure test 5 found GCC's structure passing bug."); - - free (ts5_result); - } - -# if FFI_CLOSURES - /* A simple closure test */ - { - ffi_closure cl; - ffi_type * cl_arg_types[3]; - - cl_arg_types[0] = &ffi_type_sint; - cl_arg_types[1] = &ffi_type_float; - cl_arg_types[2] = NULL; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, - &ffi_type_sint, cl_arg_types) == FFI_OK); - - CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn, - (void *) 3 /* userdata */) - == FFI_OK); - CHECK((*((closure_test_type)(&cl)))(1, 2.0) == 6); - } -# endif - - /* If we arrived here, all is good */ - (void) puts("\nLooks good. No surprises.\n"); - - /*@-compdestroy@*/ - - return 0; -} - diff --git a/libffi/src/ia64/ffi.c b/libffi/src/ia64/ffi.c deleted file mode 100644 index bb4fbb73a72..00000000000 --- a/libffi/src/ia64/ffi.c +++ /dev/null @@ -1,670 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1998 Cygnus Solutions - Copyright (c) 2000 Hewlett Packard Company - - IA64 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> - -#include "ia64_flags.h" - -/* Memory image of fp register contents. Should eventually be an fp */ -/* type long enough to hold an entire register. For now we use double. */ -typedef double float80; - -/* The stack layout at call to ffi_prep_regs. Other_args will remain */ -/* on the stack for the actual call. Everything else we be transferred */ -/* to registers and popped by the assembly code. */ - -struct ia64_args { - long scratch[2]; /* Two scratch words at top of stack. */ - /* Allows sp to passed as arg pointer. */ - void * r8_contents; /* Value to be passed in r8 */ - long spare; /* Not used. */ - float80 fp_regs[8]; /* Contents of 8 floating point argument */ - /* registers. */ - long out_regs[8]; /* Contents of the 8 out registers used */ - /* for integer parameters. */ - long other_args[0]; /* Arguments passed on stack, variable size */ - /* Treated as continuation of out_regs. */ -}; - -static size_t float_type_size(unsigned short tp) -{ - switch(tp) { - case FFI_TYPE_FLOAT: - return sizeof(float); - case FFI_TYPE_DOUBLE: - return sizeof(double); -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - return sizeof(long double); -#endif - default: - FFI_ASSERT(0); - } -} - -/* - * Is type a struct containing at most n floats, doubles, or extended - * doubles, all of the same fp type? - * If so, set *element_type to the fp type. - */ -static bool is_homogeneous_fp_aggregate(ffi_type * type, int n, - unsigned short * element_type) -{ - ffi_type **ptr; - unsigned short element, struct_element; - - int type_set = 0; - - FFI_ASSERT(type != NULL); - - FFI_ASSERT(type->elements != NULL); - - ptr = &(type->elements[0]); - - while ((*ptr) != NULL) - { - switch((*ptr) -> type) { - case FFI_TYPE_FLOAT: - if (type_set && element != FFI_TYPE_FLOAT) return 0; - if (--n < 0) return FALSE; - type_set = 1; - element = FFI_TYPE_FLOAT; - break; - case FFI_TYPE_DOUBLE: - if (type_set && element != FFI_TYPE_DOUBLE) return 0; - if (--n < 0) return FALSE; - type_set = 1; - element = FFI_TYPE_DOUBLE; - break; - case FFI_TYPE_STRUCT: - if (!is_homogeneous_fp_aggregate(type, n, &struct_element)) - return FALSE; - if (type_set && struct_element != element) return FALSE; - n -= (type -> size)/float_type_size(element); - element = struct_element; - if (n < 0) return FALSE; - break; - /* case FFI_TYPE_LONGDOUBLE: - Not yet implemented. */ - default: - return FALSE; - } - ptr++; - } - *element_type = element; - return TRUE; - -} - -/* ffi_prep_args is called by the assembly routine once stack space - has been allocated for the function's arguments. Returns nonzero - if fp registers are used for arguments. */ - -static bool -ffi_prep_args(struct ia64_args *stack, extended_cif *ecif, int bytes) -{ - register long i, avn; - register void **p_argv; - register long *argp = stack -> out_regs; - register float80 *fp_argp = stack -> fp_regs; - register ffi_type **p_arg; - - /* For big return structs, r8 needs to contain the target address. */ - /* Since r8 is otherwise dead, we set it unconditionally. */ - stack -> r8_contents = ecif -> rvalue; - i = 0; - avn = ecif->cif->nargs; - p_arg = ecif->cif->arg_types; - p_argv = ecif->avalue; - while (i < avn) - { - size_t z; /* z is in units of arg slots or words, not bytes. */ - - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - z = 1; - *(SINT64 *) argp = *(SINT8 *)(* p_argv); - break; - - case FFI_TYPE_UINT8: - z = 1; - *(UINT64 *) argp = *(UINT8 *)(* p_argv); - break; - - case FFI_TYPE_SINT16: - z = 1; - *(SINT64 *) argp = *(SINT16 *)(* p_argv); - break; - - case FFI_TYPE_UINT16: - z = 1; - *(UINT64 *) argp = *(UINT16 *)(* p_argv); - break; - - case FFI_TYPE_SINT32: - z = 1; - *(SINT64 *) argp = *(SINT32 *)(* p_argv); - break; - - case FFI_TYPE_UINT32: - z = 1; - *(UINT64 *) argp = *(UINT32 *)(* p_argv); - break; - - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - case FFI_TYPE_POINTER: - z = 1; - *(UINT64 *) argp = *(UINT64 *)(* p_argv); - break; - - case FFI_TYPE_FLOAT: - z = 1; - if (fp_argp - stack->fp_regs < 8) - { - /* Note the conversion -- all the fp regs are loaded as - doubles. */ - *fp_argp++ = *(float *)(* p_argv); - } - /* Also put it into the integer registers or memory: */ - *(UINT64 *) argp = *(UINT32 *)(* p_argv); - break; - - case FFI_TYPE_DOUBLE: - z = 1; - if (fp_argp - stack->fp_regs < 8) - *fp_argp++ = *(double *)(* p_argv); - /* Also put it into the integer registers or memory: */ - *(double *) argp = *(double *)(* p_argv); - break; - - case FFI_TYPE_STRUCT: - { - size_t sz = (*p_arg)->size; - unsigned short element_type; - z = ((*p_arg)->size + SIZEOF_ARG - 1)/SIZEOF_ARG; - if (is_homogeneous_fp_aggregate(*p_arg, 8, &element_type)) { - int i; - int nelements = sz/float_type_size(element_type); - for (i = 0; i < nelements; ++i) { - switch (element_type) { - case FFI_TYPE_FLOAT: - if (fp_argp - stack->fp_regs < 8) - *fp_argp++ = ((float *)(* p_argv))[i]; - break; - case FFI_TYPE_DOUBLE: - if (fp_argp - stack->fp_regs < 8) - *fp_argp++ = ((double *)(* p_argv))[i]; - break; - default: - /* Extended precision not yet implemented. */ - abort(); - } - } - } - /* And pass it in integer registers as a struct, with */ - /* its actual field sizes packed into registers. */ - memcpy(argp, *p_argv, (*p_arg)->size); - } - break; - - default: - FFI_ASSERT(0); - } - - argp += z; - i++, p_arg++, p_argv++; - } - return (fp_argp != stack -> fp_regs); -} - -/* Perform machine dependent cif processing */ -ffi_status -ffi_prep_cif_machdep(ffi_cif *cif) -{ - long i, avn; - bool is_simple = TRUE; - long simple_flag = FFI_SIMPLE_V; - /* Adjust cif->bytes to include space for the 2 scratch words, - r8 register contents, spare word, - the 8 fp register contents, and all 8 integer register contents. - This will be removed before the call, though 2 scratch words must - remain. */ - - cif->bytes += 4*sizeof(long) + 8 *sizeof(float80); - if (cif->bytes < sizeof(struct ia64_args)) - cif->bytes = sizeof(struct ia64_args); - - /* The stack must be double word aligned, so round bytes up - appropriately. */ - - cif->bytes = ALIGN(cif->bytes, 2*sizeof(void*)); - - avn = cif->nargs; - if (avn <= 2) { - for (i = 0; i < avn; ++i) { - switch(cif -> arg_types[i] -> type) { - case FFI_TYPE_SINT32: - simple_flag = FFI_ADD_INT_ARG(simple_flag); - break; - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - case FFI_TYPE_POINTER: - simple_flag = FFI_ADD_LONG_ARG(simple_flag); - break; - default: - is_simple = FALSE; - } - } - } else { - is_simple = FALSE; - } - - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_VOID: - cif->flags = FFI_TYPE_VOID; - break; - - case FFI_TYPE_STRUCT: - { - size_t sz = cif -> rtype -> size; - unsigned short element_type; - - is_simple = FALSE; - if (is_homogeneous_fp_aggregate(cif -> rtype, 8, &element_type)) { - int nelements = sz/float_type_size(element_type); - if (nelements <= 1) { - if (0 == nelements) { - cif -> flags = FFI_TYPE_VOID; - } else { - cif -> flags = element_type; - } - } else { - switch(element_type) { - case FFI_TYPE_FLOAT: - cif -> flags = FFI_IS_FLOAT_FP_AGGREGATE | nelements; - break; - case FFI_TYPE_DOUBLE: - cif -> flags = FFI_IS_DOUBLE_FP_AGGREGATE | nelements; - break; - default: - /* long double NYI */ - abort(); - } - } - break; - } - if (sz <= 32) { - if (sz <= 8) { - cif->flags = FFI_TYPE_INT; - } else if (sz <= 16) { - cif->flags = FFI_IS_SMALL_STRUCT2; - } else if (sz <= 24) { - cif->flags = FFI_IS_SMALL_STRUCT3; - } else { - cif->flags = FFI_IS_SMALL_STRUCT4; - } - } else { - cif->flags = FFI_TYPE_STRUCT; - } - } - break; - - case FFI_TYPE_FLOAT: - is_simple = FALSE; - cif->flags = FFI_TYPE_FLOAT; - break; - - case FFI_TYPE_DOUBLE: - is_simple = FALSE; - cif->flags = FFI_TYPE_DOUBLE; - break; - - default: - cif->flags = FFI_TYPE_INT; - /* This seems to depend on little endian mode, and the fact that */ - /* the return pointer always points to at least 8 bytes. But */ - /* that also seems to be true for other platforms. */ - break; - } - - if (is_simple) cif -> flags |= simple_flag; - return FFI_OK; -} - -extern int ffi_call_unix(bool (*)(struct ia64_args *, extended_cif *, int), - extended_cif *, unsigned, - unsigned, unsigned *, void (*)()); - -void -ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) -{ - extended_cif ecif; - long simple = cif -> flags & FFI_SIMPLE; - - /* Should this also check for Unix ABI? */ - /* This is almost, but not quite, machine independent. Note that */ - /* we can get away with not caring about length of the result because */ - /* we assume we are little endian, and the result buffer is large */ - /* enough. */ - /* This needs work for HP/UX. */ - if (simple) { - long (*lfn)() = (long (*)())fn; - long result; - switch(simple) { - case FFI_SIMPLE_V: - result = lfn(); - break; - case FFI_SIMPLE_I: - result = lfn(*(int *)avalue[0]); - break; - case FFI_SIMPLE_L: - result = lfn(*(long *)avalue[0]); - break; - case FFI_SIMPLE_II: - result = lfn(*(int *)avalue[0], *(int *)avalue[1]); - break; - case FFI_SIMPLE_IL: - result = lfn(*(int *)avalue[0], *(long *)avalue[1]); - break; - case FFI_SIMPLE_LI: - result = lfn(*(long *)avalue[0], *(int *)avalue[1]); - break; - case FFI_SIMPLE_LL: - result = lfn(*(long *)avalue[0], *(long *)avalue[1]); - break; - } - if ((cif->flags & ~FFI_SIMPLE) != FFI_TYPE_VOID && 0 != rvalue) { - * (long *)rvalue = result; - } - return; - } - 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) - ecif.rvalue = alloca(cif->rtype->size); - else - ecif.rvalue = rvalue; - - switch (cif->abi) - { - case FFI_UNIX: - ffi_call_unix(ffi_prep_args, &ecif, cif->bytes, - cif->flags, rvalue, fn); - break; - - default: - FFI_ASSERT(0); - break; - } -} - -/* - * Closures represent a pair consisting of a function pointer, and - * some user data. A closure is invoked by reinterpreting the closure - * as a function pointer, and branching to it. Thus we can make an - * interpreted function callable as a C function: We turn the interpreter - * itself, together with a pointer specifying the interpreted procedure, - * into a closure. - * On X86, the first few words of the closure structure actually contain code, - * which will do the right thing. On most other architectures, this - * would raise some Icache/Dcache coherence issues (which can be solved, but - * often not cheaply). - * For IA64, function pointer are already pairs consisting of a code - * pointer, and a gp pointer. The latter is needed to access global variables. - * Here we set up such a pair as the first two words of the closure (in - * the "trampoline" area), but we replace the gp pointer with a pointer - * to the closure itself. We also add the real gp pointer to the - * closure. This allows the function entry code to both retrieve the - * user data, and to restire the correct gp pointer. - */ - -static void -ffi_prep_incoming_args_UNIX(struct ia64_args *args, void **rvalue, - void **avalue, ffi_cif *cif); - -/* This function is entered with the doctored gp (r1) value. - * This code is extremely gcc specific. There is some argument that - * it should really be written in assembly code, since it depends on - * gcc properties that might change over time. - */ - -/* ffi_closure_UNIX is an assembly routine, which copies the register */ -/* state into s struct ia64_args, and the invokes */ -/* ffi_closure_UNIX_inner. It also recovers the closure pointer */ -/* from its fake gp pointer. */ -void ffi_closure_UNIX(); - -#ifndef __GNUC__ -# error This requires gcc -#endif -void -ffi_closure_UNIX_inner (ffi_closure *closure, struct ia64_args * args) -/* Hopefully declarint this as a varargs function will force all args */ -/* to memory. */ -{ - // this is our return value storage - long double res; - - // our various things... - ffi_cif *cif; - unsigned short rtype; - void *resp; - void **arg_area; - - resp = (void*)&res; - 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_UNIX(args, (void**)&resp, arg_area, cif); - - (closure->fun) (cif, resp, arg_area, closure->user_data); - - rtype = cif->flags; - - /* now, do a generic return based on the value of rtype */ - if (rtype == FFI_TYPE_INT) - { - asm volatile ("ld8 r8=[%0]" : : "r" (resp) : "r8"); - } - else if (rtype == FFI_TYPE_FLOAT) - { - asm volatile ("ldfs f8=[%0]" : : "r" (resp) : "f8"); - } - else if (rtype == FFI_TYPE_DOUBLE) - { - asm volatile ("ldfd f8=[%0]" : : "r" (resp) : "f8"); - } - else if (rtype == FFI_IS_SMALL_STRUCT2) - { - asm volatile ("ld8 r8=[%0]; ld8 r9=[%1]" - : : "r" (resp), "r" (resp+8) : "r8","r9"); - } - else if (rtype == FFI_IS_SMALL_STRUCT3) - { - asm volatile ("ld8 r8=[%0]; ld8 r9=[%1]; ld8 r10=[%2]" - : : "r" (resp), "r" (resp+8), "r" (resp+16) - : "r8","r9","r10"); - } - else if (rtype == FFI_IS_SMALL_STRUCT4) - { - asm volatile ("ld8 r8=[%0]; ld8 r9=[%1]; ld8 r10=[%2]; ld8 r11=[%3]" - : : "r" (resp), "r" (resp+8), "r" (resp+16), "r" (resp+24) - : "r8","r9","r10","r11"); - } - else if (rtype != FFI_TYPE_VOID && rtype != FFI_TYPE_STRUCT) - { - /* Can only happen for homogeneous FP aggregates? */ - abort(); - } -} - -static void -ffi_prep_incoming_args_UNIX(struct ia64_args *args, void **rvalue, - void **avalue, ffi_cif *cif) -{ - register unsigned int i; - register unsigned int avn; - register void **p_argv; - register unsigned long *argp = args -> out_regs; - unsigned fp_reg_num = 0; - register ffi_type **p_arg; - - avn = cif->nargs; - p_argv = avalue; - - for (i = cif->nargs, p_arg = cif->arg_types; i != 0; i--, p_arg++) - { - size_t z; /* In units of words or argument slots. */ - - switch ((*p_arg)->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: - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - case FFI_TYPE_POINTER: - z = 1; - *p_argv = (void *)argp; - break; - - case FFI_TYPE_FLOAT: - z = 1; - /* Convert argument back to float in place from the saved value */ - if (fp_reg_num < 8) { - *(float *)argp = args -> fp_regs[fp_reg_num++]; - } else { - *(float *)argp = *(double *)argp; - } - *p_argv = (void *)argp; - break; - - case FFI_TYPE_DOUBLE: - z = 1; - if (fp_reg_num < 8) { - *p_argv = args -> fp_regs + fp_reg_num++; - } else { - *p_argv = (void *)argp; - } - break; - - case FFI_TYPE_STRUCT: - { - size_t sz = (*p_arg)->size; - unsigned short element_type; - z = ((*p_arg)->size + SIZEOF_ARG - 1)/SIZEOF_ARG; - if (is_homogeneous_fp_aggregate(*p_arg, 8, &element_type)) { - int nelements = sz/float_type_size(element_type); - if (nelements + fp_reg_num >= 8) { - /* hard case NYI. */ - abort(); - } - if (element_type == FFI_TYPE_DOUBLE) { - *p_argv = args -> fp_regs + fp_reg_num; - fp_reg_num += nelements; - break; - } - if (element_type == FFI_TYPE_FLOAT) { - int j; - for (j = 0; j < nelements; ++ j) { - ((float *)argp)[j] = args -> fp_regs[fp_reg_num + j]; - } - *p_argv = (void *)argp; - fp_reg_num += nelements; - break; - } - abort(); /* Other fp types NYI */ - } - } - break; - - default: - FFI_ASSERT(0); - } - - argp += z; - p_argv++; - - } - - return; -} - - -/* Fill in a closure to refer to the specified fun and user_data. */ -/* cif specifies the argument and result types for fun. */ -/* the cif must already be prep'ed */ - -/* The layout of a function descriptor. A C function pointer really */ -/* points to one of these. */ -typedef struct ia64_fd_struct { - void *code_pointer; - void *gp; -} ia64_fd; - -ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data) -{ - struct ffi_ia64_trampoline_struct *tramp = - (struct ffi_ia64_trampoline_struct *) (closure -> tramp); - ia64_fd *fd = (ia64_fd *)(void *)ffi_closure_UNIX; - - FFI_ASSERT (cif->abi == FFI_UNIX); - - tramp -> code_pointer = fd -> code_pointer; - tramp -> real_gp = fd -> gp; - tramp -> fake_gp = closure; - closure->cif = cif; - closure->user_data = user_data; - closure->fun = fun; - - return FFI_OK; -} - - diff --git a/libffi/src/ia64/ia64_flags.h b/libffi/src/ia64/ia64_flags.h deleted file mode 100644 index 23dbd3e0237..00000000000 --- a/libffi/src/ia64/ia64_flags.h +++ /dev/null @@ -1,62 +0,0 @@ -/* ----------------------------------------------------------------------- - ia64_flags.h - Copyright (c) 2000 Hewlett Packard Company - - IA64/unix Foreign Function Interface - - Original author: Hans Boehm, HP Labs - - 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. - ----------------------------------------------------------------------- */ - - -/* Homogeneous Floating Point Aggregates (HFAs) which are returned */ -/* in FP registers. The least significant bits specify the size in */ -/* words. */ -#define FFI_IS_FLOAT_FP_AGGREGATE 0x1000 -#define FFI_IS_DOUBLE_FP_AGGREGATE 0x0800 -#define FLOAT_FP_AGGREGATE_BIT 12 -#define DOUBLE_FP_AGGREGATE_BIT 11 - -/* Small structures containing N words. If N=1, they are returned */ -/* as though they were integers. */ -#define FFI_IS_SMALL_STRUCT2 0x40 /* Struct > 8, <=16 bytes */ -#define FFI_IS_SMALL_STRUCT3 0x41 /* Struct > 16 <= 24 bytes */ -#define FFI_IS_SMALL_STRUCT4 0x42 /* Struct > 24, <=32 bytes */ - -/* Flag values identifying particularly simple cases, which are */ -/* handled specially. We treat functions as simple if they take all */ -/* arguments can be passed as 32 or 64 bit integer quantities, there is */ -/* either no return value or it can be treated as a 64bit integer, and */ -/* if there are at most 2 arguments. */ -/* This is OR'ed with the normal flag values. */ -#define FFI_SIMPLE_V 0x10000 /* () -> X */ -#define FFI_SIMPLE_I 0x20000 /* (int) -> X */ -#define FFI_SIMPLE_L 0x30000 /* (long) -> X */ -#define FFI_SIMPLE_II 0x40000 /* (int,int) -> X */ -#define FFI_SIMPLE_IL 0x50000 /* (int,long) -> X */ -#define FFI_SIMPLE_LI 0x60000 /* (long,int) -> X */ -#define FFI_SIMPLE_LL 0x70000 /* (long,long) -> X */ - -/* Mask for all of the FFI_SIMPLE bits: */ -#define FFI_SIMPLE 0xf0000 - -/* An easy way to build FFI_SIMPLE flags from FFI_SIMPLE_V: */ -#define FFI_ADD_LONG_ARG(flag) (((flag) << 1) | 0x10000) -#define FFI_ADD_INT_ARG(flag) ((flag) << 1) diff --git a/libffi/src/ia64/unix.S b/libffi/src/ia64/unix.S deleted file mode 100644 index fdaf8be28ad..00000000000 --- a/libffi/src/ia64/unix.S +++ /dev/null @@ -1,301 +0,0 @@ -/* ----------------------------------------------------------------------- - unix.S - Copyright (c) 1998 Cygnus Solutions - Copyright (c) 2000 Hewlett Packard Company - - IA64/unix Foreign Function Interface - - Primary author: Hans Boehm, HP Labs - - Loosely modeled on Cygnus code for other platforms. - - 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 <ffi.h> -#include "ia64_flags.h" - -/* parameters: */ -#define callback in0 -#define ecifp in1 -#define bytes in2 -#define flags in3 -#define raddr in4 -#define fn in5 - -#define FLOAT_SZ 8 /* in-memory size of fp operands */ - -.text - .align 16 - .global ffi_call_unix# - .proc ffi_call_unix# -ffi_call_unix: - alloc loc0=ar.pfs,6,5,8,0 - mov loc1=b0; - sub sp=sp,bytes - mov loc4=r1 /* Save gp */ - ld8 r8=[callback],8 /* code address of callback */ - ;; - mov out0=sp - mov out1=ecifp - mov out2=bytes - ld8 r1=[callback] /* Set up gp for callback. Unnecessary? */ - mov b6=r8 - ;; - br.call.sptk.many b0 = b6 /* call ffi_prep_args */ - cmp.eq p6,p0=0,r8 /* r8 nonzero ==> need fp regs */ - ;; -(p6) add loc2=32+8*FLOAT_SZ,sp -(p6) br.cond.dptk.many fp_done - ;; /* Quiets warning; needed? */ - add loc2=32,sp - add loc3=32+FLOAT_SZ,sp - ;; - ldfd f8=[loc2],2*FLOAT_SZ - ldfd f9=[loc3],2*FLOAT_SZ - ;; - ldfd f10=[loc2],2*FLOAT_SZ - ldfd f11=[loc3],2*FLOAT_SZ - ;; - ldfd f12=[loc2],2*FLOAT_SZ - ldfd f13=[loc3],2*FLOAT_SZ - ;; - ldfd f14=[loc2],2*FLOAT_SZ - ldfd f15=[loc3] -fp_done: - add r9=16,sp /* Pointer to r8_contents */ - /* loc2 points at first integer register value. */ - add loc3=8,loc2 - ;; - ld8 r8=[r9] /* Just in case we return large struct */ - ld8 out0=[loc2],16 - ld8 out1=[loc3],16 - ;; - ld8 out2=[loc2],16 - ld8 out3=[loc3],16 - ;; - ld8 out4=[loc2],16 - ld8 out5=[loc3],16 - ;; - ld8 out6=[loc2],16 - ld8 out7=[loc3] - /* loc2 points at first stack parameter. Set sp to 16 bytes */ - /* below that. */ - add sp=-16,loc2 - - ld8 r8=[fn],8 - ;; - ld8 r1=[fn] /* Set up gp */ - mov b6=r8;; - br.call.sptk.many b0 = b6 /* call ffi_prep_args */ - - /* Handle return value. */ - cmp.eq p6,p0=0,raddr - cmp.eq p7,p0=FFI_TYPE_INT,flags - cmp.eq p10,p0=FFI_IS_SMALL_STRUCT2,flags - cmp.eq p11,p0=FFI_IS_SMALL_STRUCT3,flags - cmp.eq p12,p0=FFI_IS_SMALL_STRUCT4,flags - ;; -(p6) br.cond.dpnt.few done /* Dont copy ret values if raddr = 0 */ -(p7) br.cond.dptk.few copy1 -(p10) br.cond.dpnt.few copy2 -(p11) br.cond.dpnt.few copy3 -(p12) br.cond.dpnt.few copy4 - cmp.eq p8,p0=FFI_TYPE_FLOAT,flags - cmp.eq p9,p0=FFI_TYPE_DOUBLE,flags - tbit.nz p6,p0=flags,FLOAT_FP_AGGREGATE_BIT - tbit.nz p7,p0=flags,DOUBLE_FP_AGGREGATE_BIT - ;; -(p8) stfs [raddr]=f8 -(p9) stfd [raddr]=f8 - ;; -(p6) br.cond.dpnt.few handle_float_hfa -(p7) br.cond.dpnt.few handle_double_hfa - br done - -copy4: - add loc3=24,raddr - ;; - st8 [loc3]=r11 -copy3: - add loc3=16,raddr - ;; - st8 [loc3]=r10 -copy2: - add loc3=8,raddr - ;; - st8 [loc3]=r9 -copy1: - st8 [raddr]=r8 - /* In the big struct case, raddr was passed as an argument. */ - /* In the void case there was nothing to do. */ - -done: - mov r1=loc4 /* Restore gp */ - mov ar.pfs = loc0 - mov b0 = loc1 - br.ret.sptk.many b0 - -handle_double_hfa: - /* Homogeneous floating point array of doubles is returned in */ - /* registers f8-f15. Save one at a time to return area. */ - and flags=0xf,flags /* Retrieve size */ - ;; - cmp.eq p6,p0=2,flags - cmp.eq p7,p0=3,flags - cmp.eq p8,p0=4,flags - cmp.eq p9,p0=5,flags - cmp.eq p10,p0=6,flags - cmp.eq p11,p0=7,flags - cmp.eq p12,p0=8,flags - ;; -(p6) br.cond.dptk.few dhfa2 -(p7) br.cond.dptk.few dhfa3 -(p8) br.cond.dptk.few dhfa4 -(p9) br.cond.dptk.few dhfa5 -(p10) br.cond.dptk.few dhfa6 -(p11) br.cond.dptk.few dhfa7 -dhfa8: add loc3=7*8,raddr - ;; - stfd [loc3]=f15 -dhfa7: add loc3=6*8,raddr - ;; - stfd [loc3]=f14 -dhfa6: add loc3=5*8,raddr - ;; - stfd [loc3]=f13 -dhfa5: add loc3=4*8,raddr - ;; - stfd [loc3]=f12 -dhfa4: add loc3=3*8,raddr - ;; - stfd [loc3]=f11 -dhfa3: add loc3=2*8,raddr - ;; - stfd [loc3]=f10 -dhfa2: add loc3=1*8,raddr - ;; - stfd [loc3]=f9 - stfd [raddr]=f8 - br done - -handle_float_hfa: - /* Homogeneous floating point array of floats is returned in */ - /* registers f8-f15. Save one at a time to return area. */ - and flags=0xf,flags /* Retrieve size */ - ;; - cmp.eq p6,p0=2,flags - cmp.eq p7,p0=3,flags - cmp.eq p8,p0=4,flags - cmp.eq p9,p0=5,flags - cmp.eq p10,p0=6,flags - cmp.eq p11,p0=7,flags - cmp.eq p12,p0=8,flags - ;; -(p6) br.cond.dptk.few shfa2 -(p7) br.cond.dptk.few shfa3 -(p8) br.cond.dptk.few shfa4 -(p9) br.cond.dptk.few shfa5 -(p10) br.cond.dptk.few shfa6 -(p11) br.cond.dptk.few shfa7 -shfa8: add loc3=7*4,raddr - ;; - stfd [loc3]=f15 -shfa7: add loc3=6*4,raddr - ;; - stfd [loc3]=f14 -shfa6: add loc3=5*4,raddr - ;; - stfd [loc3]=f13 -shfa5: add loc3=4*4,raddr - ;; - stfd [loc3]=f12 -shfa4: add loc3=3*4,raddr - ;; - stfd [loc3]=f11 -shfa3: add loc3=2*4,raddr - ;; - stfd [loc3]=f10 -shfa2: add loc3=1*4,raddr - ;; - stfd [loc3]=f9 - stfd [raddr]=f8 - br done - - .endp ffi_call_unix - - -.text - .align 16 - .global ffi_closure_UNIX - .proc ffi_closure_UNIX -ffi_closure_UNIX: - alloc loc0=ar.pfs,8,2,2,0 - mov loc1=b0 - /* Retrieve closure pointer and real gp. */ - mov out0=gp - add gp=16,gp - ;; - ld8 gp=[gp] - /* Reserve a structia64_args on the stack such that arguments */ - /* past the first 8 are automatically placed in the right */ - /* slot. Note that when we start the sp points at 2 8-byte */ - /* scratch words, followed by the extra arguments. */ -# define BASIC_ARGS_SZ (8*FLOAT_SZ+8*8+2*8) -# define FIRST_FP_OFFSET (4*8) - add r14=-(BASIC_ARGS_SZ-FIRST_FP_OFFSET),sp - add r15=-(BASIC_ARGS_SZ-FIRST_FP_OFFSET-FLOAT_SZ),sp - add sp=-BASIC_ARGS_SZ,sp - /* r14 points to fp_regs[0], r15 points to fp_regs[1] */ - ;; - stfd [r14]=f8,2*FLOAT_SZ - stfd [r15]=f9,2*FLOAT_SZ - ;; - stfd [r14]=f10,2*FLOAT_SZ - stfd [r15]=f11,2*FLOAT_SZ - ;; - stfd [r14]=f12,2*FLOAT_SZ - stfd [r15]=f13,2*FLOAT_SZ - ;; - stfd [r14]=f14,FLOAT_SZ+8 - stfd [r15]=f15,2*8 - ;; - /* r14 points to first parameter register area, r15 to second. */ - st8 [r14]=in0,2*8 - st8 [r15]=in1,2*8 - ;; - st8 [r14]=in2,2*8 - st8 [r15]=in3,2*8 - ;; - st8 [r14]=in4,2*8 - st8 [r15]=in5,2*8 - ;; - st8 [r14]=in6,2*8 - st8 [r15]=in7,2*8 - /* Call ffi_closure_UNIX_inner */ - mov out1=sp - br.call.sptk.many b0=ffi_closure_UNIX_inner - ;; - mov b0=loc1 - mov ar.pfs=loc0 - br.ret.sptk.many b0 - .endp ffi_closure_UNIX - - diff --git a/libffi/src/java_raw_api.c b/libffi/src/java_raw_api.c deleted file mode 100644 index 5f85582cfde..00000000000 --- a/libffi/src/java_raw_api.c +++ /dev/null @@ -1,271 +0,0 @@ -/* ----------------------------------------------------------------------- - java_raw_api.c - Copyright (c) 1999 Cygnus Solutions - - Cloned from raw_api.c - - Raw_api.c author: Kresten Krab Thorup <krab@gnu.org> - Java_raw_api.c author: Hans-J. Boehm <hboehm@hpl.hp.com> - - $Id $ - - 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. - ----------------------------------------------------------------------- */ - -/* This defines a Java- and 64-bit specific variant of the raw API. */ -/* It assumes that "raw" argument blocks look like Java stacks on a */ -/* 64-bit machine. Arguments that can be stored in a single stack */ -/* stack slots (longs, doubles) occupy 128 bits, but only the first */ -/* 64 bits are actually used. */ - -#include <ffi.h> -#include <ffi_common.h> - -#if !defined(NO_JAVA_RAW_API) && !defined(FFI_NO_RAW_API) - -size_t -ffi_java_raw_size (ffi_cif *cif) -{ - size_t result = 0; - int i; - - ffi_type **at = cif->arg_types; - - for (i = cif->nargs-1; i >= 0; i--, at++) - { - switch((*at) -> type) { - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - result += 2 * SIZEOF_ARG; - break; - case FFI_TYPE_STRUCT: - /* No structure parameters in Java. */ - abort(); - default: - result += SIZEOF_ARG; - } - } - - return result; -} - - -void -ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args) -{ - unsigned i; - ffi_type **tp = cif->arg_types; - -#if WORDS_BIGENDIAN - - for (i = 0; i < cif->nargs; i++, tp++, args++) - { - switch ((*tp)->type) - { - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 1); - break; - - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT16: - *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 2); - break; - -#if SIZEOF_ARG >= 4 - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 4); - break; -#endif - -#if SIZEOF_ARG == 8 - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - case FFI_TYPE_DOUBLE: - *args = (void *)raw; - raw += 2; - break; -#endif - - case FFI_TYPE_POINTER: - *args = (void*) &(raw++)->ptr; - break; - - default: - *args = raw; - raw += ALIGN ((*tp)->size, SIZEOF_ARG) / SIZEOF_ARG; - } - } - -#else /* WORDS_BIGENDIAN */ - -#if !PDP - - /* then assume little endian */ - for (i = 0; i < cif->nargs; i++, tp++, args++) - { -#if SIZEOF_ARG == 8 - switch((*tp)->type) { - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - case FFI_TYPE_DOUBLE: - *args = (void*) raw; - raw += 2; - break; - default: - *args = (void*) raw++; - } -#else /* SIZEOF_ARG != 8 */ - *args = (void*) raw; - raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*); -#endif /* SIZEOF_ARG == 8 */ - } - -#else -#error "pdp endian not supported" -#endif /* ! PDP */ - -#endif /* WORDS_BIGENDIAN */ -} - -void -ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw) -{ - unsigned i; - ffi_type **tp = cif->arg_types; - - for (i = 0; i < cif->nargs; i++, tp++, args++) - { - switch ((*tp)->type) - { - case FFI_TYPE_UINT8: - (raw++)->uint = *(UINT8*) (*args); - break; - - case FFI_TYPE_SINT8: - (raw++)->sint = *(SINT8*) (*args); - break; - - case FFI_TYPE_UINT16: - (raw++)->uint = *(UINT16*) (*args); - break; - - case FFI_TYPE_SINT16: - (raw++)->sint = *(SINT16*) (*args); - break; - -#if SIZEOF_ARG >= 4 - case FFI_TYPE_UINT32: - (raw++)->uint = *(UINT32*) (*args); - break; - - case FFI_TYPE_SINT32: - (raw++)->sint = *(SINT32*) (*args); - break; -#endif - case FFI_TYPE_FLOAT: - (raw++)->flt = *(FLOAT32*) (*args); - break; - -#if SIZEOF_ARG == 8 - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - case FFI_TYPE_DOUBLE: - raw->uint = *(UINT64*) (*args); - raw += 2; - break; -#endif - - case FFI_TYPE_POINTER: - (raw++)->ptr = **(void***) args; - break; - - default: -#if SIZEOF_ARG == 8 - FFI_ASSERT(FALSE); /* Should have covered all cases */ -#else - memcpy ((void*) raw->data, (void*)*args, (*tp)->size); - raw += ALIGN ((*tp)->size, SIZEOF_ARG) / SIZEOF_ARG; -#endif - } - } -} - -#if !FFI_NATIVE_RAW_API - - -/* This is a generic definition of ffi_raw_call, to be used if the - * native system does not provide a machine-specific implementation. - * Having this, allows code to be written for the raw API, without - * the need for system-specific code to handle input in that format; - * these following couple of functions will handle the translation forth - * and back automatically. */ - -void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ ffi_raw *raw) -{ - void **avalue = (void**) alloca (cif->nargs * sizeof (void*)); - ffi_java_raw_to_ptrarray (cif, raw, avalue); - ffi_call (cif, fn, rvalue, avalue); -} - -#if FFI_CLOSURES /* base system provides closures */ - -static void -ffi_java_translate_args (ffi_cif *cif, void *rvalue, - void **avalue, void *user_data) -{ - ffi_raw *raw = (ffi_raw*)alloca (ffi_java_raw_size (cif)); - ffi_raw_closure *cl = (ffi_raw_closure*)user_data; - - ffi_java_ptrarray_to_raw (cif, avalue, raw); - (*cl->fun) (cif, rvalue, raw, cl->user_data); -} - -/* Again, here is the generic version of ffi_prep_raw_closure, which - * will install an intermediate "hub" for translation of arguments from - * the pointer-array format, to the raw format */ - -ffi_status -ffi_prep_java_raw_closure (ffi_raw_closure* cl, - ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void *user_data) -{ - ffi_status status; - - status = ffi_prep_closure ((ffi_closure*) cl, - cif, - &ffi_java_translate_args, - (void*)cl); - if (status == FFI_OK) - { - cl->fun = fun; - cl->user_data = user_data; - } - - return status; -} - -#endif /* FFI_CLOSURES */ -#endif /* !FFI_NATIVE_RAW_API */ -#endif /* !FFI_NO_RAW_API */ diff --git a/libffi/src/m68k/ffi.c b/libffi/src/m68k/ffi.c deleted file mode 100644 index c5d950786f7..00000000000 --- a/libffi/src/m68k/ffi.c +++ /dev/null @@ -1,184 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - - m68k Foreign Function Interface - ----------------------------------------------------------------------- */ - -#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. */ - -static void * -ffi_prep_args (void *stack, extended_cif *ecif) -{ - unsigned int i; - int tmp; - unsigned int avn; - void **p_argv; - char *argp; - ffi_type **p_arg; - void *struct_value_ptr; - - tmp = 0; - argp = stack; - - if (ecif->cif->rtype->type == FFI_TYPE_STRUCT - && ecif->cif->rtype->size > 8) - struct_value_ptr = ecif->rvalue; - else - struct_value_ptr = NULL; - - avn = ecif->cif->nargs; - p_argv = ecif->avalue; - - for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; - i != 0 && avn != 0; - i--, p_arg++) - { - size_t z; - - /* Align if necessary. */ - if (((*p_arg)->alignment - 1) & (unsigned) argp) - argp = (char *) ALIGN (argp, (*p_arg)->alignment); - - if (avn != 0) - { - avn--; - z = (*p_arg)->size; - if (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: - memcpy (argp + sizeof (int) - z, *p_argv, z); - break; - - default: - FFI_ASSERT (0); - } - z = sizeof (int); - } - else - memcpy (argp, *p_argv, z); - p_argv++; - argp += z; - } - } - - return struct_value_ptr; -} - -#define CIF_FLAGS_INT 1 -#define CIF_FLAGS_DINT 2 -#define CIF_FLAGS_FLOAT 4 -#define CIF_FLAGS_DOUBLE 8 -#define CIF_FLAGS_LDOUBLE 16 -#define CIF_FLAGS_POINTER 32 -#define CIF_FLAGS_STRUCT 64 - -/* Perform machine dependent cif processing */ -ffi_status -ffi_prep_cif_machdep (ffi_cif *cif) -{ - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_VOID: - cif->flags = 0; - break; - - case FFI_TYPE_STRUCT: - if (cif->rtype->size > 4 && cif->rtype->size <= 8) - cif->flags = CIF_FLAGS_DINT; - else if (cif->rtype->size <= 4) - cif->flags = CIF_FLAGS_STRUCT; - else - cif->flags = 0; - break; - - case FFI_TYPE_FLOAT: - cif->flags = CIF_FLAGS_FLOAT; - break; - - case FFI_TYPE_DOUBLE: - cif->flags = CIF_FLAGS_DOUBLE; - break; - - case FFI_TYPE_LONGDOUBLE: - cif->flags = CIF_FLAGS_LDOUBLE; - break; - - case FFI_TYPE_POINTER: - cif->flags = CIF_FLAGS_POINTER; - break; - - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - cif->flags = CIF_FLAGS_DINT; - break; - - default: - cif->flags = CIF_FLAGS_INT; - break; - } - - return FFI_OK; -} - -extern void ffi_call_SYSV (void *(*) (void *, extended_cif *), - extended_cif *, - unsigned, unsigned, unsigned, - void *, void (*fn) ()); - -void -ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, 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 - && cif->rtype->size > 8) - ecif.rvalue = alloca (cif->rtype->size); - else - ecif.rvalue = rvalue; - - - switch (cif->abi) - { - case FFI_SYSV: - ffi_call_SYSV (ffi_prep_args, &ecif, cif->bytes, - cif->flags, cif->rtype->size * 8, - ecif.rvalue, fn); - break; - - default: - FFI_ASSERT (0); - break; - } -} diff --git a/libffi/src/m68k/sysv.S b/libffi/src/m68k/sysv.S deleted file mode 100644 index a925d99e3ce..00000000000 --- a/libffi/src/m68k/sysv.S +++ /dev/null @@ -1,96 +0,0 @@ -/* ----------------------------------------------------------------------- - sysv.S - - m68k Foreign Function Interface - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM -#include <ffi.h> - - .text - - .globl ffi_call_SYSV - .type ffi_call_SYSV,@function - -ffi_call_SYSV: - link %fp,#0 - move.l %d2,-(%sp) - - | Make room for all of the new args. - sub.l 16(%fp),%sp - - | Call ffi_prep_args - move.l 12(%fp),-(%sp) - pea 4(%sp) - move.l 8(%fp),%a0 - jsr (%a0) - addq.l #8,%sp - - | Pass pointer to struct value, if any - move.l %a0,%a1 - - | Call the function - move.l 32(%fp),%a0 - jsr (%a0) - - | Remove the space we pushed for the args - add.l 16(%fp),%sp - - | Load the pointer to storage for the return value - move.l 28(%fp),%a1 - - | Load the return type code - move.l 20(%fp),%d2 - - | If the return value pointer is NULL, assume no return value. - tst.l %a1 - jbeq noretval - - btst #0,%d2 - jbeq retlongint - move.l %d0,(%a1) - jbra epilogue - -retlongint: - btst #1,%d2 - jbeq retfloat - move.l %d0,(%a1) - move.l %d1,4(%a1) - jbra epilogue - -retfloat: - btst #2,%d2 - jbeq retdouble - fmove.s %fp0,(%a1) - jbra epilogue - -retdouble: - btst #3,%d2 - jbeq retlongdouble - fmove.d %fp0,(%a1) - jbra epilogue - -retlongdouble: - btst #4,%d2 - jbeq retpointer - fmove.x %fp0,(%a1) - jbra epilogue - -retpointer: - btst #5,%d2 - jbeq retstruct - move.l %a0,(%a1) - jbra epilogue - -retstruct: - btst #6,%d2 - jbeq noretval - move.l 24(%fp),%d2 - bfins %d0,(%a1){#0,%d2} - -noretval: -epilogue: - move.l (%sp)+,%d2 - unlk %a6 - rts - .size ffi_call_SYSV,.-ffi_call_SYSV diff --git a/libffi/src/mips/ffi.c b/libffi/src/mips/ffi.c deleted file mode 100644 index f3a37bc44f2..00000000000 --- a/libffi/src/mips/ffi.c +++ /dev/null @@ -1,471 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1996 Cygnus Solutions - - MIPS Foreign Function Interface - - $Id: ffi.c,v 1.1.1.1 1998/11/29 16:48:16 green Exp $ - - 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> - -#if _MIPS_SIM == _MIPS_SIM_NABI32 -#define FIX_ARGP \ -FFI_ASSERT(argp <= &stack[bytes]); \ -if (argp == &stack[bytes]) \ -{ \ - argp = stack; \ - ffi_stop_here(); \ -} -#else -#define FIX_ARGP -#endif - - -/* ffi_prep_args is called by the assembly routine once stack space - has been allocated for the function's arguments */ - -static void ffi_prep_args(char *stack, - extended_cif *ecif, - int bytes, - int flags) -{ - register int i; - register int avn; - register void **p_argv; - register char *argp; - register ffi_type **p_arg; - -#if _MIPS_SIM == _MIPS_SIM_NABI32 - /* If more than 8 double words are used, the remainder go - on the stack. We reorder stuff on the stack here to - support this easily. */ - if (bytes > 8 * SIZEOF_ARG) - argp = &stack[bytes - (8 * SIZEOF_ARG)]; - else - argp = stack; -#else - argp = stack; -#endif - - memset(stack, 0, bytes); - -#if _MIPS_SIM == _MIPS_SIM_NABI32 - if ( ecif->cif->rstruct_flag != 0 ) -#else - if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) -#endif - { - *(SLOT_TYPE_UNSIGNED *) argp = (SLOT_TYPE_UNSIGNED) ecif->rvalue; - argp += sizeof(SLOT_TYPE_UNSIGNED); - FIX_ARGP; - } - - avn = ecif->cif->nargs; - p_argv = ecif->avalue; - - for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; - i && avn; - i--, p_arg++) - { - size_t z; - - /* Align if necessary */ - if (((*p_arg)->alignment - 1) & (unsigned) argp) { - argp = (char *) ALIGN(argp, (*p_arg)->alignment); - FIX_ARGP; - } - -#if _MIPS_SIM == _MIPS_SIM_ABI32 -#define OFFSET 0 -#else -#define OFFSET sizeof(int) -#endif - - if (avn) - { - avn--; - z = (*p_arg)->size; - if (z < sizeof(SLOT_TYPE_UNSIGNED)) - { - z = sizeof(SLOT_TYPE_UNSIGNED); - - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT8 *)(* p_argv); - break; - - case FFI_TYPE_UINT8: - *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT8 *)(* p_argv); - break; - - case FFI_TYPE_SINT16: - *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT16 *)(* p_argv); - break; - - case FFI_TYPE_UINT16: - *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT16 *)(* p_argv); - break; - - case FFI_TYPE_SINT32: - *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT32 *)(* p_argv); - break; - - case FFI_TYPE_UINT32: - case FFI_TYPE_POINTER: - *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT32 *)(* p_argv); - break; - - /* This can only happen with 64bit slots */ - case FFI_TYPE_FLOAT: - *(float *) argp = *(float *)(* p_argv); - break; - - /* Handle small structures */ - case FFI_TYPE_STRUCT: - memcpy(argp, *p_argv, (*p_arg)->size); - break; - - default: - FFI_ASSERT(0); - } - } - else - { -#if _MIPS_SIM == _MIPS_SIM_ABI32 - memcpy(argp, *p_argv, z); -#else - { - unsigned end = (unsigned) argp+z; - unsigned cap = (unsigned) stack+bytes; - - /* Check if the data will fit within the register - space. Handle it if it doesn't. */ - - if (end <= cap) - memcpy(argp, *p_argv, z); - else - { - unsigned portion = end - cap; - - memcpy(argp, *p_argv, portion); - argp = stack; - memcpy(argp, - (void*)((unsigned)(*p_argv)+portion), z - portion); - } - } -#endif - } - p_argv++; - argp += z; - FIX_ARGP; - } - } - - return; -} - -#if _MIPS_SIM == _MIPS_SIM_NABI32 - -/* The n32 spec says that if "a chunk consists solely of a double - float field (but not a double, which is part of a union), it - is passed in a floating point register. Any other chunk is - passed in an integer register". This code traverses structure - definitions and generates the appropriate flags. */ - -unsigned calc_n32_struct_flags(ffi_type *arg, unsigned *shift) -{ - unsigned flags = 0; - unsigned index = 0; - - ffi_type *e; - - while (e = arg->elements[index]) - { - if (e->type == FFI_TYPE_DOUBLE) - { - flags += (FFI_TYPE_DOUBLE << *shift); - *shift += FFI_FLAG_BITS; - } - else if (e->type == FFI_TYPE_STRUCT) - flags += calc_n32_struct_flags(e, shift); - else - *shift += FFI_FLAG_BITS; - - index++; - } - - return flags; -} - -unsigned calc_n32_return_struct_flags(ffi_type *arg) -{ - unsigned flags = 0; - unsigned index = 0; - unsigned small = FFI_TYPE_SMALLSTRUCT; - ffi_type *e; - - /* Returning structures under n32 is a tricky thing. - A struct with only one or two floating point fields - is returned in $f0 (and $f2 if necessary). Any other - struct results at most 128 bits are returned in $2 - (the first 64 bits) and $3 (remainder, if necessary). - Larger structs are handled normally. */ - - if (arg->size > 16) - return 0; - - if (arg->size > 8) - small = FFI_TYPE_SMALLSTRUCT2; - - e = arg->elements[0]; - if (e->type == FFI_TYPE_DOUBLE) - flags = FFI_TYPE_DOUBLE << FFI_FLAG_BITS; - else if (e->type == FFI_TYPE_FLOAT) - flags = FFI_TYPE_FLOAT << FFI_FLAG_BITS; - - if (flags && (e = arg->elements[1])) - { - if (e->type == FFI_TYPE_DOUBLE) - flags += FFI_TYPE_DOUBLE; - else if (e->type == FFI_TYPE_FLOAT) - flags += FFI_TYPE_FLOAT; - else - return small; - - if (flags && (arg->elements[2])) - { - /* There are three arguments and the first two are - floats! This must be passed the old way. */ - return small; - } - } - else - if (!flags) - return small; - - return flags; -} - -#endif - -/* Perform machine dependent cif processing */ -ffi_status ffi_prep_cif_machdep(ffi_cif *cif) -{ - cif->flags = 0; - -#if _MIPS_SIM == _MIPS_SIM_ABI32 - /* Set the flags necessary for O32 processing */ - - if (cif->rtype->type != FFI_TYPE_STRUCT) - { - if (cif->nargs > 0) - { - switch ((cif->arg_types)[0]->type) - { - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - cif->flags += (cif->arg_types)[0]->type; - break; - - default: - break; - } - - if (cif->nargs > 1) - { - /* Only handle the second argument if the first - is a float or double. */ - if (cif->flags) - { - switch ((cif->arg_types)[1]->type) - { - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS; - break; - - default: - break; - } - } - } - } - } - - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_VOID: - case FFI_TYPE_STRUCT: - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2); - break; - - default: - cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2); - break; - } -#endif - -#if _MIPS_SIM == _MIPS_SIM_NABI32 - /* Set the flags necessary for N32 processing */ - { - unsigned shift = 0; - unsigned count = (cif->nargs < 8) ? cif->nargs : 8; - unsigned index = 0; - - unsigned struct_flags = 0; - - if (cif->rtype->type == FFI_TYPE_STRUCT) - { - struct_flags = calc_n32_return_struct_flags(cif->rtype); - - if (struct_flags == 0) - { - /* This means that the structure is being passed as - a hidden argument */ - - shift = FFI_FLAG_BITS; - count = (cif->nargs < 7) ? cif->nargs : 7; - - cif->rstruct_flag = !0; - } - else - cif->rstruct_flag = 0; - } - else - cif->rstruct_flag = 0; - - while (count-- > 0) - { - switch ((cif->arg_types)[index]->type) - { - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - cif->flags += ((cif->arg_types)[index]->type << shift); - shift += FFI_FLAG_BITS; - break; - - case FFI_TYPE_STRUCT: - cif->flags += calc_n32_struct_flags((cif->arg_types)[index], - &shift); - break; - - default: - shift += FFI_FLAG_BITS; - } - - index++; - } - - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_STRUCT: - { - if (struct_flags == 0) - { - /* The structure is returned through a hidden - first argument. Do nothing, 'cause FFI_TYPE_VOID - is 0 */ - } - else - { - /* The structure is returned via some tricky - mechanism */ - cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8); - cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8)); - } - break; - } - - case FFI_TYPE_VOID: - /* Do nothing, 'cause FFI_TYPE_VOID is 0 */ - break; - - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8); - break; - - default: - cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8); - break; - } - } -#endif - - return FFI_OK; -} - -/* Low level routine for calling O32 functions */ -extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int), - extended_cif *, unsigned, - unsigned, unsigned *, void (*)()); - -/* Low level routine for calling N32 functions */ -extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int), - extended_cif *, unsigned, - unsigned, unsigned *, void (*)()); - -void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, 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)) - ecif.rvalue = alloca(cif->rtype->size); - else - ecif.rvalue = rvalue; - - switch (cif->abi) - { -#if _MIPS_SIM == _MIPS_SIM_ABI32 - case FFI_O32: - ffi_call_O32(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - break; -#endif - -#if _MIPS_SIM == _MIPS_SIM_NABI32 - case FFI_N32: - ffi_call_N32(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - break; -#endif - - default: - FFI_ASSERT(0); - break; - } -} diff --git a/libffi/src/mips/n32.S b/libffi/src/mips/n32.S deleted file mode 100644 index 799bc7cc872..00000000000 --- a/libffi/src/mips/n32.S +++ /dev/null @@ -1,320 +0,0 @@ -/* ----------------------------------------------------------------------- - n32.S - Copyright (c) 1996, 1998 Cygnus Solutions - - MIPS Foreign Function Interface - - $Id: n32.S,v 1.1.1.1 1998/11/29 16:48:16 green Exp $ - - 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 <ffi.h> - -/* Only build this code if we are compiling for n32 */ - -#if defined(FFI_MIPS_N32) - -#define callback a0 -#define bytes a2 -#define flags a3 -#define raddr a4 -#define fn a5 - -#define SIZEOF_FRAME ( 8 * SIZEOF_ARG ) - - .text - .align 2 - .globl ffi_call_N32 - .ent ffi_call_N32 -ffi_call_N32: - - # Prologue - SUBU $sp, SIZEOF_FRAME # Frame size - REG_S $fp, SIZEOF_FRAME - 2*SIZEOF_ARG($sp) # Save frame pointer - REG_S ra, SIZEOF_FRAME - 1*SIZEOF_ARG($sp) # Save return address - move $fp, $sp - - move t9, callback # callback function pointer - REG_S bytes, 2*SIZEOF_ARG($fp) # bytes - REG_S flags, 3*SIZEOF_ARG($fp) # flags - REG_S raddr, 4*SIZEOF_ARG($fp) # raddr - REG_S fn, 5*SIZEOF_ARG($fp) # fn - - # Allocate at least 4 words in the argstack - move v0, bytes - bge bytes, 4 * SIZEOF_ARG, bigger - LI v0, 4 * SIZEOF_ARG - b sixteen - - bigger: - ADDU t4, v0, 2 * SIZEOF_ARG -1 # make sure it is aligned - and v0, t4, -2 * SIZEOF_ARG # to a proper boundry. - -sixteen: - SUBU $sp, $sp, v0 # move the stack pointer to reflect the - # arg space - - ADDU a0, $sp, 0 # 4 * SIZEOF_ARG - ADDU a3, $fp, 3 * SIZEOF_ARG - - # Call ffi_prep_args - jal t9 - - # ADDU $sp, $sp, 4 * SIZEOF_ARG # adjust $sp to new args - - # Copy the stack pointer to t9 - move t9, $sp - - # Fix the stack if there are more than 8 64bit slots worth - # of arguments. - - # Load the number of bytes - REG_L t6, 2*SIZEOF_ARG($fp) - - # Is it bigger than 8 * SIZEOF_ARG? - dadd t7, $0, 8 * SIZEOF_ARG - dsub t8, t6, t7 - bltz t8, loadregs - - add t9, t9, t8 - -loadregs: - - REG_L t4, 3*SIZEOF_ARG($fp) # load the flags word - add t6, t4, 0 # and copy it into t6 - - and t4, ((1<<FFI_FLAG_BITS)-1) - bnez t4, arg1_floatp - REG_L a0, 0*SIZEOF_ARG(t9) - b arg1_next -arg1_floatp: - bne t4, FFI_TYPE_FLOAT, arg1_doublep - l.s $f12, 0*SIZEOF_ARG(t9) - b arg1_next -arg1_doublep: - l.d $f12, 0*SIZEOF_ARG(t9) -arg1_next: - - add t4, t6, 0 - SRL t4, 1*FFI_FLAG_BITS - and t4, ((1<<FFI_FLAG_BITS)-1) - bnez t4, arg2_floatp - REG_L a1, 1*SIZEOF_ARG(t9) - b arg2_next -arg2_floatp: - bne t4, FFI_TYPE_FLOAT, arg2_doublep - l.s $f13, 1*SIZEOF_ARG(t9) - b arg2_next -arg2_doublep: - l.d $f13, 1*SIZEOF_ARG(t9) -arg2_next: - - add t4, t6, 0 - SRL t4, 2*FFI_FLAG_BITS - and t4, ((1<<FFI_FLAG_BITS)-1) - bnez t4, arg3_floatp - REG_L a2, 2*SIZEOF_ARG(t9) - b arg3_next -arg3_floatp: - bne t4, FFI_TYPE_FLOAT, arg3_doublep - l.s $f14, 2*SIZEOF_ARG(t9) - b arg3_next -arg3_doublep: - l.d $f14, 2*SIZEOF_ARG(t9) -arg3_next: - - add t4, t6, 0 - SRL t4, 3*FFI_FLAG_BITS - and t4, ((1<<FFI_FLAG_BITS)-1) - bnez t4, arg4_floatp - REG_L a3, 3*SIZEOF_ARG(t9) - b arg4_next -arg4_floatp: - bne t4, FFI_TYPE_FLOAT, arg4_doublep - l.s $f15, 3*SIZEOF_ARG(t9) - b arg4_next -arg4_doublep: - l.d $f15, 3*SIZEOF_ARG(t9) -arg4_next: - - add t4, t6, 0 - SRL t4, 4*FFI_FLAG_BITS - and t4, ((1<<FFI_FLAG_BITS)-1) - bnez t4, arg5_floatp - REG_L a4, 4*SIZEOF_ARG(t9) - b arg5_next -arg5_floatp: - bne t4, FFI_TYPE_FLOAT, arg5_doublep - l.s $f16, 4*SIZEOF_ARG(t9) - b arg5_next -arg5_doublep: - l.d $f16, 4*SIZEOF_ARG(t9) -arg5_next: - - add t4, t6, 0 - SRL t4, 5*FFI_FLAG_BITS - and t4, ((1<<FFI_FLAG_BITS)-1) - bnez t4, arg6_floatp - REG_L a5, 5*SIZEOF_ARG(t9) - b arg6_next -arg6_floatp: - bne t4, FFI_TYPE_FLOAT, arg6_doublep - l.s $f17, 5*SIZEOF_ARG(t9) - b arg6_next -arg6_doublep: - l.d $f17, 5*SIZEOF_ARG(t9) -arg6_next: - - add t4, t6, 0 - SRL t4, 6*FFI_FLAG_BITS - and t4, ((1<<FFI_FLAG_BITS)-1) - bnez t4, arg7_floatp - REG_L a6, 6*SIZEOF_ARG(t9) - b arg7_next -arg7_floatp: - bne t4, FFI_TYPE_FLOAT, arg7_doublep - l.s $f18, 6*SIZEOF_ARG(t9) - b arg7_next -arg7_doublep: - l.d $f18, 6*SIZEOF_ARG(t9) -arg7_next: - - add t4, t6, 0 - SRL t4, 7*FFI_FLAG_BITS - and t4, ((1<<FFI_FLAG_BITS)-1) - bnez t4, arg8_floatp - REG_L a7, 7*SIZEOF_ARG(t9) - b arg8_next -arg8_floatp: - bne t4, FFI_TYPE_FLOAT, arg8_doublep - l.s $f19, 7*SIZEOF_ARG(t9) - b arg8_next -arg8_doublep: - l.d $f19, 7*SIZEOF_ARG(t9) -arg8_next: - -callit: - # Load the function pointer - REG_L t9, 5*SIZEOF_ARG($fp) - - # If the return value pointer is NULL, assume no return value. - REG_L t5, 4*SIZEOF_ARG($fp) - beqz t5, noretval - - # Shift the return type flag over - SRL t6, 8*FFI_FLAG_BITS - - bne t6, FFI_TYPE_INT, retfloat - jal t9 - REG_L t4, 4*SIZEOF_ARG($fp) - REG_S v0, 0(t4) - b epilogue - -retfloat: - bne t6, FFI_TYPE_FLOAT, retdouble - jal t9 - REG_L t4, 4*SIZEOF_ARG($fp) - s.s $f0, 0(t4) - b epilogue - -retdouble: - bne t6, FFI_TYPE_DOUBLE, retstruct_d - jal t9 - REG_L t4, 4*SIZEOF_ARG($fp) - s.d $f0, 0(t4) - b epilogue - -retstruct_d: - bne t6, FFI_TYPE_STRUCT_D, retstruct_f - jal t9 - REG_L t4, 4*SIZEOF_ARG($fp) - s.d $f0, 0(t4) - b epilogue - -retstruct_f: - bne t6, FFI_TYPE_STRUCT_F, retstruct_d_d - jal t9 - REG_L t4, 4*SIZEOF_ARG($fp) - s.s $f0, 0(t4) - b epilogue - -retstruct_d_d: - bne t6, FFI_TYPE_STRUCT_DD, retstruct_f_f - jal t9 - REG_L t4, 4*SIZEOF_ARG($fp) - s.d $f0, 0(t4) - s.d $f2, 8(t4) - b epilogue - -retstruct_f_f: - bne t6, FFI_TYPE_STRUCT_FF, retstruct_d_f - jal t9 - REG_L t4, 4*SIZEOF_ARG($fp) - s.s $f0, 0(t4) - s.s $f2, 4(t4) - b epilogue - -retstruct_d_f: - bne t6, FFI_TYPE_STRUCT_DF, retstruct_f_d - jal t9 - REG_L t4, 4*SIZEOF_ARG($fp) - s.d $f0, 0(t4) - s.s $f2, 8(t4) - b epilogue - -retstruct_f_d: - bne t6, FFI_TYPE_STRUCT_FD, retstruct_small - jal t9 - REG_L t4, 4*SIZEOF_ARG($fp) - s.s $f0, 0(t4) - s.d $f2, 8(t4) - b epilogue - -retstruct_small: - bne t6, FFI_TYPE_STRUCT_SMALL, retstruct_small2 - jal t9 - REG_L t4, 4*SIZEOF_ARG($fp) - REG_S v0, 0(t4) - b epilogue - -retstruct_small2: - bne t6, FFI_TYPE_STRUCT_SMALL2, retstruct - jal t9 - REG_L t4, 4*SIZEOF_ARG($fp) - REG_S v0, 0(t4) - REG_S v1, 8(t4) - b epilogue - -retstruct: -noretval: - jal t9 - - # Epilogue -epilogue: - move $sp, $fp - REG_L $fp, SIZEOF_FRAME - 2*SIZEOF_ARG($sp) # Restore frame pointer - REG_L ra, SIZEOF_FRAME - 1*SIZEOF_ARG($sp) # Restore return address - ADDU $sp, SIZEOF_FRAME # Fix stack pointer - j ra - - .end ffi_call_N32 - -#endif diff --git a/libffi/src/mips/n32.s b/libffi/src/mips/n32.s deleted file mode 100644 index 007f0a825b0..00000000000 --- a/libffi/src/mips/n32.s +++ /dev/null @@ -1,14 +0,0 @@ -#include "n32.S" - - - - - - - - - - - - - diff --git a/libffi/src/mips/o32.S b/libffi/src/mips/o32.S deleted file mode 100644 index 771e8b04451..00000000000 --- a/libffi/src/mips/o32.S +++ /dev/null @@ -1,173 +0,0 @@ -/* ----------------------------------------------------------------------- - o32.S - Copyright (c) 1996, 1998 Cygnus Solutions - - MIPS Foreign Function Interface - - $Id: o32.S,v 1.1.1.1 1998/11/29 16:48:16 green Exp $ - - 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 <ffi.h> - -/* Only build this code if we are compiling for o32 */ - -#if defined(FFI_MIPS_O32) - -#define callback a0 -#define bytes a2 -#define flags a3 - -#define SIZEOF_FRAME ( 4 * SIZEOF_ARG + 2 * SIZEOF_ARG ) - - .text - .align 2 - .globl ffi_call_O32 - .ent ffi_call_O32 -ffi_call_O32: - - # Prologue - SUBU $sp, SIZEOF_FRAME # Frame size - REG_S $fp, SIZEOF_FRAME - 2*SIZEOF_ARG($sp) # Save frame pointer - REG_S ra, SIZEOF_FRAME - 1*SIZEOF_ARG($sp) # Save return address - move $fp, $sp - - move t9, callback # callback function pointer - REG_S flags, SIZEOF_FRAME + 3*SIZEOF_ARG($fp) # flags - - # Allocate at least 4 words in the argstack - move v0, bytes - bge bytes, 4 * SIZEOF_ARG, bigger - LI v0, 4 * SIZEOF_ARG - b sixteen - -bigger: - ADDU t0, v0, 2 * SIZEOF_ARG -1 # make sure it is aligned - and v0, t0, -2 * SIZEOF_ARG # to an 8 byte boundry - -sixteen: - SUBU $sp, $sp, v0 # move the stack pointer to reflect the - # arg space - - ADDU a0, $sp, 4 * SIZEOF_ARG - ADDU a3, $fp, SIZEOF_FRAME + 3*SIZEOF_ARG - - jal t9 - - REG_L t0, SIZEOF_FRAME + 3*SIZEOF_ARG($fp) # load the flags word - add t2, t0, 0 # and copy it into t2 - - and t0, ((1<<4)-1) # mask out the return type - SRL t2, 4 # shift our arg info - - ADDU $sp, $sp, 4 * SIZEOF_ARG # adjust $sp to new args - - bnez t0, pass_d # make it quick for int - REG_L a0, 0*SIZEOF_ARG($sp) # just go ahead and load the - REG_L a1, 1*SIZEOF_ARG($sp) # four regs. - REG_L a2, 2*SIZEOF_ARG($sp) - REG_L a3, 3*SIZEOF_ARG($sp) - b call_it - -pass_d: - bne t0, FFI_ARGS_D, pass_f - l.d $f12, 0*SIZEOF_ARG($sp) # load $fp regs from args - REG_L a2, 2*SIZEOF_ARG($sp) # passing a double - REG_L a3, 3*SIZEOF_ARG($sp) - b call_it - -pass_f: - bne t0, FFI_ARGS_F, pass_d_d - l.s $f12, 0*SIZEOF_ARG($sp) # load $fp regs from args - REG_L a1, 1*SIZEOF_ARG($sp) # passing a float - REG_L a2, 2*SIZEOF_ARG($sp) - REG_L a3, 3*SIZEOF_ARG($sp) - b call_it - -pass_d_d: - bne t0, FFI_ARGS_DD, pass_f_f - l.d $f12, 0*SIZEOF_ARG($sp) # load $fp regs from args - l.d $f14, 2*SIZEOF_ARG($sp) # passing two doubles - b call_it - -pass_f_f: - bne t0, FFI_ARGS_FF, pass_d_f - l.s $f12, 0*SIZEOF_ARG($sp) # load $fp regs from args - l.s $f14, 1*SIZEOF_ARG($sp) # passing two floats - REG_L a2, 2*SIZEOF_ARG($sp) - REG_L a3, 3*SIZEOF_ARG($sp) - b call_it - -pass_d_f: - bne t0, FFI_ARGS_DF, pass_f_d - l.d $f12, 0*SIZEOF_ARG($sp) # load $fp regs from args - l.s $f14, 2*SIZEOF_ARG($sp) # passing double and float - REG_L a3, 3*SIZEOF_ARG($sp) - b call_it - -pass_f_d: - # assume that the only other combination must be float then double - # bne t0, FFI_ARGS_F_D, call_it - l.s $f12, 0*SIZEOF_ARG($sp) # load $fp regs from args - l.d $f14, 2*SIZEOF_ARG($sp) # passing double and float - -call_it: - # Load the function pointer - REG_L t9, SIZEOF_FRAME + 5*SIZEOF_ARG($fp) - - # If the return value pointer is NULL, assume no return value. - REG_L t1, SIZEOF_FRAME + 4*SIZEOF_ARG($fp) - beqz t1, noretval - - bne t2, FFI_TYPE_INT, retfloat - jal t9 - REG_L t0, SIZEOF_FRAME + 4*SIZEOF_ARG($fp) - REG_S v0, 0(t0) - b epilogue - -retfloat: - bne t2, FFI_TYPE_FLOAT, retdouble - jal t9 - REG_L t0, SIZEOF_FRAME + 4*SIZEOF_ARG($fp) - s.s $f0, 0(t0) - b epilogue - -retdouble: - bne t2, FFI_TYPE_DOUBLE, noretval - jal t9 - REG_L t0, SIZEOF_FRAME + 4*SIZEOF_ARG($fp) - s.d $f0, 0(t0) - b epilogue - -noretval: - jal t9 - - # Epilogue -epilogue: - move $sp, $fp - REG_L $fp, SIZEOF_FRAME - 2*SIZEOF_ARG($sp) # Restore frame pointer - REG_L ra, SIZEOF_FRAME - 1*SIZEOF_ARG($sp) # Restore return address - ADDU $sp, SIZEOF_FRAME # Fix stack pointer - j ra - - .end ffi_call_O32 - -#endif diff --git a/libffi/src/mips/o32.s b/libffi/src/mips/o32.s deleted file mode 100644 index ff505a1ede1..00000000000 --- a/libffi/src/mips/o32.s +++ /dev/null @@ -1,2 +0,0 @@ -#include "o32.S" - diff --git a/libffi/src/powerpc/asm.h b/libffi/src/powerpc/asm.h deleted file mode 100644 index 2ccdc020f58..00000000000 --- a/libffi/src/powerpc/asm.h +++ /dev/null @@ -1,128 +0,0 @@ -/* ----------------------------------------------------------------------- - asm.h - Copyright (c) 1998 Geoffrey Keating - - PowerPC Assembly glue. - - $Id: asm.h,v 1.1.1.1 1998/11/29 16:48:16 green Exp $ - - 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 AUTHOR 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 ASM_GLOBAL_DIRECTIVE .globl - - -#define C_SYMBOL_NAME(name) name -/* Macro for a label. */ -#ifdef __STDC__ -#define C_LABEL(name) name##: -#else -#define C_LABEL(name) name/**/: -#endif - -/* This seems to always be the case on PPC. */ -#define ALIGNARG(log2) log2 -/* For ELF we need the `.type' directive to make shared libs work right. */ -#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg; -#define ASM_SIZE_DIRECTIVE(name) .size name,.-name - -/* If compiled for profiling, call `_mcount' at the start of each function. */ -#ifdef PROF -/* The mcount code relies on a the return address being on the stack - to locate our caller and so it can restore it; so store one just - for its benefit. */ -#ifdef PIC -#define CALL_MCOUNT \ - .pushsection; \ - .section ".data"; \ - .align ALIGNARG(2); \ -0:.long 0; \ - .previous; \ - mflr %r0; \ - stw %r0,4(%r1); \ - bl _GLOBAL_OFFSET_TABLE_@local-4; \ - mflr %r11; \ - lwz %r0,0b@got(%r11); \ - bl JUMPTARGET(_mcount); -#else /* PIC */ -#define CALL_MCOUNT \ - .section ".data"; \ - .align ALIGNARG(2); \ -0:.long 0; \ - .previous; \ - mflr %r0; \ - lis %r11,0b@ha; \ - stw %r0,4(%r1); \ - addi %r0,%r11,0b@l; \ - bl JUMPTARGET(_mcount); -#endif /* PIC */ -#else /* PROF */ -#define CALL_MCOUNT /* Do nothing. */ -#endif /* PROF */ - -#define ENTRY(name) \ - ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ - ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ - .align ALIGNARG(2); \ - C_LABEL(name) \ - CALL_MCOUNT - -#define EALIGN_W_0 /* No words to insert. */ -#define EALIGN_W_1 nop -#define EALIGN_W_2 nop;nop -#define EALIGN_W_3 nop;nop;nop -#define EALIGN_W_4 EALIGN_W_3;nop -#define EALIGN_W_5 EALIGN_W_4;nop -#define EALIGN_W_6 EALIGN_W_5;nop -#define EALIGN_W_7 EALIGN_W_6;nop - -/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes - past a 2^align boundary. */ -#ifdef PROF -#define EALIGN(name, alignt, words) \ - ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ - ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ - .align ALIGNARG(2); \ - C_LABEL(name) \ - CALL_MCOUNT \ - b 0f; \ - .align ALIGNARG(alignt); \ - EALIGN_W_##words; \ - 0: -#else /* PROF */ -#define EALIGN(name, alignt, words) \ - ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ - ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ - .align ALIGNARG(alignt); \ - EALIGN_W_##words; \ - C_LABEL(name) -#endif - -#define END(name) \ - ASM_SIZE_DIRECTIVE(name) - -#ifdef PIC -#define JUMPTARGET(name) name##@plt -#else -#define JUMPTARGET(name) name -#endif - -/* Local labels stripped out by the linker. */ -#define L(x) .L##x - diff --git a/libffi/src/powerpc/ffi.c b/libffi/src/powerpc/ffi.c deleted file mode 100644 index 6d12d653baa..00000000000 --- a/libffi/src/powerpc/ffi.c +++ /dev/null @@ -1,423 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1998 Geoffrey Keating - - PowerPC Foreign Function Interface - - $Id: ffi.c,v 1.1.1.1 1998/11/29 16:48:16 green Exp $ - - 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 AUTHOR 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> - -enum { - /* The assembly depends on these exact flags. */ - FLAG_RETURNS_NOTHING = 1 << (31-30), /* These go in cr7 */ - FLAG_RETURNS_FP = 1 << (31-29), - FLAG_RETURNS_64BITS = 1 << (31-28), - - FLAG_ARG_NEEDS_COPY = 1 << (31- 7), - FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */ - FLAG_4_GPR_ARGUMENTS = 1 << (31- 5), - FLAG_RETVAL_REFERENCE = 1 << (31- 4) -}; - -/* About the SYSV ABI. */ -enum { - NUM_GPR_ARG_REGISTERS = 8, - NUM_FPR_ARG_REGISTERS = 8 -}; -enum { ASM_NEEDS_REGISTERS = 4 }; - -/* ffi_prep_args is called by the assembly routine once stack space - has been allocated for the function's arguments. - - The stack layout we want looks like this: - - | Return address from ffi_call_SYSV 4bytes | higher addresses - |--------------------------------------------| - | Previous backchain pointer 4 | stack pointer here - |--------------------------------------------|<+ <<< on entry to - | Saved r28-r31 4*4 | | ffi_call_SYSV - |--------------------------------------------| | - | GPR registers r3-r10 8*4 | | ffi_call_SYSV - |--------------------------------------------| | - | FPR registers f1-f8 (optional) 8*8 | | - |--------------------------------------------| | stack | - | Space for copied structures | | grows | - |--------------------------------------------| | down V - | Parameters that didn't fit in registers | | - |--------------------------------------------| | lower addresses - | Space for callee's LR 4 | | - |--------------------------------------------| | stack pointer here - | Current backchain pointer 4 |-/ during - |--------------------------------------------| <<< ffi_call_SYSV - - */ - -/*@-exportheader@*/ -void ffi_prep_args(extended_cif *ecif, unsigned *const stack) -/*@=exportheader@*/ -{ - const unsigned bytes = ecif->cif->bytes; - const unsigned flags = ecif->cif->flags; - - /* 'stacktop' points at the previous backchain pointer. */ - unsigned *const stacktop = stack + (ecif->cif->bytes / sizeof(unsigned)); - - /* 'gpr_base' points at the space for gpr3, and grows upwards as - we use GPR registers. */ - unsigned *gpr_base = stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS; - int intarg_count = 0; - - /* 'fpr_base' points at the space for fpr1, and grows upwards as - we use FPR registers. */ - double *fpr_base = (double *)gpr_base - NUM_FPR_ARG_REGISTERS; - int fparg_count = 0; - - /* 'copy_space' grows down as we put structures in it. It should - stay 16-byte aligned. */ - char *copy_space = ((flags & FLAG_FP_ARGUMENTS) - ? (char *)fpr_base - : (char *)gpr_base); - - /* 'next_arg' grows up as we put parameters in it. */ - unsigned *next_arg = stack + 2; - - int i; - ffi_type **ptr; - double double_tmp; - void **p_argv; - size_t struct_copy_size; - unsigned gprvalue; - - /* Check that everything starts aligned properly. */ - FFI_ASSERT(((unsigned)(char *)stack & 0xF) == 0); - FFI_ASSERT(((unsigned)(char *)copy_space & 0xF) == 0); - FFI_ASSERT(((unsigned)(char *)stacktop & 0xF) == 0); - FFI_ASSERT((bytes & 0xF) == 0); - FFI_ASSERT(copy_space >= (char *)next_arg); - - /* Deal with return values that are actually pass-by-reference. */ - if (flags & FLAG_RETVAL_REFERENCE) - { - *gpr_base++ = (unsigned)(char *)ecif->rvalue; - intarg_count++; - } - - /* Now for the arguments. */ - p_argv = ecif->avalue; - for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs; - i > 0; - i--, ptr++, p_argv++) - { - switch ((*ptr)->type) - { - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - if ((*ptr)->type == FFI_TYPE_FLOAT) - double_tmp = *(float *)*p_argv; - else - double_tmp = *(double *)*p_argv; - - if (fparg_count >= NUM_FPR_ARG_REGISTERS) - { - if (intarg_count%2 != 0) - { - intarg_count++; - next_arg++; - } - *(double *)next_arg = double_tmp; - next_arg += 2; - } - else - *fpr_base++ = double_tmp; - fparg_count++; - FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); - break; - - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - if (intarg_count == NUM_GPR_ARG_REGISTERS-1) - intarg_count++; - if (intarg_count >= NUM_GPR_ARG_REGISTERS) - { - if (intarg_count%2 != 0) - { - intarg_count++; - next_arg++; - } - *(long long *)next_arg = *(long long *)*p_argv; - next_arg += 2; - } - else - { - *(long long *)gpr_base = *(long long *)*p_argv; - gpr_base += 2; - } - intarg_count += 2; - break; - - case FFI_TYPE_STRUCT: -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: -#endif - struct_copy_size = ((*ptr)->size + 15) & ~0xF; - copy_space -= struct_copy_size; - memcpy(copy_space, (char *)*p_argv, (*ptr)->size); - - gprvalue = (unsigned)copy_space; - - FFI_ASSERT(copy_space > (char *)next_arg); - FFI_ASSERT(flags & FLAG_ARG_NEEDS_COPY); - goto putgpr; - - case FFI_TYPE_UINT8: - gprvalue = *(unsigned char *)*p_argv; - goto putgpr; - case FFI_TYPE_SINT8: - gprvalue = *(signed char *)*p_argv; - goto putgpr; - case FFI_TYPE_UINT16: - gprvalue = *(unsigned short *)*p_argv; - goto putgpr; - case FFI_TYPE_SINT16: - gprvalue = *(signed short *)*p_argv; - goto putgpr; - - case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - case FFI_TYPE_POINTER: - gprvalue = *(unsigned *)*p_argv; - putgpr: - if (intarg_count >= NUM_GPR_ARG_REGISTERS) - *next_arg++ = gprvalue; - else - *gpr_base++ = gprvalue; - intarg_count++; - break; - } - } - - /* Check that we didn't overrun the stack... */ - FFI_ASSERT(copy_space >= (char *)next_arg); - FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS); - FFI_ASSERT((unsigned *)fpr_base - <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS); - FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4); -} - -/* Perform machine dependent cif processing */ -ffi_status ffi_prep_cif_machdep(ffi_cif *cif) -{ - /* All this is for the SYSV ABI. */ - int i; - ffi_type **ptr; - unsigned bytes; - int fparg_count = 0, intarg_count = 0; - unsigned flags = 0; - unsigned struct_copy_size = 0; - - /* All the machine-independent calculation of cif->bytes will be wrong. - Redo the calculation for SYSV. */ - - /* Space for the frame pointer, callee's LR, and the asm's temp regs. */ - bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof(int); - - /* Space for the GPR registers. */ - bytes += NUM_GPR_ARG_REGISTERS * sizeof(int); - - /* Return value handling. The rules are as follows: - - 32-bit (or less) integer values are returned in gpr3; - - Structures of size <= 4 bytes also returned in gpr3; - - 64-bit integer values and structures between 5 and 8 bytes are returned - in gpr3 and gpr4; - - Single/double FP values are returned in fpr1; - - Larger structures and long double (if not equivalent to double) values - are allocated space and a pointer is passed as the first argument. */ - switch (cif->rtype->type) - { - case FFI_TYPE_DOUBLE: - flags |= FLAG_RETURNS_64BITS; - /* Fall through. */ - case FFI_TYPE_FLOAT: - flags |= FLAG_RETURNS_FP; - break; - - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - flags |= FLAG_RETURNS_64BITS; - break; - - case FFI_TYPE_STRUCT: - if (cif->abi != FFI_GCC_SYSV) - if (cif->rtype->size <= 4) - break; - else if (cif->rtype->size <= 8) - { - flags |= FLAG_RETURNS_64BITS; - break; - } - /* else fall through. */ -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: -#endif - intarg_count++; - flags |= FLAG_RETVAL_REFERENCE; - /* Fall through. */ - case FFI_TYPE_VOID: - flags |= FLAG_RETURNS_NOTHING; - break; - - default: - /* Returns 32-bit integer, or similar. Nothing to do here. */ - break; - } - - /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the - first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest - goes on the stack. Structures and long doubles (if not equivalent - to double) are passed as a pointer to a copy of the structure. - Stuff on the stack needs to keep proper alignment. */ - for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) - { - switch ((*ptr)->type) - { - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - fparg_count++; - /* If this FP arg is going on the stack, it must be - 8-byte-aligned. */ - if (fparg_count > NUM_FPR_ARG_REGISTERS - && intarg_count%2 != 0) - intarg_count++; - break; - - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - /* 'long long' arguments are passed as two words, but - either both words must fit in registers or both go - on the stack. If they go on the stack, they must - be 8-byte-aligned. */ - if (intarg_count == NUM_GPR_ARG_REGISTERS-1 - || intarg_count >= NUM_GPR_ARG_REGISTERS && intarg_count%2 != 0) - intarg_count++; - intarg_count += 2; - break; - - case FFI_TYPE_STRUCT: -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: -#endif - /* We must allocate space for a copy of these to enforce - pass-by-value. Pad the space up to a multiple of 16 - bytes (the maximum alignment required for anything under - the SYSV ABI). */ - struct_copy_size += ((*ptr)->size + 15) & ~0xF; - /* Fall through (allocate space for the pointer). */ - - default: - /* Everything else is passed as a 4-byte word in a GPR, either - the object itself or a pointer to it. */ - intarg_count++; - break; - } - } - - if (fparg_count != 0) - flags |= FLAG_FP_ARGUMENTS; - if (intarg_count > 4) - flags |= FLAG_4_GPR_ARGUMENTS; - if (struct_copy_size != 0) - flags |= FLAG_ARG_NEEDS_COPY; - - /* Space for the FPR registers, if needed. */ - if (fparg_count != 0) - bytes += NUM_FPR_ARG_REGISTERS * sizeof(double); - - /* Stack space. */ - if (intarg_count > NUM_GPR_ARG_REGISTERS) - bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof(int); - if (fparg_count > NUM_FPR_ARG_REGISTERS) - bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof(double); - - /* The stack space allocated needs to be a multiple of 16 bytes. */ - bytes = (bytes + 15) & ~0xF; - - /* Add in the space for the copied structures. */ - bytes += struct_copy_size; - - cif->flags = flags; - cif->bytes = bytes; - - return FFI_OK; -} - -/*@-declundef@*/ -/*@-exportheader@*/ -extern void ffi_call_SYSV(/*@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: - case FFI_GCC_SYSV: - /*@-usedef@*/ - ffi_call_SYSV(&ecif, -cif->bytes, - cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ - break; - default: - FFI_ASSERT(0); - break; - } -} diff --git a/libffi/src/powerpc/sysv.S b/libffi/src/powerpc/sysv.S deleted file mode 100644 index 88b037844f3..00000000000 --- a/libffi/src/powerpc/sysv.S +++ /dev/null @@ -1,119 +0,0 @@ -/* ----------------------------------------------------------------------- - sysv.h - Copyright (c) 1998 Geoffrey Keating - - PowerPC Assembly glue. - - $Id: sysv.S,v 1.1.1.1 1998/11/29 16:48:16 green Exp $ - - 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 AUTHOR 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 <ffi.h> -#include <powerpc/asm.h> - - .globl ffi_prep_args -ENTRY(ffi_call_SYSV) - /* Save the old stack pointer as AP. */ - mr %r8,%r1 - - /* Allocate the stack space we need. */ - stwux %r1,%r1,%r4 - /* Save registers we use. */ - mflr %r9 - stw %r28,-16(%r8) - stw %r29,-12(%r8) - stw %r30, -8(%r8) - stw %r31, -4(%r8) - stw %r9, 4(%r8) - - /* Save arguments over call... */ - mr %r31,%r5 /* flags, */ - mr %r30,%r6 /* rvalue, */ - mr %r29,%r7 /* function address, */ - mr %r28,%r8 /* our AP. */ - - /* Call ffi_prep_args. */ - mr %r4,%r1 - bl JUMPTARGET(ffi_prep_args) - - /* Now do the call. */ - /* Set up cr1 with bits 4-7 of the flags. */ - mtcrf 0x40,%r31 - /* Get the address to call into CTR. */ - mtctr %r29 - /* Load all those argument registers. */ - lwz %r3,-16-(8*4)(%r28) - lwz %r4,-16-(7*4)(%r28) - lwz %r5,-16-(6*4)(%r28) - lwz %r6,-16-(5*4)(%r28) - bf- 5,1f - nop - lwz %r7,-16-(4*4)(%r28) - lwz %r8,-16-(3*4)(%r28) - lwz %r9,-16-(2*4)(%r28) - lwz %r10,-16-(1*4)(%r28) - nop -1: - - /* Load all the FP registers. */ - bf- 6,2f - lfd %f1,-16-(8*4)-(8*8)(%r28) - lfd %f2,-16-(8*4)-(7*8)(%r28) - lfd %f3,-16-(8*4)-(6*8)(%r28) - lfd %f4,-16-(8*4)-(5*8)(%r28) - nop - lfd %f5,-16-(8*4)-(4*8)(%r28) - lfd %f6,-16-(8*4)-(3*8)(%r28) - lfd %f7,-16-(8*4)-(2*8)(%r28) - lfd %f8,-16-(8*4)-(1*8)(%r28) -2: - - /* Make the call. */ - bctrl - - /* Now, deal with the return value. */ - mtcrf 0x01,%r31 - bt- 30,L(done_return_value) - bt- 29,L(fp_return_value) - stw %r3,0(%r30) - bf+ 28,L(done_return_value) - stw %r4,4(%r30) - /* Fall through... */ - -L(done_return_value): - /* Restore the registers we used and return. */ - lwz %r9, 4(%r28) - lwz %r31, -4(%r28) - mtlr %r9 - lwz %r30, -8(%r28) - lwz %r29,-12(%r28) - lwz %r28,-16(%r28) - lwz %r1,0(%r1) - blr - -L(fp_return_value): - bf 28,L(float_return_value) - stfd %f1,0(%r30) - b L(done_return_value) -L(float_return_value): - stfs %f1,0(%r30) - b L(done_return_value) -END(ffi_call_SYSV) diff --git a/libffi/src/prep_cif.c b/libffi/src/prep_cif.c deleted file mode 100644 index 4c731b99455..00000000000 --- a/libffi/src/prep_cif.c +++ /dev/null @@ -1,143 +0,0 @@ -/* ----------------------------------------------------------------------- - prep_cif.c - Copyright (c) 1996, 1998 Cygnus Solutions - - $Id: prep_cif.c,v 1.1.1.1 1998/11/29 16:48:16 green Exp $ - - 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> - - -/* Round up to SIZEOF_ARG. */ - -#define STACK_ARG_SIZE(x) ALIGN(x, SIZEOF_ARG) - -/* Perform machine independent initialization of aggregate type - specifications. */ - -static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg) -{ - ffi_type **ptr; - - FFI_ASSERT(arg != NULL); - - /*@-usedef@*/ - - FFI_ASSERT(arg->elements != NULL); - FFI_ASSERT(arg->size == 0); - FFI_ASSERT(arg->alignment == 0); - - ptr = &(arg->elements[0]); - - while ((*ptr) != NULL) - { - if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) - return FFI_BAD_TYPEDEF; - - /* Perform a sanity check on the argument type */ - FFI_ASSERT(ffi_type_test((*ptr))); - - arg->size = ALIGN(arg->size, (*ptr)->alignment); - arg->size += (*ptr)->size; - - arg->alignment = (arg->alignment > (*ptr)->alignment) ? - arg->alignment : (*ptr)->alignment; - - ptr++; - } - - if (arg->size == 0) - return FFI_BAD_TYPEDEF; - else - return FFI_OK; - - /*@=usedef@*/ -} - -/* Perform machine independent ffi_cif preparation, then call - machine dependent routine. */ - -ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, - ffi_abi abi, unsigned int nargs, - /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, - /*@dependent@*/ ffi_type **atypes) -{ - unsigned bytes = 0; - unsigned int i; - ffi_type **ptr; - - FFI_ASSERT(cif != NULL); - FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi < FFI_LAST_ABI)); - - cif->abi = abi; - cif->arg_types = atypes; - cif->nargs = nargs; - cif->rtype = rtype; - - cif->flags = 0; - - /* Initialize the return type if necessary */ - /*@-usedef@*/ - if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK)) - return FFI_BAD_TYPEDEF; - /*@=usedef@*/ - - /* Perform a sanity check on the return type */ - FFI_ASSERT(ffi_type_test(cif->rtype)); - -#ifndef M68K - /* Make space for the return structure pointer */ - if (cif->rtype->type == FFI_TYPE_STRUCT) - bytes = STACK_ARG_SIZE(sizeof(void*)); -#endif - - for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) - { - /* Perform a sanity check on the argument type */ - FFI_ASSERT(ffi_type_test(*ptr)); - - /* Initialize any uninitialized aggregate type definitions */ - if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) - return FFI_BAD_TYPEDEF; - -#ifdef SPARC - if ((*ptr)->type == FFI_TYPE_STRUCT - || (*ptr)->type == FFI_TYPE_LONGDOUBLE) - bytes += sizeof(void*); - else -#endif - { - /* Add any padding if necessary */ - if (((*ptr)->alignment - 1) & bytes) - bytes = ALIGN(bytes, (*ptr)->alignment); - - bytes += STACK_ARG_SIZE((*ptr)->size); - } - } - - cif->bytes = bytes; - - /* Perform machine dependent cif processing */ - return ffi_prep_cif_machdep(cif); -} - diff --git a/libffi/src/raw_api.c b/libffi/src/raw_api.c deleted file mode 100644 index 45cb0043c4d..00000000000 --- a/libffi/src/raw_api.c +++ /dev/null @@ -1,242 +0,0 @@ -/* ----------------------------------------------------------------------- - raw_api.c - Copyright (c) 1999 Cygnus Solutions - - Author: Kresten Krab Thorup <krab@gnu.org> - - $Id $ - - 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. - ----------------------------------------------------------------------- */ - -/* This file defines generic functions for use with the raw api. */ - -#include <ffi.h> -#include <ffi_common.h> - -#if !FFI_NO_RAW_API - -size_t -ffi_raw_size (ffi_cif *cif) -{ - size_t result = 0; - int i; - - ffi_type **at = cif->arg_types; - - for (i = cif->nargs-1; i >= 0; i--, at++) - { -#if !FFI_NO_STRUCTS - if ((*at)->type == FFI_TYPE_STRUCT) - result += ALIGN (sizeof (void*), SIZEOF_ARG); - else -#endif - result += ALIGN ((*at)->size, SIZEOF_ARG); - } - - return result; -} - - -void -ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args) -{ - unsigned i; - ffi_type **tp = cif->arg_types; - -#if WORDS_BIGENDIAN - - for (i = 0; i < cif->nargs; i++, tp++, args++) - { - switch ((*tp)->type) - { - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 1); - break; - - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT16: - *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 2); - break; - -#if SIZEOF_ARG >= 4 - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 4); - break; -#endif - -#if !FFI_NO_STRUCTS - case FFI_TYPE_STRUCT: - *args = (raw++)->ptr; - break; -#endif - - case FFI_TYPE_POINTER: - *args = (void*) &(raw++)->ptr; - break; - - default: - *args = raw; - raw += ALIGN ((*tp)->size, SIZEOF_ARG) / SIZEOF_ARG; - } - } - -#else /* WORDS_BIGENDIAN */ - -#if !PDP - - /* then assume little endian */ - for (i = 0; i < cif->nargs; i++, tp++, args++) - { -#if !FFI_NO_STRUCTS - if ((*tp)->type == FFI_TYPE_STRUCT) - { - *args = (raw++)->ptr; - } - else -#endif - { - *args = (void*) raw; - raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*); - } - } - -#else -#error "pdp endian not supported" -#endif /* ! PDP */ - -#endif /* WORDS_BIGENDIAN */ -} - -void -ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw) -{ - unsigned i; - ffi_type **tp = cif->arg_types; - - for (i = 0; i < cif->nargs; i++, tp++, args++) - { - switch ((*tp)->type) - { - case FFI_TYPE_UINT8: - (raw++)->uint = *(UINT8*) (*args); - break; - - case FFI_TYPE_SINT8: - (raw++)->sint = *(SINT8*) (*args); - break; - - case FFI_TYPE_UINT16: - (raw++)->uint = *(UINT16*) (*args); - break; - - case FFI_TYPE_SINT16: - (raw++)->sint = *(SINT16*) (*args); - break; - -#if SIZEOF_ARG >= 4 - case FFI_TYPE_UINT32: - (raw++)->uint = *(UINT32*) (*args); - break; - - case FFI_TYPE_SINT32: - (raw++)->sint = *(SINT32*) (*args); - break; -#endif - -#if !FFI_NO_STRUCTS - case FFI_TYPE_STRUCT: - (raw++)->ptr = *args; - break; -#endif - - case FFI_TYPE_POINTER: - (raw++)->ptr = **(void***) args; - break; - - default: - memcpy ((void*) raw->data, (void*)*args, (*tp)->size); - raw += ALIGN ((*tp)->size, SIZEOF_ARG) / SIZEOF_ARG; - } - } -} - -#if !FFI_NATIVE_RAW_API - - -/* This is a generic definition of ffi_raw_call, to be used if the - * native system does not provide a machine-specific implementation. - * Having this, allows code to be written for the raw API, without - * the need for system-specific code to handle input in that format; - * these following couple of functions will handle the translation forth - * and back automatically. */ - -void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ ffi_raw *raw) -{ - void **avalue = (void**) alloca (cif->nargs * sizeof (void*)); - ffi_raw_to_ptrarray (cif, raw, avalue); - ffi_call (cif, fn, rvalue, avalue); -} - -#if FFI_CLOSURES /* base system provides closures */ - -static void -ffi_translate_args (ffi_cif *cif, void *rvalue, - void **avalue, void *user_data) -{ - ffi_raw *raw = (ffi_raw*)alloca (ffi_raw_size (cif)); - ffi_raw_closure *cl = (ffi_raw_closure*)user_data; - - ffi_ptrarray_to_raw (cif, avalue, raw); - (*cl->fun) (cif, rvalue, raw, cl->user_data); -} - -/* Again, here is the generic version of ffi_prep_raw_closure, which - * will install an intermediate "hub" for translation of arguments from - * the pointer-array format, to the raw format */ - -ffi_status -ffi_prep_raw_closure (ffi_raw_closure* cl, - ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void *user_data) -{ - ffi_status status; - - status = ffi_prep_closure ((ffi_closure*) cl, - cif, - &ffi_translate_args, - (void*)cl); - if (status == FFI_OK) - { - cl->fun = fun; - cl->user_data = user_data; - } - - return status; -} - -#endif /* FFI_CLOSURES */ -#endif /* !FFI_NATIVE_RAW_API */ -#endif /* !FFI_NO_RAW_API */ diff --git a/libffi/src/sparc/ffi.c b/libffi/src/sparc/ffi.c deleted file mode 100644 index 8ca6710c94a..00000000000 --- a/libffi/src/sparc/ffi.c +++ /dev/null @@ -1,216 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1996 Cygnus Solutions - - Sparc Foreign Function Interface - - $Id: ffi.c,v 1.1.1.1 1998/11/29 16:48:16 green Exp $ - - 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> - -/* 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) -{ - int i; - int tmp; - int avn; - void **p_argv; - char *argp; - ffi_type **p_arg; - - tmp = 0; - - /* Skip 16 words for the window save area */ - argp = stack + 16*sizeof(void*); - - /* This should only really be done when we are returning a structure, - however, it's faster just to do it all the time... - - if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) */ - *(void **) argp = ecif->rvalue; - - /* And 1 word for the structure return value. */ - argp += sizeof(void*); - -#ifdef USING_PURIFY - /* Purify will probably complain in our assembly routine, unless we - zero out this memory. */ - - ((int*)argp)[0] = 0; - ((int*)argp)[1] = 0; - ((int*)argp)[2] = 0; - ((int*)argp)[3] = 0; - ((int*)argp)[4] = 0; - ((int*)argp)[5] = 0; -#endif - - avn = ecif->cif->nargs; - p_argv = ecif->avalue; - - for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; - i && avn; - i--, p_arg++) - { - size_t z; - - if (avn) - { - avn--; - if ((*p_arg)->type == FFI_TYPE_STRUCT - || (*p_arg)->type == FFI_TYPE_LONGDOUBLE) - { - *(unsigned int *) argp = (unsigned int)(* p_argv); - z = sizeof(void*); - } - else - { - z = (*p_arg)->size; - if (z < sizeof(int)) - { - z = sizeof(int); - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - *(signed int *) argp = *(SINT8 *)(* p_argv); - break; - - case FFI_TYPE_UINT8: - *(unsigned int *) argp = *(UINT8 *)(* p_argv); - break; - - case FFI_TYPE_SINT16: - *(signed int *) argp = *(SINT16 *)(* p_argv); - break; - - case FFI_TYPE_UINT16: - *(unsigned int *) argp = *(UINT16 *)(* p_argv); - break; - - case FFI_TYPE_SINT32: - *(signed int *) argp = *(SINT32 *)(* p_argv); - break; - - case FFI_TYPE_UINT32: - *(unsigned int *) argp = *(UINT32 *)(* p_argv); - break; - - default: - FFI_ASSERT(0); - } - } - 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) -{ - /* If we are returning a struct, this will already have been added. - Otherwise we need to add it because it's always got to be there! */ - - if (cif->rtype->type != FFI_TYPE_STRUCT) - cif->bytes += sizeof(void*); - - /* sparc call frames require that space is allocated for 6 args, - even if they aren't used. Make that space if necessary. */ - - if (cif->bytes < 4*6+4) - cif->bytes = 4*6+4; - - /* Adjust cif->bytes. to include 16 words for the window save area, - and maybe the struct/union return pointer area, */ - - cif->bytes += 64; - - /* The stack must be double word aligned, so round bytes up - appropriately. */ - - cif->bytes = ALIGN(cif->bytes, 2*sizeof(void*)); - - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_VOID: - case FFI_TYPE_STRUCT: - cif->flags = cif->rtype->type; - break; - - case FFI_TYPE_FLOAT: - cif->flags = FFI_TYPE_FLOAT; - break; - - case FFI_TYPE_DOUBLE: - cif->flags = FFI_TYPE_DOUBLE; - break; - - default: - cif->flags = FFI_TYPE_INT; - break; - } - - return FFI_OK; -} - -extern int ffi_call_V8(void *, extended_cif *, unsigned, - unsigned, unsigned *, void (*fn)()); - -void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, 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)) - ecif.rvalue = alloca(cif->rtype->size); - else - ecif.rvalue = rvalue; - - switch (cif->abi) - { - case FFI_V8: - ffi_call_V8(ffi_prep_args, &ecif, cif->bytes, - cif->flags, rvalue, fn); - break; - default: - FFI_ASSERT(0); - break; - } -} diff --git a/libffi/src/sparc/v8.S b/libffi/src/sparc/v8.S deleted file mode 100644 index da0dbe694b4..00000000000 --- a/libffi/src/sparc/v8.S +++ /dev/null @@ -1,85 +0,0 @@ -/* ----------------------------------------------------------------------- - v8.S - Copyright (c) 1996, 1997 Cygnus Solutions - - Sparc Foreign Function Interface - - $Id: v8.S,v 1.1.1.1 1998/11/29 16:48:16 green Exp $ - - 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 <ffi.h> - -#define STACKFRAME 96 /* Minimum stack framesize for SPARC */ -#define ARGS (64+4) /* Offset of register area in frame */ - -.text - .align 8 -.globl ffi_call_V8 -.globl _ffi_call_V8 - -ffi_call_V8: -_ffi_call_V8: - save %sp, -STACKFRAME, %sp - - sub %sp, %i2, %sp ! alloca() space in stack for frame to set up - add %sp, STACKFRAME, %l0 ! %l0 has start of - ! frame to set up - - mov %l0, %o0 ! call routine to set up frame - call %i0 - mov %i1, %o1 ! (delay) - - ld [%l0+ARGS], %o0 ! call foreign function - ld [%l0+ARGS+4], %o1 - ld [%l0+ARGS+8], %o2 - ld [%l0+ARGS+12], %o3 - ld [%l0+ARGS+16], %o4 - ld [%l0+ARGS+20], %o5 - call %i5 - mov %l0, %sp ! (delay) switch to frame - - ! If the return value pointer is NULL, assume no return value. - tst %i4 - bz done - nop - - cmp %i3, FFI_TYPE_INT - be,a done - st %o0, [%i4] ! (delay) - - cmp %i3, FFI_TYPE_FLOAT - be,a done - st %f0, [%i4+0] ! (delay) - - cmp %i3, FFI_TYPE_DOUBLE - bne done - nop - st %f0, [%i4+0] - st %f1, [%i4+4] - -done: - ret - restore - -.ffi_call_V8_end: - .size ffi_call_V8,.ffi_call_V8_end-ffi_call_V8 - diff --git a/libffi/src/types.c b/libffi/src/types.c deleted file mode 100644 index abf276d5cdd..00000000000 --- a/libffi/src/types.c +++ /dev/null @@ -1,98 +0,0 @@ -/* ----------------------------------------------------------------------- - types.c - Copyright (c) 1996, 1998 Cygnus Solutions - - Predefined ffi_types needed by libffi. - - $Id: types.c,v 1.1.1.1 1998/11/29 16:48:16 green Exp $ - - 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> - -/* Type definitions */ - -#define FFI_INTEGRAL_TYPEDEF(n, s, a, t) ffi_type ffi_type_##n = { s, a, t, NULL } -#define FFI_AGGREGATE_TYPEDEF(n, e) ffi_type ffi_type_##n = { 0, 0, FFI_TYPE_STRUCT, e } - -/* Size and alignment are fake here. They must not be 0. */ -FFI_INTEGRAL_TYPEDEF(void, 1, 1, FFI_TYPE_VOID); - -FFI_INTEGRAL_TYPEDEF(uint8, 1, 1, FFI_TYPE_UINT8); -FFI_INTEGRAL_TYPEDEF(sint8, 1, 1, FFI_TYPE_SINT8); -FFI_INTEGRAL_TYPEDEF(uint16, 2, 2, FFI_TYPE_UINT16); -FFI_INTEGRAL_TYPEDEF(sint16, 2, 2, FFI_TYPE_SINT16); -FFI_INTEGRAL_TYPEDEF(uint32, 4, 4, FFI_TYPE_UINT32); -FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32); -FFI_INTEGRAL_TYPEDEF(pointer, 4, 4, FFI_TYPE_POINTER); -FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT); - - -#ifdef X86 - -FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); - -#elif defined ARM - -FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); - -#elif defined M68K - -FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); - -#else - -FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64); - -#endif - - -#ifdef X86 - -FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE); - -#elif defined ARM - -FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE); - -#elif defined M68K - -FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE); - -#elif defined SPARC - -FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 16, 8, FFI_TYPE_LONGDOUBLE); - -#else - -FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 8, 8, FFI_TYPE_LONGDOUBLE); - -#endif - diff --git a/libffi/src/x86/ffi.c b/libffi/src/x86/ffi.c deleted file mode 100644 index 1e58e031e63..00000000000 --- a/libffi/src/x86/ffi.c +++ /dev/null @@ -1,510 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1996, 1998, 1999 Cygnus Solutions - - x86 Foreign Function Interface - - $Id: ffi.c,v 1.3 1999/08/08 13:05:12 green Exp $ - - 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> - -/* 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; - - tmp = 0; - argp = stack; - - if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) { - *(void **) argp = ecif->rvalue; - argp += 4; - } - - avn = ecif->cif->nargs; - p_argv = ecif->avalue; - - for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; - (i != 0) && (avn != 0); - i--, p_arg++) - { - size_t z; - - /* Align if necessary */ - if (((*p_arg)->alignment - 1) & (unsigned) argp) { - argp = (char *) ALIGN(argp, (*p_arg)->alignment); - } - - if (avn != 0) - { - avn--; - 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_SINT32: - *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv); - break; - - case FFI_TYPE_UINT32: - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); - break; - - case FFI_TYPE_STRUCT: - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); - break; - - default: - FFI_ASSERT(0); - } - } - 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) -{ - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_VOID: - case FFI_TYPE_STRUCT: - case FFI_TYPE_SINT64: - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - case FFI_TYPE_LONGDOUBLE: - cif->flags = (unsigned) cif->rtype->type; - break; - - case FFI_TYPE_UINT64: - cif->flags = FFI_TYPE_SINT64; - break; - - default: - cif->flags = FFI_TYPE_INT; - 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; - } -} - - -/** private members **/ - -static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, - void** args, ffi_cif* cif); -static void ffi_closure_SYSV (); -static void ffi_closure_raw_SYSV (); - -/* This function is jumped to by the trampoline, on entry, %ecx (a - * caller-save register) holds the address of the closure. - * Clearly, this requires __GNUC__, so perhaps we should translate this - * into an assembly file if this is to be distributed with ffi. - */ - -static void -ffi_closure_SYSV () -{ - // this is our return value storage - long double res; - - // our various things... - void *args; - ffi_cif *cif; - void **arg_area; - ffi_closure *closure; - unsigned short rtype; - void *resp = (void*)&res; - - /* grab the trampoline context pointer */ - asm ("movl %%ecx,%0" : "=r" (closure)); - - cif = closure->cif; - arg_area = (void**) alloca (cif->nargs * sizeof (void*)); - asm ("leal 8(%%ebp),%0" : "=q" (args)); - - /* 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, (void**)&resp, arg_area, cif); - - (closure->fun) (cif, resp, arg_area, closure->user_data); - - rtype = cif->flags; - - /* now, do a generic return based on the value of rtype */ - if (rtype == FFI_TYPE_INT) - { - asm ("movl (%0),%%eax" : : "r" (resp) : "eax"); - } - else if (rtype == FFI_TYPE_FLOAT) - { - asm ("flds (%0)" : : "r" (resp) : "st" ); - } - else if (rtype == FFI_TYPE_DOUBLE) - { - asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_LONGDOUBLE) - { - asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_SINT64) - { - asm ("movl 0(%0),%%eax;" - "movl 4(%0),%%edx" - : : "r"(resp) - : "eax", "edx"); - } -} - -/*@-exportheader@*/ -static void -ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, - void **avalue, ffi_cif *cif) -/*@=exportheader@*/ -{ - register unsigned int i; - register int tmp; - register unsigned int avn; - register void **p_argv; - register char *argp; - register ffi_type **p_arg; - - tmp = 0; - argp = stack; - - if ( cif->rtype->type == FFI_TYPE_STRUCT ) { - *rvalue = *(void **) argp; - argp += 4; - } - - avn = cif->nargs; - p_argv = avalue; - - for (i = cif->nargs, p_arg = cif->arg_types; - (i != 0) && (avn != 0); - i--, p_arg++) - { - size_t z; - - /* Align if necessary */ - if (((*p_arg)->alignment - 1) & (unsigned) argp) { - argp = (char *) ALIGN(argp, (*p_arg)->alignment); - } - - if (avn != 0) - { - avn--; - z = (*p_arg)->size; - - /* because we're little endian, this is - what it turns into. */ - - *p_argv = (void*) argp; - - p_argv++; - argp += z; - } - } - - return; -} - -/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */ - -#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 int __dis = __fun - ((unsigned int) __tramp + 10); \ - *(unsigned char*) &__tramp[0] = 0xb9; \ - *(unsigned int*) &__tramp[1] = __ctx; \ - *(unsigned char*) &__tramp[5] = 0xe9; \ - *(unsigned int*) &__tramp[6] = __dis; \ - }) - - -/* the cif must already be prep'ed */ - -ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data) -{ - FFI_ASSERT (cif->abi == FFI_SYSV); - - FFI_INIT_TRAMPOLINE (&closure->tramp[0], \ - &ffi_closure_SYSV, \ - (void*)closure); - - closure->cif = cif; - closure->user_data = user_data; - closure->fun = fun; - - return FFI_OK; -} - -/* ------- Native raw API support -------------------------------- */ - -#if !FFI_NO_RAW_API - -static void -ffi_closure_raw_SYSV () -{ - // this is our return value storage - long double res; - - // our various things... - void *args; - ffi_raw *raw_args; - ffi_cif *cif; - ffi_raw_closure *closure; - unsigned short rtype; - void *resp = (void*)&res; - - /* grab the trampoline context pointer */ - asm ("movl %%ecx,%0" : "=r" (closure)); - - /* take the argument pointer */ - asm ("leal 8(%%ebp),%0" : "=q" (args)); - - /* get the cif */ - cif = closure->cif; - - /* the SYSV/X86 abi matches the RAW API exactly, well.. almost */ - raw_args = (ffi_raw*) args; - - (closure->fun) (cif, resp, raw_args, closure->user_data); - - rtype = cif->flags; - - /* now, do a generic return based on the value of rtype */ - if (rtype == FFI_TYPE_INT) - { - asm ("movl (%0),%%eax" : : "r" (resp) : "eax"); - } - else if (rtype == FFI_TYPE_FLOAT) - { - asm ("flds (%0)" : : "r" (resp) : "st" ); - } - else if (rtype == FFI_TYPE_DOUBLE) - { - asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_LONGDOUBLE) - { - asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_SINT64) - { - asm ("movl 0(%0),%%eax; movl 4(%0),%%edx" - : : "r"(resp) - : "eax", "edx"); - } -} - - - - -ffi_status -ffi_prep_raw_closure (ffi_raw_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void *user_data) -{ - int i; - - FFI_ASSERT (cif->abi == FFI_SYSV); - - // we currently don't support certain kinds of arguments for raw - // closures. This should be implemented by a seperate assembly language - // routine, since it would require argument processing, something we - // don't do now for performance. - - for (i = cif->nargs-1; i >= 0; i--) - { - FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT); - FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE); - } - - - FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV, - (void*)closure); - - closure->cif = cif; - closure->user_data = user_data; - closure->fun = fun; - - return FFI_OK; -} - -static void -ffi_prep_args_raw(char *stack, extended_cif *ecif) -{ - memcpy (stack, ecif->avalue, ecif->cif->bytes); -} - -/* we borrow this routine from libffi (it must be changed, though, to - * actually call the function passed in the first argument. as of - * libffi-1.20, this is not the case.) - */ - -extern void -ffi_call_SYSV(void (*)(char *, extended_cif *), - /*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, - void (*fn)()); - -void -ffi_raw_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ ffi_raw *fake_avalue) -{ - extended_cif ecif; - void **avalue = (void **)fake_avalue; - - 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_raw, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ - break; - default: - FFI_ASSERT(0); - break; - } -} - -#endif diff --git a/libffi/src/x86/sysv.S b/libffi/src/x86/sysv.S deleted file mode 100644 index 4c8473ae901..00000000000 --- a/libffi/src/x86/sysv.S +++ /dev/null @@ -1,168 +0,0 @@ -/* ----------------------------------------------------------------------- - sysv.S - Copyright (c) 1996, 1998 Cygnus Solutions - - X86 Foreign Function Interface - - $Id: sysv.S,v 1.2 1999/08/04 18:00:05 green Exp $ - - 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 <ffi.h> - -.text - -.globl ffi_prep_args - - # This assumes we are using gas. - .balign 16 -.globl ffi_call_SYSV - .type ffi_call_SYSV,@function - -ffi_call_SYSV: -.LFB1: - pushl %ebp -.LCFI0: - movl %esp,%ebp -.LCFI1: - # Make room for all of the new args. - movl 16(%ebp),%ecx - subl %ecx,%esp - - movl %esp,%eax - - # Place all of the ffi_prep_args in position - pushl 12(%ebp) - pushl %eax - call *8(%ebp) - - # Return stack to previous state and call the function - addl $8,%esp - - call *28(%ebp) - - # Remove the space we pushed for the args - movl 16(%ebp),%ecx - addl %ecx,%esp - - # Load %ecx with the return type code - movl 20(%ebp),%ecx - - # If the return value pointer is NULL, assume no return value. - cmpl $0,24(%ebp) - jne retint - - # Even if there is no space for the return value, we are - # obliged to handle floating-point values. - cmpl $FFI_TYPE_FLOAT,%ecx - jne noretval - fstp %st(0) - - jmp epilogue - -retint: - cmpl $FFI_TYPE_INT,%ecx - jne retfloat - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - movl %eax,0(%ecx) - jmp epilogue - -retfloat: - cmpl $FFI_TYPE_FLOAT,%ecx - jne retdouble - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - fstps (%ecx) - jmp epilogue - -retdouble: - cmpl $FFI_TYPE_DOUBLE,%ecx - jne retlongdouble - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - fstpl (%ecx) - jmp epilogue - -retlongdouble: - cmpl $FFI_TYPE_LONGDOUBLE,%ecx - jne retint64 - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - fstpt (%ecx) - jmp epilogue - -retint64: - cmpl $FFI_TYPE_SINT64,%ecx - jne retstruct - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - movl %eax,0(%ecx) - movl %edx,4(%ecx) - -retstruct: - # Nothing to do! - -noretval: -epilogue: - movl %ebp,%esp - popl %ebp - ret -.LFE1: -.ffi_call_SYSV_end: - .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV - -.section .eh_frame,"aw",@progbits -__FRAME_BEGIN__: - .4byte .LLCIE1 -.LSCIE1: - .4byte 0x0 - .byte 0x1 - .byte 0x0 - .byte 0x1 - .byte 0x7c - .byte 0x8 - .byte 0xc - .byte 0x4 - .byte 0x4 - .byte 0x88 - .byte 0x1 - .align 4 -.LECIE1: - .set .LLCIE1,.LECIE1-.LSCIE1 - .4byte .LLFDE1 -.LSFDE1: - .4byte .LSFDE1-__FRAME_BEGIN__ - .4byte .LFB1 - .4byte .LFE1-.LFB1 - .byte 0x4 - .4byte .LCFI0-.LFB1 - .byte 0xe - .byte 0x8 - .byte 0x85 - .byte 0x2 - .byte 0x4 - .4byte .LCFI1-.LCFI0 - .byte 0xd - .byte 0x5 - .align 4 -.LEFDE1: - .set .LLFDE1,.LEFDE1-.LSFDE1 |