45 argp = stack + 16*
sizeof(int);
51 *(
int *) argp = (
long)ecif->
rvalue;
70 for (i = ecif->
cif->nargs, p_arg = ecif->
cif->arg_types; i; i--, p_arg++)
74 if ((*p_arg)->type == FFI_TYPE_STRUCT
80 *(
unsigned int *) argp = (
unsigned long)(* p_argv);
89 switch ((*p_arg)->type)
92 *(
signed int *) argp = *(SINT8 *)(* p_argv);
96 *(
unsigned int *) argp = *(UINT8 *)(* p_argv);
100 *(
signed int *) argp = *(SINT16 *)(* p_argv);
103 case FFI_TYPE_UINT16:
104 *(
unsigned int *) argp = *(UINT16 *)(* p_argv);
134 argp = stack + 16*
sizeof(
long long);
140 ((
long long*)argp)[0] = 0;
141 ((
long long*)argp)[1] = 0;
142 ((
long long*)argp)[2] = 0;
143 ((
long long*)argp)[3] = 0;
144 ((
long long*)argp)[4] = 0;
145 ((
long long*)argp)[5] = 0;
150 if (ecif->
cif->rtype->type == FFI_TYPE_STRUCT &&
151 ecif->
cif->rtype->size > 32)
153 *(
unsigned long long *) argp = (
unsigned long)ecif->
rvalue;
154 argp +=
sizeof(
long long);
158 for (i = 0, p_arg = ecif->
cif->arg_types; i < ecif->cif->nargs;
164 switch ((*p_arg)->type)
166 case FFI_TYPE_STRUCT:
170 *(
unsigned long long *) argp = (
unsigned long)* p_argv;
171 argp +=
sizeof(
long long);
178 case FFI_TYPE_DOUBLE:
179 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE 185 if (z <
sizeof(
long long))
187 switch ((*p_arg)->type)
190 *(
signed long long *) argp = *(SINT8 *)(* p_argv);
194 *(
unsigned long long *) argp = *(UINT8 *)(* p_argv);
197 case FFI_TYPE_SINT16:
198 *(
signed long long *) argp = *(SINT16 *)(* p_argv);
201 case FFI_TYPE_UINT16:
202 *(
unsigned long long *) argp = *(UINT16 *)(* p_argv);
205 case FFI_TYPE_SINT32:
206 *(
signed long long *) argp = *(SINT32 *)(* p_argv);
209 case FFI_TYPE_UINT32:
210 *(
unsigned long long *) argp = *(UINT32 *)(* p_argv);
214 *(
float *) (argp + 4) = *(
FLOAT32 *)(* p_argv);
217 case FFI_TYPE_STRUCT:
224 z =
sizeof(
long long);
227 else if (z ==
sizeof(
long long))
230 z =
sizeof(
long long);
235 if ((tmp & 1) && (*p_arg)->alignment > 8)
238 argp +=
sizeof(
long long);
241 z = 2 *
sizeof(
long long);
263 if (cif->rtype->type != FFI_TYPE_STRUCT)
264 cif->bytes += wordsize;
269 if (cif->bytes < 4*6+4)
279 if (cif->bytes < 8*6)
286 cif->bytes += 16 * wordsize;
291 cif->bytes =
ALIGN(cif->bytes, 2 * wordsize);
294 switch (cif->rtype->type)
298 case FFI_TYPE_DOUBLE:
299 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE 302 cif->flags = cif->rtype->type;
305 case FFI_TYPE_STRUCT:
306 if (cif->abi ==
FFI_V9 && cif->rtype->size > 32)
307 cif->flags = FFI_TYPE_VOID;
309 cif->flags = FFI_TYPE_STRUCT;
314 case FFI_TYPE_SINT16:
315 case FFI_TYPE_UINT16:
317 cif->flags = FFI_TYPE_INT;
319 cif->flags = cif->rtype->type;
322 case FFI_TYPE_SINT64:
323 case FFI_TYPE_UINT64:
325 cif->flags = FFI_TYPE_INT;
327 cif->flags = FFI_TYPE_SINT64;
331 cif->flags = FFI_TYPE_INT;
339 ffi_type **ptr = &arg->elements[0];
343 if (off & ((*ptr)->alignment - 1))
344 off =
ALIGN(off, (*ptr)->alignment);
346 switch ((*ptr)->type)
348 case FFI_TYPE_STRUCT:
353 case FFI_TYPE_DOUBLE:
354 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE 357 memmove(ret + off, flt + off, (*ptr)->size);
361 memmove(ret + off, intg + off, (*ptr)->size);
372 extern int ffi_call_v9(
void *,
extended_cif *,
unsigned,
373 unsigned,
unsigned *,
void (*fn)(
void));
376 unsigned,
unsigned *,
void (*fn)(
void));
383 void ffi_call(ffi_cif *cif,
void (*fn)(
void),
void *rvalue,
void **avalue)
395 if (cif->rtype->type == FFI_TYPE_STRUCT)
397 if (cif->rtype->size <= 32)
414 if (rvalue && (cif->rtype->type == FFI_TYPE_STRUCT
423 unsigned int *call_struct =
NULL;
424 ffi_closure_alloc(32, (
void **)&call_struct);
427 unsigned long f = (
unsigned long)fn;
428 call_struct[0] = 0xae10001f;
429 call_struct[1] = 0xbe10000f;
430 call_struct[2] = 0x03000000 | f >> 10;
431 call_struct[3] = 0x9fc06000 | (f & 0x3ff);
432 call_struct[4] = 0x01000000;
433 if (cif->rtype->size < 0x7f)
434 call_struct[5] = cif->rtype->size;
436 call_struct[5] = 0x01000000;
437 call_struct[6] = 0x81c7e008;
438 call_struct[7] = 0xbe100017;
440 asm volatile (
"iflush %0; iflush %0+8; iflush %0+16; iflush %0+24" : :
441 "r" (call_struct) :
"memory");
443 asm volatile (
"nop; nop; nop; nop; nop");
448 cif->flags, rvalue, call_struct);
449 ffi_closure_free(call_struct);
454 cif->flags, rvalue, fn);
460 cif->flags, rvalue, fn);
467 cif->flags, rval, fn);
468 if (rvalue && rval && cif->rtype->type == FFI_TYPE_STRUCT)
483 extern void ffi_closure_v9(
void);
491 void (*fun)(ffi_cif*,
void*,
void**,
void*),
495 unsigned int *tramp = (
unsigned int *) &closure->tramp[0];
502 fn = (
unsigned long) ffi_closure_v9;
503 tramp[0] = 0x83414000;
504 tramp[1] = 0xca586010;
505 tramp[2] = 0x81c14000;
506 tramp[3] = 0x01000000;
507 *((
unsigned long *) &tramp[4]) = fn;
509 unsigned long ctx = (
unsigned long) codeloc;
512 fn = (
unsigned long) ffi_closure_v8;
513 tramp[0] = 0x03000000 | fn >> 10;
514 tramp[1] = 0x05000000 | ctx >> 10;
515 tramp[2] = 0x81c06000 | (fn & 0x3ff);
516 tramp[3] = 0x8410a000 | (ctx & 0x3ff);
521 closure->user_data = user_data;
526 asm volatile (
"flush %0; flush %0+8" : :
"r" (closure) :
"memory");
528 asm volatile (
"iflush %0; iflush %0+8" : :
"r" (closure) :
"memory");
530 asm volatile (
"nop; nop; nop; nop; nop");
541 void *rvalue,
unsigned long *gpr,
unsigned long *scratch)
544 ffi_type **arg_types;
549 arg_types = cif->arg_types;
550 avalue =
alloca(cif->nargs *
sizeof(
void *));
554 if (cif->flags == FFI_TYPE_STRUCT
559 rvalue = (
void *) gpr[0];
565 for (i = 0; i < cif->nargs; i++)
567 if (arg_types[i]->type == FFI_TYPE_STRUCT
574 avalue[i] = (
void *)gpr[argn++];
576 else if ((arg_types[i]->type == FFI_TYPE_DOUBLE
577 || arg_types[i]->type == FFI_TYPE_SINT64
578 || arg_types[i]->type == FFI_TYPE_UINT64)
583 scratch[0] = gpr[argn];
584 scratch[1] = gpr[argn+1];
593 avalue[i] = ((
char *) &gpr[argn]) - arg_types[i]->size;
598 (closure->fun) (cif, rvalue, avalue, closure->user_data);
601 return cif->rtype->type;
606 void *rvalue,
unsigned long *gpr,
double *fpr)
609 ffi_type **arg_types;
611 int i, argn, fp_slot_max;
614 arg_types = cif->arg_types;
615 avalue =
alloca(cif->nargs *
sizeof(
void *));
619 if (cif->flags == FFI_TYPE_VOID
620 && cif->rtype->type == FFI_TYPE_STRUCT)
622 rvalue = (
void *) gpr[0];
629 fp_slot_max = 16 - argn;
632 for (i = 0; i < cif->nargs; i++)
634 if (arg_types[i]->type == FFI_TYPE_STRUCT)
636 if (arg_types[i]->
size > 16)
639 avalue[i] = (
void *)gpr[argn++];
648 (
char *) &fpr[argn]);
649 avalue[i] = &gpr[argn];
659 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE 664 && (arg_types[i]->type == FFI_TYPE_FLOAT
665 || arg_types[i]->type == FFI_TYPE_DOUBLE
670 avalue[i] = ((
char *) &fpr[argn]) - arg_types[i]->size;
672 avalue[i] = ((
char *) &gpr[argn]) - arg_types[i]->size;
677 (closure->fun) (cif, rvalue, avalue, closure->user_data);
680 return cif->rtype->type;
int ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt)
if(len<=MAX_WORD_LENGTH &&len >=MIN_WORD_LENGTH)
int ffi_closure_sparc_inner_v9(ffi_closure *closure, void *rvalue, unsigned long *gpr, double *fpr)
RUBY_EXTERN void * memmove(void *, const void *, size_t)
int ffi_prep_args_v9(char *stack, extended_cif *ecif)
void ffi_flush_icache(void *, size_t)
void ffi_closure_v8(void)
int ffi_closure_sparc_inner_v8(ffi_closure *closure, void *rvalue, unsigned long *gpr, unsigned long *scratch)
#define FFI_TYPE_LONGDOUBLE
ffi_status ffi_prep_closure_loc(ffi_closure *closure, ffi_cif *cif, void(*fun)(ffi_cif *, void *, void **, void *), void *user_data, void *codeloc)
int ffi_call_v8(void *, extended_cif *, unsigned, unsigned, unsigned *, void(*fn)(void))
void ffi_call(ffi_cif *cif, void(*fn)(void), void *rvalue, void **avalue)
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
void ffi_prep_args_v8(char *stack, extended_cif *ecif)