34 #include <asm/unistd.h> 39 unsigned int,
unsigned int,
unsigned int*,
unsigned int,
45 if(type->type != FFI_TYPE_STRUCT)
48 if(type->alignment < type->size &&
49 !(type->size == 4 || type->size == 8) &&
50 !(type->size == 8 && type->alignment >= 4))
53 if(type->size == 3 || type->size == 5 || type->size == 6 ||
72 char *reg_base = stack;
73 char *stack_base = stack + 20;
74 unsigned int stack_offset = 0;
75 unsigned int reg_mask = 0;
80 if(ecif->
cif->flags == FFI_TYPE_STRUCT)
82 *(
void**)reg_base = ecif->
rvalue;
86 for(i = 0, p_arg = ecif->
cif->arg_types; i < ecif->cif->nargs;
89 size_t z = (*p_arg)->size;
90 int alignment = (*p_arg)->alignment;
91 int type = (*p_arg)->type;
101 addr = stack_base + stack_offset;
104 else if(z ==
sizeof(
int))
108 while((reg_mask >> index) & 1)
111 addr = reg_base + (index * 4);
112 reg_mask |= (1 << index);
114 else if(z == 2 *
sizeof(
int))
116 if(!((reg_mask >> 1) & 1))
119 reg_mask |= (3 << 1);
121 else if(!((reg_mask >> 3) & 1))
123 addr = reg_base + 12;
124 reg_mask |= (3 << 3);
131 addr = stack_base + stack_offset;
135 if(type == FFI_TYPE_STRUCT && (*p_arg)->elements[1] ==
NULL)
136 type = (*p_arg)->elements[0]->type;
141 *(
unsigned int *)addr = (
unsigned int)*(UINT8 *)(*p_argv);
144 *(
signed int *)addr = (
signed int)*(SINT8 *)(*p_argv);
146 case FFI_TYPE_UINT16:
147 *(
unsigned int *)addr = (
unsigned int)*(UINT16 *)(*p_argv);
149 case FFI_TYPE_SINT16:
150 *(
signed int *)addr = (
signed int)*(SINT16 *)(*p_argv);
161 for(i = 0; i < 5; i++)
163 if((reg_mask & (1 << i)) == 0)
164 printf(
"r%d: (unused)\n", 12 - i);
166 printf(
"r%d: 0x%08x\n", 12 - i, ((
unsigned int*)reg_base)[i]);
169 for(i = 0; i < stack_offset / 4; i++)
171 printf(
"sp+%d: 0x%08x\n", i*4, ((
unsigned int*)stack_base)[i]);
182 cif->bytes = (cif->bytes + 7) & ~7;
185 cif->rstruct_flag = 0;
188 switch(cif->rtype->type)
192 cif->flags = (unsigned)FFI_TYPE_UINT8;
194 case FFI_TYPE_SINT16:
195 case FFI_TYPE_UINT16:
196 cif->flags = (unsigned)FFI_TYPE_UINT16;
199 case FFI_TYPE_SINT32:
200 case FFI_TYPE_UINT32:
201 case FFI_TYPE_POINTER:
202 cif->flags = (unsigned)FFI_TYPE_UINT32;
204 case FFI_TYPE_DOUBLE:
205 case FFI_TYPE_SINT64:
206 case FFI_TYPE_UINT64:
207 cif->flags = (unsigned)FFI_TYPE_UINT64;
209 case FFI_TYPE_STRUCT:
210 cif->rstruct_flag = 1;
213 if(cif->rtype->size <= 1)
214 cif->flags = (unsigned)FFI_TYPE_UINT8;
215 else if(cif->rtype->size <= 2)
216 cif->flags = (unsigned)FFI_TYPE_UINT16;
217 else if(cif->rtype->size <= 4)
218 cif->flags = (unsigned)FFI_TYPE_UINT32;
219 else if(cif->rtype->size <= 8)
220 cif->flags = (unsigned)FFI_TYPE_UINT64;
222 cif->flags = (unsigned)cif->rtype->type;
225 cif->flags = (unsigned)cif->rtype->type;
228 cif->flags = (
unsigned)cif->rtype->type;
235 void ffi_call(ffi_cif *cif,
void (*fn)(
void),
void *rvalue,
void **avalue)
239 unsigned int size = 0, i = 0;
245 for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
246 size += (*p_arg)->size + (4 - (*p_arg)->size % 4);
252 if((rvalue ==
NULL) && (cif->flags == FFI_TYPE_STRUCT))
261 ecif.
rvalue, cif->rstruct_flag, fn);
270 void **avalue, ffi_cif *cif)
272 register unsigned int i, reg_mask = 0;
273 register void **p_argv;
274 register ffi_type **p_arg;
275 register char *reg_base = stack;
276 register char *stack_base = stack + 20;
277 register unsigned int stack_offset = 0;
281 for(i = 0; i < cif->nargs + 7; i++)
283 printf(
"sp+%d: 0x%08x\n", i*4, ((
unsigned int*)stack)[i]);
288 if(cif->flags == FFI_TYPE_STRUCT)
290 *rvalue = *(
void **)reg_base;
296 for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
298 size_t z = (*p_arg)->size;
299 int alignment = (*p_arg)->alignment;
310 *p_argv = (
void*)stack_base + stack_offset;
313 else if(z <=
sizeof(
int))
317 while((reg_mask >> index) & 1)
320 *p_argv = (
void*)reg_base + (index * 4);
321 reg_mask |= (1 << index);
323 else if(z == 2 *
sizeof(
int))
325 if(!((reg_mask >> 1) & 1))
327 *p_argv = (
void*)reg_base + 4;
328 reg_mask |= (3 << 1);
330 else if(!((reg_mask >> 3) & 1))
332 *p_argv = (
void*)reg_base + 12;
333 reg_mask |= (3 << 3);
340 *p_argv = (
void*)stack_base + stack_offset;
344 if((*p_arg)->type != FFI_TYPE_STRUCT ||
345 (*p_arg)->elements[1] ==
NULL)
348 **(
unsigned int**)p_argv <<= 24;
349 else if(alignment == 2)
350 **(
unsigned int**)p_argv <<= 16;
358 for(i = 0; i < cif->nargs; i++)
360 printf(
"sp+%d: 0x%08x\n", i*4, *(((
unsigned int**)avalue)[i]));
372 unsigned int i,
size = 0;
377 for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
378 size += (*p_arg)->size + (4 - (*p_arg)->size % 4);
380 arg_area = (
void **)
alloca(size);
389 (closure->fun)(cif, *respp, arg_area, closure->user_data);
395 void (*fun)(ffi_cif*,
void*,
void**,
void*),
void *user_data,
401 unsigned char *__tramp = (
unsigned char*)(&closure->tramp[0]);
403 unsigned int __ctx = (
unsigned int)(codeloc);
404 unsigned int __rstruct_flag = (
unsigned int)(cif->rstruct_flag);
406 *(
unsigned int*) &__tramp[0] = 0xebcd1f00;
407 *(
unsigned int*) &__tramp[4] = 0xfefc0010;
408 *(
unsigned int*) &__tramp[8] = 0xfefb0010;
409 *(
unsigned int*) &__tramp[12] = 0xfefa0010;
410 *(
unsigned int*) &__tramp[16] = 0xfeff0010;
411 *(
unsigned int*) &__tramp[20] = __ctx;
412 *(
unsigned int*) &__tramp[24] = __rstruct_flag;
413 *(
unsigned int*) &__tramp[28] = __inner;
414 *(
unsigned int*) &__tramp[32] = __fun;
415 syscall(__NR_cacheflush, 0, (&__tramp[0]), 36);
418 closure->user_data = user_data;
void FFI_HIDDEN ffi_closure_SYSV_inner(ffi_closure *closure, struct call_context *context, void *stack)
void ffi_call_SYSV(unsigned(*)(struct call_context *context, unsigned char *, extended_cif *), struct call_context *context, extended_cif *, size_t, void(*fn)(void))
unsigned int pass_struct_on_stack(ffi_type *type)
ffi_status ffi_prep_closure_loc(ffi_closure *closure, ffi_cif *cif, void(*fun)(ffi_cif *, void *, void **, void *), void *user_data, void *codeloc)
static void ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, ffi_cif *cif)
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 *)