33 #include <arch/icache.h>
34 #include <arch/opcode.h>
38 #define NUM_ARG_REGS 10
44 size_t stack_args_bytes,
63 cif->flags = FFI_TYPE_STRUCT;
65 cif->flags = FFI_TYPE_INT;
73 assign_to_ffi_arg(
ffi_sarg *out,
void *in,
const ffi_type *
type,
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:
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];
180 if (
type->type == FFI_TYPE_STRUCT)
182 const size_t arg_size_in_words =
193 argp += arg_size_in_words;
197 argp += assign_to_ffi_arg(argp, arg_in, arg_types[
i], 1);
206 assign_to_ffi_arg(rvalue, reg_args, cif->rtype, 0);
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 =
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)
353 assign_to_ffi_arg(reg_args_out, &closure_ret, cif->rtype, 1);