diff options
Diffstat (limited to 'Modules/_ctypes/libffi/src/mips')
-rw-r--r-- | Modules/_ctypes/libffi/src/mips/ffi.c | 1050 | ||||
-rw-r--r-- | Modules/_ctypes/libffi/src/mips/ffitarget.h | 247 | ||||
-rw-r--r-- | Modules/_ctypes/libffi/src/mips/n32.S | 576 | ||||
-rw-r--r-- | Modules/_ctypes/libffi/src/mips/o32.S | 381 |
4 files changed, 0 insertions, 2254 deletions
diff --git a/Modules/_ctypes/libffi/src/mips/ffi.c b/Modules/_ctypes/libffi/src/mips/ffi.c deleted file mode 100644 index 5d0dd70cb3..0000000000 --- a/Modules/_ctypes/libffi/src/mips/ffi.c +++ /dev/null @@ -1,1050 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 2011 Anthony Green - Copyright (c) 2008 David Daney - Copyright (c) 1996, 2007, 2008, 2011 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 THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include <ffi.h> -#include <ffi_common.h> - -#include <stdlib.h> - -#ifdef __GNUC__ -# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) -# define USE__BUILTIN___CLEAR_CACHE 1 -# endif -#endif - -#ifndef USE__BUILTIN___CLEAR_CACHE -# if defined(__OpenBSD__) -# include <mips64/sysarch.h> -# else -# include <sys/cachectl.h> -# endif -#endif - -#ifdef FFI_DEBUG -# define FFI_MIPS_STOP_HERE() ffi_stop_here() -#else -# define FFI_MIPS_STOP_HERE() do {} while(0) -#endif - -#ifdef FFI_MIPS_N32 -#define FIX_ARGP \ -FFI_ASSERT(argp <= &stack[bytes]); \ -if (argp == &stack[bytes]) \ -{ \ - argp = stack; \ - FFI_MIPS_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) -{ - int i; - void **p_argv; - char *argp; - ffi_type **p_arg; - -#ifdef FFI_MIPS_N32 - /* 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(ffi_arg)) - argp = &stack[bytes - (8 * sizeof(ffi_arg))]; - else - argp = stack; -#else - argp = stack; -#endif - - memset(stack, 0, bytes); - -#ifdef FFI_MIPS_N32 - 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 = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs; i++, p_arg++) - { - size_t z; - unsigned int a; - - /* Align if necessary. */ - a = (*p_arg)->alignment; - if (a < sizeof(ffi_arg)) - a = sizeof(ffi_arg); - - if ((a - 1) & (unsigned long) argp) - { - argp = (char *) ALIGN(argp, a); - FIX_ARGP; - } - - z = (*p_arg)->size; - if (z <= sizeof(ffi_arg)) - { - int type = (*p_arg)->type; - z = sizeof(ffi_arg); - - /* The size of a pointer depends on the ABI */ - if (type == FFI_TYPE_POINTER) - type = (ecif->cif->abi == FFI_N64 - || ecif->cif->abi == FFI_N64_SOFT_FLOAT) - ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32; - - if (i < 8 && (ecif->cif->abi == FFI_N32_SOFT_FLOAT - || ecif->cif->abi == FFI_N64_SOFT_FLOAT)) - { - switch (type) - { - case FFI_TYPE_FLOAT: - type = FFI_TYPE_UINT32; - break; - case FFI_TYPE_DOUBLE: - type = FFI_TYPE_UINT64; - break; - default: - break; - } - } - switch (type) - { - case FFI_TYPE_SINT8: - *(ffi_arg *)argp = *(SINT8 *)(* p_argv); - break; - - case FFI_TYPE_UINT8: - *(ffi_arg *)argp = *(UINT8 *)(* p_argv); - break; - - case FFI_TYPE_SINT16: - *(ffi_arg *)argp = *(SINT16 *)(* p_argv); - break; - - case FFI_TYPE_UINT16: - *(ffi_arg *)argp = *(UINT16 *)(* p_argv); - break; - - case FFI_TYPE_SINT32: - *(ffi_arg *)argp = *(SINT32 *)(* p_argv); - break; - - case FFI_TYPE_UINT32: -#ifdef FFI_MIPS_N32 - /* The N32 ABI requires that 32-bit integers - be sign-extended to 64-bits, regardless of - whether they are signed or unsigned. */ - *(ffi_arg *)argp = *(SINT32 *)(* p_argv); -#else - *(ffi_arg *)argp = *(UINT32 *)(* p_argv); -#endif - break; - - /* This can only happen with 64bit slots. */ - case FFI_TYPE_FLOAT: - *(float *) argp = *(float *)(* p_argv); - break; - - /* Handle structures. */ - default: - memcpy(argp, *p_argv, (*p_arg)->size); - break; - } - } - else - { -#ifdef FFI_MIPS_O32 - memcpy(argp, *p_argv, z); -#else - { - unsigned long end = (unsigned long) argp + z; - unsigned long cap = (unsigned long) 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 long portion = cap - (unsigned long)argp; - - memcpy(argp, *p_argv, portion); - argp = stack; - z -= portion; - memcpy(argp, (void*)((unsigned long)(*p_argv) + portion), - z); - } - } -#endif - } - p_argv++; - argp += z; - FIX_ARGP; - } -} - -#ifdef FFI_MIPS_N32 - -/* 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. */ - -static unsigned -calc_n32_struct_flags(int soft_float, ffi_type *arg, - unsigned *loc, unsigned *arg_reg) -{ - unsigned flags = 0; - unsigned index = 0; - - ffi_type *e; - - if (soft_float) - return 0; - - while ((e = arg->elements[index])) - { - /* Align this object. */ - *loc = ALIGN(*loc, e->alignment); - if (e->type == FFI_TYPE_DOUBLE) - { - /* Already aligned to FFI_SIZEOF_ARG. */ - *arg_reg = *loc / FFI_SIZEOF_ARG; - if (*arg_reg > 7) - break; - flags += (FFI_TYPE_DOUBLE << (*arg_reg * FFI_FLAG_BITS)); - *loc += e->size; - } - else - *loc += e->size; - index++; - } - /* Next Argument register at alignment of FFI_SIZEOF_ARG. */ - *arg_reg = ALIGN(*loc, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; - - return flags; -} - -static unsigned -calc_n32_return_struct_flags(int soft_float, ffi_type *arg) -{ - unsigned flags = 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; - else if (e->type == FFI_TYPE_FLOAT) - flags = FFI_TYPE_FLOAT; - - if (flags && (e = arg->elements[1])) - { - 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; - 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; - } - if (soft_float) - flags += FFI_TYPE_STRUCT_SOFT; - } - 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; - -#ifdef FFI_MIPS_O32 - /* Set the flags necessary for O32 processing. FFI_O32_SOFT_FLOAT - * does not have special handling for floating point args. - */ - - if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32) - { - 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 */ - - if (cif->abi == FFI_O32_SOFT_FLOAT) - { - switch (cif->rtype->type) - { - case FFI_TYPE_VOID: - case FFI_TYPE_STRUCT: - cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2); - break; - - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - case FFI_TYPE_DOUBLE: - cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2); - break; - - case FFI_TYPE_FLOAT: - default: - cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2); - break; - } - } - else - { - /* FFI_O32 */ - 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; - - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2); - break; - - default: - cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2); - break; - } - } -#endif - -#ifdef FFI_MIPS_N32 - /* Set the flags necessary for N32 processing */ - { - int type; - unsigned arg_reg = 0; - unsigned loc = 0; - unsigned count = (cif->nargs < 8) ? cif->nargs : 8; - unsigned index = 0; - - unsigned struct_flags = 0; - int soft_float = (cif->abi == FFI_N32_SOFT_FLOAT - || cif->abi == FFI_N64_SOFT_FLOAT); - - if (cif->rtype->type == FFI_TYPE_STRUCT) - { - struct_flags = calc_n32_return_struct_flags(soft_float, cif->rtype); - - if (struct_flags == 0) - { - /* This means that the structure is being passed as - a hidden argument */ - - arg_reg = 1; - count = (cif->nargs < 7) ? cif->nargs : 7; - - cif->rstruct_flag = !0; - } - else - cif->rstruct_flag = 0; - } - else - cif->rstruct_flag = 0; - - while (count-- > 0 && arg_reg < 8) - { - type = (cif->arg_types)[index]->type; - if (soft_float) - { - switch (type) - { - case FFI_TYPE_FLOAT: - type = FFI_TYPE_UINT32; - break; - case FFI_TYPE_DOUBLE: - type = FFI_TYPE_UINT64; - break; - default: - break; - } - } - switch (type) - { - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - cif->flags += - ((cif->arg_types)[index]->type << (arg_reg * FFI_FLAG_BITS)); - arg_reg++; - break; - case FFI_TYPE_LONGDOUBLE: - /* Align it. */ - arg_reg = ALIGN(arg_reg, 2); - /* Treat it as two adjacent doubles. */ - if (soft_float) - { - arg_reg += 2; - } - else - { - cif->flags += - (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS)); - arg_reg++; - cif->flags += - (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS)); - arg_reg++; - } - break; - - case FFI_TYPE_STRUCT: - loc = arg_reg * FFI_SIZEOF_ARG; - cif->flags += calc_n32_struct_flags(soft_float, - (cif->arg_types)[index], - &loc, &arg_reg); - break; - - default: - arg_reg++; - break; - } - - 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_POINTER: - if (cif->abi == FFI_N32_SOFT_FLOAT || cif->abi == FFI_N32) - cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8); - else - cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8); - break; - - case FFI_TYPE_FLOAT: - if (soft_float) - { - cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8); - break; - } - /* else fall through */ - case FFI_TYPE_DOUBLE: - if (soft_float) - cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8); - else - cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8); - break; - - case FFI_TYPE_LONGDOUBLE: - /* Long double is returned as if it were a struct containing - two doubles. */ - if (soft_float) - { - cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8); - cif->flags += FFI_TYPE_SMALLSTRUCT2 << (4 + (FFI_FLAG_BITS * 8)); - } - else - { - cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8); - cif->flags += (FFI_TYPE_DOUBLE - + (FFI_TYPE_DOUBLE << FFI_FLAG_BITS)) - << (4 + (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 (*)(void)); - -/* Low level routine for calling N32 functions */ -extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int), - extended_cif *, unsigned, - unsigned, void *, void (*)(void)); - -void ffi_call(ffi_cif *cif, void (*fn)(void), 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) - { -#ifdef FFI_MIPS_O32 - case FFI_O32: - case FFI_O32_SOFT_FLOAT: - ffi_call_O32(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - break; -#endif - -#ifdef FFI_MIPS_N32 - case FFI_N32: - case FFI_N32_SOFT_FLOAT: - case FFI_N64: - case FFI_N64_SOFT_FLOAT: - { - int copy_rvalue = 0; - int copy_offset = 0; - char *rvalue_copy = ecif.rvalue; - if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16) - { - /* For structures smaller than 16 bytes we clobber memory - in 8 byte increments. Make a copy so we don't clobber - the callers memory outside of the struct bounds. */ - rvalue_copy = alloca(16); - copy_rvalue = 1; - } - else if (cif->rtype->type == FFI_TYPE_FLOAT - && (cif->abi == FFI_N64_SOFT_FLOAT - || cif->abi == FFI_N32_SOFT_FLOAT)) - { - rvalue_copy = alloca (8); - copy_rvalue = 1; -#if defined(__MIPSEB__) || defined(_MIPSEB) - copy_offset = 4; -#endif - } - ffi_call_N32(ffi_prep_args, &ecif, cif->bytes, - cif->flags, rvalue_copy, fn); - if (copy_rvalue) - memcpy(ecif.rvalue, rvalue_copy + copy_offset, cif->rtype->size); - } - break; -#endif - - default: - FFI_ASSERT(0); - break; - } -} - -#if FFI_CLOSURES -#if defined(FFI_MIPS_O32) -extern void ffi_closure_O32(void); -#else -extern void ffi_closure_N32(void); -#endif /* FFI_MIPS_O32 */ - -ffi_status -ffi_prep_closure_loc (ffi_closure *closure, - ffi_cif *cif, - void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data, - void *codeloc) -{ - unsigned int *tramp = (unsigned int *) &closure->tramp[0]; - void * fn; - char *clear_location = (char *) codeloc; - -#if defined(FFI_MIPS_O32) - if (cif->abi != FFI_O32 && cif->abi != FFI_O32_SOFT_FLOAT) - return FFI_BAD_ABI; - fn = ffi_closure_O32; -#else -#if _MIPS_SIM ==_ABIN32 - if (cif->abi != FFI_N32 - && cif->abi != FFI_N32_SOFT_FLOAT) - return FFI_BAD_ABI; -#else - if (cif->abi != FFI_N64 - && cif->abi != FFI_N64_SOFT_FLOAT) - return FFI_BAD_ABI; -#endif - fn = ffi_closure_N32; -#endif /* FFI_MIPS_O32 */ - -#if defined(FFI_MIPS_O32) || (_MIPS_SIM ==_ABIN32) - /* lui $25,high(fn) */ - tramp[0] = 0x3c190000 | ((unsigned)fn >> 16); - /* ori $25,low(fn) */ - tramp[1] = 0x37390000 | ((unsigned)fn & 0xffff); - /* lui $12,high(codeloc) */ - tramp[2] = 0x3c0c0000 | ((unsigned)codeloc >> 16); - /* jr $25 */ - tramp[3] = 0x03200008; - /* ori $12,low(codeloc) */ - tramp[4] = 0x358c0000 | ((unsigned)codeloc & 0xffff); -#else - /* N64 has a somewhat larger trampoline. */ - /* lui $25,high(fn) */ - tramp[0] = 0x3c190000 | ((unsigned long)fn >> 48); - /* lui $12,high(codeloc) */ - tramp[1] = 0x3c0c0000 | ((unsigned long)codeloc >> 48); - /* ori $25,mid-high(fn) */ - tramp[2] = 0x37390000 | (((unsigned long)fn >> 32 ) & 0xffff); - /* ori $12,mid-high(codeloc) */ - tramp[3] = 0x358c0000 | (((unsigned long)codeloc >> 32) & 0xffff); - /* dsll $25,$25,16 */ - tramp[4] = 0x0019cc38; - /* dsll $12,$12,16 */ - tramp[5] = 0x000c6438; - /* ori $25,mid-low(fn) */ - tramp[6] = 0x37390000 | (((unsigned long)fn >> 16 ) & 0xffff); - /* ori $12,mid-low(codeloc) */ - tramp[7] = 0x358c0000 | (((unsigned long)codeloc >> 16) & 0xffff); - /* dsll $25,$25,16 */ - tramp[8] = 0x0019cc38; - /* dsll $12,$12,16 */ - tramp[9] = 0x000c6438; - /* ori $25,low(fn) */ - tramp[10] = 0x37390000 | ((unsigned long)fn & 0xffff); - /* jr $25 */ - tramp[11] = 0x03200008; - /* ori $12,low(codeloc) */ - tramp[12] = 0x358c0000 | ((unsigned long)codeloc & 0xffff); - -#endif - - closure->cif = cif; - closure->fun = fun; - closure->user_data = user_data; - -#ifdef USE__BUILTIN___CLEAR_CACHE - __builtin___clear_cache(clear_location, clear_location + FFI_TRAMPOLINE_SIZE); -#else - cacheflush (clear_location, FFI_TRAMPOLINE_SIZE, ICACHE); -#endif - return FFI_OK; -} - -/* - * Decodes the arguments to a function, which will be stored on the - * stack. AR is the pointer to the beginning of the integer arguments - * (and, depending upon the arguments, some floating-point arguments - * as well). FPR is a pointer to the area where floating point - * registers have been saved, if any. - * - * RVALUE is the location where the function return value will be - * stored. CLOSURE is the prepared closure to invoke. - * - * This function should only be called from assembly, which is in - * turn called from a trampoline. - * - * Returns the function return type. - * - * Based on the similar routine for sparc. - */ -int -ffi_closure_mips_inner_O32 (ffi_closure *closure, - void *rvalue, ffi_arg *ar, - double *fpr) -{ - ffi_cif *cif; - void **avaluep; - ffi_arg *avalue; - ffi_type **arg_types; - int i, avn, argn, seen_int; - - cif = closure->cif; - avalue = alloca (cif->nargs * sizeof (ffi_arg)); - avaluep = alloca (cif->nargs * sizeof (ffi_arg)); - - seen_int = (cif->abi == FFI_O32_SOFT_FLOAT); - argn = 0; - - if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT) - { - rvalue = (void *)(UINT32)ar[0]; - argn = 1; - } - - i = 0; - avn = cif->nargs; - arg_types = cif->arg_types; - - while (i < avn) - { - if (i < 2 && !seen_int && - (arg_types[i]->type == FFI_TYPE_FLOAT || - arg_types[i]->type == FFI_TYPE_DOUBLE || - arg_types[i]->type == FFI_TYPE_LONGDOUBLE)) - { -#if defined(__MIPSEB__) || defined(_MIPSEB) - if (arg_types[i]->type == FFI_TYPE_FLOAT) - avaluep[i] = ((char *) &fpr[i]) + sizeof (float); - else -#endif - avaluep[i] = (char *) &fpr[i]; - } - else - { - if (arg_types[i]->alignment == 8 && (argn & 0x1)) - argn++; - switch (arg_types[i]->type) - { - case FFI_TYPE_SINT8: - avaluep[i] = &avalue[i]; - *(SINT8 *) &avalue[i] = (SINT8) ar[argn]; - break; - - case FFI_TYPE_UINT8: - avaluep[i] = &avalue[i]; - *(UINT8 *) &avalue[i] = (UINT8) ar[argn]; - break; - - case FFI_TYPE_SINT16: - avaluep[i] = &avalue[i]; - *(SINT16 *) &avalue[i] = (SINT16) ar[argn]; - break; - - case FFI_TYPE_UINT16: - avaluep[i] = &avalue[i]; - *(UINT16 *) &avalue[i] = (UINT16) ar[argn]; - break; - - default: - avaluep[i] = (char *) &ar[argn]; - break; - } - seen_int = 1; - } - argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; - i++; - } - - /* Invoke the closure. */ - (closure->fun) (cif, rvalue, avaluep, closure->user_data); - - if (cif->abi == FFI_O32_SOFT_FLOAT) - { - switch (cif->rtype->type) - { - case FFI_TYPE_FLOAT: - return FFI_TYPE_INT; - case FFI_TYPE_DOUBLE: - return FFI_TYPE_UINT64; - default: - return cif->rtype->type; - } - } - else - { - return cif->rtype->type; - } -} - -#if defined(FFI_MIPS_N32) - -static void -copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type, - int argn, unsigned arg_offset, ffi_arg *ar, - ffi_arg *fpr, int soft_float) -{ - ffi_type **elt_typep = type->elements; - while(*elt_typep) - { - ffi_type *elt_type = *elt_typep; - unsigned o; - char *tp; - char *argp; - char *fpp; - - o = ALIGN(offset, elt_type->alignment); - arg_offset += o - offset; - offset = o; - argn += arg_offset / sizeof(ffi_arg); - arg_offset = arg_offset % sizeof(ffi_arg); - - argp = (char *)(ar + argn); - fpp = (char *)(argn >= 8 ? ar + argn : fpr + argn); - - tp = target + offset; - - if (elt_type->type == FFI_TYPE_DOUBLE && !soft_float) - *(double *)tp = *(double *)fpp; - else - memcpy(tp, argp + arg_offset, elt_type->size); - - offset += elt_type->size; - arg_offset += elt_type->size; - elt_typep++; - argn += arg_offset / sizeof(ffi_arg); - arg_offset = arg_offset % sizeof(ffi_arg); - } -} - -/* - * Decodes the arguments to a function, which will be stored on the - * stack. AR is the pointer to the beginning of the integer - * arguments. FPR is a pointer to the area where floating point - * registers have been saved. - * - * RVALUE is the location where the function return value will be - * stored. CLOSURE is the prepared closure to invoke. - * - * This function should only be called from assembly, which is in - * turn called from a trampoline. - * - * Returns the function return flags. - * - */ -int -ffi_closure_mips_inner_N32 (ffi_closure *closure, - void *rvalue, ffi_arg *ar, - ffi_arg *fpr) -{ - ffi_cif *cif; - void **avaluep; - ffi_arg *avalue; - ffi_type **arg_types; - int i, avn, argn; - int soft_float; - ffi_arg *argp; - - cif = closure->cif; - soft_float = cif->abi == FFI_N64_SOFT_FLOAT - || cif->abi == FFI_N32_SOFT_FLOAT; - avalue = alloca (cif->nargs * sizeof (ffi_arg)); - avaluep = alloca (cif->nargs * sizeof (ffi_arg)); - - argn = 0; - - if (cif->rstruct_flag) - { -#if _MIPS_SIM==_ABIN32 - rvalue = (void *)(UINT32)ar[0]; -#else /* N64 */ - rvalue = (void *)ar[0]; -#endif - argn = 1; - } - - i = 0; - avn = cif->nargs; - arg_types = cif->arg_types; - - while (i < avn) - { - if (arg_types[i]->type == FFI_TYPE_FLOAT - || arg_types[i]->type == FFI_TYPE_DOUBLE - || arg_types[i]->type == FFI_TYPE_LONGDOUBLE) - { - argp = (argn >= 8 || soft_float) ? ar + argn : fpr + argn; - if ((arg_types[i]->type == FFI_TYPE_LONGDOUBLE) && ((unsigned)argp & (arg_types[i]->alignment-1))) - { - argp=(ffi_arg*)ALIGN(argp,arg_types[i]->alignment); - argn++; - } -#if defined(__MIPSEB__) || defined(_MIPSEB) - if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8) - avaluep[i] = ((char *) argp) + sizeof (float); - else -#endif - avaluep[i] = (char *) argp; - } - else - { - unsigned type = arg_types[i]->type; - - if (arg_types[i]->alignment > sizeof(ffi_arg)) - argn = ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg)); - - argp = ar + argn; - - /* The size of a pointer depends on the ABI */ - if (type == FFI_TYPE_POINTER) - type = (cif->abi == FFI_N64 || cif->abi == FFI_N64_SOFT_FLOAT) - ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32; - - if (soft_float && type == FFI_TYPE_FLOAT) - type = FFI_TYPE_UINT32; - - switch (type) - { - case FFI_TYPE_SINT8: - avaluep[i] = &avalue[i]; - *(SINT8 *) &avalue[i] = (SINT8) *argp; - break; - - case FFI_TYPE_UINT8: - avaluep[i] = &avalue[i]; - *(UINT8 *) &avalue[i] = (UINT8) *argp; - break; - - case FFI_TYPE_SINT16: - avaluep[i] = &avalue[i]; - *(SINT16 *) &avalue[i] = (SINT16) *argp; - break; - - case FFI_TYPE_UINT16: - avaluep[i] = &avalue[i]; - *(UINT16 *) &avalue[i] = (UINT16) *argp; - break; - - case FFI_TYPE_SINT32: - avaluep[i] = &avalue[i]; - *(SINT32 *) &avalue[i] = (SINT32) *argp; - break; - - case FFI_TYPE_UINT32: - avaluep[i] = &avalue[i]; - *(UINT32 *) &avalue[i] = (UINT32) *argp; - break; - - case FFI_TYPE_STRUCT: - if (argn < 8) - { - /* Allocate space for the struct as at least part of - it was passed in registers. */ - avaluep[i] = alloca(arg_types[i]->size); - copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i], - argn, 0, ar, fpr, soft_float); - - break; - } - /* Else fall through. */ - default: - avaluep[i] = (char *) argp; - break; - } - } - argn += ALIGN(arg_types[i]->size, sizeof(ffi_arg)) / sizeof(ffi_arg); - i++; - } - - /* Invoke the closure. */ - (closure->fun) (cif, rvalue, avaluep, closure->user_data); - - return cif->flags >> (FFI_FLAG_BITS * 8); -} - -#endif /* FFI_MIPS_N32 */ - -#endif /* FFI_CLOSURES */ diff --git a/Modules/_ctypes/libffi/src/mips/ffitarget.h b/Modules/_ctypes/libffi/src/mips/ffitarget.h deleted file mode 100644 index 717d65951c..0000000000 --- a/Modules/_ctypes/libffi/src/mips/ffitarget.h +++ /dev/null @@ -1,247 +0,0 @@ -/* -----------------------------------------------------------------*-C-*- - ffitarget.h - Copyright (c) 2012 Anthony Green - 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 THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------- */ - -#ifndef LIBFFI_TARGET_H -#define LIBFFI_TARGET_H - -#ifndef LIBFFI_H -#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." -#endif - -#ifdef linux -# include <asm/sgidefs.h> -#elif defined(__rtems__) -/* - * Subprogram calling convention - copied from sgidefs.h - */ -#define _MIPS_SIM_ABI32 1 -#define _MIPS_SIM_NABI32 2 -#define _MIPS_SIM_ABI64 3 -#elif !defined(__OpenBSD__) -# include <sgidefs.h> -#endif - -# ifndef _ABIN32 -# define _ABIN32 _MIPS_SIM_NABI32 -# endif -# ifndef _ABI64 -# define _ABI64 _MIPS_SIM_ABI64 -# endif -# ifndef _ABIO32 -# define _ABIO32 _MIPS_SIM_ABI32 -# endif - -#if !defined(_MIPS_SIM) -# error -- 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 -# error -- 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 -# if _MIPS_SIM == _ABIN32 -# define FFI_SIZEOF_JAVA_RAW 4 -# endif -#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 - -/* and for n32 soft float, add 16 * 2^4 */ -#define FFI_TYPE_STRUCT_D_SOFT 317 -#define FFI_TYPE_STRUCT_F_SOFT 301 -#define FFI_TYPE_STRUCT_DD_SOFT 509 -#define FFI_TYPE_STRUCT_FF_SOFT 429 -#define FFI_TYPE_STRUCT_FD_SOFT 493 -#define FFI_TYPE_STRUCT_DF_SOFT 445 -#define FFI_TYPE_STRUCT_SOFT 16 -#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 -# if (_MIPS_SIM==_ABI64) -# define LA dla -# define EH_FRAME_ALIGN 3 -# define FDE_ADDR_BYTES .8byte -# else -# define LA la -# define EH_FRAME_ALIGN 2 -# define FDE_ADDR_BYTES .4byte -# endif /* _MIPS_SIM==_ABI64 */ -#endif /* !FFI_MIPS_O32 */ -#else /* !LIBFFI_ASM */ -# ifdef __GNUC__ -# 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 -# else -# ifdef FFI_MIPS_O32 -/* O32 stack frames have 32bit integer args */ -typedef __uint32_t ffi_arg; -typedef __int32_t ffi_sarg; -# else -/* N32 and N64 frames have 64bit integer args */ -typedef __uint64_t ffi_arg; -typedef __int64_t ffi_sarg; -# endif -# endif /* __GNUC__ */ - -typedef enum ffi_abi { - FFI_FIRST_ABI = 0, - FFI_O32, - FFI_N32, - FFI_N64, - FFI_O32_SOFT_FLOAT, - FFI_N32_SOFT_FLOAT, - FFI_N64_SOFT_FLOAT, - FFI_LAST_ABI, - -#ifdef FFI_MIPS_O32 -#ifdef __mips_soft_float - FFI_DEFAULT_ABI = FFI_O32_SOFT_FLOAT -#else - FFI_DEFAULT_ABI = FFI_O32 -#endif -#else -# if _MIPS_SIM==_ABI64 -# ifdef __mips_soft_float - FFI_DEFAULT_ABI = FFI_N64_SOFT_FLOAT -# else - FFI_DEFAULT_ABI = FFI_N64 -# endif -# else -# ifdef __mips_soft_float - FFI_DEFAULT_ABI = FFI_N32_SOFT_FLOAT -# else - FFI_DEFAULT_ABI = FFI_N32 -# endif -# endif -#endif -} ffi_abi; - -#define FFI_EXTRA_CIF_FIELDS unsigned rstruct_flag -#endif /* !LIBFFI_ASM */ - -/* ---- Definitions for closures ----------------------------------------- */ - -#if defined(FFI_MIPS_O32) -#define FFI_CLOSURES 1 -#define FFI_TRAMPOLINE_SIZE 20 -#else -/* N32/N64. */ -# define FFI_CLOSURES 1 -#if _MIPS_SIM==_ABI64 -#define FFI_TRAMPOLINE_SIZE 52 -#else -#define FFI_TRAMPOLINE_SIZE 20 -#endif -#endif /* FFI_MIPS_O32 */ -#define FFI_NATIVE_RAW_API 0 - -#endif - diff --git a/Modules/_ctypes/libffi/src/mips/n32.S b/Modules/_ctypes/libffi/src/mips/n32.S deleted file mode 100644 index c6985d30a6..0000000000 --- a/Modules/_ctypes/libffi/src/mips/n32.S +++ /dev/null @@ -1,576 +0,0 @@ -/* ----------------------------------------------------------------------- - n32.S - Copyright (c) 1996, 1998, 2005, 2007, 2009, 2010 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 THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM -#include <fficonfig.h> -#include <ffi.h> - -/* 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 ) - -#ifdef __GNUC__ - .abicalls -#endif - .set mips4 - .text - .align 2 - .globl ffi_call_N32 - .ent ffi_call_N32 -ffi_call_N32: -.LFB3: - .frame $fp, SIZEOF_FRAME, ra - .mask 0xc0000000,-FFI_SIZEOF_ARG - .fmask 0x00000000,0 - - # Prologue - SUBU $sp, SIZEOF_FRAME # Frame size -.LCFI0: - 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 -.LCFI1: - move $fp, $sp -.LCFI3: - 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 - - move a0, $sp # 4 * FFI_SIZEOF_ARG - ADDU a3, $fp, 3 * FFI_SIZEOF_ARG - - # Call ffi_prep_args - jal t9 - - # 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? - daddiu t8, t6, -(8 * FFI_SIZEOF_ARG) - bltz t8, loadregs - - ADDU t9, t9, t8 - -loadregs: - - REG_L t6, 3*FFI_SIZEOF_ARG($fp) # load the flags word into t6. - - and t4, t6, ((1<<FFI_FLAG_BITS)-1) - REG_L a0, 0*FFI_SIZEOF_ARG(t9) - beqz t4, arg1_next - bne t4, FFI_TYPE_FLOAT, arg1_doublep - l.s $f12, 0*FFI_SIZEOF_ARG(t9) - b arg1_next -arg1_doublep: - l.d $f12, 0*FFI_SIZEOF_ARG(t9) -arg1_next: - - SRL t4, t6, 1*FFI_FLAG_BITS - and t4, ((1<<FFI_FLAG_BITS)-1) - REG_L a1, 1*FFI_SIZEOF_ARG(t9) - beqz t4, arg2_next - bne t4, FFI_TYPE_FLOAT, arg2_doublep - l.s $f13, 1*FFI_SIZEOF_ARG(t9) - b arg2_next -arg2_doublep: - l.d $f13, 1*FFI_SIZEOF_ARG(t9) -arg2_next: - - SRL t4, t6, 2*FFI_FLAG_BITS - and t4, ((1<<FFI_FLAG_BITS)-1) - REG_L a2, 2*FFI_SIZEOF_ARG(t9) - beqz t4, arg3_next - bne t4, FFI_TYPE_FLOAT, arg3_doublep - l.s $f14, 2*FFI_SIZEOF_ARG(t9) - b arg3_next -arg3_doublep: - l.d $f14, 2*FFI_SIZEOF_ARG(t9) -arg3_next: - - SRL t4, t6, 3*FFI_FLAG_BITS - and t4, ((1<<FFI_FLAG_BITS)-1) - REG_L a3, 3*FFI_SIZEOF_ARG(t9) - beqz t4, arg4_next - bne t4, FFI_TYPE_FLOAT, arg4_doublep - l.s $f15, 3*FFI_SIZEOF_ARG(t9) - b arg4_next -arg4_doublep: - l.d $f15, 3*FFI_SIZEOF_ARG(t9) -arg4_next: - - SRL t4, t6, 4*FFI_FLAG_BITS - and t4, ((1<<FFI_FLAG_BITS)-1) - REG_L a4, 4*FFI_SIZEOF_ARG(t9) - beqz t4, arg5_next - bne t4, FFI_TYPE_FLOAT, arg5_doublep - l.s $f16, 4*FFI_SIZEOF_ARG(t9) - b arg5_next -arg5_doublep: - l.d $f16, 4*FFI_SIZEOF_ARG(t9) -arg5_next: - - SRL t4, t6, 5*FFI_FLAG_BITS - and t4, ((1<<FFI_FLAG_BITS)-1) - REG_L a5, 5*FFI_SIZEOF_ARG(t9) - beqz t4, arg6_next - bne t4, FFI_TYPE_FLOAT, arg6_doublep - l.s $f17, 5*FFI_SIZEOF_ARG(t9) - b arg6_next -arg6_doublep: - l.d $f17, 5*FFI_SIZEOF_ARG(t9) -arg6_next: - - SRL t4, t6, 6*FFI_FLAG_BITS - and t4, ((1<<FFI_FLAG_BITS)-1) - REG_L a6, 6*FFI_SIZEOF_ARG(t9) - beqz t4, arg7_next - bne t4, FFI_TYPE_FLOAT, arg7_doublep - l.s $f18, 6*FFI_SIZEOF_ARG(t9) - b arg7_next -arg7_doublep: - l.d $f18, 6*FFI_SIZEOF_ARG(t9) -arg7_next: - - SRL t4, t6, 7*FFI_FLAG_BITS - and t4, ((1<<FFI_FLAG_BITS)-1) - REG_L a7, 7*FFI_SIZEOF_ARG(t9) - beqz t4, arg8_next - bne t4, FFI_TYPE_FLOAT, arg8_doublep - l.s $f19, 7*FFI_SIZEOF_ARG(t9) - b arg8_next -arg8_doublep: - l.d $f19, 7*FFI_SIZEOF_ARG(t9) -arg8_next: - -callit: - # Load the function pointer - REG_L t9, 5*FFI_SIZEOF_ARG($fp) - - # If the return value pointer is NULL, assume no return value. - REG_L t5, 4*FFI_SIZEOF_ARG($fp) - beqz t5, noretval - - # Shift the return type flag over - SRL t6, 8*FFI_FLAG_BITS - - beq t6, FFI_TYPE_SINT32, retint - bne t6, FFI_TYPE_INT, retfloat -retint: - jal t9 - REG_L t4, 4*FFI_SIZEOF_ARG($fp) - REG_S v0, 0(t4) - b epilogue - -retfloat: - bne t6, FFI_TYPE_FLOAT, retdouble - jal t9 - REG_L t4, 4*FFI_SIZEOF_ARG($fp) - s.s $f0, 0(t4) - b epilogue - -retdouble: - bne t6, FFI_TYPE_DOUBLE, retstruct_d - jal t9 - REG_L t4, 4*FFI_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*FFI_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*FFI_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*FFI_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*FFI_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*FFI_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_d_soft - jal t9 - REG_L t4, 4*FFI_SIZEOF_ARG($fp) - s.s $f0, 0(t4) - s.d $f2, 8(t4) - b epilogue - -retstruct_d_soft: - bne t6, FFI_TYPE_STRUCT_D_SOFT, retstruct_f_soft - jal t9 - REG_L t4, 4*FFI_SIZEOF_ARG($fp) - sd v0, 0(t4) - b epilogue - -retstruct_f_soft: - bne t6, FFI_TYPE_STRUCT_F_SOFT, retstruct_d_d_soft - jal t9 - REG_L t4, 4*FFI_SIZEOF_ARG($fp) - sw v0, 0(t4) - b epilogue - -retstruct_d_d_soft: - bne t6, FFI_TYPE_STRUCT_DD_SOFT, retstruct_f_f_soft - jal t9 - REG_L t4, 4*FFI_SIZEOF_ARG($fp) - sd v0, 0(t4) - sd v1, 8(t4) - b epilogue - -retstruct_f_f_soft: - bne t6, FFI_TYPE_STRUCT_FF_SOFT, retstruct_d_f_soft - jal t9 - REG_L t4, 4*FFI_SIZEOF_ARG($fp) - sw v0, 0(t4) - sw v1, 4(t4) - b epilogue - -retstruct_d_f_soft: - bne t6, FFI_TYPE_STRUCT_DF_SOFT, retstruct_f_d_soft - jal t9 - REG_L t4, 4*FFI_SIZEOF_ARG($fp) - sd v0, 0(t4) - sw v1, 8(t4) - b epilogue - -retstruct_f_d_soft: - bne t6, FFI_TYPE_STRUCT_FD_SOFT, retstruct_small - jal t9 - REG_L t4, 4*FFI_SIZEOF_ARG($fp) - sw v0, 0(t4) - sd v1, 8(t4) - b epilogue - -retstruct_small: - bne t6, FFI_TYPE_STRUCT_SMALL, retstruct_small2 - jal t9 - REG_L t4, 4*FFI_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*FFI_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*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 - -.LFE3: - .end ffi_call_N32 - -/* ffi_closure_N32. Expects address of the passed-in ffi_closure in t0 - ($12). Stores any arguments passed in registers onto the stack, - then calls ffi_closure_mips_inner_N32, which then decodes - them. - - Stack layout: - - 20 - Start of parameters, original sp - 19 - Called function a7 save - 18 - Called function a6 save - 17 - Called function a5 save - 16 - Called function a4 save - 15 - Called function a3 save - 14 - Called function a2 save - 13 - Called function a1 save - 12 - Called function a0 save - 11 - Called function f19 - 10 - Called function f18 - 9 - Called function f17 - 8 - Called function f16 - 7 - Called function f15 - 6 - Called function f14 - 5 - Called function f13 - 4 - Called function f12 - 3 - return value high (v1 or $f2) - 2 - return value low (v0 or $f0) - 1 - ra save - 0 - gp save our sp points here - */ - -#define SIZEOF_FRAME2 (20 * FFI_SIZEOF_ARG) - -#define A7_OFF2 (19 * FFI_SIZEOF_ARG) -#define A6_OFF2 (18 * FFI_SIZEOF_ARG) -#define A5_OFF2 (17 * FFI_SIZEOF_ARG) -#define A4_OFF2 (16 * FFI_SIZEOF_ARG) -#define A3_OFF2 (15 * FFI_SIZEOF_ARG) -#define A2_OFF2 (14 * FFI_SIZEOF_ARG) -#define A1_OFF2 (13 * FFI_SIZEOF_ARG) -#define A0_OFF2 (12 * FFI_SIZEOF_ARG) - -#define F19_OFF2 (11 * FFI_SIZEOF_ARG) -#define F18_OFF2 (10 * FFI_SIZEOF_ARG) -#define F17_OFF2 (9 * FFI_SIZEOF_ARG) -#define F16_OFF2 (8 * FFI_SIZEOF_ARG) -#define F15_OFF2 (7 * FFI_SIZEOF_ARG) -#define F14_OFF2 (6 * FFI_SIZEOF_ARG) -#define F13_OFF2 (5 * FFI_SIZEOF_ARG) -#define F12_OFF2 (4 * FFI_SIZEOF_ARG) - -#define V1_OFF2 (3 * FFI_SIZEOF_ARG) -#define V0_OFF2 (2 * FFI_SIZEOF_ARG) - -#define RA_OFF2 (1 * FFI_SIZEOF_ARG) -#define GP_OFF2 (0 * FFI_SIZEOF_ARG) - - .align 2 - .globl ffi_closure_N32 - .ent ffi_closure_N32 -ffi_closure_N32: -.LFB2: - .frame $sp, SIZEOF_FRAME2, ra - .mask 0x90000000,-(SIZEOF_FRAME2 - RA_OFF2) - .fmask 0x00000000,0 - SUBU $sp, SIZEOF_FRAME2 -.LCFI5: - .cpsetup t9, GP_OFF2, ffi_closure_N32 - REG_S ra, RA_OFF2($sp) # Save return address -.LCFI6: - # Store all possible argument registers. If there are more than - # fit in registers, then they were stored on the stack. - REG_S a0, A0_OFF2($sp) - REG_S a1, A1_OFF2($sp) - REG_S a2, A2_OFF2($sp) - REG_S a3, A3_OFF2($sp) - REG_S a4, A4_OFF2($sp) - REG_S a5, A5_OFF2($sp) - REG_S a6, A6_OFF2($sp) - REG_S a7, A7_OFF2($sp) - - # Store all possible float/double registers. - s.d $f12, F12_OFF2($sp) - s.d $f13, F13_OFF2($sp) - s.d $f14, F14_OFF2($sp) - s.d $f15, F15_OFF2($sp) - s.d $f16, F16_OFF2($sp) - s.d $f17, F17_OFF2($sp) - s.d $f18, F18_OFF2($sp) - s.d $f19, F19_OFF2($sp) - - # Call ffi_closure_mips_inner_N32 to do the real work. - LA t9, ffi_closure_mips_inner_N32 - move a0, $12 # Pointer to the ffi_closure - ADDU a1, $sp, V0_OFF2 - ADDU a2, $sp, A0_OFF2 - ADDU a3, $sp, F12_OFF2 - jalr t9 - - # Return flags are in v0 - bne v0, FFI_TYPE_SINT32, cls_retint - lw v0, V0_OFF2($sp) - b cls_epilogue - -cls_retint: - bne v0, FFI_TYPE_INT, cls_retfloat - REG_L v0, V0_OFF2($sp) - b cls_epilogue - -cls_retfloat: - bne v0, FFI_TYPE_FLOAT, cls_retdouble - l.s $f0, V0_OFF2($sp) - b cls_epilogue - -cls_retdouble: - bne v0, FFI_TYPE_DOUBLE, cls_retstruct_d - l.d $f0, V0_OFF2($sp) - b cls_epilogue - -cls_retstruct_d: - bne v0, FFI_TYPE_STRUCT_D, cls_retstruct_f - l.d $f0, V0_OFF2($sp) - b cls_epilogue - -cls_retstruct_f: - bne v0, FFI_TYPE_STRUCT_F, cls_retstruct_d_d - l.s $f0, V0_OFF2($sp) - b cls_epilogue - -cls_retstruct_d_d: - bne v0, FFI_TYPE_STRUCT_DD, cls_retstruct_f_f - l.d $f0, V0_OFF2($sp) - l.d $f2, V1_OFF2($sp) - b cls_epilogue - -cls_retstruct_f_f: - bne v0, FFI_TYPE_STRUCT_FF, cls_retstruct_d_f - l.s $f0, V0_OFF2($sp) - l.s $f2, V1_OFF2($sp) - b cls_epilogue - -cls_retstruct_d_f: - bne v0, FFI_TYPE_STRUCT_DF, cls_retstruct_f_d - l.d $f0, V0_OFF2($sp) - l.s $f2, V1_OFF2($sp) - b cls_epilogue - -cls_retstruct_f_d: - bne v0, FFI_TYPE_STRUCT_FD, cls_retstruct_small2 - l.s $f0, V0_OFF2($sp) - l.d $f2, V1_OFF2($sp) - b cls_epilogue - -cls_retstruct_small2: - REG_L v0, V0_OFF2($sp) - REG_L v1, V1_OFF2($sp) - - # Epilogue -cls_epilogue: - REG_L ra, RA_OFF2($sp) # Restore return address - .cpreturn - ADDU $sp, SIZEOF_FRAME2 - j ra -.LFE2: - .end ffi_closure_N32 - -#ifdef __GNUC__ - .section .eh_frame,"aw",@progbits -.Lframe1: - .4byte .LECIE1-.LSCIE1 # length -.LSCIE1: - .4byte 0x0 # CIE - .byte 0x1 # Version 1 - .ascii "\000" # Augmentation - .uleb128 0x1 # Code alignment 1 - .sleb128 -4 # Data alignment -4 - .byte 0x1f # Return Address $31 - .byte 0xc # DW_CFA_def_cfa - .uleb128 0x1d # in $sp - .uleb128 0x0 # offset 0 - .align EH_FRAME_ALIGN -.LECIE1: - -.LSFDE1: - .4byte .LEFDE1-.LASFDE1 # length. -.LASFDE1: - .4byte .LASFDE1-.Lframe1 # CIE_pointer. - FDE_ADDR_BYTES .LFB3 # initial_location. - FDE_ADDR_BYTES .LFE3-.LFB3 # address_range. - .byte 0x4 # DW_CFA_advance_loc4 - .4byte .LCFI0-.LFB3 # to .LCFI0 - .byte 0xe # DW_CFA_def_cfa_offset - .uleb128 SIZEOF_FRAME # adjust stack.by SIZEOF_FRAME - .byte 0x4 # DW_CFA_advance_loc4 - .4byte .LCFI1-.LCFI0 # to .LCFI1 - .byte 0x9e # DW_CFA_offset of $fp - .uleb128 2*FFI_SIZEOF_ARG/4 # - .byte 0x9f # DW_CFA_offset of ra - .uleb128 1*FFI_SIZEOF_ARG/4 # - .byte 0x4 # DW_CFA_advance_loc4 - .4byte .LCFI3-.LCFI1 # to .LCFI3 - .byte 0xd # DW_CFA_def_cfa_register - .uleb128 0x1e # in $fp - .align EH_FRAME_ALIGN -.LEFDE1: -.LSFDE3: - .4byte .LEFDE3-.LASFDE3 # length -.LASFDE3: - .4byte .LASFDE3-.Lframe1 # CIE_pointer. - FDE_ADDR_BYTES .LFB2 # initial_location. - FDE_ADDR_BYTES .LFE2-.LFB2 # address_range. - .byte 0x4 # DW_CFA_advance_loc4 - .4byte .LCFI5-.LFB2 # to .LCFI5 - .byte 0xe # DW_CFA_def_cfa_offset - .uleb128 SIZEOF_FRAME2 # adjust stack.by SIZEOF_FRAME - .byte 0x4 # DW_CFA_advance_loc4 - .4byte .LCFI6-.LCFI5 # to .LCFI6 - .byte 0x9c # DW_CFA_offset of $gp ($28) - .uleb128 (SIZEOF_FRAME2 - GP_OFF2)/4 - .byte 0x9f # DW_CFA_offset of ra ($31) - .uleb128 (SIZEOF_FRAME2 - RA_OFF2)/4 - .align EH_FRAME_ALIGN -.LEFDE3: -#endif /* __GNUC__ */ - -#endif diff --git a/Modules/_ctypes/libffi/src/mips/o32.S b/Modules/_ctypes/libffi/src/mips/o32.S deleted file mode 100644 index eb279813a7..0000000000 --- a/Modules/_ctypes/libffi/src/mips/o32.S +++ /dev/null @@ -1,381 +0,0 @@ -/* ----------------------------------------------------------------------- - o32.S - Copyright (c) 1996, 1998, 2005 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 THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM -#include <fficonfig.h> -#include <ffi.h> - -/* 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) -#define A3_OFF (SIZEOF_FRAME + 3 * FFI_SIZEOF_ARG) -#define FP_OFF (SIZEOF_FRAME - 2 * FFI_SIZEOF_ARG) -#define RA_OFF (SIZEOF_FRAME - 1 * FFI_SIZEOF_ARG) - - .abicalls - .text - .align 2 - .globl ffi_call_O32 - .ent ffi_call_O32 -ffi_call_O32: -$LFB0: - # Prologue - SUBU $sp, SIZEOF_FRAME # Frame size -$LCFI0: - REG_S $fp, FP_OFF($sp) # Save frame pointer -$LCFI1: - REG_S ra, RA_OFF($sp) # Save return address -$LCFI2: - move $fp, $sp - -$LCFI3: - move t9, callback # callback function pointer - REG_S flags, A3_OFF($fp) # flags - - # Allocate at least 4 words in the argstack - LI v0, 4 * FFI_SIZEOF_ARG - blt bytes, v0, sixteen - - ADDU v0, bytes, 7 # make sure it is aligned - and v0, -8 # to an 8 byte boundry - -sixteen: - SUBU $sp, v0 # move the stack pointer to reflect the - # arg space - - ADDU a0, $sp, 4 * FFI_SIZEOF_ARG - - jalr t9 - - REG_L t0, A3_OFF($fp) # load the flags word - SRL t2, t0, 4 # shift our arg info - and t0, ((1<<4)-1) # mask out the return type - - ADDU $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, retlonglong - jalr t9 - REG_L t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp) - REG_S v0, 0(t0) - b epilogue - -retlonglong: - # Really any 64-bit int, signed or not. - bne t2, FFI_TYPE_UINT64, retfloat - jalr t9 - REG_L t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp) - REG_S v1, 4(t0) - REG_S v0, 0(t0) - b epilogue - -retfloat: - bne t2, FFI_TYPE_FLOAT, retdouble - jalr 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 - jalr t9 - REG_L t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp) - s.d $f0, 0(t0) - b epilogue - -noretval: - jalr t9 - - # Epilogue -epilogue: - move $sp, $fp - REG_L $fp, FP_OFF($sp) # Restore frame pointer - REG_L ra, RA_OFF($sp) # Restore return address - ADDU $sp, SIZEOF_FRAME # Fix stack pointer - j ra - -$LFE0: - .end ffi_call_O32 - - -/* ffi_closure_O32. Expects address of the passed-in ffi_closure - in t4 ($12). Stores any arguments passed in registers onto the - stack, then calls ffi_closure_mips_inner_O32, which - then decodes them. - - Stack layout: - - 3 - a3 save - 2 - a2 save - 1 - a1 save - 0 - a0 save, original sp - -1 - ra save - -2 - fp save - -3 - $16 (s0) save - -4 - cprestore - -5 - return value high (v1) - -6 - return value low (v0) - -7 - f14 (le high, be low) - -8 - f14 (le low, be high) - -9 - f12 (le high, be low) - -10 - f12 (le low, be high) - -11 - Called function a3 save - -12 - Called function a2 save - -13 - Called function a1 save - -14 - Called function a0 save, our sp and fp point here - */ - -#define SIZEOF_FRAME2 (14 * FFI_SIZEOF_ARG) -#define A3_OFF2 (SIZEOF_FRAME2 + 3 * FFI_SIZEOF_ARG) -#define A2_OFF2 (SIZEOF_FRAME2 + 2 * FFI_SIZEOF_ARG) -#define A1_OFF2 (SIZEOF_FRAME2 + 1 * FFI_SIZEOF_ARG) -#define A0_OFF2 (SIZEOF_FRAME2 + 0 * FFI_SIZEOF_ARG) -#define RA_OFF2 (SIZEOF_FRAME2 - 1 * FFI_SIZEOF_ARG) -#define FP_OFF2 (SIZEOF_FRAME2 - 2 * FFI_SIZEOF_ARG) -#define S0_OFF2 (SIZEOF_FRAME2 - 3 * FFI_SIZEOF_ARG) -#define GP_OFF2 (SIZEOF_FRAME2 - 4 * FFI_SIZEOF_ARG) -#define V1_OFF2 (SIZEOF_FRAME2 - 5 * FFI_SIZEOF_ARG) -#define V0_OFF2 (SIZEOF_FRAME2 - 6 * FFI_SIZEOF_ARG) -#define FA_1_1_OFF2 (SIZEOF_FRAME2 - 7 * FFI_SIZEOF_ARG) -#define FA_1_0_OFF2 (SIZEOF_FRAME2 - 8 * FFI_SIZEOF_ARG) -#define FA_0_1_OFF2 (SIZEOF_FRAME2 - 9 * FFI_SIZEOF_ARG) -#define FA_0_0_OFF2 (SIZEOF_FRAME2 - 10 * FFI_SIZEOF_ARG) - - .text - .align 2 - .globl ffi_closure_O32 - .ent ffi_closure_O32 -ffi_closure_O32: -$LFB1: - # Prologue - .frame $fp, SIZEOF_FRAME2, ra - .set noreorder - .cpload t9 - .set reorder - SUBU $sp, SIZEOF_FRAME2 - .cprestore GP_OFF2 -$LCFI4: - REG_S $16, S0_OFF2($sp) # Save s0 - REG_S $fp, FP_OFF2($sp) # Save frame pointer - REG_S ra, RA_OFF2($sp) # Save return address -$LCFI6: - move $fp, $sp - -$LCFI7: - # Store all possible argument registers. If there are more than - # four arguments, then they are stored above where we put a3. - REG_S a0, A0_OFF2($fp) - REG_S a1, A1_OFF2($fp) - REG_S a2, A2_OFF2($fp) - REG_S a3, A3_OFF2($fp) - - # Load ABI enum to s0 - REG_L $16, 20($12) # cif pointer follows tramp. - REG_L $16, 0($16) # abi is first member. - - li $13, 1 # FFI_O32 - bne $16, $13, 1f # Skip fp save if FFI_O32_SOFT_FLOAT - - # Store all possible float/double registers. - s.d $f12, FA_0_0_OFF2($fp) - s.d $f14, FA_1_0_OFF2($fp) -1: - # Call ffi_closure_mips_inner_O32 to do the work. - la t9, ffi_closure_mips_inner_O32 - move a0, $12 # Pointer to the ffi_closure - addu a1, $fp, V0_OFF2 - addu a2, $fp, A0_OFF2 - addu a3, $fp, FA_0_0_OFF2 - jalr t9 - - # Load the return value into the appropriate register. - move $8, $2 - li $9, FFI_TYPE_VOID - beq $8, $9, closure_done - - li $13, 1 # FFI_O32 - bne $16, $13, 1f # Skip fp restore if FFI_O32_SOFT_FLOAT - - li $9, FFI_TYPE_FLOAT - l.s $f0, V0_OFF2($fp) - beq $8, $9, closure_done - - li $9, FFI_TYPE_DOUBLE - l.d $f0, V0_OFF2($fp) - beq $8, $9, closure_done -1: - REG_L $3, V1_OFF2($fp) - REG_L $2, V0_OFF2($fp) - -closure_done: - # Epilogue - move $sp, $fp - REG_L $16, S0_OFF2($sp) # Restore s0 - REG_L $fp, FP_OFF2($sp) # Restore frame pointer - REG_L ra, RA_OFF2($sp) # Restore return address - ADDU $sp, SIZEOF_FRAME2 - j ra -$LFE1: - .end ffi_closure_O32 - -/* DWARF-2 unwind info. */ - - .section .eh_frame,"a",@progbits -$Lframe0: - .4byte $LECIE0-$LSCIE0 # Length of Common Information Entry -$LSCIE0: - .4byte 0x0 # CIE Identifier Tag - .byte 0x1 # CIE Version - .ascii "zR\0" # CIE Augmentation - .uleb128 0x1 # CIE Code Alignment Factor - .sleb128 4 # CIE Data Alignment Factor - .byte 0x1f # CIE RA Column - .uleb128 0x1 # Augmentation size - .byte 0x00 # FDE Encoding (absptr) - .byte 0xc # DW_CFA_def_cfa - .uleb128 0x1d - .uleb128 0x0 - .align 2 -$LECIE0: -$LSFDE0: - .4byte $LEFDE0-$LASFDE0 # FDE Length -$LASFDE0: - .4byte $LASFDE0-$Lframe0 # FDE CIE offset - .4byte $LFB0 # FDE initial location - .4byte $LFE0-$LFB0 # FDE address range - .uleb128 0x0 # Augmentation size - .byte 0x4 # DW_CFA_advance_loc4 - .4byte $LCFI0-$LFB0 - .byte 0xe # DW_CFA_def_cfa_offset - .uleb128 0x18 - .byte 0x4 # DW_CFA_advance_loc4 - .4byte $LCFI2-$LCFI0 - .byte 0x11 # DW_CFA_offset_extended_sf - .uleb128 0x1e # $fp - .sleb128 -2 # SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp) - .byte 0x11 # DW_CFA_offset_extended_sf - .uleb128 0x1f # $ra - .sleb128 -1 # SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp) - .byte 0x4 # DW_CFA_advance_loc4 - .4byte $LCFI3-$LCFI2 - .byte 0xc # DW_CFA_def_cfa - .uleb128 0x1e - .uleb128 0x18 - .align 2 -$LEFDE0: -$LSFDE1: - .4byte $LEFDE1-$LASFDE1 # FDE Length -$LASFDE1: - .4byte $LASFDE1-$Lframe0 # FDE CIE offset - .4byte $LFB1 # FDE initial location - .4byte $LFE1-$LFB1 # FDE address range - .uleb128 0x0 # Augmentation size - .byte 0x4 # DW_CFA_advance_loc4 - .4byte $LCFI4-$LFB1 - .byte 0xe # DW_CFA_def_cfa_offset - .uleb128 0x38 - .byte 0x4 # DW_CFA_advance_loc4 - .4byte $LCFI6-$LCFI4 - .byte 0x11 # DW_CFA_offset_extended_sf - .uleb128 0x10 # $16 - .sleb128 -3 # SIZEOF_FRAME2 - 3*FFI_SIZEOF_ARG($sp) - .byte 0x11 # DW_CFA_offset_extended_sf - .uleb128 0x1e # $fp - .sleb128 -2 # SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp) - .byte 0x11 # DW_CFA_offset_extended_sf - .uleb128 0x1f # $ra - .sleb128 -1 # SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp) - .byte 0x4 # DW_CFA_advance_loc4 - .4byte $LCFI7-$LCFI6 - .byte 0xc # DW_CFA_def_cfa - .uleb128 0x1e - .uleb128 0x38 - .align 2 -$LEFDE1: - -#endif |