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;
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;
87 switch ((*p_arg)->type)
101 case FFI_TYPE_UINT16:
105 case FFI_TYPE_STRUCT:
106 memcpy (argp, *p_argv, z);
114 else if (z ==
sizeof (
UINT32) && align ==
sizeof (
UINT32))
116 switch ((*p_arg)->type)
119 case FFI_TYPE_SINT32:
124 case FFI_TYPE_POINTER:
125 case FFI_TYPE_UINT32:
126 case FFI_TYPE_STRUCT:
136 else if (z ==
sizeof (
UINT64)
137 && align ==
sizeof (
UINT64)
138 && ((
int) *p_argv & (
sizeof (
UINT64) - 1)) == 0)
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++)
171 type = (cif->arg_types)[i]->type;
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++);
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),
361 avalue =
alloca (cif->nargs * sizeof (
void *));
365 if (return_type (cif->rtype) == FFI_TYPE_STRUCT)
378 for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
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);
459 avalue[i] = pgr + greg;
464 (closure->fun) (cif, rvalue, avalue, closure->user_data);
467 return return_type (cif->rtype);
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)
void ffi_closure_SYSV(void)
void ffi_closure_helper_SYSV(ffi_closure *closure, unsigned long *p_gpr, unsigned long long *p_fpr, unsigned long *p_ov)
void __ic_invalidate(void *line)