1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 1998 Geoffrey Keating
4 PowerPC Foreign Function Interface
6 $Id: ffi.c,v 1.1.1.1 1998/11/29 16:48:16 green Exp $
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>
34 extern void ffi_closure_SYSV(void);
37 /* The assembly depends on these exact flags. */
38 FLAG_RETURNS_NOTHING
= 1 << (31-30), /* These go in cr7 */
39 FLAG_RETURNS_FP
= 1 << (31-29),
40 FLAG_RETURNS_64BITS
= 1 << (31-28),
42 FLAG_ARG_NEEDS_COPY
= 1 << (31- 7),
43 FLAG_FP_ARGUMENTS
= 1 << (31- 6), /* cr1.eq; specified by ABI */
44 FLAG_4_GPR_ARGUMENTS
= 1 << (31- 5),
45 FLAG_RETVAL_REFERENCE
= 1 << (31- 4)
48 /* About the SYSV ABI. */
50 NUM_GPR_ARG_REGISTERS
= 8,
51 NUM_FPR_ARG_REGISTERS
= 8
53 enum { ASM_NEEDS_REGISTERS
= 4 };
55 /* ffi_prep_args is called by the assembly routine once stack space
56 has been allocated for the function's arguments.
58 The stack layout we want looks like this:
60 | Return address from ffi_call_SYSV 4bytes | higher addresses
61 |--------------------------------------------|
62 | Previous backchain pointer 4 | stack pointer here
63 |--------------------------------------------|<+ <<< on entry to
64 | Saved r28-r31 4*4 | | ffi_call_SYSV
65 |--------------------------------------------| |
66 | GPR registers r3-r10 8*4 | | ffi_call_SYSV
67 |--------------------------------------------| |
68 | FPR registers f1-f8 (optional) 8*8 | |
69 |--------------------------------------------| | stack |
70 | Space for copied structures | | grows |
71 |--------------------------------------------| | down V
72 | Parameters that didn't fit in registers | |
73 |--------------------------------------------| | lower addresses
74 | Space for callee's LR 4 | |
75 |--------------------------------------------| | stack pointer here
76 | Current backchain pointer 4 |-/ during
77 |--------------------------------------------| <<< ffi_call_SYSV
82 void ffi_prep_args(extended_cif
*ecif
, unsigned *const stack
)
85 const unsigned bytes
= ecif
->cif
->bytes
;
86 const unsigned flags
= ecif
->cif
->flags
;
88 /* 'stacktop' points at the previous backchain pointer. */
89 unsigned *const stacktop
= stack
+ (ecif
->cif
->bytes
/ sizeof(unsigned));
91 /* 'gpr_base' points at the space for gpr3, and grows upwards as
92 we use GPR registers. */
93 unsigned *gpr_base
= stacktop
- ASM_NEEDS_REGISTERS
- NUM_GPR_ARG_REGISTERS
;
96 /* 'fpr_base' points at the space for fpr1, and grows upwards as
97 we use FPR registers. */
98 double *fpr_base
= (double *)gpr_base
- NUM_FPR_ARG_REGISTERS
;
101 /* 'copy_space' grows down as we put structures in it. It should
102 stay 16-byte aligned. */
103 char *copy_space
= ((flags
& FLAG_FP_ARGUMENTS
)
107 /* 'next_arg' grows up as we put parameters in it. */
108 unsigned *next_arg
= stack
+ 2;
114 size_t struct_copy_size
;
117 /* Check that everything starts aligned properly. */
118 FFI_ASSERT(((unsigned)(char *)stack
& 0xF) == 0);
119 FFI_ASSERT(((unsigned)(char *)copy_space
& 0xF) == 0);
120 FFI_ASSERT(((unsigned)(char *)stacktop
& 0xF) == 0);
121 FFI_ASSERT((bytes
& 0xF) == 0);
122 FFI_ASSERT(copy_space
>= (char *)next_arg
);
124 /* Deal with return values that are actually pass-by-reference. */
125 if (flags
& FLAG_RETVAL_REFERENCE
)
127 *gpr_base
++ = (unsigned)(char *)ecif
->rvalue
;
131 /* Now for the arguments. */
132 p_argv
= ecif
->avalue
;
133 for (ptr
= ecif
->cif
->arg_types
, i
= ecif
->cif
->nargs
;
135 i
--, ptr
++, p_argv
++)
137 switch ((*ptr
)->type
)
140 double_tmp
= *(float *)*p_argv
;
141 if (fparg_count
>= NUM_FPR_ARG_REGISTERS
)
143 *(float *)next_arg
= (float)double_tmp
;
147 *fpr_base
++ = double_tmp
;
149 FFI_ASSERT(flags
& FLAG_FP_ARGUMENTS
);
152 case FFI_TYPE_DOUBLE
:
153 double_tmp
= *(double *)*p_argv
;
155 if (fparg_count
>= NUM_FPR_ARG_REGISTERS
)
157 if (intarg_count
%2 != 0)
162 *(double *)next_arg
= double_tmp
;
166 *fpr_base
++ = double_tmp
;
168 FFI_ASSERT(flags
& FLAG_FP_ARGUMENTS
);
171 case FFI_TYPE_UINT64
:
172 case FFI_TYPE_SINT64
:
173 if (intarg_count
== NUM_GPR_ARG_REGISTERS
-1)
175 if (intarg_count
>= NUM_GPR_ARG_REGISTERS
)
177 if (intarg_count
%2 != 0)
182 *(long long *)next_arg
= *(long long *)*p_argv
;
187 /* whoops: abi states only certain register pairs
188 * can be used for passing long long int
189 * specifically (r3,r4), (r5,r6), (r7,r8),
190 * (r9,r10) and if next arg is long long but
191 * not correct starting register of pair then skip
192 * until the proper starting register
194 if (intarg_count
%2 != 0)
199 *(long long *)gpr_base
= *(long long *)*p_argv
;
205 case FFI_TYPE_STRUCT
:
206 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
207 case FFI_TYPE_LONGDOUBLE
:
209 struct_copy_size
= ((*ptr
)->size
+ 15) & ~0xF;
210 copy_space
-= struct_copy_size
;
211 memcpy(copy_space
, (char *)*p_argv
, (*ptr
)->size
);
213 gprvalue
= (unsigned)copy_space
;
215 FFI_ASSERT(copy_space
> (char *)next_arg
);
216 FFI_ASSERT(flags
& FLAG_ARG_NEEDS_COPY
);
220 gprvalue
= *(unsigned char *)*p_argv
;
223 gprvalue
= *(signed char *)*p_argv
;
225 case FFI_TYPE_UINT16
:
226 gprvalue
= *(unsigned short *)*p_argv
;
228 case FFI_TYPE_SINT16
:
229 gprvalue
= *(signed short *)*p_argv
;
233 case FFI_TYPE_UINT32
:
234 case FFI_TYPE_SINT32
:
235 case FFI_TYPE_POINTER
:
236 gprvalue
= *(unsigned *)*p_argv
;
238 if (intarg_count
>= NUM_GPR_ARG_REGISTERS
)
239 *next_arg
++ = gprvalue
;
241 *gpr_base
++ = gprvalue
;
247 /* Check that we didn't overrun the stack... */
248 FFI_ASSERT(copy_space
>= (char *)next_arg
);
249 FFI_ASSERT(gpr_base
<= stacktop
- ASM_NEEDS_REGISTERS
);
250 FFI_ASSERT((unsigned *)fpr_base
251 <= stacktop
- ASM_NEEDS_REGISTERS
- NUM_GPR_ARG_REGISTERS
);
252 FFI_ASSERT(flags
& FLAG_4_GPR_ARGUMENTS
|| intarg_count
<= 4);
255 /* Perform machine dependent cif processing */
256 ffi_status
ffi_prep_cif_machdep(ffi_cif
*cif
)
258 /* All this is for the SYSV ABI. */
262 int fparg_count
= 0, intarg_count
= 0;
264 unsigned struct_copy_size
= 0;
266 /* All the machine-independent calculation of cif->bytes will be wrong.
267 Redo the calculation for SYSV. */
269 /* Space for the frame pointer, callee's LR, and the asm's temp regs. */
270 bytes
= (2 + ASM_NEEDS_REGISTERS
) * sizeof(int);
272 /* Space for the GPR registers. */
273 bytes
+= NUM_GPR_ARG_REGISTERS
* sizeof(int);
275 /* Return value handling. The rules are as follows:
276 - 32-bit (or less) integer values are returned in gpr3;
277 - Structures of size <= 4 bytes also returned in gpr3;
278 - 64-bit integer values and structures between 5 and 8 bytes are returned
280 - Single/double FP values are returned in fpr1;
281 - Larger structures and long double (if not equivalent to double) values
282 are allocated space and a pointer is passed as the first argument. */
283 switch (cif
->rtype
->type
)
285 case FFI_TYPE_DOUBLE
:
286 flags
|= FLAG_RETURNS_64BITS
;
289 flags
|= FLAG_RETURNS_FP
;
292 case FFI_TYPE_UINT64
:
293 case FFI_TYPE_SINT64
:
294 flags
|= FLAG_RETURNS_64BITS
;
297 case FFI_TYPE_STRUCT
:
298 if (cif
->abi
!= FFI_GCC_SYSV
)
299 if (cif
->rtype
->size
<= 4)
301 else if (cif
->rtype
->size
<= 8)
303 flags
|= FLAG_RETURNS_64BITS
;
306 /* else fall through. */
307 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
308 case FFI_TYPE_LONGDOUBLE
:
311 flags
|= FLAG_RETVAL_REFERENCE
;
314 flags
|= FLAG_RETURNS_NOTHING
;
318 /* Returns 32-bit integer, or similar. Nothing to do here. */
322 /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
323 first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
324 goes on the stack. Structures and long doubles (if not equivalent
325 to double) are passed as a pointer to a copy of the structure.
326 Stuff on the stack needs to keep proper alignment. */
327 for (ptr
= cif
->arg_types
, i
= cif
->nargs
; i
> 0; i
--, ptr
++)
329 switch ((*ptr
)->type
)
333 /* floating singles are not 8-aligned on stack */
336 case FFI_TYPE_DOUBLE
:
338 /* If this FP arg is going on the stack, it must be
340 if (fparg_count
> NUM_FPR_ARG_REGISTERS
341 && intarg_count
%2 != 0)
345 case FFI_TYPE_UINT64
:
346 case FFI_TYPE_SINT64
:
347 /* 'long long' arguments are passed as two words, but
348 either both words must fit in registers or both go
349 on the stack. If they go on the stack, they must
350 be 8-byte-aligned. */
351 if (intarg_count
== NUM_GPR_ARG_REGISTERS
-1
352 || intarg_count
>= NUM_GPR_ARG_REGISTERS
&& intarg_count
%2 != 0)
357 case FFI_TYPE_STRUCT
:
358 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
359 case FFI_TYPE_LONGDOUBLE
:
361 /* We must allocate space for a copy of these to enforce
362 pass-by-value. Pad the space up to a multiple of 16
363 bytes (the maximum alignment required for anything under
365 struct_copy_size
+= ((*ptr
)->size
+ 15) & ~0xF;
366 /* Fall through (allocate space for the pointer). */
369 /* Everything else is passed as a 4-byte word in a GPR, either
370 the object itself or a pointer to it. */
376 if (fparg_count
!= 0)
377 flags
|= FLAG_FP_ARGUMENTS
;
378 if (intarg_count
> 4)
379 flags
|= FLAG_4_GPR_ARGUMENTS
;
380 if (struct_copy_size
!= 0)
381 flags
|= FLAG_ARG_NEEDS_COPY
;
383 /* Space for the FPR registers, if needed. */
384 if (fparg_count
!= 0)
385 bytes
+= NUM_FPR_ARG_REGISTERS
* sizeof(double);
388 if (intarg_count
> NUM_GPR_ARG_REGISTERS
)
389 bytes
+= (intarg_count
- NUM_GPR_ARG_REGISTERS
) * sizeof(int);
390 if (fparg_count
> NUM_FPR_ARG_REGISTERS
)
391 bytes
+= (fparg_count
- NUM_FPR_ARG_REGISTERS
) * sizeof(double);
393 /* The stack space allocated needs to be a multiple of 16 bytes. */
394 bytes
= (bytes
+ 15) & ~0xF;
396 /* Add in the space for the copied structures. */
397 bytes
+= struct_copy_size
;
407 extern void ffi_call_SYSV(/*@out@*/ extended_cif
*,
409 /*@out@*/ unsigned *,
414 void ffi_call(/*@dependent@*/ ffi_cif
*cif
,
416 /*@out@*/ void *rvalue
,
417 /*@dependent@*/ void **avalue
)
422 ecif
.avalue
= avalue
;
424 /* If the return value is a struct and we don't have a return */
425 /* value address then we need to make one */
427 if ((rvalue
== NULL
) &&
428 (cif
->rtype
->type
== FFI_TYPE_STRUCT
))
431 ecif
.rvalue
= alloca(cif
->rtype
->size
);
435 ecif
.rvalue
= rvalue
;
443 ffi_call_SYSV(&ecif
, -cif
->bytes
,
444 cif
->flags
, ecif
.rvalue
, fn
);
454 static void flush_icache(char *, int);
457 ffi_prep_closure (ffi_closure
* closure
,
459 void (*fun
)(ffi_cif
*, void*, void**, void*),
464 FFI_ASSERT (cif
->abi
== FFI_GCC_SYSV
);
466 tramp
= (unsigned int *) &closure
->tramp
[0];
467 tramp
[0] = 0x7c0802a6; /* mflr r0 */
468 tramp
[1] = 0x4800000d; /* bl 10 <trampoline_initial+0x10> */
469 tramp
[4] = 0x7d6802a6; /* mflr r11 */
470 tramp
[5] = 0x7c0803a6; /* mtlr r0 */
471 tramp
[6] = 0x800b0000; /* lwz r0,0(r11) */
472 tramp
[7] = 0x816b0004; /* lwz r11,4(r11) */
473 tramp
[8] = 0x7c0903a6; /* mtctr r0 */
474 tramp
[9] = 0x4e800420; /* bctr */
475 *(void **) &tramp
[2] = (void *)ffi_closure_SYSV
; /* function */
476 *(void **) &tramp
[3] = (void *)closure
; /* context */
480 closure
->user_data
= user_data
;
482 /* Flush the icache. */
483 flush_icache(&closure
->tramp
[0],FFI_TRAMPOLINE_SIZE
);
489 #define MIN_CACHE_LINE_SIZE 8
491 static void flush_icache(char * addr1
, int size
)
495 for (i
= 0; i
< size
; i
+= MIN_CACHE_LINE_SIZE
) {
497 __asm__
volatile ("icbi 0,%0;" "dcbf 0,%0;" : : "r"(addr
) : "memory");
499 addr
= addr1
+ size
- 1;
500 __asm__
volatile ("icbi 0,%0;" "dcbf 0,%0;" "sync;" "isync;" : : "r"(addr
) : "memory");
504 int ffi_closure_helper_SYSV (ffi_closure
*, void*, unsigned long*,
505 unsigned long*, unsigned long*);
507 /* Basically the trampoline invokes ffi_closure_SYSV, and on
508 * entry, r11 holds the address of the closure.
509 * After storing the registers that could possibly contain
510 * parameters to be passed into the stack frame and setting
511 * up space for a return value, ffi_closure_SYSV invokes the
512 * following helper function to do most of the work
516 ffi_closure_helper_SYSV (ffi_closure
* closure
, void * rvalue
,
517 unsigned long * pgr
, unsigned long * pfr
,
520 /* rvalue is the pointer to space for return value in closure assembly */
521 /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
522 /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV */
523 /* pst is the pointer to outgoing parameter stack in original caller */
526 ffi_type
** arg_types
;
528 long nf
; /* number of floating registers already used */
529 long ng
; /* number of general registers already used */
534 avalue
= alloca(cif
->nargs
* sizeof(void *));
539 /* Copy the caller's structure return value address so that the closure
540 returns the data directly to the caller. */
541 if (cif
->rtype
->type
== FFI_TYPE_STRUCT
)
550 arg_types
= cif
->arg_types
;
552 /* Grab the addresses of the arguments from the stack frame. */
555 switch (arg_types
[i
]->type
)
559 /* there are 8 gpr registers used to pass values */
561 avalue
[i
] = (((char *)pgr
)+3);
565 avalue
[i
] = (((char *)pst
)+3);
570 case FFI_TYPE_SINT16
:
571 case FFI_TYPE_UINT16
:
572 /* there are 8 gpr registers used to pass values */
574 avalue
[i
] = (((char *)pgr
)+2);
578 avalue
[i
] = (((char *)pst
)+2);
583 case FFI_TYPE_SINT32
:
584 case FFI_TYPE_UINT32
:
585 case FFI_TYPE_POINTER
:
586 case FFI_TYPE_STRUCT
:
587 /* there are 8 gpr registers used to pass values */
598 case FFI_TYPE_SINT64
:
599 case FFI_TYPE_UINT64
:
600 /* passing long long ints are complex, they must
601 * be passed in suitable register pairs such as
602 * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
603 * and if the entire pair aren't available then the outgoing
604 * parameter stack is used for both but an alignment of 8
605 * must will be kept. So we must either look in pgr
606 * or pst to find the correct address for this type
611 /* skip r4, r6, r8 as starting points */
619 if (((long)pst
) & 4) pst
++;
626 /* unfortunately float values are stored as doubles
627 * in the ffi_closure_SYSV code (since we don't check
628 * the type in that routine).
631 /* there are 8 64bit floating point registers */
634 temp
= *(double*)pfr
;
635 *(float*)pfr
= (float)temp
;
640 /* FIXME? here we are really changing the values
641 * stored in the original calling routines outgoing
642 * parameter stack. This is probably a really
643 * naughty thing to do but...
651 case FFI_TYPE_DOUBLE
:
652 /* On the outgoing stack all values are aligned to 8 */
653 /* there are 8 64bit floating point registers */
660 if (((long)pst
) & 4) pst
++;
675 (closure
->fun
) (cif
, rvalue
, avalue
, closure
->user_data
);
677 /* Tell ffi_closure_osf how to perform return type promotions. */
678 return cif
->rtype
->type
;