From cd11ae061b002913740483529e31b3f6d3da753d Mon Sep 17 00:00:00 2001 From: Matthias Benkard Date: Mon, 3 Mar 2008 21:39:37 +0100 Subject: Update libffi to 3.0.4. darcs-hash:d0cdf89441c98da668f268b1af91e536dc3ed76e --- libffi/src/mips/ffi.c | 461 -------------------------------------------- libffi/src/mips/ffitarget.h | 160 --------------- libffi/src/mips/n32.S | 319 ------------------------------ libffi/src/mips/o32.S | 172 ----------------- 4 files changed, 1112 deletions(-) delete mode 100644 libffi/src/mips/ffi.c delete mode 100644 libffi/src/mips/ffitarget.h delete mode 100644 libffi/src/mips/n32.S delete mode 100644 libffi/src/mips/o32.S (limited to 'libffi/src/mips') diff --git a/libffi/src/mips/ffi.c b/libffi/src/mips/ffi.c deleted file mode 100644 index cc2078b..0000000 --- a/libffi/src/mips/ffi.c +++ /dev/null @@ -1,461 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1996 Red Hat, Inc. - - MIPS 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 -#include - -#include - -#if _MIPS_SIM == _ABIN32 -#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 void **p_argv; - register char *argp; - register ffi_type **p_arg; - -#if _MIPS_SIM == _ABIN32 - /* 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 * FFI_SIZEOF_ARG) - argp = &stack[bytes - (8 * FFI_SIZEOF_ARG)]; - else - argp = stack; -#else - argp = stack; -#endif - - memset(stack, 0, bytes); - -#if _MIPS_SIM == _ABIN32 - if ( ecif->cif->rstruct_flag != 0 ) -#else - if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) -#endif - { - *(ffi_arg *) argp = (ffi_arg) ecif->rvalue; - argp += sizeof(ffi_arg); - FIX_ARGP; - } - - p_argv = ecif->avalue; - - for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; 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 == _ABIO32 -#define OFFSET 0 -#else -#define OFFSET sizeof(int) -#endif - - z = (*p_arg)->size; - if (z < sizeof(ffi_arg)) - { - z = sizeof(ffi_arg); - - 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 == _ABIO32 - 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 == _ABIN32 - -/* 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 == _ABIO32 - /* 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 == _ABIN32 - /* 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 == _ABIO32 - case FFI_O32: - ffi_call_O32(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - break; -#endif - -#if _MIPS_SIM == _ABIN32 - 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/ffitarget.h b/libffi/src/mips/ffitarget.h deleted file mode 100644 index 9378ed0..0000000 --- a/libffi/src/mips/ffitarget.h +++ /dev/null @@ -1,160 +0,0 @@ -/* -----------------------------------------------------------------*-C-*- - ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. - Target configuration macros for MIPS. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------- */ - -#ifndef LIBFFI_TARGET_H -#define LIBFFI_TARGET_H - -#ifndef LIBFFI_ASM -#include -#endif - -#if !defined(_MIPS_SIM) --- something is very wrong -- -#else -# if (_MIPS_SIM==_ABIN32 && defined(_ABIN32)) || (_MIPS_SIM==_ABI64 && defined(_ABI64)) -# define FFI_MIPS_N32 -# else -# if _MIPS_SIM==_ABIO32 && defined(_ABIO32) -# define FFI_MIPS_O32 -# else --- this is an unsupported platform -- -# endif -# endif -#endif - -#ifdef FFI_MIPS_O32 -/* O32 stack frames have 32bit integer args */ -#define FFI_SIZEOF_ARG 4 -#else -/* N32 and N64 frames have 64bit integer args */ -#define FFI_SIZEOF_ARG 8 -#endif - -#define FFI_FLAG_BITS 2 - -/* SGI's strange assembler requires that we multiply by 4 rather - than shift left by FFI_FLAG_BITS */ - -#define FFI_ARGS_D FFI_TYPE_DOUBLE -#define FFI_ARGS_F FFI_TYPE_FLOAT -#define FFI_ARGS_DD FFI_TYPE_DOUBLE * 4 + FFI_TYPE_DOUBLE -#define FFI_ARGS_FF FFI_TYPE_FLOAT * 4 + FFI_TYPE_FLOAT -#define FFI_ARGS_FD FFI_TYPE_DOUBLE * 4 + FFI_TYPE_FLOAT -#define FFI_ARGS_DF FFI_TYPE_FLOAT * 4 + FFI_TYPE_DOUBLE - -/* Needed for N32 structure returns */ -#define FFI_TYPE_SMALLSTRUCT FFI_TYPE_UINT8 -#define FFI_TYPE_SMALLSTRUCT2 FFI_TYPE_SINT8 - -#if 0 -/* The SGI assembler can't handle this.. */ -#define FFI_TYPE_STRUCT_DD (( FFI_ARGS_DD ) << 4) + FFI_TYPE_STRUCT -/* (and so on) */ -#else -/* ...so we calculate these by hand! */ -#define FFI_TYPE_STRUCT_D 61 -#define FFI_TYPE_STRUCT_F 45 -#define FFI_TYPE_STRUCT_DD 253 -#define FFI_TYPE_STRUCT_FF 173 -#define FFI_TYPE_STRUCT_FD 237 -#define FFI_TYPE_STRUCT_DF 189 -#define FFI_TYPE_STRUCT_SMALL 93 -#define FFI_TYPE_STRUCT_SMALL2 109 -#endif - -#ifdef LIBFFI_ASM -#define v0 $2 -#define v1 $3 -#define a0 $4 -#define a1 $5 -#define a2 $6 -#define a3 $7 -#define a4 $8 -#define a5 $9 -#define a6 $10 -#define a7 $11 -#define t0 $8 -#define t1 $9 -#define t2 $10 -#define t3 $11 -#define t4 $12 -#define t5 $13 -#define t6 $14 -#define t7 $15 -#define t8 $24 -#define t9 $25 -#define ra $31 - -#ifdef FFI_MIPS_O32 -#define REG_L lw -#define REG_S sw -#define SUBU subu -#define ADDU addu -#define SRL srl -#define LI li -#else /* !FFI_MIPS_O32 */ -#define REG_L ld -#define REG_S sd -#define SUBU dsubu -#define ADDU daddu -#define SRL dsrl -#define LI dli -#endif /* !FFI_MIPS_O32 */ -#else /* !LIBFFI_ASM */ -#ifdef FFI_MIPS_O32 -/* O32 stack frames have 32bit integer args */ -typedef unsigned int ffi_arg __attribute__((__mode__(__SI__))); -typedef signed int ffi_sarg __attribute__((__mode__(__SI__))); -#else -/* N32 and N64 frames have 64bit integer args */ -typedef unsigned int ffi_arg __attribute__((__mode__(__DI__))); -typedef signed int ffi_sarg __attribute__((__mode__(__DI__))); -#endif - -typedef enum ffi_abi { - FFI_FIRST_ABI = 0, - FFI_O32, - FFI_N32, - FFI_N64, - -#ifdef FFI_MIPS_O32 - FFI_DEFAULT_ABI = FFI_O32, -#else - FFI_DEFAULT_ABI = FFI_N32, -#endif - - FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 -} ffi_abi; - -#define FFI_EXTRA_CIF_FIELDS unsigned rstruct_flag -#endif /* !LIBFFI_ASM */ - -/* ---- Definitions for closures ----------------------------------------- */ - -#define FFI_CLOSURES 0 -#define FFI_NATIVE_RAW_API 0 - -#endif - diff --git a/libffi/src/mips/n32.S b/libffi/src/mips/n32.S deleted file mode 100644 index 767fa52..0000000 --- a/libffi/src/mips/n32.S +++ /dev/null @@ -1,319 +0,0 @@ -/* ----------------------------------------------------------------------- - n32.S - Copyright (c) 1996, 1998 Red Hat, Inc. - - MIPS Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM -#include -#include - -/* 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 * FFI_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*FFI_SIZEOF_ARG($sp) # Save frame pointer - REG_S ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp) # Save return address - move $fp, $sp - - move t9, callback # callback function pointer - REG_S bytes, 2*FFI_SIZEOF_ARG($fp) # bytes - REG_S flags, 3*FFI_SIZEOF_ARG($fp) # flags - REG_S raddr, 4*FFI_SIZEOF_ARG($fp) # raddr - REG_S fn, 5*FFI_SIZEOF_ARG($fp) # fn - - # Allocate at least 4 words in the argstack - move v0, bytes - bge bytes, 4 * FFI_SIZEOF_ARG, bigger - LI v0, 4 * FFI_SIZEOF_ARG - b sixteen - - bigger: - ADDU t4, v0, 2 * FFI_SIZEOF_ARG -1 # make sure it is aligned - and v0, t4, -2 * FFI_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 * FFI_SIZEOF_ARG - ADDU a3, $fp, 3 * FFI_SIZEOF_ARG - - # Call ffi_prep_args - jal t9 - - # ADDU $sp, $sp, 4 * FFI_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*FFI_SIZEOF_ARG($fp) - - # Is it bigger than 8 * FFI_SIZEOF_ARG? - dadd t7, $0, 8 * FFI_SIZEOF_ARG - dsub t8, t6, t7 - bltz t8, loadregs - - add t9, t9, t8 - -loadregs: - - REG_L t4, 3*FFI_SIZEOF_ARG($fp) # load the flags word - add t6, t4, 0 # and copy it into t6 - - and t4, ((1< -#include - -/* 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 * FFI_SIZEOF_ARG + 2 * FFI_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*FFI_SIZEOF_ARG($sp) # Save frame pointer - REG_S ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp) # Save return address - move $fp, $sp - - move t9, callback # callback function pointer - REG_S flags, SIZEOF_FRAME + 3*FFI_SIZEOF_ARG($fp) # flags - - # Allocate at least 4 words in the argstack - move v0, bytes - bge bytes, 4 * FFI_SIZEOF_ARG, bigger - LI v0, 4 * FFI_SIZEOF_ARG - b sixteen - -bigger: - ADDU t0, v0, 2 * FFI_SIZEOF_ARG -1 # make sure it is aligned - and v0, t0, -2 * FFI_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 * FFI_SIZEOF_ARG - ADDU a3, $fp, SIZEOF_FRAME + 3*FFI_SIZEOF_ARG - - jal t9 - - REG_L t0, SIZEOF_FRAME + 3*FFI_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 * FFI_SIZEOF_ARG # adjust $sp to new args - - bnez t0, pass_d # make it quick for int - REG_L a0, 0*FFI_SIZEOF_ARG($sp) # just go ahead and load the - REG_L a1, 1*FFI_SIZEOF_ARG($sp) # four regs. - REG_L a2, 2*FFI_SIZEOF_ARG($sp) - REG_L a3, 3*FFI_SIZEOF_ARG($sp) - b call_it - -pass_d: - bne t0, FFI_ARGS_D, pass_f - l.d $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args - REG_L a2, 2*FFI_SIZEOF_ARG($sp) # passing a double - REG_L a3, 3*FFI_SIZEOF_ARG($sp) - b call_it - -pass_f: - bne t0, FFI_ARGS_F, pass_d_d - l.s $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args - REG_L a1, 1*FFI_SIZEOF_ARG($sp) # passing a float - REG_L a2, 2*FFI_SIZEOF_ARG($sp) - REG_L a3, 3*FFI_SIZEOF_ARG($sp) - b call_it - -pass_d_d: - bne t0, FFI_ARGS_DD, pass_f_f - l.d $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args - l.d $f14, 2*FFI_SIZEOF_ARG($sp) # passing two doubles - b call_it - -pass_f_f: - bne t0, FFI_ARGS_FF, pass_d_f - l.s $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args - l.s $f14, 1*FFI_SIZEOF_ARG($sp) # passing two floats - REG_L a2, 2*FFI_SIZEOF_ARG($sp) - REG_L a3, 3*FFI_SIZEOF_ARG($sp) - b call_it - -pass_d_f: - bne t0, FFI_ARGS_DF, pass_f_d - l.d $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args - l.s $f14, 2*FFI_SIZEOF_ARG($sp) # passing double and float - REG_L a3, 3*FFI_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*FFI_SIZEOF_ARG($sp) # load $fp regs from args - l.d $f14, 2*FFI_SIZEOF_ARG($sp) # passing double and float - -call_it: - # Load the function pointer - REG_L t9, SIZEOF_FRAME + 5*FFI_SIZEOF_ARG($fp) - - # If the return value pointer is NULL, assume no return value. - REG_L t1, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp) - beqz t1, noretval - - bne t2, FFI_TYPE_INT, retfloat - jal t9 - REG_L t0, SIZEOF_FRAME + 4*FFI_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*FFI_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*FFI_SIZEOF_ARG($fp) - s.d $f0, 0(t0) - b epilogue - -noretval: - jal t9 - - # Epilogue -epilogue: - move $sp, $fp - REG_L $fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Restore frame pointer - REG_L ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp) # Restore return address - ADDU $sp, SIZEOF_FRAME # Fix stack pointer - j ra - - .end ffi_call_O32 - -#endif -- cgit v1.2.3