33 #include <arch/icache.h> 34 #include <arch/opcode.h> 38 #define NUM_ARG_REGS 10 44 size_t stack_args_bytes,
62 if (cif->rtype->size > NUM_ARG_REGS * FFI_SIZEOF_ARG)
63 cif->flags = FFI_TYPE_STRUCT;
65 cif->flags = FFI_TYPE_INT;
97 case FFI_TYPE_POINTER:
101 *out = *(SINT32 *)in;
109 union {
float f; SINT32 s32; }
val;
110 val.f = *(
float *)in;
116 *(
float *)out = *(
float *)in;
120 case FFI_TYPE_SINT64:
121 case FFI_TYPE_UINT64:
122 case FFI_TYPE_DOUBLE:
124 case FFI_TYPE_POINTER:
126 *(UINT64 *)out = *(UINT64 *)in;
129 case FFI_TYPE_STRUCT:
130 memcpy(out, in, type->size);
145 ffi_call(ffi_cif *cif,
void (*fn)(
void),
void *rvalue,
void **avalue)
148 ffi_sarg *
const reg_args = arg_mem;
151 ffi_type **
const arg_types = cif->arg_types;
152 const long num_args = cif->nargs;
155 if (cif->flags == FFI_TYPE_STRUCT)
166 for (i = 0; i < num_args; i++)
168 ffi_type *type = arg_types[i];
169 void *
const arg_in = avalue[i];
170 ptrdiff_t arg_word = argp - arg_mem;
180 if (type->type == FFI_TYPE_STRUCT)
182 const size_t arg_size_in_words =
185 if (arg_word < NUM_ARG_REGS &&
186 arg_word + arg_size_in_words > NUM_ARG_REGS)
192 memcpy(argp, arg_in, type->size);
193 argp += arg_size_in_words;
211 extern const UINT64 ffi_template_tramp_tile[]
FFI_HIDDEN;
217 void (*fun)(ffi_cif*,
void*,
void**,
void*),
231 out = (UINT64 *)closure->tramp;
240 while ((c >> s) != (SINT16)(c >> s) || (h >> s) != (SINT16)(h >> s))
243 #define OPS(a, b, shift) \ 244 (create_Imm16_X0((a) >> (shift)) | create_Imm16_X1((b) >> (shift))) 247 *out++ = ffi_template_tramp_tile[0] | OPS(c, h, s);
248 for (s -= 16; s >= 0; s -= 16)
249 *out++ = ffi_template_tramp_tile[1] | OPS(c, h, s);
253 *out++ = ffi_template_tramp_tile[2];
263 out = (UINT64 *)closure->tramp;
266 *out++ = ffi_template_tramp_tile[0] | create_JOffLong_X1(delta >> 3);
271 closure->user_data = user_data;
273 invalidate_icache(closure->tramp, (
char *)out - closure->tramp,
289 ffi_cif *
const cif = closure->cif;
290 void **
const avalue =
alloca(cif->nargs *
sizeof(
void *));
292 ffi_type **
const arg_types = cif->arg_types;
293 ffi_sarg *
const reg_args_in = reg_args[0];
294 ffi_sarg *
const reg_args_out = reg_args[1];
296 long i, arg_word, nargs = cif->nargs;
305 if (cif->flags == FFI_TYPE_STRUCT)
314 rvalue = &closure_ret;
319 for (i = 0; i < nargs; i++)
321 ffi_type *
const type = arg_types[i];
322 const size_t arg_size_in_words =
333 if (arg_word == NUM_ARG_REGS ||
334 (arg_word < NUM_ARG_REGS &&
335 arg_word + arg_size_in_words > NUM_ARG_REGS))
343 argp += arg_size_in_words;
344 arg_word += arg_size_in_words;
348 closure->fun(cif, rvalue, avalue, closure->user_data);
350 if (cif->flags != FFI_TYPE_STRUCT)
void FFI_HIDDEN ffi_closure_tile_inner(ffi_closure *closure, ffi_sarg reg_args[2][NUM_ARG_REGS], ffi_sarg *stack_args)
void ffi_call_tile(ffi_sarg reg_args[NUM_ARG_REGS], const ffi_sarg *stack_args, size_t stack_args_bytes, void(*fnaddr)(void)) FFI_HIDDEN
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)
const UINT64 ffi_template_tramp_tile [] FFI_HIDDEN
static long assign_to_ffi_arg(ffi_sarg *out, void *in, const ffi_type *type, int write_to_reg)
void ffi_closure_tile(void)
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)