97#if defined(POWERPC_DARWIN64)
99darwin64_pass_struct_by_value
100 (ffi_type *,
char *,
unsigned,
unsigned *,
double **,
unsigned long **);
108 const unsigned bytes = ecif->
cif->bytes;
109 const unsigned flags = ecif->
cif->flags;
110 const unsigned nargs = ecif->
cif->nargs;
111#if !defined(POWERPC_DARWIN64)
116 unsigned long *
const stacktop = stack + (bytes /
sizeof(
unsigned long));
121 int gp_count = 0, fparg_count = 0;
128 void **p_argv = ecif->
avalue;
129 unsigned long gprvalue;
130 ffi_type**
ptr = ecif->
cif->arg_types;
131#if !defined(POWERPC_DARWIN64)
134 unsigned size_al = 0;
137 FFI_ASSERT(((
unsigned) (
char *) stack & 0xF) == 0);
138 FFI_ASSERT(((
unsigned) (
char *) stacktop & 0xF) == 0);
146 *next_arg++ = (
unsigned long) (
char *) ecif->
rvalue;
149 for (
i = nargs;
i > 0;
i--,
ptr++, p_argv++)
151 switch ((*ptr)->type)
157 double_tmp = *(
float *) *p_argv;
159 *fpr_base++ = double_tmp;
160#if defined(POWERPC_DARWIN)
161 *(
float *)next_arg = *(
float *) *p_argv;
163 *(
double *)next_arg = double_tmp;
171 case FFI_TYPE_DOUBLE:
172 double_tmp = *(
double *) *p_argv;
174 *fpr_base++ = double_tmp;
175 *(
double *)next_arg = double_tmp;
187#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
190# if defined(POWERPC64) && !defined(POWERPC_DARWIN64)
194 *(
long double *) fpr_base++ = *(
long double *) *p_argv;
196 *(
long double *) next_arg = *(
long double *) *p_argv;
200 double_tmp = ((
double *) *p_argv)[0];
202 *fpr_base++ = double_tmp;
203 *(
double *) next_arg = double_tmp;
204# if defined(POWERPC_DARWIN64)
212 double_tmp = ((
double *) *p_argv)[1];
214 *fpr_base++ = double_tmp;
215 *(
double *) next_arg = double_tmp;
216# if defined(POWERPC_DARWIN64)
228 case FFI_TYPE_UINT64:
229 case FFI_TYPE_SINT64:
231 gprvalue = *(
long long *) *p_argv;
234 *(
long long *) next_arg = *(
long long *) *p_argv;
239 case FFI_TYPE_POINTER:
240 gprvalue = *(
unsigned long *) *p_argv;
243 gprvalue = *(
unsigned char *) *p_argv;
246 gprvalue = *(
signed char *) *p_argv;
248 case FFI_TYPE_UINT16:
249 gprvalue = *(
unsigned short *) *p_argv;
251 case FFI_TYPE_SINT16:
252 gprvalue = *(
signed short *) *p_argv;
255 case FFI_TYPE_STRUCT:
256 size_al = (*ptr)->size;
257#if defined(POWERPC_DARWIN64)
258 next_arg = (
unsigned long *)
ALIGN((
char *)next_arg, (*ptr)->alignment);
259 darwin64_pass_struct_by_value (*
ptr, (
char *) *p_argv,
261 (
unsigned int *) &fparg_count,
262 &fpr_base, &next_arg);
264 dest_cpy = (
char *) next_arg;
268 if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
269 size_al =
ALIGN((*ptr)->size, 8);
271# if defined(POWERPC64)
273 memcpy ((
char *) dest_cpy, (
char *) *p_argv, size_al);
274 next_arg += (size_al + 7) / 8;
279 if (size_al < 3 && abi == FFI_DARWIN)
280 dest_cpy += 4 - size_al;
282 memcpy((
char *) dest_cpy, (
char *) *p_argv, size_al);
283 next_arg += (size_al + 3) / 4;
289 case FFI_TYPE_SINT32:
290 gprvalue = *(
signed int *) *p_argv;
293 case FFI_TYPE_UINT32:
294 gprvalue = *(
unsigned int *) *p_argv;
296 *next_arg++ = gprvalue;
311#if defined(POWERPC_DARWIN64)
317darwin64_scan_struct_for_floats (ffi_type *s,
unsigned *nfpr)
323 for (
i = 0; s->elements[
i] !=
NULL;
i++)
325 ffi_type *p = s->elements[
i];
328 case FFI_TYPE_STRUCT:
329 darwin64_scan_struct_for_floats (p, nfpr);
334 case FFI_TYPE_DOUBLE:
345darwin64_struct_size_exceeds_gprs_p (ffi_type *s,
char *
src,
unsigned *nfpr)
347 unsigned struct_offset=0,
i;
349 for (
i = 0; s->elements[
i] !=
NULL;
i++)
352 ffi_type *p = s->elements[
i];
355 struct_offset =
ALIGN(struct_offset, p->alignment);
357 item_base =
src + struct_offset;
361 case FFI_TYPE_STRUCT:
362 if (darwin64_struct_size_exceeds_gprs_p (p, item_base, nfpr))
371 case FFI_TYPE_DOUBLE:
384 if ((
unsigned long)item_base >= 8*8)
389 struct_offset += p->size;
396darwin64_struct_ret_by_value_p (ffi_type *s)
407 darwin64_scan_struct_for_floats (s, &nfp);
418 if (darwin64_struct_size_exceeds_gprs_p (s,
NULL, &nfp))
425darwin64_pass_struct_floats (ffi_type *s,
char *
src,
426 unsigned *nfpr,
double **fprs)
429 double *fpr_base = *fprs;
430 unsigned struct_offset = 0;
433 for (
i = 0; s->elements[
i] !=
NULL;
i++)
436 ffi_type *p = s->elements[
i];
439 struct_offset =
ALIGN(struct_offset, p->alignment);
440 item_base =
src + struct_offset;
444 case FFI_TYPE_STRUCT:
445 darwin64_pass_struct_floats (p, item_base, nfpr,
450 *fpr_base++ = *(
double *)item_base;
454 case FFI_TYPE_DOUBLE:
456 *fpr_base++ = *(
double *)item_base;
461 *fpr_base++ = (
double) *(
float *)item_base;
468 struct_offset += p->size;
477darwin64_pass_struct_by_value (ffi_type *s,
char *
src,
unsigned size,
478 unsigned *nfpr,
double **fprs,
unsigned long **
arg)
480 unsigned long *next_arg = *
arg;
481 char *dest_cpy = (
char *)next_arg;
492 && s->elements[0]->type != FFI_TYPE_FLOAT))
497 dest_cpy += 8 -
size;
510 darwin64_pass_struct_floats (s,
src, nfpr, fprs);
511 next_arg += (
size+7)/8;
518darwin64_struct_floats_to_mem (ffi_type *s,
char *dest,
double *fprs,
unsigned *nf)
521 unsigned struct_offset = 0;
524 for (
i = 0; s->elements[
i] !=
NULL;
i++)
527 ffi_type *p = s->elements[
i];
530 struct_offset =
ALIGN(struct_offset, p->alignment);
531 item_base = dest + struct_offset;
535 case FFI_TYPE_STRUCT:
536 fprs = darwin64_struct_floats_to_mem (p, item_base, fprs, nf);
541 *(
double *)item_base = *fprs++ ;
546 case FFI_TYPE_DOUBLE:
549 *(
double *)item_base = *fprs++ ;
556 *(
float *)item_base = (
float) *fprs++ ;
564 struct_offset += p->size;
576darwin_adjust_aggregate_sizes (ffi_type *s)
580 if (s->type != FFI_TYPE_STRUCT)
584 for (
i = 0; s->elements[
i] !=
NULL;
i++)
590 if (p->type == FFI_TYPE_STRUCT)
591 darwin_adjust_aggregate_sizes (p);
592#if defined(POWERPC_DARWIN64)
594 align = p->alignment;
598 align = p->alignment;
599 else if (p->alignment == 16 || p->alignment < 4)
601 align = p->alignment;
607 s->size =
ALIGN(s->size, align) + p->size;
610 s->size =
ALIGN(s->size, s->alignment);
613 if (s->elements[0]->type == FFI_TYPE_UINT64
614 || s->elements[0]->type == FFI_TYPE_SINT64
615 || s->elements[0]->type == FFI_TYPE_DOUBLE
616 || s->elements[0]->alignment == 8)
617 s->alignment = s->alignment > 8 ? s->alignment : 8;
625aix_adjust_aggregate_sizes (ffi_type *s)
629 if (s->type != FFI_TYPE_STRUCT)
633 for (
i = 0; s->elements[
i] !=
NULL;
i++)
639 aix_adjust_aggregate_sizes (p);
640 align = p->alignment;
641 if (
i != 0 && p->type == FFI_TYPE_DOUBLE)
643 s->size =
ALIGN(s->size, align) + p->size;
646 s->size =
ALIGN(s->size, s->alignment);
648 if (s->elements[0]->type == FFI_TYPE_UINT64
649 || s->elements[0]->type == FFI_TYPE_SINT64
650 || s->elements[0]->type == FFI_TYPE_DOUBLE
651 || s->elements[0]->alignment == 8)
652 s->alignment = s->alignment > 8 ? s->alignment : 8;
664 unsigned fparg_count = 0, intarg_count = 0;
666 unsigned size_al = 0;
672 if (cif->abi == FFI_DARWIN)
674 darwin_adjust_aggregate_sizes (cif->rtype);
675 for (
i = 0;
i < cif->nargs;
i++)
676 darwin_adjust_aggregate_sizes (cif->arg_types[
i]);
679 if (cif->abi == FFI_AIX)
681 aix_adjust_aggregate_sizes (cif->rtype);
682 for (
i = 0;
i < cif->nargs;
i++)
683 aix_adjust_aggregate_sizes (cif->arg_types[
i]);
710 switch (cif->rtype->type)
713#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
720 case FFI_TYPE_DOUBLE:
727 case FFI_TYPE_UINT64:
728 case FFI_TYPE_SINT64:
730 case FFI_TYPE_POINTER:
735 case FFI_TYPE_STRUCT:
736#if defined(POWERPC_DARWIN64)
739 if (darwin64_struct_ret_by_value_p (cif->rtype))
743 if (cif->rtype->size != 16)
744 darwin64_scan_struct_for_floats (cif->rtype, &nfpr) ;
758#elif defined(DARWIN_PPC)
759 if (cif->rtype->size <= 4)
788 for (
ptr = cif->arg_types,
i = cif->nargs;
i > 0;
i--,
ptr++)
790 unsigned align_words;
791 switch ((*ptr)->type)
794 case FFI_TYPE_DOUBLE:
796#if !defined(POWERPC_DARWIN64)
800 && (intarg_count & 0x01) != 0)
805#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
811#if defined (POWERPC64)
812 intarg_count =
ALIGN(intarg_count, 2);
814 intarg_count =
ALIGN(intarg_count, 4);
819 case FFI_TYPE_UINT64:
820 case FFI_TYPE_SINT64:
821#if defined(POWERPC64)
830 && (intarg_count & 0x01) != 0))
836 case FFI_TYPE_STRUCT:
837 size_al = (*ptr)->size;
838#if defined(POWERPC_DARWIN64)
839 align_words = (*ptr)->alignment >> 3;
841 intarg_count =
ALIGN(intarg_count, align_words);
843 intarg_count += (size_al + 7) / 8;
847 darwin64_scan_struct_for_floats (*
ptr, &fparg_count) ;
849 align_words = (*ptr)->alignment >> 2;
851 intarg_count =
ALIGN(intarg_count, align_words);
857 intarg_count += (size_al + 7) / 8;
859 intarg_count += (size_al + 3) / 4;
872 if (fparg_count != 0)
875#if defined(POWERPC_DARWIN64)
884 if (fparg_count != 0)
891 bytes += (intarg_count + fparg_count) *
sizeof(
long);
894 bytes += (intarg_count + 2 * fparg_count) *
sizeof(
long);
900 bytes =
ALIGN(bytes, 16) ;
909 void (*fn)(
void),
void (*fn2)(
void));
912 void (*fn)(
void),
void (*fn2)(
void), ffi_type*);
915ffi_call (ffi_cif *cif,
void (*fn)(
void),
void *rvalue,
void **avalue)
925 if ((rvalue ==
NULL) &&
926 (cif->rtype->type == FFI_TYPE_STRUCT))
949static void flush_icache(
char *);
950static void flush_range(
char *,
int);
1006 void (*fun)(ffi_cif*,
void*,
void**,
void*),
1010 unsigned int *tramp;
1011 struct ffi_aix_trampoline_struct *tramp_aix;
1020 tramp = (
unsigned int *) &closure->tramp[0];
1021#
if defined(POWERPC_DARWIN64)
1022 tramp[0] = 0x7c0802a6;
1023 tramp[1] = 0x429f0015;
1025 tramp[6] = 0x7d6802a6;
1026 tramp[7] = 0xe98b0000;
1027 tramp[8] = 0x7c0803a6;
1028 tramp[9] = 0x7d8903a6;
1029 tramp[10] = 0xe96b0008;
1030 tramp[11] = 0x4e800420;
1033 *((
unsigned long *)&tramp[4]) = (
unsigned long) codeloc;
1035 tramp[0] = 0x7c0802a6;
1036 tramp[1] = 0x429f000d;
1037 tramp[4] = 0x7d6802a6;
1038 tramp[5] = 0x818b0000;
1039 tramp[6] = 0x7c0803a6;
1040 tramp[7] = 0x7d8903a6;
1041 tramp[8] = 0x816b0004;
1042 tramp[9] = 0x4e800420;
1044 tramp[3] = (
unsigned long) codeloc;
1048 closure->user_data = user_data;
1057 tramp_aix = (
struct ffi_aix_trampoline_struct *) (closure->tramp);
1063 tramp_aix->toc = fd->
toc;
1064 tramp_aix->static_chain = codeloc;
1067 closure->user_data = user_data;
1078flush_icache(
char *addr)
1087 : :
"r"(addr) :
"memory");
1092flush_range(
char * addr1,
int size)
1094#define MIN_LINE_SIZE 32
1097 flush_icache(addr1+
i);
1098 flush_icache(addr1+
size-1);
1126 typedef double ldbits[2];
1135 ffi_type ** arg_types;
1140#if defined(POWERPC_DARWIN64)
1141 unsigned fpsused = 0;
1145 avalue =
alloca (cif->nargs *
sizeof(
void *));
1147 if (cif->rtype->type == FFI_TYPE_STRUCT)
1149#if defined(POWERPC_DARWIN64)
1150 if (!darwin64_struct_ret_by_value_p (cif->rtype))
1153 rvalue = (
void *) *pgr;
1156#elif defined(DARWIN_PPC)
1157 if (cif->rtype->size > 4)
1159 rvalue = (
void *) *pgr;
1163 rvalue = (
void *) *pgr;
1170 arg_types = cif->arg_types;
1175 switch (arg_types[
i]->
type)
1177 case FFI_TYPE_SINT8:
1178 case FFI_TYPE_UINT8:
1179#if defined(POWERPC64)
1180 avalue[
i] = (
char *) pgr + 7;
1182 avalue[
i] = (
char *) pgr + 3;
1187 case FFI_TYPE_SINT16:
1188 case FFI_TYPE_UINT16:
1189#if defined(POWERPC64)
1190 avalue[
i] = (
char *) pgr + 6;
1192 avalue[
i] = (
char *) pgr + 2;
1197 case FFI_TYPE_SINT32:
1198 case FFI_TYPE_UINT32:
1199#if defined(POWERPC64)
1200 avalue[
i] = (
char *) pgr + 4;
1202 case FFI_TYPE_POINTER:
1208 case FFI_TYPE_STRUCT:
1209 size_al = arg_types[
i]->size;
1210#if defined(POWERPC_DARWIN64)
1211 pgr = (
unsigned long *)
ALIGN((
char *)pgr, arg_types[
i]->alignment);
1212 if (size_al < 3 || size_al == 4)
1214 avalue[
i] = ((
char *)pgr)+8-size_al;
1215 if (arg_types[
i]->elements[0]->
type == FFI_TYPE_FLOAT
1218 *(
float *)pgr = (
float) *(
double *)pfr;
1227 darwin64_struct_floats_to_mem (arg_types[
i], (
char *)pgr,
1228 (
double *)pfr, &fpsused);
1231 pgr += (size_al + 7) / 8;
1235 if (arg_types[
i]->elements[0]->
type == FFI_TYPE_DOUBLE)
1237# if defined(POWERPC64)
1240 pgr += (size_al + 7) / 8;
1244 if (size_al < 3 && cif->abi == FFI_DARWIN)
1245 avalue[
i] = (
char*) pgr + 4 - size_al;
1248 pgr += (size_al + 3) / 4;
1253 case FFI_TYPE_SINT64:
1254 case FFI_TYPE_UINT64:
1255#if defined(POWERPC64)
1256 case FFI_TYPE_POINTER:
1267 case FFI_TYPE_FLOAT:
1272 double temp = pfr->
d;
1273 pfr->
f = (float) temp;
1284 case FFI_TYPE_DOUBLE:
1303#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1307 if (pfr + 1 < end_pfr)
1316 *pgr = *(
unsigned long *) pfr;
1325 if (pfr + 1 < end_pfr)
1333 else if (pfr + 1 == end_pfr)
1336 memcpy (&temp_ld.lb[0], pfr,
sizeof(ldbits));
1337 memcpy (&temp_ld.lb[1], pgr + 2,
sizeof(ldbits));
1338 avalue[
i] = &temp_ld.ld;
1355 (closure->fun) (cif, rvalue, avalue, closure->user_data);
#define FFI_TRAMPOLINE_SIZE
#define FFI_TYPE_LONGDOUBLE
void ffi_call_AIX(extended_cif *, long, unsigned, unsigned *, void(*fn)(void), void(*fn2)(void))
void ffi_closure_ASM(void)
void ffi_call_DARWIN(extended_cif *, long, unsigned, unsigned *, void(*fn)(void), void(*fn2)(void), ffi_type *)
ffi_status ffi_prep_closure_loc(ffi_closure *closure, ffi_cif *cif, void(*fun)(ffi_cif *, void *, void **, void *), void *user_data, void *codeloc)
void ffi_prep_args(extended_cif *ecif, unsigned long *const stack)
ffi_type * ffi_closure_helper_DARWIN(ffi_closure *, void *, unsigned long *, ffi_dblfl *)
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
struct aix_fd_struct aix_fd
void ffi_call(ffi_cif *cif, void(*fn)(void), void *rvalue, void **avalue)
VALUE type(ANYARGS)
ANYARGS-ed function type.