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
;
190 *fpr_base
.d
++ = double_tmp
;
192 FFI_ASSERT (flags
& FLAG_FP_ARGUMENTS
);
195 case FFI_TYPE_DOUBLE
:
196 /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64. */
197 if (ecif
->cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
198 goto soft_double_prep
;
199 double_tmp
= **p_argv
.d
;
201 if (fparg_count
>= NUM_FPR_ARG_REGISTERS
)
203 if (intarg_count
>= NUM_GPR_ARG_REGISTERS
204 && intarg_count
% 2 != 0)
209 *next_arg
.d
= double_tmp
;
213 *fpr_base
.d
++ = double_tmp
;
215 FFI_ASSERT (flags
& FLAG_FP_ARGUMENTS
);
218 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
219 case FFI_TYPE_LONGDOUBLE
:
220 if ((ecif
->cif
->abi
!= FFI_LINUX
)
221 && (ecif
->cif
->abi
!= FFI_LINUX_SOFT_FLOAT
))
223 /* The soft float ABI for long doubles works like this,
224 a long double is passed in four consecutive gprs if available.
225 A maximum of 2 long doubles can be passed in gprs.
226 If we do not have 4 gprs left, the long double is passed on the
227 stack, 4-byte aligned. */
228 if (ecif
->cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
230 unsigned int int_tmp
= (*p_argv
.ui
)[0];
231 if (intarg_count
>= NUM_GPR_ARG_REGISTERS
- 3)
233 if (intarg_count
< NUM_GPR_ARG_REGISTERS
)
234 intarg_count
+= NUM_GPR_ARG_REGISTERS
- intarg_count
;
235 *next_arg
.u
= int_tmp
;
237 for (ii
= 1; ii
< 4; ii
++)
239 int_tmp
= (*p_argv
.ui
)[ii
];
240 *next_arg
.u
= int_tmp
;
246 *gpr_base
.u
++ = int_tmp
;
247 for (ii
= 1; ii
< 4; ii
++)
249 int_tmp
= (*p_argv
.ui
)[ii
];
250 *gpr_base
.u
++ = int_tmp
;
257 double_tmp
= (*p_argv
.d
)[0];
259 if (fparg_count
>= NUM_FPR_ARG_REGISTERS
- 1)
261 if (intarg_count
>= NUM_GPR_ARG_REGISTERS
262 && intarg_count
% 2 != 0)
267 *next_arg
.d
= double_tmp
;
269 double_tmp
= (*p_argv
.d
)[1];
270 *next_arg
.d
= double_tmp
;
275 *fpr_base
.d
++ = double_tmp
;
276 double_tmp
= (*p_argv
.d
)[1];
277 *fpr_base
.d
++ = double_tmp
;
281 FFI_ASSERT (flags
& FLAG_FP_ARGUMENTS
);
286 case FFI_TYPE_UINT64
:
287 case FFI_TYPE_SINT64
:
289 if (intarg_count
== NUM_GPR_ARG_REGISTERS
-1)
291 if (intarg_count
>= NUM_GPR_ARG_REGISTERS
)
293 if (intarg_count
% 2 != 0)
298 *next_arg
.ll
= **p_argv
.ll
;
303 /* whoops: abi states only certain register pairs
304 * can be used for passing long long int
305 * specifically (r3,r4), (r5,r6), (r7,r8),
306 * (r9,r10) and if next arg is long long but
307 * not correct starting register of pair then skip
308 * until the proper starting register
310 if (intarg_count
% 2 != 0)
315 *gpr_base
.ll
++ = **p_argv
.ll
;
320 case FFI_TYPE_STRUCT
:
321 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
324 struct_copy_size
= ((*ptr
)->size
+ 15) & ~0xF;
325 copy_space
.c
-= struct_copy_size
;
326 memcpy (copy_space
.c
, *p_argv
.c
, (*ptr
)->size
);
328 gprvalue
= (unsigned long) copy_space
.c
;
330 FFI_ASSERT (copy_space
.c
> next_arg
.c
);
331 FFI_ASSERT (flags
& FLAG_ARG_NEEDS_COPY
);
335 gprvalue
= **p_argv
.uc
;
338 gprvalue
= **p_argv
.sc
;
340 case FFI_TYPE_UINT16
:
341 gprvalue
= **p_argv
.us
;
343 case FFI_TYPE_SINT16
:
344 gprvalue
= **p_argv
.ss
;
348 case FFI_TYPE_UINT32
:
349 case FFI_TYPE_SINT32
:
350 case FFI_TYPE_POINTER
:
353 gprvalue
= **p_argv
.ui
;
356 if (intarg_count
>= NUM_GPR_ARG_REGISTERS
)
357 *next_arg
.u
++ = gprvalue
;
359 *gpr_base
.u
++ = gprvalue
;
365 /* Check that we didn't overrun the stack... */
366 FFI_ASSERT (copy_space
.c
>= next_arg
.c
);
367 FFI_ASSERT (gpr_base
.u
<= stacktop
.u
- ASM_NEEDS_REGISTERS
);
368 FFI_ASSERT (fpr_base
.u
369 <= stacktop
.u
- ASM_NEEDS_REGISTERS
- NUM_GPR_ARG_REGISTERS
);
370 FFI_ASSERT (flags
& FLAG_4_GPR_ARGUMENTS
|| intarg_count
<= 4);
373 /* About the LINUX64 ABI. */
375 NUM_GPR_ARG_REGISTERS64
= 8,
376 NUM_FPR_ARG_REGISTERS64
= 13
378 enum { ASM_NEEDS_REGISTERS64
= 4 };
380 /* ffi_prep_args64 is called by the assembly routine once stack space
381 has been allocated for the function's arguments.
383 The stack layout we want looks like this:
385 | Ret addr from ffi_call_LINUX64 8bytes | higher addresses
386 |--------------------------------------------|
387 | CR save area 8bytes |
388 |--------------------------------------------|
389 | Previous backchain pointer 8 | stack pointer here
390 |--------------------------------------------|<+ <<< on entry to
391 | Saved r28-r31 4*8 | | ffi_call_LINUX64
392 |--------------------------------------------| |
393 | GPR registers r3-r10 8*8 | |
394 |--------------------------------------------| |
395 | FPR registers f1-f13 (optional) 13*8 | |
396 |--------------------------------------------| |
397 | Parameter save area | |
398 |--------------------------------------------| |
399 | TOC save area 8 | |
400 |--------------------------------------------| | stack |
401 | Linker doubleword 8 | | grows |
402 |--------------------------------------------| | down V
403 | Compiler doubleword 8 | |
404 |--------------------------------------------| | lower addresses
405 | Space for callee's LR 8 | |
406 |--------------------------------------------| |
408 |--------------------------------------------| | stack pointer here
409 | Current backchain pointer 8 |-/ during
410 |--------------------------------------------| <<< ffi_call_LINUX64
415 ffi_prep_args64 (extended_cif
*ecif
, unsigned long *const stack
)
417 const unsigned long bytes
= ecif
->cif
->bytes
;
418 const unsigned long flags
= ecif
->cif
->flags
;
427 /* 'stacktop' points at the previous backchain pointer. */
430 /* 'next_arg' points at the space for gpr3, and grows upwards as
431 we use GPR registers, then continues at rest. */
437 /* 'fpr_base' points at the space for fpr3, and grows upwards as
438 we use FPR registers. */
458 unsigned long gprvalue
;
460 stacktop
.c
= (char *) stack
+ bytes
;
461 gpr_base
.ul
= stacktop
.ul
- ASM_NEEDS_REGISTERS64
- NUM_GPR_ARG_REGISTERS64
;
462 gpr_end
.ul
= gpr_base
.ul
+ NUM_GPR_ARG_REGISTERS64
;
463 rest
.ul
= stack
+ 6 + NUM_GPR_ARG_REGISTERS64
;
464 fpr_base
.d
= gpr_base
.d
- NUM_FPR_ARG_REGISTERS64
;
466 next_arg
.ul
= gpr_base
.ul
;
468 /* Check that everything starts aligned properly. */
469 FFI_ASSERT (((unsigned long) (char *) stack
& 0xF) == 0);
470 FFI_ASSERT (((unsigned long) stacktop
.c
& 0xF) == 0);
471 FFI_ASSERT ((bytes
& 0xF) == 0);
473 /* Deal with return values that are actually pass-by-reference. */
474 if (flags
& FLAG_RETVAL_REFERENCE
)
475 *next_arg
.ul
++ = (unsigned long) (char *) ecif
->rvalue
;
477 /* Now for the arguments. */
478 p_argv
.v
= ecif
->avalue
;
479 for (ptr
= ecif
->cif
->arg_types
, i
= ecif
->cif
->nargs
;
481 i
--, ptr
++, p_argv
.v
++)
483 switch ((*ptr
)->type
)
486 double_tmp
= **p_argv
.f
;
487 *next_arg
.f
= (float) double_tmp
;
488 if (++next_arg
.ul
== gpr_end
.ul
)
489 next_arg
.ul
= rest
.ul
;
490 if (fparg_count
< NUM_FPR_ARG_REGISTERS64
)
491 *fpr_base
.d
++ = double_tmp
;
493 FFI_ASSERT (flags
& FLAG_FP_ARGUMENTS
);
496 case FFI_TYPE_DOUBLE
:
497 double_tmp
= **p_argv
.d
;
498 *next_arg
.d
= double_tmp
;
499 if (++next_arg
.ul
== gpr_end
.ul
)
500 next_arg
.ul
= rest
.ul
;
501 if (fparg_count
< NUM_FPR_ARG_REGISTERS64
)
502 *fpr_base
.d
++ = double_tmp
;
504 FFI_ASSERT (flags
& FLAG_FP_ARGUMENTS
);
507 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
508 case FFI_TYPE_LONGDOUBLE
:
509 double_tmp
= (*p_argv
.d
)[0];
510 *next_arg
.d
= double_tmp
;
511 if (++next_arg
.ul
== gpr_end
.ul
)
512 next_arg
.ul
= rest
.ul
;
513 if (fparg_count
< NUM_FPR_ARG_REGISTERS64
)
514 *fpr_base
.d
++ = double_tmp
;
516 double_tmp
= (*p_argv
.d
)[1];
517 *next_arg
.d
= double_tmp
;
518 if (++next_arg
.ul
== gpr_end
.ul
)
519 next_arg
.ul
= rest
.ul
;
520 if (fparg_count
< NUM_FPR_ARG_REGISTERS64
)
521 *fpr_base
.d
++ = double_tmp
;
523 FFI_ASSERT (__LDBL_MANT_DIG__
== 106);
524 FFI_ASSERT (flags
& FLAG_FP_ARGUMENTS
);
528 case FFI_TYPE_STRUCT
:
529 words
= ((*ptr
)->size
+ 7) / 8;
530 if (next_arg
.ul
>= gpr_base
.ul
&& next_arg
.ul
+ words
> gpr_end
.ul
)
532 size_t first
= gpr_end
.c
- next_arg
.c
;
533 memcpy (next_arg
.c
, *p_argv
.c
, first
);
534 memcpy (rest
.c
, *p_argv
.c
+ first
, (*ptr
)->size
- first
);
535 next_arg
.c
= rest
.c
+ words
* 8 - first
;
539 char *where
= next_arg
.c
;
541 /* Structures with size less than eight bytes are passed
543 if ((*ptr
)->size
< 8)
544 where
+= 8 - (*ptr
)->size
;
546 memcpy (where
, *p_argv
.c
, (*ptr
)->size
);
547 next_arg
.ul
+= words
;
548 if (next_arg
.ul
== gpr_end
.ul
)
549 next_arg
.ul
= rest
.ul
;
554 gprvalue
= **p_argv
.uc
;
557 gprvalue
= **p_argv
.sc
;
559 case FFI_TYPE_UINT16
:
560 gprvalue
= **p_argv
.us
;
562 case FFI_TYPE_SINT16
:
563 gprvalue
= **p_argv
.ss
;
565 case FFI_TYPE_UINT32
:
566 gprvalue
= **p_argv
.ui
;
569 case FFI_TYPE_SINT32
:
570 gprvalue
= **p_argv
.si
;
573 case FFI_TYPE_UINT64
:
574 case FFI_TYPE_SINT64
:
575 case FFI_TYPE_POINTER
:
576 gprvalue
= **p_argv
.ul
;
578 *next_arg
.ul
++ = gprvalue
;
579 if (next_arg
.ul
== gpr_end
.ul
)
580 next_arg
.ul
= rest
.ul
;
585 FFI_ASSERT (flags
& FLAG_4_GPR_ARGUMENTS
586 || (next_arg
.ul
>= gpr_base
.ul
587 && next_arg
.ul
<= gpr_base
.ul
+ 4));
592 /* Perform machine dependent cif processing */
594 ffi_prep_cif_machdep (ffi_cif
*cif
)
596 /* All this is for the SYSV and LINUX64 ABI. */
600 int fparg_count
= 0, intarg_count
= 0;
602 unsigned struct_copy_size
= 0;
603 unsigned type
= cif
->rtype
->type
;
604 unsigned size
= cif
->rtype
->size
;
606 if (cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
607 NUM_FPR_ARG_REGISTERS
= 0;
609 if (cif
->abi
!= FFI_LINUX64
)
611 /* All the machine-independent calculation of cif->bytes will be wrong.
612 Redo the calculation for SYSV. */
614 /* Space for the frame pointer, callee's LR, and the asm's temp regs. */
615 bytes
= (2 + ASM_NEEDS_REGISTERS
) * sizeof (int);
617 /* Space for the GPR registers. */
618 bytes
+= NUM_GPR_ARG_REGISTERS
* sizeof (int);
624 /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp
626 bytes
= (6 + ASM_NEEDS_REGISTERS64
) * sizeof (long);
628 /* Space for the mandatory parm save area and general registers. */
629 bytes
+= 2 * NUM_GPR_ARG_REGISTERS64
* sizeof (long);
632 /* Return value handling. The rules for SYSV are as follows:
633 - 32-bit (or less) integer values are returned in gpr3;
634 - Structures of size <= 4 bytes also returned in gpr3;
635 - 64-bit integer values and structures between 5 and 8 bytes are returned
637 - Single/double FP values are returned in fpr1;
638 - Larger structures are allocated space and a pointer is passed as
640 - long doubles (if not equivalent to double) are returned in
641 fpr1,fpr2 for Linux and as for large structs for SysV.
643 - integer values in gpr3;
644 - Structures/Unions by reference;
645 - Single/double FP values in fpr1, long double in fpr1,fpr2.
646 - soft-float float/doubles are treated as UINT32/UINT64 respectivley.
647 - soft-float long doubles are returned in gpr3-gpr6. */
650 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
651 case FFI_TYPE_LONGDOUBLE
:
652 if (cif
->abi
!= FFI_LINUX
&& cif
->abi
!= FFI_LINUX64
653 && cif
->abi
!= FFI_LINUX_SOFT_FLOAT
)
655 flags
|= FLAG_RETURNS_128BITS
;
658 case FFI_TYPE_DOUBLE
:
659 flags
|= FLAG_RETURNS_64BITS
;
662 /* With FFI_LINUX_SOFT_FLOAT no fp registers are used. */
663 if (cif
->abi
!= FFI_LINUX_SOFT_FLOAT
)
664 flags
|= FLAG_RETURNS_FP
;
667 case FFI_TYPE_UINT64
:
668 case FFI_TYPE_SINT64
:
669 flags
|= FLAG_RETURNS_64BITS
;
672 case FFI_TYPE_STRUCT
:
673 if (cif
->abi
== FFI_SYSV
)
675 /* The final SYSV ABI says that structures smaller or equal 8 bytes
676 are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them
679 /* Treat structs with size <= 8 bytes. */
682 flags
|= FLAG_RETURNS_SMST
;
683 /* These structs are returned in r3. We pack the type and the
684 precalculated shift value (needed in the sysv.S) into flags.
685 The same applies for the structs returned in r3/r4. */
688 flags
|= FLAG_SYSV_SMST_R3
;
689 flags
|= 8 * (4 - size
) << 8;
692 /* These structs are returned in r3 and r4. See above. */
695 flags
|= FLAG_SYSV_SMST_R3
| FLAG_SYSV_SMST_R4
;
696 flags
|= 8 * (8 - size
) << 8;
701 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
705 flags
|= FLAG_RETVAL_REFERENCE
;
708 flags
|= FLAG_RETURNS_NOTHING
;
712 /* Returns 32-bit integer, or similar. Nothing to do here. */
716 if (cif
->abi
!= FFI_LINUX64
)
717 /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
718 first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
719 goes on the stack. Structures and long doubles (if not equivalent
720 to double) are passed as a pointer to a copy of the structure.
721 Stuff on the stack needs to keep proper alignment. */
722 for (ptr
= cif
->arg_types
, i
= cif
->nargs
; i
> 0; i
--, ptr
++)
724 switch ((*ptr
)->type
)
727 /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32. */
728 if (cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
731 /* floating singles are not 8-aligned on stack */
734 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
735 case FFI_TYPE_LONGDOUBLE
:
736 if (cif
->abi
!= FFI_LINUX
&& cif
->abi
!= FFI_LINUX_SOFT_FLOAT
)
738 if (cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
740 if (intarg_count
>= NUM_GPR_ARG_REGISTERS
- 3
741 || intarg_count
< NUM_GPR_ARG_REGISTERS
)
742 /* A long double in FFI_LINUX_SOFT_FLOAT can use only
743 a set of four consecutive gprs. If we have not enough,
744 we have to adjust the intarg_count value. */
745 intarg_count
+= NUM_GPR_ARG_REGISTERS
- intarg_count
;
753 case FFI_TYPE_DOUBLE
:
754 /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64. */
755 if (cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
756 goto soft_double_cif
;
758 /* If this FP arg is going on the stack, it must be
760 if (fparg_count
> NUM_FPR_ARG_REGISTERS
761 && intarg_count
>= NUM_GPR_ARG_REGISTERS
762 && intarg_count
% 2 != 0)
766 case FFI_TYPE_UINT64
:
767 case FFI_TYPE_SINT64
:
769 /* 'long long' arguments are passed as two words, but
770 either both words must fit in registers or both go
771 on the stack. If they go on the stack, they must
774 Also, only certain register pairs can be used for
775 passing long long int -- specifically (r3,r4), (r5,r6),
778 if (intarg_count
== NUM_GPR_ARG_REGISTERS
-1
779 || intarg_count
% 2 != 0)
784 case FFI_TYPE_STRUCT
:
785 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
788 /* We must allocate space for a copy of these to enforce
789 pass-by-value. Pad the space up to a multiple of 16
790 bytes (the maximum alignment required for anything under
792 struct_copy_size
+= ((*ptr
)->size
+ 15) & ~0xF;
793 /* Fall through (allocate space for the pointer). */
797 /* Everything else is passed as a 4-byte word in a GPR, either
798 the object itself or a pointer to it. */
804 for (ptr
= cif
->arg_types
, i
= cif
->nargs
; i
> 0; i
--, ptr
++)
806 switch ((*ptr
)->type
)
808 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
809 case FFI_TYPE_LONGDOUBLE
:
810 if (cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
820 case FFI_TYPE_DOUBLE
:
825 case FFI_TYPE_STRUCT
:
826 intarg_count
+= ((*ptr
)->size
+ 7) / 8;
830 /* Everything else is passed as a 8-byte word in a GPR, either
831 the object itself or a pointer to it. */
837 if (fparg_count
!= 0)
838 flags
|= FLAG_FP_ARGUMENTS
;
839 if (intarg_count
> 4)
840 flags
|= FLAG_4_GPR_ARGUMENTS
;
841 if (struct_copy_size
!= 0)
842 flags
|= FLAG_ARG_NEEDS_COPY
;
844 if (cif
->abi
!= FFI_LINUX64
)
846 /* Space for the FPR registers, if needed. */
847 if (fparg_count
!= 0)
848 bytes
+= NUM_FPR_ARG_REGISTERS
* sizeof (double);
851 if (intarg_count
> NUM_GPR_ARG_REGISTERS
)
852 bytes
+= (intarg_count
- NUM_GPR_ARG_REGISTERS
) * sizeof (int);
853 if (fparg_count
> NUM_FPR_ARG_REGISTERS
)
854 bytes
+= (fparg_count
- NUM_FPR_ARG_REGISTERS
) * sizeof (double);
858 /* Space for the FPR registers, if needed. */
859 if (fparg_count
!= 0)
860 bytes
+= NUM_FPR_ARG_REGISTERS64
* sizeof (double);
863 if (intarg_count
> NUM_GPR_ARG_REGISTERS64
)
864 bytes
+= (intarg_count
- NUM_GPR_ARG_REGISTERS64
) * sizeof (long);
867 /* The stack space allocated needs to be a multiple of 16 bytes. */
868 bytes
= (bytes
+ 15) & ~0xF;
870 /* Add in the space for the copied structures. */
871 bytes
+= struct_copy_size
;
879 extern void ffi_call_SYSV(extended_cif
*, unsigned, unsigned, unsigned *,
881 extern void FFI_HIDDEN
ffi_call_LINUX64(extended_cif
*, unsigned long,
882 unsigned long, unsigned long *,
886 ffi_call(ffi_cif
*cif
, void (*fn
)(void), void *rvalue
, void **avalue
)
891 ecif
.avalue
= avalue
;
893 /* If the return value is a struct and we don't have a return */
894 /* value address then we need to make one */
896 if ((rvalue
== NULL
) && (cif
->rtype
->type
== FFI_TYPE_STRUCT
))
898 ecif
.rvalue
= alloca(cif
->rtype
->size
);
901 ecif
.rvalue
= rvalue
;
910 case FFI_LINUX_SOFT_FLOAT
:
911 ffi_call_SYSV (&ecif
, -cif
->bytes
, cif
->flags
, ecif
.rvalue
, fn
);
915 ffi_call_LINUX64 (&ecif
, -(long) cif
->bytes
, cif
->flags
, ecif
.rvalue
, fn
);
926 #define MIN_CACHE_LINE_SIZE 8
929 flush_icache (char *wraddr
, char *xaddr
, int size
)
932 for (i
= 0; i
< size
; i
+= MIN_CACHE_LINE_SIZE
)
933 __asm__
volatile ("icbi 0,%0;" "dcbf 0,%1;"
934 : : "r" (xaddr
+ i
), "r" (wraddr
+ i
) : "memory");
935 __asm__
volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;"
936 : : "r"(xaddr
+ size
- 1), "r"(wraddr
+ size
- 1)
942 ffi_prep_closure_loc (ffi_closure
*closure
,
944 void (*fun
) (ffi_cif
*, void *, void **, void *),
949 void **tramp
= (void **) &closure
->tramp
[0];
951 FFI_ASSERT (cif
->abi
== FFI_LINUX64
);
952 /* Copy function address and TOC from ffi_closure_LINUX64. */
953 memcpy (tramp
, (char *) ffi_closure_LINUX64
, 16);
958 FFI_ASSERT (cif
->abi
== FFI_GCC_SYSV
|| cif
->abi
== FFI_SYSV
);
960 tramp
= (unsigned int *) &closure
->tramp
[0];
961 tramp
[0] = 0x7c0802a6; /* mflr r0 */
962 tramp
[1] = 0x4800000d; /* bl 10 <trampoline_initial+0x10> */
963 tramp
[4] = 0x7d6802a6; /* mflr r11 */
964 tramp
[5] = 0x7c0803a6; /* mtlr r0 */
965 tramp
[6] = 0x800b0000; /* lwz r0,0(r11) */
966 tramp
[7] = 0x816b0004; /* lwz r11,4(r11) */
967 tramp
[8] = 0x7c0903a6; /* mtctr r0 */
968 tramp
[9] = 0x4e800420; /* bctr */
969 *(void **) &tramp
[2] = (void *) ffi_closure_SYSV
; /* function */
970 *(void **) &tramp
[3] = codeloc
; /* context */
972 /* Flush the icache. */
973 flush_icache ((char *)tramp
, (char *)codeloc
, FFI_TRAMPOLINE_SIZE
);
978 closure
->user_data
= user_data
;
989 int ffi_closure_helper_SYSV (ffi_closure
*, void *, unsigned long *,
990 ffi_dblfl
*, unsigned long *);
992 /* Basically the trampoline invokes ffi_closure_SYSV, and on
993 * entry, r11 holds the address of the closure.
994 * After storing the registers that could possibly contain
995 * parameters to be passed into the stack frame and setting
996 * up space for a return value, ffi_closure_SYSV invokes the
997 * following helper function to do most of the work
1001 ffi_closure_helper_SYSV (ffi_closure
*closure
, void *rvalue
,
1002 unsigned long *pgr
, ffi_dblfl
*pfr
,
1005 /* rvalue is the pointer to space for return value in closure assembly */
1006 /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
1007 /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV */
1008 /* pst is the pointer to outgoing parameter stack in original caller */
1011 ffi_type
** arg_types
;
1013 long nf
; /* number of floating registers already used */
1014 long ng
; /* number of general registers already used */
1020 avalue
= alloca (cif
->nargs
* sizeof (void *));
1021 size
= cif
->rtype
->size
;
1026 /* Copy the caller's structure return value address so that the closure
1027 returns the data directly to the caller.
1028 For FFI_SYSV the result is passed in r3/r4 if the struct size is less
1029 or equal 8 bytes. */
1031 if ((cif
->rtype
->type
== FFI_TYPE_STRUCT
1032 && !((cif
->abi
== FFI_SYSV
) && (size
<= 8)))
1033 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1034 || (cif
->rtype
->type
== FFI_TYPE_LONGDOUBLE
1035 && cif
->abi
!= FFI_LINUX
&& cif
->abi
!= FFI_LINUX_SOFT_FLOAT
)
1039 rvalue
= (void *) *pgr
;
1046 arg_types
= cif
->arg_types
;
1048 /* Grab the addresses of the arguments from the stack frame. */
1051 switch (arg_types
[i
]->type
)
1053 case FFI_TYPE_SINT8
:
1054 case FFI_TYPE_UINT8
:
1055 /* there are 8 gpr registers used to pass values */
1058 avalue
[i
] = (char *) pgr
+ 3;
1064 avalue
[i
] = (char *) pst
+ 3;
1069 case FFI_TYPE_SINT16
:
1070 case FFI_TYPE_UINT16
:
1071 /* there are 8 gpr registers used to pass values */
1074 avalue
[i
] = (char *) pgr
+ 2;
1080 avalue
[i
] = (char *) pst
+ 2;
1085 case FFI_TYPE_SINT32
:
1086 case FFI_TYPE_UINT32
:
1087 case FFI_TYPE_POINTER
:
1089 /* there are 8 gpr registers used to pass values */
1103 case FFI_TYPE_STRUCT
:
1104 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1107 /* Structs are passed by reference. The address will appear in a
1108 gpr if it is one of the first 8 arguments. */
1111 avalue
[i
] = (void *) *pgr
;
1117 avalue
[i
] = (void *) *pst
;
1122 case FFI_TYPE_SINT64
:
1123 case FFI_TYPE_UINT64
:
1124 soft_double_closure
:
1125 /* passing long long ints are complex, they must
1126 * be passed in suitable register pairs such as
1127 * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
1128 * and if the entire pair aren't available then the outgoing
1129 * parameter stack is used for both but an alignment of 8
1130 * must will be kept. So we must either look in pgr
1131 * or pst to find the correct address for this type
1138 /* skip r4, r6, r8 as starting points */
1148 if (((long) pst
) & 4)
1155 case FFI_TYPE_FLOAT
:
1156 /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32. */
1157 if (cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
1158 goto soft_float_closure
;
1159 /* unfortunately float values are stored as doubles
1160 * in the ffi_closure_SYSV code (since we don't check
1161 * the type in that routine).
1164 /* there are 8 64bit floating point registers */
1169 pfr
->f
= (float) temp
;
1176 /* FIXME? here we are really changing the values
1177 * stored in the original calling routines outgoing
1178 * parameter stack. This is probably a really
1179 * naughty thing to do but...
1186 case FFI_TYPE_DOUBLE
:
1187 /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64. */
1188 if (cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
1189 goto soft_double_closure
;
1190 /* On the outgoing stack all values are aligned to 8 */
1191 /* there are 8 64bit floating point registers */
1201 if (((long) pst
) & 4)
1208 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1209 case FFI_TYPE_LONGDOUBLE
:
1210 if (cif
->abi
!= FFI_LINUX
&& cif
->abi
!= FFI_LINUX_SOFT_FLOAT
)
1212 if (cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
1213 { /* Test if for the whole long double, 4 gprs are available.
1214 otherwise the stuff ends up on the stack. */
1236 if (((long) pst
) & 4)
1253 (closure
->fun
) (cif
, rvalue
, avalue
, closure
->user_data
);
1255 /* Tell ffi_closure_SYSV how to perform return type promotions.
1256 Because the FFI_SYSV ABI returns the structures <= 8 bytes in r3/r4
1257 we have to tell ffi_closure_SYSV how to treat them. We combine the base
1258 type FFI_SYSV_TYPE_SMALL_STRUCT - 1 with the size of the struct.
1259 So a one byte struct gets the return type 16. Return type 1 to 15 are
1260 already used and we never have a struct with size zero. That is the reason
1261 for the subtraction of 1. See the comment in ffitarget.h about ordering.
1263 if (cif
->abi
== FFI_SYSV
&& cif
->rtype
->type
== FFI_TYPE_STRUCT
1265 return (FFI_SYSV_TYPE_SMALL_STRUCT
- 1) + size
;
1266 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1267 else if (cif
->rtype
->type
== FFI_TYPE_LONGDOUBLE
1268 && cif
->abi
!= FFI_LINUX
&& cif
->abi
!= FFI_LINUX_SOFT_FLOAT
)
1269 return FFI_TYPE_STRUCT
;
1271 /* With FFI_LINUX_SOFT_FLOAT floats and doubles are handled like UINT32
1272 respectivley UINT64. */
1273 if (cif
->abi
== FFI_LINUX_SOFT_FLOAT
)
1275 switch (cif
->rtype
->type
)
1277 case FFI_TYPE_FLOAT
:
1278 return FFI_TYPE_UINT32
;
1280 case FFI_TYPE_DOUBLE
:
1281 return FFI_TYPE_UINT64
;
1283 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1284 case FFI_TYPE_LONGDOUBLE
:
1285 return FFI_TYPE_UINT128
;
1289 return cif
->rtype
->type
;
1294 return cif
->rtype
->type
;
1298 int FFI_HIDDEN
ffi_closure_helper_LINUX64 (ffi_closure
*, void *,
1299 unsigned long *, ffi_dblfl
*);
1302 ffi_closure_helper_LINUX64 (ffi_closure
*closure
, void *rvalue
,
1303 unsigned long *pst
, ffi_dblfl
*pfr
)
1305 /* rvalue is the pointer to space for return value in closure assembly */
1306 /* pst is the pointer to parameter save area
1307 (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */
1308 /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */
1311 ffi_type
**arg_types
;
1314 ffi_dblfl
*end_pfr
= pfr
+ NUM_FPR_ARG_REGISTERS64
;
1317 avalue
= alloca (cif
->nargs
* sizeof (void *));
1319 /* Copy the caller's structure return value address so that the closure
1320 returns the data directly to the caller. */
1321 if (cif
->rtype
->type
== FFI_TYPE_STRUCT
)
1323 rvalue
= (void *) *pst
;
1329 arg_types
= cif
->arg_types
;
1331 /* Grab the addresses of the arguments from the stack frame. */
1334 switch (arg_types
[i
]->type
)
1336 case FFI_TYPE_SINT8
:
1337 case FFI_TYPE_UINT8
:
1338 avalue
[i
] = (char *) pst
+ 7;
1342 case FFI_TYPE_SINT16
:
1343 case FFI_TYPE_UINT16
:
1344 avalue
[i
] = (char *) pst
+ 6;
1348 case FFI_TYPE_SINT32
:
1349 case FFI_TYPE_UINT32
:
1350 avalue
[i
] = (char *) pst
+ 4;
1354 case FFI_TYPE_SINT64
:
1355 case FFI_TYPE_UINT64
:
1356 case FFI_TYPE_POINTER
:
1361 case FFI_TYPE_STRUCT
:
1362 /* Structures with size less than eight bytes are passed
1364 if (arg_types
[i
]->size
< 8)
1365 avalue
[i
] = (char *) pst
+ 8 - arg_types
[i
]->size
;
1368 pst
+= (arg_types
[i
]->size
+ 7) / 8;
1371 case FFI_TYPE_FLOAT
:
1372 /* unfortunately float values are stored as doubles
1373 * in the ffi_closure_LINUX64 code (since we don't check
1374 * the type in that routine).
1377 /* there are 13 64bit floating point registers */
1381 double temp
= pfr
->d
;
1382 pfr
->f
= (float) temp
;
1391 case FFI_TYPE_DOUBLE
:
1392 /* On the outgoing stack all values are aligned to 8 */
1393 /* there are 13 64bit floating point registers */
1405 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1406 case FFI_TYPE_LONGDOUBLE
:
1407 if (pfr
+ 1 < end_pfr
)
1416 /* Passed partly in f13 and partly on the stack.
1417 Move it all to the stack. */
1418 *pst
= *(unsigned long *) pfr
;
1435 (closure
->fun
) (cif
, rvalue
, avalue
, closure
->user_data
);
1437 /* Tell ffi_closure_LINUX64 how to perform return type promotions. */
1438 return cif
->rtype
->type
;