1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 1998 Geoffrey Keating
3 Copyright (C) 2007, 2008 Free Software Foundation, Inc
4 Copyright (C) 2008 Red Hat, Inc
6 PowerPC Foreign Function Interface
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 ``Software''), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
16 The above copyright notice and this permission notice shall be included
17 in all copies or substantial portions of the Software.
19 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 OTHER DEALINGS IN THE SOFTWARE.
26 ----------------------------------------------------------------------- */
29 #include <ffi_common.h>
35 extern void ffi_closure_SYSV (void);
36 extern void FFI_HIDDEN
ffi_closure_LINUX64 (void);
39 /* The assembly depends on these exact flags. */
40 FLAG_RETURNS_SMST
= 1 << (31-31), /* Used for FFI_SYSV small structs. */
41 FLAG_RETURNS_NOTHING
= 1 << (31-30), /* These go in cr7 */
42 FLAG_RETURNS_FP
= 1 << (31-29),
43 FLAG_RETURNS_64BITS
= 1 << (31-28),
45 FLAG_RETURNS_128BITS
= 1 << (31-27), /* cr6 */
46 FLAG_SYSV_SMST_R4
= 1 << (31-26), /* use r4 for FFI_SYSV 8 byte
48 FLAG_SYSV_SMST_R3
= 1 << (31-25), /* use r3 for FFI_SYSV 4 byte
50 /* Bits (31-24) through (31-19) store shift value for SMST */
52 FLAG_ARG_NEEDS_COPY
= 1 << (31- 7),
53 FLAG_FP_ARGUMENTS
= 1 << (31- 6), /* cr1.eq; specified by ABI */
54 FLAG_4_GPR_ARGUMENTS
= 1 << (31- 5),
55 FLAG_RETVAL_REFERENCE
= 1 << (31- 4)
58 /* About the SYSV ABI. */
59 unsigned int NUM_GPR_ARG_REGISTERS
= 8;
61 unsigned int NUM_FPR_ARG_REGISTERS
= 8;
63 unsigned int NUM_FPR_ARG_REGISTERS
= 0;
66 enum { ASM_NEEDS_REGISTERS
= 4 };
68 /* ffi_prep_args_SYSV is called by the assembly routine once stack space
69 has been allocated for the function's arguments.
71 The stack layout we want looks like this:
73 | Return address from ffi_call_SYSV 4bytes | higher addresses
74 |--------------------------------------------|
75 | Previous backchain pointer 4 | stack pointer here
76 |--------------------------------------------|<+ <<< on entry to
77 | Saved r28-r31 4*4 | | ffi_call_SYSV
78 |--------------------------------------------| |
79 | GPR registers r3-r10 8*4 | | ffi_call_SYSV
80 |--------------------------------------------| |
81 | FPR registers f1-f8 (optional) 8*8 | |
82 |--------------------------------------------| | stack |
83 | Space for copied structures | | grows |
84 |--------------------------------------------| | down V
85 | Parameters that didn't fit in registers | |
86 |--------------------------------------------| | lower addresses
87 | Space for callee's LR 4 | |
88 |--------------------------------------------| | stack pointer here
89 | Current backchain pointer 4 |-/ during
90 |--------------------------------------------| <<< ffi_call_SYSV
95 ffi_prep_args_SYSV (extended_cif
*ecif
, unsigned *const stack
)
97 const unsigned bytes
= ecif
->cif
->bytes
;
98 const unsigned flags
= ecif
->cif
->flags
;
108 /* 'stacktop' points at the previous backchain pointer. */
111 /* 'gpr_base' points at the space for gpr3, and grows upwards as
112 we use GPR registers. */
116 /* 'fpr_base' points at the space for fpr1, and grows upwards as
117 we use FPR registers. */
121 /* 'copy_space' grows down as we put structures in it. It should
122 stay 16-byte aligned. */
125 /* 'next_arg' grows up as we put parameters in it. */
128 int i
, ii MAYBE_UNUSED
;
143 size_t struct_copy_size
;
146 if (ecif
->cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
147 NUM_FPR_ARG_REGISTERS
= 0;
149 stacktop
.c
= (char *) stack
+ bytes
;
150 gpr_base
.u
= stacktop
.u
- ASM_NEEDS_REGISTERS
- NUM_GPR_ARG_REGISTERS
;
152 fpr_base
.d
= gpr_base
.d
- NUM_FPR_ARG_REGISTERS
;
154 copy_space
.c
= ((flags
& FLAG_FP_ARGUMENTS
) ? fpr_base
.c
: gpr_base
.c
);
155 next_arg
.u
= stack
+ 2;
157 /* Check that everything starts aligned properly. */
158 FFI_ASSERT (((unsigned) (char *) stack
& 0xF) == 0);
159 FFI_ASSERT (((unsigned) copy_space
.c
& 0xF) == 0);
160 FFI_ASSERT (((unsigned) stacktop
.c
& 0xF) == 0);
161 FFI_ASSERT ((bytes
& 0xF) == 0);
162 FFI_ASSERT (copy_space
.c
>= next_arg
.c
);
164 /* Deal with return values that are actually pass-by-reference. */
165 if (flags
& FLAG_RETVAL_REFERENCE
)
167 *gpr_base
.u
++ = (unsigned long) (char *) ecif
->rvalue
;
171 /* Now for the arguments. */
172 p_argv
.v
= ecif
->avalue
;
173 for (ptr
= ecif
->cif
->arg_types
, i
= ecif
->cif
->nargs
;
175 i
--, ptr
++, p_argv
.v
++)
177 switch ((*ptr
)->type
)
180 /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32. */
181 if (ecif
->cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
182 goto soft_float_prep
;
183 double_tmp
= **p_argv
.f
;
184 if (fparg_count
>= NUM_FPR_ARG_REGISTERS
)
186 *next_arg
.f
= (float) double_tmp
;
191 *fpr_base
.d
++ = double_tmp
;
193 FFI_ASSERT (flags
& FLAG_FP_ARGUMENTS
);
196 case FFI_TYPE_DOUBLE
:
197 /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64. */
198 if (ecif
->cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
199 goto soft_double_prep
;
200 double_tmp
= **p_argv
.d
;
202 if (fparg_count
>= NUM_FPR_ARG_REGISTERS
)
204 if (intarg_count
>= NUM_GPR_ARG_REGISTERS
205 && intarg_count
% 2 != 0)
210 *next_arg
.d
= double_tmp
;
214 *fpr_base
.d
++ = double_tmp
;
216 FFI_ASSERT (flags
& FLAG_FP_ARGUMENTS
);
219 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
220 case FFI_TYPE_LONGDOUBLE
:
221 if ((ecif
->cif
->abi
!= FFI_LINUX
)
222 && (ecif
->cif
->abi
!= FFI_LINUX_SOFT_FLOAT
))
224 /* The soft float ABI for long doubles works like this,
225 a long double is passed in four consecutive gprs if available.
226 A maximum of 2 long doubles can be passed in gprs.
227 If we do not have 4 gprs left, the long double is passed on the
228 stack, 4-byte aligned. */
229 if (ecif
->cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
231 unsigned int int_tmp
= (*p_argv
.ui
)[0];
232 if (intarg_count
>= NUM_GPR_ARG_REGISTERS
- 3)
234 if (intarg_count
< NUM_GPR_ARG_REGISTERS
)
235 intarg_count
+= NUM_GPR_ARG_REGISTERS
- intarg_count
;
236 *next_arg
.u
= int_tmp
;
238 for (ii
= 1; ii
< 4; ii
++)
240 int_tmp
= (*p_argv
.ui
)[ii
];
241 *next_arg
.u
= int_tmp
;
247 *gpr_base
.u
++ = int_tmp
;
248 for (ii
= 1; ii
< 4; ii
++)
250 int_tmp
= (*p_argv
.ui
)[ii
];
251 *gpr_base
.u
++ = int_tmp
;
258 double_tmp
= (*p_argv
.d
)[0];
260 if (fparg_count
>= NUM_FPR_ARG_REGISTERS
- 1)
262 if (intarg_count
>= NUM_GPR_ARG_REGISTERS
263 && intarg_count
% 2 != 0)
268 *next_arg
.d
= double_tmp
;
270 double_tmp
= (*p_argv
.d
)[1];
271 *next_arg
.d
= double_tmp
;
276 *fpr_base
.d
++ = double_tmp
;
277 double_tmp
= (*p_argv
.d
)[1];
278 *fpr_base
.d
++ = double_tmp
;
282 FFI_ASSERT (flags
& FLAG_FP_ARGUMENTS
);
287 case FFI_TYPE_UINT64
:
288 case FFI_TYPE_SINT64
:
290 if (intarg_count
== NUM_GPR_ARG_REGISTERS
-1)
292 if (intarg_count
>= NUM_GPR_ARG_REGISTERS
)
294 if (intarg_count
% 2 != 0)
299 *next_arg
.ll
= **p_argv
.ll
;
304 /* whoops: abi states only certain register pairs
305 * can be used for passing long long int
306 * specifically (r3,r4), (r5,r6), (r7,r8),
307 * (r9,r10) and if next arg is long long but
308 * not correct starting register of pair then skip
309 * until the proper starting register
311 if (intarg_count
% 2 != 0)
316 *gpr_base
.ll
++ = **p_argv
.ll
;
321 case FFI_TYPE_STRUCT
:
322 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
325 struct_copy_size
= ((*ptr
)->size
+ 15) & ~0xF;
326 copy_space
.c
-= struct_copy_size
;
327 memcpy (copy_space
.c
, *p_argv
.c
, (*ptr
)->size
);
329 gprvalue
= (unsigned long) copy_space
.c
;
331 FFI_ASSERT (copy_space
.c
> next_arg
.c
);
332 FFI_ASSERT (flags
& FLAG_ARG_NEEDS_COPY
);
336 gprvalue
= **p_argv
.uc
;
339 gprvalue
= **p_argv
.sc
;
341 case FFI_TYPE_UINT16
:
342 gprvalue
= **p_argv
.us
;
344 case FFI_TYPE_SINT16
:
345 gprvalue
= **p_argv
.ss
;
349 case FFI_TYPE_UINT32
:
350 case FFI_TYPE_SINT32
:
351 case FFI_TYPE_POINTER
:
354 gprvalue
= **p_argv
.ui
;
357 if (intarg_count
>= NUM_GPR_ARG_REGISTERS
)
358 *next_arg
.u
++ = gprvalue
;
360 *gpr_base
.u
++ = gprvalue
;
366 /* Check that we didn't overrun the stack... */
367 FFI_ASSERT (copy_space
.c
>= next_arg
.c
);
368 FFI_ASSERT (gpr_base
.u
<= stacktop
.u
- ASM_NEEDS_REGISTERS
);
369 FFI_ASSERT (fpr_base
.u
370 <= stacktop
.u
- ASM_NEEDS_REGISTERS
- NUM_GPR_ARG_REGISTERS
);
371 FFI_ASSERT (flags
& FLAG_4_GPR_ARGUMENTS
|| intarg_count
<= 4);
374 /* About the LINUX64 ABI. */
376 NUM_GPR_ARG_REGISTERS64
= 8,
377 NUM_FPR_ARG_REGISTERS64
= 13
379 enum { ASM_NEEDS_REGISTERS64
= 4 };
381 /* ffi_prep_args64 is called by the assembly routine once stack space
382 has been allocated for the function's arguments.
384 The stack layout we want looks like this:
386 | Ret addr from ffi_call_LINUX64 8bytes | higher addresses
387 |--------------------------------------------|
388 | CR save area 8bytes |
389 |--------------------------------------------|
390 | Previous backchain pointer 8 | stack pointer here
391 |--------------------------------------------|<+ <<< on entry to
392 | Saved r28-r31 4*8 | | ffi_call_LINUX64
393 |--------------------------------------------| |
394 | GPR registers r3-r10 8*8 | |
395 |--------------------------------------------| |
396 | FPR registers f1-f13 (optional) 13*8 | |
397 |--------------------------------------------| |
398 | Parameter save area | |
399 |--------------------------------------------| |
400 | TOC save area 8 | |
401 |--------------------------------------------| | stack |
402 | Linker doubleword 8 | | grows |
403 |--------------------------------------------| | down V
404 | Compiler doubleword 8 | |
405 |--------------------------------------------| | lower addresses
406 | Space for callee's LR 8 | |
407 |--------------------------------------------| |
409 |--------------------------------------------| | stack pointer here
410 | Current backchain pointer 8 |-/ during
411 |--------------------------------------------| <<< ffi_call_LINUX64
416 ffi_prep_args64 (extended_cif
*ecif
, unsigned long *const stack
)
418 const unsigned long bytes
= ecif
->cif
->bytes
;
419 const unsigned long flags
= ecif
->cif
->flags
;
428 /* 'stacktop' points at the previous backchain pointer. */
431 /* 'next_arg' points at the space for gpr3, and grows upwards as
432 we use GPR registers, then continues at rest. */
438 /* 'fpr_base' points at the space for fpr3, and grows upwards as
439 we use FPR registers. */
459 unsigned long gprvalue
;
461 stacktop
.c
= (char *) stack
+ bytes
;
462 gpr_base
.ul
= stacktop
.ul
- ASM_NEEDS_REGISTERS64
- NUM_GPR_ARG_REGISTERS64
;
463 gpr_end
.ul
= gpr_base
.ul
+ NUM_GPR_ARG_REGISTERS64
;
464 rest
.ul
= stack
+ 6 + NUM_GPR_ARG_REGISTERS64
;
465 fpr_base
.d
= gpr_base
.d
- NUM_FPR_ARG_REGISTERS64
;
467 next_arg
.ul
= gpr_base
.ul
;
469 /* Check that everything starts aligned properly. */
470 FFI_ASSERT (((unsigned long) (char *) stack
& 0xF) == 0);
471 FFI_ASSERT (((unsigned long) stacktop
.c
& 0xF) == 0);
472 FFI_ASSERT ((bytes
& 0xF) == 0);
474 /* Deal with return values that are actually pass-by-reference. */
475 if (flags
& FLAG_RETVAL_REFERENCE
)
476 *next_arg
.ul
++ = (unsigned long) (char *) ecif
->rvalue
;
478 /* Now for the arguments. */
479 p_argv
.v
= ecif
->avalue
;
480 for (ptr
= ecif
->cif
->arg_types
, i
= ecif
->cif
->nargs
;
482 i
--, ptr
++, p_argv
.v
++)
484 switch ((*ptr
)->type
)
487 double_tmp
= **p_argv
.f
;
488 *next_arg
.f
= (float) double_tmp
;
489 if (++next_arg
.ul
== gpr_end
.ul
)
490 next_arg
.ul
= rest
.ul
;
491 if (fparg_count
< NUM_FPR_ARG_REGISTERS64
)
492 *fpr_base
.d
++ = double_tmp
;
494 FFI_ASSERT (flags
& FLAG_FP_ARGUMENTS
);
497 case FFI_TYPE_DOUBLE
:
498 double_tmp
= **p_argv
.d
;
499 *next_arg
.d
= double_tmp
;
500 if (++next_arg
.ul
== gpr_end
.ul
)
501 next_arg
.ul
= rest
.ul
;
502 if (fparg_count
< NUM_FPR_ARG_REGISTERS64
)
503 *fpr_base
.d
++ = double_tmp
;
505 FFI_ASSERT (flags
& FLAG_FP_ARGUMENTS
);
508 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
509 case FFI_TYPE_LONGDOUBLE
:
510 double_tmp
= (*p_argv
.d
)[0];
511 *next_arg
.d
= double_tmp
;
512 if (++next_arg
.ul
== gpr_end
.ul
)
513 next_arg
.ul
= rest
.ul
;
514 if (fparg_count
< NUM_FPR_ARG_REGISTERS64
)
515 *fpr_base
.d
++ = double_tmp
;
517 double_tmp
= (*p_argv
.d
)[1];
518 *next_arg
.d
= double_tmp
;
519 if (++next_arg
.ul
== gpr_end
.ul
)
520 next_arg
.ul
= rest
.ul
;
521 if (fparg_count
< NUM_FPR_ARG_REGISTERS64
)
522 *fpr_base
.d
++ = double_tmp
;
524 FFI_ASSERT (__LDBL_MANT_DIG__
== 106);
525 FFI_ASSERT (flags
& FLAG_FP_ARGUMENTS
);
529 case FFI_TYPE_STRUCT
:
530 words
= ((*ptr
)->size
+ 7) / 8;
531 if (next_arg
.ul
>= gpr_base
.ul
&& next_arg
.ul
+ words
> gpr_end
.ul
)
533 size_t first
= gpr_end
.c
- next_arg
.c
;
534 memcpy (next_arg
.c
, *p_argv
.c
, first
);
535 memcpy (rest
.c
, *p_argv
.c
+ first
, (*ptr
)->size
- first
);
536 next_arg
.c
= rest
.c
+ words
* 8 - first
;
540 char *where
= next_arg
.c
;
542 /* Structures with size less than eight bytes are passed
544 if ((*ptr
)->size
< 8)
545 where
+= 8 - (*ptr
)->size
;
547 memcpy (where
, *p_argv
.c
, (*ptr
)->size
);
548 next_arg
.ul
+= words
;
549 if (next_arg
.ul
== gpr_end
.ul
)
550 next_arg
.ul
= rest
.ul
;
555 gprvalue
= **p_argv
.uc
;
558 gprvalue
= **p_argv
.sc
;
560 case FFI_TYPE_UINT16
:
561 gprvalue
= **p_argv
.us
;
563 case FFI_TYPE_SINT16
:
564 gprvalue
= **p_argv
.ss
;
566 case FFI_TYPE_UINT32
:
567 gprvalue
= **p_argv
.ui
;
570 case FFI_TYPE_SINT32
:
571 gprvalue
= **p_argv
.si
;
574 case FFI_TYPE_UINT64
:
575 case FFI_TYPE_SINT64
:
576 case FFI_TYPE_POINTER
:
577 gprvalue
= **p_argv
.ul
;
579 *next_arg
.ul
++ = gprvalue
;
580 if (next_arg
.ul
== gpr_end
.ul
)
581 next_arg
.ul
= rest
.ul
;
586 FFI_ASSERT (flags
& FLAG_4_GPR_ARGUMENTS
587 || (next_arg
.ul
>= gpr_base
.ul
588 && next_arg
.ul
<= gpr_base
.ul
+ 4));
593 /* Perform machine dependent cif processing */
595 ffi_prep_cif_machdep (ffi_cif
*cif
)
597 /* All this is for the SYSV and LINUX64 ABI. */
601 int fparg_count
= 0, intarg_count
= 0;
603 unsigned struct_copy_size
= 0;
604 unsigned type
= cif
->rtype
->type
;
605 unsigned size
= cif
->rtype
->size
;
607 if (cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
608 NUM_FPR_ARG_REGISTERS
= 0;
610 if (cif
->abi
!= FFI_LINUX64
)
612 /* All the machine-independent calculation of cif->bytes will be wrong.
613 Redo the calculation for SYSV. */
615 /* Space for the frame pointer, callee's LR, and the asm's temp regs. */
616 bytes
= (2 + ASM_NEEDS_REGISTERS
) * sizeof (int);
618 /* Space for the GPR registers. */
619 bytes
+= NUM_GPR_ARG_REGISTERS
* sizeof (int);
625 /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp
627 bytes
= (6 + ASM_NEEDS_REGISTERS64
) * sizeof (long);
629 /* Space for the mandatory parm save area and general registers. */
630 bytes
+= 2 * NUM_GPR_ARG_REGISTERS64
* sizeof (long);
633 /* Return value handling. The rules for SYSV are as follows:
634 - 32-bit (or less) integer values are returned in gpr3;
635 - Structures of size <= 4 bytes also returned in gpr3;
636 - 64-bit integer values and structures between 5 and 8 bytes are returned
638 - Single/double FP values are returned in fpr1;
639 - Larger structures are allocated space and a pointer is passed as
641 - long doubles (if not equivalent to double) are returned in
642 fpr1,fpr2 for Linux and as for large structs for SysV.
644 - integer values in gpr3;
645 - Structures/Unions by reference;
646 - Single/double FP values in fpr1, long double in fpr1,fpr2.
647 - soft-float float/doubles are treated as UINT32/UINT64 respectivley.
648 - soft-float long doubles are returned in gpr3-gpr6. */
651 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
652 case FFI_TYPE_LONGDOUBLE
:
653 if (cif
->abi
!= FFI_LINUX
&& cif
->abi
!= FFI_LINUX64
654 && cif
->abi
!= FFI_LINUX_SOFT_FLOAT
)
656 flags
|= FLAG_RETURNS_128BITS
;
659 case FFI_TYPE_DOUBLE
:
660 flags
|= FLAG_RETURNS_64BITS
;
663 /* With FFI_LINUX_SOFT_FLOAT no fp registers are used. */
664 if (cif
->abi
!= FFI_LINUX_SOFT_FLOAT
)
665 flags
|= FLAG_RETURNS_FP
;
668 case FFI_TYPE_UINT64
:
669 case FFI_TYPE_SINT64
:
670 flags
|= FLAG_RETURNS_64BITS
;
673 case FFI_TYPE_STRUCT
:
674 if (cif
->abi
== FFI_SYSV
)
676 /* The final SYSV ABI says that structures smaller or equal 8 bytes
677 are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them
680 /* Treat structs with size <= 8 bytes. */
683 flags
|= FLAG_RETURNS_SMST
;
684 /* These structs are returned in r3. We pack the type and the
685 precalculated shift value (needed in the sysv.S) into flags.
686 The same applies for the structs returned in r3/r4. */
689 flags
|= FLAG_SYSV_SMST_R3
;
690 flags
|= 8 * (4 - size
) << 8;
693 /* These structs are returned in r3 and r4. See above. */
696 flags
|= FLAG_SYSV_SMST_R3
| FLAG_SYSV_SMST_R4
;
697 flags
|= 8 * (8 - size
) << 8;
702 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
706 flags
|= FLAG_RETVAL_REFERENCE
;
709 flags
|= FLAG_RETURNS_NOTHING
;
713 /* Returns 32-bit integer, or similar. Nothing to do here. */
717 if (cif
->abi
!= FFI_LINUX64
)
718 /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
719 first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
720 goes on the stack. Structures and long doubles (if not equivalent
721 to double) are passed as a pointer to a copy of the structure.
722 Stuff on the stack needs to keep proper alignment. */
723 for (ptr
= cif
->arg_types
, i
= cif
->nargs
; i
> 0; i
--, ptr
++)
725 switch ((*ptr
)->type
)
728 /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32. */
729 if (cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
732 /* floating singles are not 8-aligned on stack */
735 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
736 case FFI_TYPE_LONGDOUBLE
:
737 if (cif
->abi
!= FFI_LINUX
&& cif
->abi
!= FFI_LINUX_SOFT_FLOAT
)
739 if (cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
741 if (intarg_count
>= NUM_GPR_ARG_REGISTERS
- 3
742 || intarg_count
< NUM_GPR_ARG_REGISTERS
)
743 /* A long double in FFI_LINUX_SOFT_FLOAT can use only
744 a set of four consecutive gprs. If we have not enough,
745 we have to adjust the intarg_count value. */
746 intarg_count
+= NUM_GPR_ARG_REGISTERS
- intarg_count
;
754 case FFI_TYPE_DOUBLE
:
755 /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64. */
756 if (cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
757 goto soft_double_cif
;
759 /* If this FP arg is going on the stack, it must be
761 if (fparg_count
> NUM_FPR_ARG_REGISTERS
762 && intarg_count
>= NUM_GPR_ARG_REGISTERS
763 && intarg_count
% 2 != 0)
767 case FFI_TYPE_UINT64
:
768 case FFI_TYPE_SINT64
:
770 /* 'long long' arguments are passed as two words, but
771 either both words must fit in registers or both go
772 on the stack. If they go on the stack, they must
775 Also, only certain register pairs can be used for
776 passing long long int -- specifically (r3,r4), (r5,r6),
779 if (intarg_count
== NUM_GPR_ARG_REGISTERS
-1
780 || intarg_count
% 2 != 0)
785 case FFI_TYPE_STRUCT
:
786 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
789 /* We must allocate space for a copy of these to enforce
790 pass-by-value. Pad the space up to a multiple of 16
791 bytes (the maximum alignment required for anything under
793 struct_copy_size
+= ((*ptr
)->size
+ 15) & ~0xF;
794 /* Fall through (allocate space for the pointer). */
798 /* Everything else is passed as a 4-byte word in a GPR, either
799 the object itself or a pointer to it. */
805 for (ptr
= cif
->arg_types
, i
= cif
->nargs
; i
> 0; i
--, ptr
++)
807 switch ((*ptr
)->type
)
809 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
810 case FFI_TYPE_LONGDOUBLE
:
811 if (cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
821 case FFI_TYPE_DOUBLE
:
826 case FFI_TYPE_STRUCT
:
827 intarg_count
+= ((*ptr
)->size
+ 7) / 8;
831 /* Everything else is passed as a 8-byte word in a GPR, either
832 the object itself or a pointer to it. */
838 if (fparg_count
!= 0)
839 flags
|= FLAG_FP_ARGUMENTS
;
840 if (intarg_count
> 4)
841 flags
|= FLAG_4_GPR_ARGUMENTS
;
842 if (struct_copy_size
!= 0)
843 flags
|= FLAG_ARG_NEEDS_COPY
;
845 if (cif
->abi
!= FFI_LINUX64
)
847 /* Space for the FPR registers, if needed. */
848 if (fparg_count
!= 0)
849 bytes
+= NUM_FPR_ARG_REGISTERS
* sizeof (double);
852 if (intarg_count
> NUM_GPR_ARG_REGISTERS
)
853 bytes
+= (intarg_count
- NUM_GPR_ARG_REGISTERS
) * sizeof (int);
854 if (fparg_count
> NUM_FPR_ARG_REGISTERS
)
855 bytes
+= (fparg_count
- NUM_FPR_ARG_REGISTERS
) * sizeof (double);
859 /* Space for the FPR registers, if needed. */
860 if (fparg_count
!= 0)
861 bytes
+= NUM_FPR_ARG_REGISTERS64
* sizeof (double);
864 if (intarg_count
> NUM_GPR_ARG_REGISTERS64
)
865 bytes
+= (intarg_count
- NUM_GPR_ARG_REGISTERS64
) * sizeof (long);
868 /* The stack space allocated needs to be a multiple of 16 bytes. */
869 bytes
= (bytes
+ 15) & ~0xF;
871 /* Add in the space for the copied structures. */
872 bytes
+= struct_copy_size
;
880 extern void ffi_call_SYSV(extended_cif
*, unsigned, unsigned, unsigned *,
882 extern void FFI_HIDDEN
ffi_call_LINUX64(extended_cif
*, unsigned long,
883 unsigned long, unsigned long *,
887 ffi_call(ffi_cif
*cif
, void (*fn
)(void), void *rvalue
, void **avalue
)
892 ecif
.avalue
= avalue
;
894 /* If the return value is a struct and we don't have a return */
895 /* value address then we need to make one */
897 if ((rvalue
== NULL
) && (cif
->rtype
->type
== FFI_TYPE_STRUCT
))
899 ecif
.rvalue
= alloca(cif
->rtype
->size
);
902 ecif
.rvalue
= rvalue
;
911 case FFI_LINUX_SOFT_FLOAT
:
912 ffi_call_SYSV (&ecif
, -cif
->bytes
, cif
->flags
, ecif
.rvalue
, fn
);
916 ffi_call_LINUX64 (&ecif
, -(long) cif
->bytes
, cif
->flags
, ecif
.rvalue
, fn
);
927 #define MIN_CACHE_LINE_SIZE 8
930 flush_icache (char *wraddr
, char *xaddr
, int size
)
933 for (i
= 0; i
< size
; i
+= MIN_CACHE_LINE_SIZE
)
934 __asm__
volatile ("icbi 0,%0;" "dcbf 0,%1;"
935 : : "r" (xaddr
+ i
), "r" (wraddr
+ i
) : "memory");
936 __asm__
volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;"
937 : : "r"(xaddr
+ size
- 1), "r"(wraddr
+ size
- 1)
943 ffi_prep_closure_loc (ffi_closure
*closure
,
945 void (*fun
) (ffi_cif
*, void *, void **, void *),
950 void **tramp
= (void **) &closure
->tramp
[0];
952 FFI_ASSERT (cif
->abi
== FFI_LINUX64
);
953 /* Copy function address and TOC from ffi_closure_LINUX64. */
954 memcpy (tramp
, (char *) ffi_closure_LINUX64
, 16);
959 FFI_ASSERT (cif
->abi
== FFI_GCC_SYSV
|| cif
->abi
== FFI_SYSV
);
961 tramp
= (unsigned int *) &closure
->tramp
[0];
962 tramp
[0] = 0x7c0802a6; /* mflr r0 */
963 tramp
[1] = 0x4800000d; /* bl 10 <trampoline_initial+0x10> */
964 tramp
[4] = 0x7d6802a6; /* mflr r11 */
965 tramp
[5] = 0x7c0803a6; /* mtlr r0 */
966 tramp
[6] = 0x800b0000; /* lwz r0,0(r11) */
967 tramp
[7] = 0x816b0004; /* lwz r11,4(r11) */
968 tramp
[8] = 0x7c0903a6; /* mtctr r0 */
969 tramp
[9] = 0x4e800420; /* bctr */
970 *(void **) &tramp
[2] = (void *) ffi_closure_SYSV
; /* function */
971 *(void **) &tramp
[3] = codeloc
; /* context */
973 /* Flush the icache. */
974 flush_icache ((char *)tramp
, (char *)codeloc
, FFI_TRAMPOLINE_SIZE
);
979 closure
->user_data
= user_data
;
990 int ffi_closure_helper_SYSV (ffi_closure
*, void *, unsigned long *,
991 ffi_dblfl
*, unsigned long *);
993 /* Basically the trampoline invokes ffi_closure_SYSV, and on
994 * entry, r11 holds the address of the closure.
995 * After storing the registers that could possibly contain
996 * parameters to be passed into the stack frame and setting
997 * up space for a return value, ffi_closure_SYSV invokes the
998 * following helper function to do most of the work
1002 ffi_closure_helper_SYSV (ffi_closure
*closure
, void *rvalue
,
1003 unsigned long *pgr
, ffi_dblfl
*pfr
,
1006 /* rvalue is the pointer to space for return value in closure assembly */
1007 /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
1008 /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV */
1009 /* pst is the pointer to outgoing parameter stack in original caller */
1012 ffi_type
** arg_types
;
1014 long nf
; /* number of floating registers already used */
1015 long ng
; /* number of general registers already used */
1021 avalue
= alloca (cif
->nargs
* sizeof (void *));
1022 size
= cif
->rtype
->size
;
1027 /* Copy the caller's structure return value address so that the closure
1028 returns the data directly to the caller.
1029 For FFI_SYSV the result is passed in r3/r4 if the struct size is less
1030 or equal 8 bytes. */
1032 if ((cif
->rtype
->type
== FFI_TYPE_STRUCT
1033 && !((cif
->abi
== FFI_SYSV
) && (size
<= 8)))
1034 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1035 || (cif
->rtype
->type
== FFI_TYPE_LONGDOUBLE
1036 && cif
->abi
!= FFI_LINUX
&& cif
->abi
!= FFI_LINUX_SOFT_FLOAT
)
1040 rvalue
= (void *) *pgr
;
1047 arg_types
= cif
->arg_types
;
1049 /* Grab the addresses of the arguments from the stack frame. */
1052 switch (arg_types
[i
]->type
)
1054 case FFI_TYPE_SINT8
:
1055 case FFI_TYPE_UINT8
:
1056 /* there are 8 gpr registers used to pass values */
1059 avalue
[i
] = (char *) pgr
+ 3;
1065 avalue
[i
] = (char *) pst
+ 3;
1070 case FFI_TYPE_SINT16
:
1071 case FFI_TYPE_UINT16
:
1072 /* there are 8 gpr registers used to pass values */
1075 avalue
[i
] = (char *) pgr
+ 2;
1081 avalue
[i
] = (char *) pst
+ 2;
1086 case FFI_TYPE_SINT32
:
1087 case FFI_TYPE_UINT32
:
1088 case FFI_TYPE_POINTER
:
1090 /* there are 8 gpr registers used to pass values */
1104 case FFI_TYPE_STRUCT
:
1105 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1108 /* Structs are passed by reference. The address will appear in a
1109 gpr if it is one of the first 8 arguments. */
1112 avalue
[i
] = (void *) *pgr
;
1118 avalue
[i
] = (void *) *pst
;
1123 case FFI_TYPE_SINT64
:
1124 case FFI_TYPE_UINT64
:
1125 soft_double_closure
:
1126 /* passing long long ints are complex, they must
1127 * be passed in suitable register pairs such as
1128 * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
1129 * and if the entire pair aren't available then the outgoing
1130 * parameter stack is used for both but an alignment of 8
1131 * must will be kept. So we must either look in pgr
1132 * or pst to find the correct address for this type
1139 /* skip r4, r6, r8 as starting points */
1149 if (((long) pst
) & 4)
1157 case FFI_TYPE_FLOAT
:
1158 /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32. */
1159 if (cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
1160 goto soft_float_closure
;
1161 /* unfortunately float values are stored as doubles
1162 * in the ffi_closure_SYSV code (since we don't check
1163 * the type in that routine).
1166 /* there are 8 64bit floating point registers */
1171 pfr
->f
= (float) temp
;
1178 /* FIXME? here we are really changing the values
1179 * stored in the original calling routines outgoing
1180 * parameter stack. This is probably a really
1181 * naughty thing to do but...
1188 case FFI_TYPE_DOUBLE
:
1189 /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64. */
1190 if (cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
1191 goto soft_double_closure
;
1192 /* On the outgoing stack all values are aligned to 8 */
1193 /* there are 8 64bit floating point registers */
1203 if (((long) pst
) & 4)
1210 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1211 case FFI_TYPE_LONGDOUBLE
:
1212 if (cif
->abi
!= FFI_LINUX
&& cif
->abi
!= FFI_LINUX_SOFT_FLOAT
)
1214 if (cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
1215 { /* Test if for the whole long double, 4 gprs are available.
1216 otherwise the stuff ends up on the stack. */
1239 if (((long) pst
) & 4)
1256 (closure
->fun
) (cif
, rvalue
, avalue
, closure
->user_data
);
1258 /* Tell ffi_closure_SYSV how to perform return type promotions.
1259 Because the FFI_SYSV ABI returns the structures <= 8 bytes in r3/r4
1260 we have to tell ffi_closure_SYSV how to treat them. We combine the base
1261 type FFI_SYSV_TYPE_SMALL_STRUCT - 1 with the size of the struct.
1262 So a one byte struct gets the return type 16. Return type 1 to 15 are
1263 already used and we never have a struct with size zero. That is the reason
1264 for the subtraction of 1. See the comment in ffitarget.h about ordering.
1266 if (cif
->abi
== FFI_SYSV
&& cif
->rtype
->type
== FFI_TYPE_STRUCT
1268 return (FFI_SYSV_TYPE_SMALL_STRUCT
- 1) + size
;
1269 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1270 else if (cif
->rtype
->type
== FFI_TYPE_LONGDOUBLE
1271 && cif
->abi
!= FFI_LINUX
&& cif
->abi
!= FFI_LINUX_SOFT_FLOAT
)
1272 return FFI_TYPE_STRUCT
;
1274 /* With FFI_LINUX_SOFT_FLOAT floats and doubles are handled like UINT32
1275 respectivley UINT64. */
1276 if (cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
1278 switch (cif
->rtype
->type
)
1280 case FFI_TYPE_FLOAT
:
1281 return FFI_TYPE_UINT32
;
1283 case FFI_TYPE_DOUBLE
:
1284 return FFI_TYPE_UINT64
;
1286 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1287 case FFI_TYPE_LONGDOUBLE
:
1288 return FFI_TYPE_UINT128
;
1292 return cif
->rtype
->type
;
1297 return cif
->rtype
->type
;
1301 int FFI_HIDDEN
ffi_closure_helper_LINUX64 (ffi_closure
*, void *,
1302 unsigned long *, ffi_dblfl
*);
1305 ffi_closure_helper_LINUX64 (ffi_closure
*closure
, void *rvalue
,
1306 unsigned long *pst
, ffi_dblfl
*pfr
)
1308 /* rvalue is the pointer to space for return value in closure assembly */
1309 /* pst is the pointer to parameter save area
1310 (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */
1311 /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */
1314 ffi_type
**arg_types
;
1317 ffi_dblfl
*end_pfr
= pfr
+ NUM_FPR_ARG_REGISTERS64
;
1320 avalue
= alloca (cif
->nargs
* sizeof (void *));
1322 /* Copy the caller's structure return value address so that the closure
1323 returns the data directly to the caller. */
1324 if (cif
->rtype
->type
== FFI_TYPE_STRUCT
)
1326 rvalue
= (void *) *pst
;
1332 arg_types
= cif
->arg_types
;
1334 /* Grab the addresses of the arguments from the stack frame. */
1337 switch (arg_types
[i
]->type
)
1339 case FFI_TYPE_SINT8
:
1340 case FFI_TYPE_UINT8
:
1341 avalue
[i
] = (char *) pst
+ 7;
1345 case FFI_TYPE_SINT16
:
1346 case FFI_TYPE_UINT16
:
1347 avalue
[i
] = (char *) pst
+ 6;
1351 case FFI_TYPE_SINT32
:
1352 case FFI_TYPE_UINT32
:
1353 avalue
[i
] = (char *) pst
+ 4;
1357 case FFI_TYPE_SINT64
:
1358 case FFI_TYPE_UINT64
:
1359 case FFI_TYPE_POINTER
:
1364 case FFI_TYPE_STRUCT
:
1365 /* Structures with size less than eight bytes are passed
1367 if (arg_types
[i
]->size
< 8)
1368 avalue
[i
] = (char *) pst
+ 8 - arg_types
[i
]->size
;
1371 pst
+= (arg_types
[i
]->size
+ 7) / 8;
1374 case FFI_TYPE_FLOAT
:
1375 /* unfortunately float values are stored as doubles
1376 * in the ffi_closure_LINUX64 code (since we don't check
1377 * the type in that routine).
1380 /* there are 13 64bit floating point registers */
1384 double temp
= pfr
->d
;
1385 pfr
->f
= (float) temp
;
1394 case FFI_TYPE_DOUBLE
:
1395 /* On the outgoing stack all values are aligned to 8 */
1396 /* there are 13 64bit floating point registers */
1408 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1409 case FFI_TYPE_LONGDOUBLE
:
1410 if (pfr
+ 1 < end_pfr
)
1419 /* Passed partly in f13 and partly on the stack.
1420 Move it all to the stack. */
1421 *pst
= *(unsigned long *) pfr
;
1438 (closure
->fun
) (cif
, rvalue
, avalue
, closure
->user_data
);
1440 /* Tell ffi_closure_LINUX64 how to perform return type promotions. */
1441 return cif
->rtype
->type
;