35# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))
36# define USE__BUILTIN___CLEAR_CACHE 1
40#ifndef USE__BUILTIN___CLEAR_CACHE
41# if defined(__OpenBSD__)
42# include <mips64/sysarch.h>
44# include <sys/cachectl.h>
49# define FFI_MIPS_STOP_HERE() ffi_stop_here()
51# define FFI_MIPS_STOP_HERE() do {} while(0)
56FFI_ASSERT(argp <= &stack[bytes]); \
57if (argp == &stack[bytes]) \
60 FFI_MIPS_STOP_HERE(); \
84 if (bytes > 8 *
sizeof(
ffi_arg))
85 argp = &stack[bytes - (8 *
sizeof(
ffi_arg))];
92 memset(stack, 0, bytes);
95 if ( ecif->
cif->rstruct_flag != 0 )
97 if ( ecif->
cif->rtype->type == FFI_TYPE_STRUCT )
107 for (i = 0, p_arg = ecif->
cif->arg_types; i < ecif->cif->nargs; i++, p_arg++)
113 a = (*p_arg)->alignment;
117 if ((a - 1) & (
unsigned long) argp)
119 argp = (
char *)
ALIGN(argp, a);
126 int type = (*p_arg)->type;
130 if (type == FFI_TYPE_POINTER)
133 ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
141 type = FFI_TYPE_UINT32;
143 case FFI_TYPE_DOUBLE:
144 type = FFI_TYPE_UINT64;
160 case FFI_TYPE_SINT16:
164 case FFI_TYPE_UINT16:
168 case FFI_TYPE_SINT32:
172 case FFI_TYPE_UINT32:
185 *(
float *) argp = *(
float *)(* p_argv);
190 memcpy(argp, *p_argv, (*p_arg)->size);
200 unsigned long end = (
unsigned long) argp + z;
201 unsigned long cap = (
unsigned long) stack + bytes;
210 unsigned long portion = cap - (
unsigned long)argp;
212 memcpy(argp, *p_argv, portion);
215 memcpy(argp, (
void*)((
unsigned long)(*p_argv) + portion),
236calc_n32_struct_flags(
int soft_float, ffi_type *arg,
237 unsigned *loc,
unsigned *arg_reg)
247 while ((e = arg->elements[index]))
250 *loc =
ALIGN(*loc, e->alignment);
251 if (e->type == FFI_TYPE_DOUBLE)
271calc_n32_return_struct_flags(
int soft_float, ffi_type *arg)
290 e = arg->elements[0];
292 if (e->type == FFI_TYPE_DOUBLE)
293 flags = FFI_TYPE_DOUBLE;
294 else if (e->type == FFI_TYPE_FLOAT)
295 flags = FFI_TYPE_FLOAT;
297 if (flags && (e = arg->elements[1]))
299 if (e->type == FFI_TYPE_DOUBLE)
301 else if (e->type == FFI_TYPE_FLOAT)
306 if (flags && (arg->elements[2]))
334 if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi ==
FFI_O32)
338 switch ((cif->arg_types)[0]->type)
341 case FFI_TYPE_DOUBLE:
342 cif->flags += (cif->arg_types)[0]->type;
355 switch ((cif->arg_types)[1]->type)
358 case FFI_TYPE_DOUBLE:
374 switch (cif->rtype->type)
377 case FFI_TYPE_STRUCT:
381 case FFI_TYPE_SINT64:
382 case FFI_TYPE_UINT64:
383 case FFI_TYPE_DOUBLE:
396 switch (cif->rtype->type)
399 case FFI_TYPE_STRUCT:
401 case FFI_TYPE_DOUBLE:
405 case FFI_TYPE_SINT64:
406 case FFI_TYPE_UINT64:
421 unsigned arg_reg = 0;
423 unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
426 unsigned struct_flags = 0;
430 if (cif->rtype->type == FFI_TYPE_STRUCT)
432 struct_flags = calc_n32_return_struct_flags(soft_float, cif->rtype);
434 if (struct_flags == 0)
440 count = (cif->nargs < 7) ? cif->nargs : 7;
442 cif->rstruct_flag = !0;
445 cif->rstruct_flag = 0;
448 cif->rstruct_flag = 0;
450 while (
count-- > 0 && arg_reg < 8)
452 type = (cif->arg_types)[index]->type;
458 type = FFI_TYPE_UINT32;
460 case FFI_TYPE_DOUBLE:
461 type = FFI_TYPE_UINT64;
470 case FFI_TYPE_DOUBLE:
472 ((cif->arg_types)[index]->type << (arg_reg *
FFI_FLAG_BITS));
477 arg_reg =
ALIGN(arg_reg, 2);
494 case FFI_TYPE_STRUCT:
496 cif->flags += calc_n32_struct_flags(soft_float,
497 (cif->arg_types)[index],
510 switch (cif->rtype->type)
512 case FFI_TYPE_STRUCT:
514 if (struct_flags == 0)
534 case FFI_TYPE_POINTER:
548 case FFI_TYPE_DOUBLE:
566 cif->flags += (FFI_TYPE_DOUBLE
584 unsigned,
unsigned *,
void (*)(
void));
589 unsigned,
void *,
void (*)(
void));
591void ffi_call(ffi_cif *cif,
void (*fn)(
void),
void *rvalue,
void **avalue)
601 if ((rvalue ==
NULL) &&
602 (cif->rtype->type == FFI_TYPE_STRUCT))
613 cif->flags, ecif.
rvalue, fn);
625 char *rvalue_copy = ecif.
rvalue;
626 if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16)
634 else if (cif->rtype->type == FFI_TYPE_FLOAT
640#if defined(__MIPSEB__) || defined(_MIPSEB)
645 cif->flags, rvalue_copy, fn);
647 memcpy(ecif.
rvalue, rvalue_copy + copy_offset, cif->rtype->size);
659#if defined(FFI_MIPS_O32)
660extern void ffi_closure_O32(
void);
662extern void ffi_closure_N32(
void);
668 void (*fun)(ffi_cif*,
void*,
void**,
void*),
672 unsigned int *tramp = (
unsigned int *) &closure->tramp[0];
674 char *clear_location = (
char *) codeloc;
676#if defined(FFI_MIPS_O32)
679 fn = ffi_closure_O32;
681#if _MIPS_SIM ==_ABIN32
690 fn = ffi_closure_N32;
693#if defined(FFI_MIPS_O32) || (_MIPS_SIM ==_ABIN32)
695 tramp[0] = 0x3c190000 | ((unsigned)fn >> 16);
697 tramp[1] = 0x37390000 | ((unsigned)fn & 0xffff);
699 tramp[2] = 0x3c0c0000 | ((unsigned)codeloc >> 16);
701 tramp[3] = 0x03200008;
703 tramp[4] = 0x358c0000 | ((unsigned)codeloc & 0xffff);
707 tramp[0] = 0x3c190000 | ((
unsigned long)fn >> 48);
709 tramp[1] = 0x3c0c0000 | ((
unsigned long)codeloc >> 48);
711 tramp[2] = 0x37390000 | (((
unsigned long)fn >> 32 ) & 0xffff);
713 tramp[3] = 0x358c0000 | (((
unsigned long)codeloc >> 32) & 0xffff);
715 tramp[4] = 0x0019cc38;
717 tramp[5] = 0x000c6438;
719 tramp[6] = 0x37390000 | (((
unsigned long)fn >> 16 ) & 0xffff);
721 tramp[7] = 0x358c0000 | (((
unsigned long)codeloc >> 16) & 0xffff);
723 tramp[8] = 0x0019cc38;
725 tramp[9] = 0x000c6438;
727 tramp[10] = 0x37390000 | ((
unsigned long)fn & 0xffff);
729 tramp[11] = 0x03200008;
731 tramp[12] = 0x358c0000 | ((
unsigned long)codeloc & 0xffff);
737 closure->user_data = user_data;
739#ifdef USE__BUILTIN___CLEAR_CACHE
765ffi_closure_mips_inner_O32 (ffi_closure *closure,
772 ffi_type **arg_types;
773 int i, avn, argn, seen_int;
784 rvalue = (
void *)(
UINT32)ar[0];
790 arg_types = cif->arg_types;
794 if (i < 2 && !seen_int &&
795 (arg_types[i]->type == FFI_TYPE_FLOAT ||
796 arg_types[i]->type == FFI_TYPE_DOUBLE ||
799#if defined(__MIPSEB__) || defined(_MIPSEB)
800 if (arg_types[i]->type == FFI_TYPE_FLOAT)
801 avaluep[i] = ((
char *) &fpr[i]) +
sizeof (float);
804 avaluep[i] = (
char *) &fpr[i];
808 if (arg_types[i]->alignment == 8 && (argn & 0x1))
810 switch (arg_types[i]->type)
813 avaluep[i] = &avalue[i];
818 avaluep[i] = &avalue[i];
822 case FFI_TYPE_SINT16:
823 avaluep[i] = &avalue[i];
827 case FFI_TYPE_UINT16:
828 avaluep[i] = &avalue[i];
833 avaluep[i] = (
char *) &ar[argn];
843 (closure->fun) (cif, rvalue, avaluep, closure->user_data);
847 switch (cif->rtype->type)
851 case FFI_TYPE_DOUBLE:
852 return FFI_TYPE_UINT64;
854 return cif->rtype->type;
859 return cif->rtype->type;
863#if defined(FFI_MIPS_N32)
866copy_struct_N32(
char *target,
unsigned offset,
ffi_abi abi, ffi_type *type,
867 int argn,
unsigned arg_offset,
ffi_arg *ar,
870 ffi_type **elt_typep =
type->elements;
873 ffi_type *elt_type = *elt_typep;
882 argn += arg_offset /
sizeof(
ffi_arg);
883 arg_offset = arg_offset %
sizeof(
ffi_arg);
885 argp = (
char *)(ar + argn);
886 fpp = (
char *)(argn >= 8 ? ar + argn : fpr + argn);
890 if (elt_type->type == FFI_TYPE_DOUBLE && !soft_float)
891 *(
double *)tp = *(
double *)fpp;
893 memcpy(tp, argp + arg_offset, elt_type->size);
896 arg_offset += elt_type->size;
898 argn += arg_offset /
sizeof(
ffi_arg);
899 arg_offset = arg_offset %
sizeof(
ffi_arg);
919ffi_closure_mips_inner_N32 (ffi_closure *closure,
926 ffi_type **arg_types;
939 if (cif->rstruct_flag)
941#if _MIPS_SIM==_ABIN32
942 rvalue = (
void *)(
UINT32)ar[0];
944 rvalue = (
void *)ar[0];
951 arg_types = cif->arg_types;
955 if (arg_types[i]->type == FFI_TYPE_FLOAT
956 || arg_types[i]->type == FFI_TYPE_DOUBLE
959 argp = (argn >= 8 || soft_float) ? ar + argn : fpr + argn;
960 if ((arg_types[i]->type ==
FFI_TYPE_LONGDOUBLE) && ((unsigned)argp & (arg_types[i]->alignment-1)))
965#if defined(__MIPSEB__) || defined(_MIPSEB)
966 if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8)
967 avaluep[i] = ((
char *) argp) +
sizeof (float);
970 avaluep[i] = (
char *) argp;
974 unsigned type = arg_types[i]->type;
976 if (arg_types[i]->alignment >
sizeof(
ffi_arg))
977 argn =
ALIGN(argn, arg_types[i]->alignment /
sizeof(
ffi_arg));
982 if (type == FFI_TYPE_POINTER)
984 ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
986 if (soft_float && type == FFI_TYPE_FLOAT)
987 type = FFI_TYPE_UINT32;
992 avaluep[i] = &avalue[i];
997 avaluep[i] = &avalue[i];
1001 case FFI_TYPE_SINT16:
1002 avaluep[i] = &avalue[i];
1006 case FFI_TYPE_UINT16:
1007 avaluep[i] = &avalue[i];
1011 case FFI_TYPE_SINT32:
1012 avaluep[i] = &avalue[i];
1016 case FFI_TYPE_UINT32:
1017 avaluep[i] = &avalue[i];
1021 case FFI_TYPE_STRUCT:
1027 copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i],
1028 argn, 0, ar, fpr, soft_float);
1034 avaluep[i] = (
char *) argp;
1043 (closure->fun) (cif, rvalue, avaluep, closure->user_data);
ffi_status ffi_prep_closure_loc(ffi_closure *closure, ffi_cif *cif, void(*fun)(ffi_cif *, void *, void **, void *), void *user_data, void *codeloc)
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
void ffi_call(ffi_cif *cif, void(*fn)(void), void *rvalue, void **avalue)
#define FFI_TRAMPOLINE_SIZE
#define FFI_TYPE_LONGDOUBLE
void ffi_prep_args(char *stack, extended_cif *ecif)
typedef long(ZCALLBACK *tell_file_func) OF((voidpf opaque
int ffi_call_O32(void(*)(char *, extended_cif *, int, int), extended_cif *, unsigned, unsigned, unsigned *, void(*)(void))
int ffi_call_N32(void(*)(char *, extended_cif *, int, int), extended_cif *, unsigned, unsigned, void *, void(*)(void))
#define FFI_TYPE_SMALLSTRUCT
#define FFI_TYPE_SMALLSTRUCT2
#define FFI_TYPE_STRUCT_SOFT
VALUE type(ANYARGS)
ANYARGS-ed function type.