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;
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++)
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++);
202 size = (cif->arg_types)[i]->size;
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:
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
268 else if ((rvalue ==
NULL) &&
269 (cif->rtype->type == FFI_TYPE_STRUCT))
288 && cif->rtype->type == 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;
323 tramp[2] = 0xcc000010 | (((UINT32) ffi_closure_SYSV) >> 16) << 10;
324 tramp[3] = 0xc8000010 | (((UINT32) ffi_closure_SYSV) & 0xffff) << 10;
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 *));
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);
void __ic_invalidate(void *line)
static int return_type(ffi_type *arg)
void ffi_closure_helper_SYSV(ffi_closure *, unsigned long *, unsigned long long *, unsigned long *)
void ffi_call_SYSV(unsigned(*)(struct call_context *context, unsigned char *, extended_cif *), struct call_context *context, extended_cif *, size_t, void(*fn)(void))
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_call(ffi_cif *cif, void(*fn)(void), void *rvalue, void **avalue)
void ffi_prep_args(char *stack, extended_cif *ecif)
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
void ffi_closure_SYSV(ffi_closure *)