37return_type (ffi_type *
arg)
40 if (
arg->type != FFI_TYPE_STRUCT)
44 if (
arg->size <= sizeof (UINT8))
45 return FFI_TYPE_UINT8;
46 else if (
arg->size <= sizeof (UINT16))
47 return FFI_TYPE_UINT16;
48 else if (
arg->size <= sizeof (UINT32))
49 return FFI_TYPE_UINT32;
50 else if (
arg->size <= sizeof (UINT64))
51 return FFI_TYPE_UINT64;
53 return FFI_TYPE_STRUCT;
61 register unsigned int i;
62 register unsigned int avn;
63 register void **p_argv;
65 register ffi_type **p_arg;
69 if (return_type (ecif->
cif->rtype) == FFI_TYPE_STRUCT)
71 *(
void **) argp = ecif->
rvalue;
72 argp += sizeof (UINT64);
75 avn = ecif->
cif->nargs;
78 for (
i = 0, p_arg = ecif->
cif->arg_types;
i < avn;
i++, p_arg++, p_argv++)
84 align = (*p_arg)->alignment;
85 if (z <
sizeof (UINT32))
87 switch ((*p_arg)->type)
90 *(SINT64 *) argp = (SINT64) *(SINT8 *)(*p_argv);
94 *(UINT64 *) argp = (UINT64) *(UINT8 *)(*p_argv);
98 *(SINT64 *) argp = (SINT64) *(SINT16 *)(*p_argv);
101 case FFI_TYPE_UINT16:
102 *(UINT64 *) argp = (UINT64) *(UINT16 *)(*p_argv);
105 case FFI_TYPE_STRUCT:
106 memcpy (argp, *p_argv, z);
112 argp +=
sizeof (UINT64);
114 else if (z ==
sizeof (UINT32) && align ==
sizeof (UINT32))
116 switch ((*p_arg)->type)
119 case FFI_TYPE_SINT32:
120 *(SINT64 *) argp = (SINT64) *(SINT32 *) (*p_argv);
124 case FFI_TYPE_POINTER:
125 case FFI_TYPE_UINT32:
126 case FFI_TYPE_STRUCT:
127 *(UINT64 *) argp = (UINT64) *(UINT32 *) (*p_argv);
134 argp +=
sizeof (UINT64);
136 else if (z ==
sizeof (UINT64)
137 && align ==
sizeof (UINT64)
138 && ((
int) *p_argv & (
sizeof (UINT64) - 1)) == 0)
140 *(UINT64 *) argp = *(UINT64 *) (*p_argv);
141 argp +=
sizeof (UINT64);
145 int n = (z +
sizeof (UINT64) - 1) /
sizeof (UINT64);
147 memcpy (argp, *p_argv, z);
148 argp +=
n *
sizeof (UINT64);
165 greg = (return_type (cif->rtype) == FFI_TYPE_STRUCT ? 1 : 0);
169 for (
i = j = 0;
i < cif->nargs;
i++)
176 cif->bytes +=
sizeof (UINT64) -
sizeof (
float);
186 cif->flags2 += ((cif->arg_types)[
i]->
type) << (2 * j++);
189 case FFI_TYPE_DOUBLE:
195 cif->flags2 += ((cif->arg_types)[
i]->
type) << (2 * j++);
198 cif->flags2 += FFI_TYPE_INT << (2 * j++);
203 if (
size <
sizeof (UINT64))
204 cif->bytes += sizeof (UINT64) -
size;
205 n = (
size +
sizeof (UINT64) - 1) /
sizeof (UINT64);
212 for (m = 0; m <
n; m++)
213 cif->flags2 += FFI_TYPE_INT << (2 * j++);
219 switch (cif->rtype->type)
221 case FFI_TYPE_STRUCT:
222 cif->flags = return_type (cif->rtype);
227 case FFI_TYPE_DOUBLE:
228 case FFI_TYPE_SINT64:
229 case FFI_TYPE_UINT64:
230 cif->flags = cif->rtype->type;
234 cif->flags = FFI_TYPE_INT;
245 unsigned,
unsigned,
long long,
265 if (cif->rtype->type == FFI_TYPE_STRUCT
266 && return_type (cif->rtype) != FFI_TYPE_STRUCT)
268 else if ((rvalue ==
NULL) &&
269 (cif->rtype->type == FFI_TYPE_STRUCT))
288 && cif->rtype->type == FFI_TYPE_STRUCT
289 && return_type (cif->rtype) != FFI_TYPE_STRUCT)
290 memcpy (rvalue, &trvalue, cif->rtype->size);
299 void (*fun)(ffi_cif*,
void*,
void**,
void*),
308 tramp = (
unsigned int *) &closure->tramp[0];
316#ifdef __LITTLE_ENDIAN__
317 tramp[0] = 0x7001c701;
318 tramp[1] = 0x0009402b;
320 tramp[0] = 0xc7017001;
321 tramp[1] = 0x402b0009;
325 tramp[4] = 0x6bf10600;
326 tramp[5] = 0xcc000010 | (((UINT32) codeloc) >> 16) << 10;
327 tramp[6] = 0xc8000010 | (((UINT32) codeloc) & 0xffff) << 10;
328 tramp[7] = 0x4401fff0;
332 closure->user_data = user_data;
335 asm volatile (
"ocbwb %0,0; synco; icbi %1,0; synci" : :
"r" (tramp),
351 UINT64 *pgr, UINT64 *pfr, UINT64 *pst)
361 avalue =
alloca (cif->nargs * sizeof (
void *));
365 if (return_type (cif->rtype) == FFI_TYPE_STRUCT)
367 rvalue = (UINT64 *) *pgr;
378 for (
i = 0, p_arg = cif->arg_types;
i < avn;
i++, p_arg++)
384 if (z <
sizeof (UINT32))
388 switch ((*p_arg)->type)
392 case FFI_TYPE_SINT16:
393 case FFI_TYPE_UINT16:
394 case FFI_TYPE_STRUCT:
395#ifdef __LITTLE_ENDIAN__
398 avalue[
i] = ((
char *) p) +
sizeof (UINT32) - z;
406 else if (z ==
sizeof (UINT32))
408 if ((*p_arg)->type == FFI_TYPE_FLOAT)
414 avalue[
i] = (UINT32 *) pfr + fpair;
419#ifdef __LITTLE_ENDIAN__
421 avalue[
i] = (UINT32 *) pfr + (1 ^ freg);
424 avalue[
i] = (UINT32 *) pfr + freg;
430#ifdef __LITTLE_ENDIAN__
431 avalue[
i] = pgr + greg;
433 avalue[
i] = (UINT32 *) (pgr + greg) + 1;
437#ifdef __LITTLE_ENDIAN__
438 avalue[
i] = pgr + greg;
440 avalue[
i] = (UINT32 *) (pgr + greg) + 1;
444 else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
447 avalue[
i] = pgr + greg;
450 avalue[
i] = pfr + (freg >> 1);
457 int n = (z +
sizeof (UINT64) - 1) /
sizeof (UINT64);
459 avalue[
i] = pgr + greg;
464 (closure->fun) (cif, rvalue, avalue, closure->user_data);
467 return return_type (cif->rtype);
void ffi_closure_SYSV(ffi_closure *)
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)
void ffi_call_SYSV(unsigned(*)(struct call_context *context, unsigned char *, extended_cif *), struct call_context *context, extended_cif *, size_t, void(*fn)(void))
void ffi_prep_args(char *stack, extended_cif *ecif)
VALUE type(ANYARGS)
ANYARGS-ed function type.
void ffi_closure_helper_SYSV(ffi_closure *, unsigned long *, unsigned long long *, unsigned long *)
void __ic_invalidate(void *line)