37 #define ROUND_UP(v, a) (((size_t)(v) + (a) - 1) & ~((a) - 1))
39 #define MIN_STACK_SIZE 64
40 #define FIRST_ARG_SLOT 9
43 #define fldw(addr, fpreg) \
44 __asm__ volatile ("fldw 0(%0), %%" #fpreg "L" : : "r"(addr) : #fpreg)
45 #define fstw(fpreg, addr) \
46 __asm__ volatile ("fstw %%" #fpreg "L, 0(%0)" : : "r"(addr))
47 #define fldd(addr, fpreg) \
48 __asm__ volatile ("fldd 0(%0), %%" #fpreg : : "r"(addr) : #fpreg)
49 #define fstd(fpreg, addr) \
50 __asm__ volatile ("fstd %%" #fpreg "L, 0(%0)" : : "r"(addr))
52 #define debug(lvl, x...) do { if (lvl <= DEBUG_LEVEL) { printf(x); } } while (0)
54 static inline int ffi_struct_type(ffi_type *t)
65 return FFI_TYPE_UINT8;
81 return FFI_TYPE_STRUCT;
144 register unsigned int i;
145 register ffi_type **p_arg;
146 register void **p_argv;
151 debug(1,
"%s: stack = %p, ecif = %p, bytes = %u\n", __FUNCTION__, stack,
154 p_arg = ecif->
cif->arg_types;
157 for (
i = 0;
i < ecif->
cif->nargs;
i++)
159 int type = (*p_arg)->type;
164 *(SINT32 *)(stack - slot) = *(SINT8 *)(*p_argv);
168 *(UINT32 *)(stack - slot) = *(UINT8 *)(*p_argv);
171 case FFI_TYPE_SINT16:
172 *(SINT32 *)(stack - slot) = *(SINT16 *)(*p_argv);
175 case FFI_TYPE_UINT16:
176 *(UINT32 *)(stack - slot) = *(UINT16 *)(*p_argv);
179 case FFI_TYPE_UINT32:
180 case FFI_TYPE_SINT32:
181 case FFI_TYPE_POINTER:
182 debug(3,
"Storing UINT32 %u in slot %u\n", *(UINT32 *)(*p_argv),
184 *(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv);
187 case FFI_TYPE_UINT64:
188 case FFI_TYPE_SINT64:
190 slot += (slot & 1) ? 1 : 2;
191 *(UINT64 *)(stack - slot) = *(UINT64 *)(*p_argv);
196 debug(3,
"Storing UINT32(float) in slot %u\n", slot);
197 *(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv);
201 case 0:
fldw(stack - slot, fr4);
break;
202 case 1:
fldw(stack - slot, fr5);
break;
203 case 2:
fldw(stack - slot, fr6);
break;
204 case 3:
fldw(stack - slot, fr7);
break;
208 case FFI_TYPE_DOUBLE:
210 slot += (slot & 1) ? 1 : 2;
211 debug(3,
"Storing UINT64(double) at slot %u\n", slot);
212 *(UINT64 *)(stack - slot) = *(UINT64 *)(*p_argv);
216 case 1:
fldd(stack - slot, fr5);
break;
217 case 3:
fldd(stack - slot, fr7);
break;
225 *(UINT32 *)(stack - slot) = (UINT32)(*p_argv);
229 case FFI_TYPE_STRUCT:
235 len = (*p_arg)->size;
238 dest_cpy = (
char *)(stack - slot) + 4 -
len;
243 slot += (slot & 1) ? 1 : 2;
244 dest_cpy = (
char *)(stack - slot) + 8 -
len;
248 *(UINT32 *)(stack - slot) = (UINT32)(*p_argv);
264 debug(5,
"Stack setup:\n");
265 for (
n = 0;
n < (bytes + 3) / 4;
n++)
267 if ((
n%4) == 0) {
debug(5,
"\n%08x: ", (
unsigned int)(stack -
n)); }
268 debug(5,
"%08x ", *(stack -
n));
278 static void ffi_size_stack_pa32(ffi_cif *cif)
284 for (
ptr = cif->arg_types,
i = 0; i < cif->nargs;
ptr++,
i++)
286 int type = (*ptr)->type;
290 case FFI_TYPE_DOUBLE:
291 case FFI_TYPE_UINT64:
292 case FFI_TYPE_SINT64:
299 case FFI_TYPE_STRUCT:
315 debug(3,
"Calculated stack size is %u bytes\n", cif->bytes);
322 switch (cif->rtype->type)
326 case FFI_TYPE_DOUBLE:
327 cif->flags = (
unsigned) cif->rtype->type;
333 cif->flags = FFI_TYPE_STRUCT;
337 case FFI_TYPE_STRUCT:
343 cif->flags = ffi_struct_type(cif->rtype);
346 case FFI_TYPE_UINT64:
347 case FFI_TYPE_SINT64:
348 cif->flags = FFI_TYPE_UINT64;
352 cif->flags = FFI_TYPE_INT;
361 ffi_size_stack_pa32(cif);
376 void ffi_call(ffi_cif *cif,
void (*fn)(
void),
void *rvalue,
void **avalue)
388 && (cif->rtype->type == FFI_TYPE_STRUCT
391 && cif->rtype->type == FFI_TYPE_STRUCT)
403 debug(3,
"Calling ffi_call_pa32: ecif=%p, bytes=%u, flags=%u, rvalue=%p, fn=%p\n", &ecif, cif->bytes, cif->flags, ecif.
rvalue, (
void *)fn);
405 cif->flags, ecif.
rvalue, fn);
419 ffi_status ffi_closure_inner_pa32(ffi_closure *closure, UINT32 *stack)
429 register UINT32 r28
asm(
"r28");
434 if (cif->flags == FFI_TYPE_STRUCT)
435 rvalue = (
void *)r28;
441 p_arg = cif->arg_types;
443 for (
i = 0;
i < avn;
i++)
445 int type = (*p_arg)->type;
451 case FFI_TYPE_SINT16:
452 case FFI_TYPE_UINT16:
453 case FFI_TYPE_SINT32:
454 case FFI_TYPE_UINT32:
455 case FFI_TYPE_POINTER:
456 avalue[
i] = (
char *)(stack - slot) +
sizeof(UINT32) - (*p_arg)->size;
459 case FFI_TYPE_SINT64:
460 case FFI_TYPE_UINT64:
461 slot += (slot & 1) ? 1 : 2;
462 avalue[
i] = (
void *)(stack - slot);
475 case 0:
fstw(fr4, (
void *)(stack - slot));
break;
476 case 1:
fstw(fr5, (
void *)(stack - slot));
break;
477 case 2:
fstw(fr6, (
void *)(stack - slot));
break;
478 case 3:
fstw(fr7, (
void *)(stack - slot));
break;
481 avalue[
i] = (
void *)(stack - slot);
484 case FFI_TYPE_DOUBLE:
485 slot += (slot & 1) ? 1 : 2;
490 case 1:
fstd(fr5, (
void *)(stack - slot));
break;
491 case 3:
fstd(fr7, (
void *)(stack - slot));
break;
494 avalue[
i] = (
void *)(stack - slot);
500 avalue[
i] = (
void *) *(stack - slot);
504 case FFI_TYPE_STRUCT:
508 if((*p_arg)->size <= 4)
510 avalue[
i] = (
void *)(stack - slot) +
sizeof(UINT32) -
513 else if ((*p_arg)->size <= 8)
515 slot += (slot & 1) ? 1 : 2;
516 avalue[
i] = (
void *)(stack - slot) +
sizeof(UINT64) -
520 avalue[
i] = (
void *) *(stack - slot);
532 (closure->fun) (cif, rvalue, avalue, closure->user_data);
534 debug(3,
"after calling function, ret[0] = %08x, ret[1] = %08x\n", ret[0],
546 case FFI_TYPE_UINT16:
549 case FFI_TYPE_SINT16:
553 case FFI_TYPE_SINT32:
554 case FFI_TYPE_UINT32:
557 case FFI_TYPE_SINT64:
558 case FFI_TYPE_UINT64:
563 case FFI_TYPE_DOUBLE:
571 case FFI_TYPE_STRUCT:
579 tmp += 4 - cif->rtype->size;
580 memcpy((
void*)tmp, &ret[0], cif->rtype->size);
588 unsigned int ret2[2];
597 default: off = 0;
break;
600 memset (ret2, 0,
sizeof (ret2));
601 memcpy ((
char *)ret2 + off, ret, 8 - off);
608 case FFI_TYPE_POINTER:
613 debug(0,
"assert with cif->flags: %d\n",cif->flags);
624 extern void ffi_closure_pa32(
void);
629 void (*fun)(ffi_cif*,
void*,
void**,
void*),
633 UINT32 *tramp = (UINT32 *)(closure->tramp);
638 if (cif->abi != FFI_PA32)
645 tramp[0] = 0xeaa00000;
646 tramp[1] = 0xd6a01c1e;
647 tramp[2] = 0x4aa10028;
648 tramp[3] = 0x36b53ff1;
649 tramp[4] = 0x0c201096;
650 tramp[5] = 0xeac0c000;
651 tramp[6] = 0x0c281093;
652 tramp[7] = ((UINT32)(ffi_closure_pa32) & ~2);
659 "fic 0(%%sr4, %0)\n\t"
660 "fic %1(%%sr4, %0)\n\t"
670 :
"r"((
unsigned long)tramp & ~31),
676 tramp[0] = 0xeaa00000;
677 tramp[1] = 0xd6a01c1e;
678 tramp[2] = 0x4aa10038;
679 tramp[3] = 0x36b53ff1;
680 tramp[4] = 0x0c201096;
681 tramp[5] = 0x02c010b4;
682 tramp[6] = 0x00141820;
683 tramp[7] = 0xe2c00000;
684 tramp[8] = 0x0c281093;
685 tramp[9] = ((UINT32)(ffi_closure_pa32) & ~2);
696 "fic,m %2(%%sr0,%0)\n\t"
697 "fic,m %2(%%sr0,%0)\n\t"
698 "fic,m %2(%%sr0,%0)\n\t"
707 :
"=&r" ((
unsigned long)tmp)
708 :
"r" ((
unsigned long)tramp & ~31),
714 closure->user_data = user_data;