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;
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;
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;
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;
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;
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;
447 # if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE 449 double_tmp = (*p_argv.d)[0];
453 if (intarg_count >= NUM_GPR_ARG_REGISTERS
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;
481 if (intarg_count >= NUM_GPR_ARG_REGISTERS
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;
519 if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3)
521 if (intarg_count < NUM_GPR_ARG_REGISTERS)
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:
543 if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
545 if (intarg_count >= NUM_GPR_ARG_REGISTERS)
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;
604 if (intarg_count >= NUM_GPR_ARG_REGISTERS)
605 *next_arg.u++ = gprvalue;
607 *gpr_base.u++ = gprvalue;
629 #define MIN_CACHE_LINE_SIZE 8 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 *));
715 if (rtypenum == FFI_TYPE_STRUCT
718 rvalue = (
void *) *pgr;
725 arg_types = cif->arg_types;
729 unsigned short typenum = arg_types[i]->type;
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
#define MIN_CACHE_LINE_SIZE
ffi_status FFI_HIDDEN ffi_prep_cif_sysv(ffi_cif *cif)
#define FFI_TRAMPOLINE_SIZE
int ffi_closure_helper_SYSV(ffi_closure *closure, void *rvalue, unsigned long *pgr, ffi_dblfl *pfr, unsigned long *pst)
void FFI_HIDDEN ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack)
void FFI_HIDDEN ffi_prep_types_sysv(ffi_abi)
#define FFI_TYPE_LONGDOUBLE
static int translate_float(int abi, int type)
#define FFI_SYSV_TYPE_SMALL_STRUCT
const UINT64 ffi_template_tramp_tile [] FFI_HIDDEN
static ffi_status ffi_prep_cif_sysv_core(ffi_cif *cif)
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 ASM_NEEDS_REGISTERS
#define NUM_GPR_ARG_REGISTERS
static void flush_icache(char *wraddr, char *xaddr, int size)
#define NUM_FPR_ARG_REGISTERS
void ffi_closure_SYSV(ffi_closure *)