39#define ASM_NEEDS_REGISTERS 4
40#define NUM_GPR_ARG_REGISTERS 8
41#define NUM_FPR_ARG_REGISTERS 8
44#if HAVE_LONG_DOUBLE_VARIANT && FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
51 ffi_type_longdouble.size = 8;
52 ffi_type_longdouble.alignment = 8;
56 ffi_type_longdouble.size = 16;
57 ffi_type_longdouble.alignment = 16;
64translate_float (
int abi,
int type)
66#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
69 type = FFI_TYPE_DOUBLE;
73 if (
type == FFI_TYPE_FLOAT)
74 type = FFI_TYPE_UINT32;
75 else if (
type == FFI_TYPE_DOUBLE)
76 type = FFI_TYPE_UINT64;
77#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
84 type = FFI_TYPE_STRUCT;
92ffi_prep_cif_sysv_core (ffi_cif *cif)
96 unsigned i, fparg_count = 0, intarg_count = 0;
97 unsigned flags = cif->flags;
98 unsigned struct_copy_size = 0;
99 unsigned type = cif->rtype->type;
100 unsigned size = cif->rtype->size;
122 type = translate_float (cif->abi,
type);
126#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
131 case FFI_TYPE_DOUBLE:
144 case FFI_TYPE_UINT64:
145 case FFI_TYPE_SINT64:
149 case FFI_TYPE_STRUCT:
175 for (
ptr = cif->arg_types,
i = cif->nargs;
i > 0;
i--,
ptr++)
177 unsigned short typenum = (*ptr)->type;
179 typenum = translate_float (cif->abi, typenum);
183#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
188 case FFI_TYPE_DOUBLE:
194 && intarg_count % 2 != 0)
218 case FFI_TYPE_UINT64:
219 case FFI_TYPE_SINT64:
229 || intarg_count % 2 != 0)
234 case FFI_TYPE_STRUCT:
239 struct_copy_size += ((*ptr)->size + 15) & ~0xF;
242 case FFI_TYPE_POINTER:
244 case FFI_TYPE_UINT32:
245 case FFI_TYPE_SINT32:
246 case FFI_TYPE_UINT16:
247 case FFI_TYPE_SINT16:
260 if (fparg_count != 0)
262 if (intarg_count > 4)
264 if (struct_copy_size != 0)
268 if (fparg_count != 0)
278 bytes = (bytes + 15) & ~0xF;
281 bytes += struct_copy_size;
320 return ffi_prep_cif_sysv_core (cif);
352 const unsigned bytes = ecif->
cif->bytes;
353 const unsigned flags = ecif->
cif->flags;
404 size_t struct_copy_size;
407 stacktop.c = (
char *) stack + bytes;
415 copy_space.c = gpr_base.c;
417 next_arg.u = stack + 2;
420 FFI_ASSERT (((
unsigned long) (
char *) stack & 0xF) == 0);
421 FFI_ASSERT (((
unsigned long) copy_space.c & 0xF) == 0);
422 FFI_ASSERT (((
unsigned long) stacktop.c & 0xF) == 0);
429 *gpr_base.u++ = (
unsigned long) (
char *) ecif->
rvalue;
435 for (
ptr = ecif->
cif->arg_types,
i = ecif->
cif->nargs;
437 i--,
ptr++, p_argv.v++)
439 unsigned int typenum = (*ptr)->type;
441 typenum = translate_float (ecif->
cif->abi, typenum);
447# if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
449 double_tmp = (*p_argv.d)[0];
454 && intarg_count % 2 != 0)
459 *next_arg.d = double_tmp;
461 double_tmp = (*p_argv.d)[1];
462 *next_arg.d = double_tmp;
467 *fpr_base.d++ = double_tmp;
468 double_tmp = (*p_argv.d)[1];
469 *fpr_base.d++ = double_tmp;
476 case FFI_TYPE_DOUBLE:
477 double_tmp = **p_argv.d;
482 && intarg_count % 2 != 0)
487 *next_arg.d = double_tmp;
491 *fpr_base.d++ = double_tmp;
497 double_tmp = **p_argv.f;
500 *next_arg.f = (float) double_tmp;
505 *fpr_base.d++ = double_tmp;
517 unsigned int int_tmp;
523 for (ii = 0; ii < 4; ii++)
525 int_tmp = (*p_argv.ui)[ii];
526 *next_arg.u++ = int_tmp;
531 for (ii = 0; ii < 4; ii++)
533 int_tmp = (*p_argv.ui)[ii];
534 *gpr_base.u++ = int_tmp;
541 case FFI_TYPE_UINT64:
542 case FFI_TYPE_SINT64:
547 if (intarg_count % 2 != 0)
552 *next_arg.ll = **p_argv.ll;
562 if (intarg_count % 2 != 0)
567 *gpr_base.ll++ = **p_argv.ll;
572 case FFI_TYPE_STRUCT:
573 struct_copy_size = ((*ptr)->size + 15) & ~0xF;
574 copy_space.c -= struct_copy_size;
575 memcpy (copy_space.c, *p_argv.c, (*ptr)->size);
577 gprvalue = (
unsigned long) copy_space.c;
584 gprvalue = **p_argv.uc;
587 gprvalue = **p_argv.sc;
589 case FFI_TYPE_UINT16:
590 gprvalue = **p_argv.us;
592 case FFI_TYPE_SINT16:
593 gprvalue = **p_argv.ss;
597 case FFI_TYPE_UINT32:
598 case FFI_TYPE_SINT32:
599 case FFI_TYPE_POINTER:
601 gprvalue = **p_argv.ui;
605 *next_arg.u++ = gprvalue;
607 *gpr_base.u++ = gprvalue;
629#define MIN_CACHE_LINE_SIZE 8
632flush_icache (
char *wraddr,
char *xaddr,
int size)
636 __asm__ volatile (
"icbi 0,%0;" "dcbf 0,%1;"
637 : :
"r" (xaddr +
i),
"r" (wraddr +
i) :
"memory");
638 __asm__ volatile (
"icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;"
639 : :
"r"(xaddr +
size - 1),
"r"(wraddr +
size - 1)
646 void (*fun) (ffi_cif *,
void *,
void **,
void *),
655 tramp = (
unsigned int *) &closure->tramp[0];
656 tramp[0] = 0x7c0802a6;
657 tramp[1] = 0x4800000d;
658 tramp[4] = 0x7d6802a6;
659 tramp[5] = 0x7c0803a6;
660 tramp[6] = 0x800b0000;
661 tramp[7] = 0x816b0004;
662 tramp[8] = 0x7c0903a6;
663 tramp[9] = 0x4e800420;
665 *(
void **) &tramp[3] = codeloc;
672 closure->user_data = user_data;
695 ffi_type ** arg_types;
702 ffi_cif *cif = closure->cif;
703 unsigned size = cif->rtype->size;
704 unsigned short rtypenum = cif->rtype->type;
706 avalue =
alloca (cif->nargs * sizeof (
void *));
709 rtypenum = translate_float (cif->abi, rtypenum);
715 if (rtypenum == FFI_TYPE_STRUCT
718 rvalue = (
void *) *pgr;
725 arg_types = cif->arg_types;
729 unsigned short typenum = arg_types[
i]->type;
732 typenum = translate_float (cif->abi, typenum);
747 double temp = pfr->
d;
748 pfr->
f = (float) temp;
760 case FFI_TYPE_DOUBLE:
769 if (((
long) pst) & 4)
776# if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
786 if (((
long) pst) & 4)
815#ifndef __LITTLE_ENDIAN__
818 avalue[
i] = (
char *) pgr + 3;
824 avalue[
i] = (
char *) pst + 3;
830 case FFI_TYPE_SINT16:
831 case FFI_TYPE_UINT16:
832#ifndef __LITTLE_ENDIAN__
835 avalue[
i] = (
char *) pgr + 2;
841 avalue[
i] = (
char *) pst + 2;
847 case FFI_TYPE_SINT32:
848 case FFI_TYPE_UINT32:
849 case FFI_TYPE_POINTER:
863 case FFI_TYPE_STRUCT:
868 avalue[
i] = (
void *) *pgr;
874 avalue[
i] = (
void *) *pst;
879 case FFI_TYPE_SINT64:
880 case FFI_TYPE_UINT64:
903 if (((
long) pst) & 4)
918 (closure->fun) (cif, rvalue, avalue, closure->user_data);
926 if (rtypenum == FFI_TYPE_STRUCT
void ffi_closure_SYSV(ffi_closure *)
#define FFI_TRAMPOLINE_SIZE
#define FFI_TYPE_LONGDOUBLE
void FFI_HIDDEN ffi_prep_types_sysv(ffi_abi)
int ffi_closure_helper_SYSV(ffi_closure *closure, void *rvalue, unsigned long *pgr, ffi_dblfl *pfr, unsigned long *pst)
#define ASM_NEEDS_REGISTERS
#define MIN_CACHE_LINE_SIZE
ffi_status FFI_HIDDEN ffi_prep_cif_sysv(ffi_cif *cif)
#define NUM_GPR_ARG_REGISTERS
ffi_status FFI_HIDDEN ffi_prep_closure_loc_sysv(ffi_closure *closure, ffi_cif *cif, void(*fun)(ffi_cif *, void *, void **, void *), void *user_data, void *codeloc)
#define NUM_FPR_ARG_REGISTERS
void FFI_HIDDEN ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack)
VALUE type(ANYARGS)
ANYARGS-ed function type.
#define FFI_SYSV_TYPE_SMALL_STRUCT
@ FFI_SYSV_LONG_DOUBLE_128
@ FFI_SYSV_IBM_LONG_DOUBLE
@ FFI_COMPAT_LINUX_SOFT_FLOAT
const UINT64 ffi_template_tramp_tile[] FFI_HIDDEN