65 endian_adjust (
void *addr,
size_t len)
68 return addr + (8 -
len);
79 #define stf_spill(addr, value) \
80 asm ("stf.spill %0 = %1%P0" : "=m" (*addr) : "f"(value));
85 #define ldf_fill(result, addr) \
86 asm ("ldf.fill %0 = %1%P1" : "=f"(result) : "m"(*addr));
92 hfa_type_size (
int type)
101 return sizeof(__float80);
111 hfa_type_load (
fpreg *fpaddr,
int type,
void *addr)
133 hfa_type_store (
int type,
void *addr,
fpreg *fpaddr)
141 *(
float *) addr = result;
148 *(
double *) addr = result;
155 *(__float80 *) addr = result;
168 hfa_element_type (ffi_type *
type,
int nested)
170 int element = FFI_TYPE_VOID;
181 case FFI_TYPE_DOUBLE:
191 if (LDBL_MANT_DIG == 64 && nested)
195 case FFI_TYPE_STRUCT:
197 ffi_type **
ptr = &
type->elements[0];
201 int sub_element = hfa_element_type (*
ptr, 1);
202 if (sub_element == FFI_TYPE_VOID)
203 return FFI_TYPE_VOID;
205 if (element == FFI_TYPE_VOID)
206 element = sub_element;
207 else if (element != sub_element)
208 return FFI_TYPE_VOID;
214 return FFI_TYPE_VOID;
233 if (cif->bytes <
sizeof(
struct ia64_args))
237 flags = cif->rtype->type;
238 switch (cif->rtype->type)
243 if (LDBL_MANT_DIG != 64)
247 case FFI_TYPE_STRUCT:
249 size_t size = cif->rtype->size;
250 int hfa_type = hfa_element_type (cif->rtype, 0);
252 if (hfa_type != FFI_TYPE_VOID)
254 size_t nelts =
size / hfa_type_size (hfa_type);
256 flags = hfa_type | (
size << 8);
277 ffi_call(ffi_cif *cif,
void (*fn)(
void),
void *rvalue,
void **avalue)
280 long i, avn, gpcount, fpcount;
286 if (rvalue ==
NULL && cif->rtype->type != FFI_TYPE_VOID)
287 rvalue =
alloca (cif->rtype->size);
290 stack =
alloca (cif->bytes);
292 gpcount = fpcount = 0;
294 for (
i = 0, p_arg = cif->arg_types;
i < avn;
i++, p_arg++)
296 switch ((*p_arg)->type)
299 stack->
gp_regs[gpcount++] = *(SINT8 *)avalue[
i];
302 stack->
gp_regs[gpcount++] = *(UINT8 *)avalue[
i];
304 case FFI_TYPE_SINT16:
305 stack->
gp_regs[gpcount++] = *(SINT16 *)avalue[
i];
307 case FFI_TYPE_UINT16:
308 stack->
gp_regs[gpcount++] = *(UINT16 *)avalue[
i];
310 case FFI_TYPE_SINT32:
311 stack->
gp_regs[gpcount++] = *(SINT32 *)avalue[
i];
313 case FFI_TYPE_UINT32:
314 stack->
gp_regs[gpcount++] = *(UINT32 *)avalue[
i];
316 case FFI_TYPE_SINT64:
317 case FFI_TYPE_UINT64:
318 stack->
gp_regs[gpcount++] = *(UINT64 *)avalue[
i];
321 case FFI_TYPE_POINTER:
322 stack->
gp_regs[gpcount++] = (UINT64)(PTR64) *(
void **)avalue[
i];
326 if (gpcount < 8 && fpcount < 8)
330 memcpy (&tmp, avalue[
i],
sizeof (UINT32));
331 stack->
gp_regs[gpcount++] = tmp;
335 case FFI_TYPE_DOUBLE:
336 if (gpcount < 8 && fpcount < 8)
344 if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8)
350 case FFI_TYPE_STRUCT:
352 size_t size = (*p_arg)->size;
353 size_t align = (*p_arg)->alignment;
354 int hfa_type = hfa_element_type (*p_arg, 0);
357 if (align == 16 && (gpcount & 1))
360 if (hfa_type != FFI_TYPE_VOID)
362 size_t hfa_size = hfa_type_size (hfa_type);
364 size_t gp_offset = gpcount * 8;
368 && gp_offset < 8 * 8)
370 hfa_type_load (&stack->
fp_regs[fpcount], hfa_type,
373 gp_offset += hfa_size;
379 gpcount += (
size + 7) / 8;
411 void (*fun)(ffi_cif*,
void*,
void**,
void*),
423 struct ffi_ia64_trampoline_struct
430 struct ffi_ia64_trampoline_struct *tramp;
436 tramp = (
struct ffi_ia64_trampoline_struct *)closure->tramp;
439 tramp->code_pointer = fd->code_pointer;
440 tramp->real_gp = fd->gp;
441 tramp->fake_gp = (UINT64)(PTR64)codeloc;
443 closure->user_data = user_data;
452 void *rvalue,
void *r8)
457 long i, avn, gpcount, fpcount;
461 avalue =
alloca (avn *
sizeof (
void *));
465 if (cif->flags == FFI_TYPE_STRUCT)
468 gpcount = fpcount = 0;
469 for (
i = 0, p_arg = cif->arg_types;
i < avn;
i++, p_arg++)
471 switch ((*p_arg)->type)
475 avalue[
i] = endian_adjust(&stack->
gp_regs[gpcount++], 1);
477 case FFI_TYPE_SINT16:
478 case FFI_TYPE_UINT16:
479 avalue[
i] = endian_adjust(&stack->
gp_regs[gpcount++], 2);
481 case FFI_TYPE_SINT32:
482 case FFI_TYPE_UINT32:
483 avalue[
i] = endian_adjust(&stack->
gp_regs[gpcount++], 4);
485 case FFI_TYPE_SINT64:
486 case FFI_TYPE_UINT64:
487 avalue[
i] = &stack->
gp_regs[gpcount++];
489 case FFI_TYPE_POINTER:
490 avalue[
i] = endian_adjust(&stack->
gp_regs[gpcount++],
sizeof(
void*));
494 if (gpcount < 8 && fpcount < 8)
500 *(
float *)addr = result;
503 avalue[
i] = endian_adjust(&stack->
gp_regs[gpcount], 4);
507 case FFI_TYPE_DOUBLE:
508 if (gpcount < 8 && fpcount < 8)
514 *(
double *)addr = result;
517 avalue[
i] = &stack->
gp_regs[gpcount];
524 if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8)
530 *(__float80 *)addr = result;
533 avalue[
i] = &stack->
gp_regs[gpcount];
537 case FFI_TYPE_STRUCT:
539 size_t size = (*p_arg)->size;
540 size_t align = (*p_arg)->alignment;
541 int hfa_type = hfa_element_type (*p_arg, 0);
544 if (align == 16 && (gpcount & 1))
547 if (hfa_type != FFI_TYPE_VOID)
549 size_t hfa_size = hfa_type_size (hfa_type);
551 size_t gp_offset = gpcount * 8;
558 && gp_offset < 8 * 8)
560 hfa_type_store (hfa_type, addr + offset,
563 gp_offset += hfa_size;
572 avalue[
i] = &stack->
gp_regs[gpcount];
574 gpcount += (
size + 7) / 8;
583 closure->fun (cif, rvalue, avalue, closure->user_data);