FSF GCC merge 02/23/03
[official-gcc.git] / libffi / src / powerpc / ffi.c
blobea1a14e8f65dc1a32c2146b5f54181c23114940f
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 ----------------------------------------------------------------------- */
28 #include <ffi.h>
29 #include <ffi_common.h>
31 #include <stdlib.h>
32 #include <stdio.h>
34 extern void ffi_closure_SYSV(void);
36 enum {
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. */
49 enum {
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
81 /*@-exportheader@*/
82 void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
83 /*@=exportheader@*/
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;
94 int intarg_count = 0;
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;
99 int fparg_count = 0;
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)
104 ? (char *)fpr_base
105 : (char *)gpr_base);
107 /* 'next_arg' grows up as we put parameters in it. */
108 unsigned *next_arg = stack + 2;
110 int i;
111 ffi_type **ptr;
112 double double_tmp;
113 void **p_argv;
114 size_t struct_copy_size;
115 unsigned gprvalue;
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;
128 intarg_count++;
131 /* Now for the arguments. */
132 p_argv = ecif->avalue;
133 for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
134 i > 0;
135 i--, ptr++, p_argv++)
137 switch ((*ptr)->type)
139 case FFI_TYPE_FLOAT:
140 double_tmp = *(float *)*p_argv;
141 if (fparg_count >= NUM_FPR_ARG_REGISTERS)
143 *(float *)next_arg = (float)double_tmp;
144 next_arg += 1;
146 else
147 *fpr_base++ = double_tmp;
148 fparg_count++;
149 FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
150 break;
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)
159 intarg_count++;
160 next_arg++;
162 *(double *)next_arg = double_tmp;
163 next_arg += 2;
165 else
166 *fpr_base++ = double_tmp;
167 fparg_count++;
168 FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
169 break;
171 case FFI_TYPE_UINT64:
172 case FFI_TYPE_SINT64:
173 if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
174 intarg_count++;
175 if (intarg_count >= NUM_GPR_ARG_REGISTERS)
177 if (intarg_count%2 != 0)
179 intarg_count++;
180 next_arg++;
182 *(long long *)next_arg = *(long long *)*p_argv;
183 next_arg += 2;
185 else
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)
196 intarg_count ++;
197 gpr_base++;
199 *(long long *)gpr_base = *(long long *)*p_argv;
200 gpr_base += 2;
202 intarg_count += 2;
203 break;
205 case FFI_TYPE_STRUCT:
206 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
207 case FFI_TYPE_LONGDOUBLE:
208 #endif
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);
217 goto putgpr;
219 case FFI_TYPE_UINT8:
220 gprvalue = *(unsigned char *)*p_argv;
221 goto putgpr;
222 case FFI_TYPE_SINT8:
223 gprvalue = *(signed char *)*p_argv;
224 goto putgpr;
225 case FFI_TYPE_UINT16:
226 gprvalue = *(unsigned short *)*p_argv;
227 goto putgpr;
228 case FFI_TYPE_SINT16:
229 gprvalue = *(signed short *)*p_argv;
230 goto putgpr;
232 case FFI_TYPE_INT:
233 case FFI_TYPE_UINT32:
234 case FFI_TYPE_SINT32:
235 case FFI_TYPE_POINTER:
236 gprvalue = *(unsigned *)*p_argv;
237 putgpr:
238 if (intarg_count >= NUM_GPR_ARG_REGISTERS)
239 *next_arg++ = gprvalue;
240 else
241 *gpr_base++ = gprvalue;
242 intarg_count++;
243 break;
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. */
259 int i;
260 ffi_type **ptr;
261 unsigned bytes;
262 int fparg_count = 0, intarg_count = 0;
263 unsigned flags = 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
279 in gpr3 and gpr4;
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;
287 /* Fall through. */
288 case FFI_TYPE_FLOAT:
289 flags |= FLAG_RETURNS_FP;
290 break;
292 case FFI_TYPE_UINT64:
293 case FFI_TYPE_SINT64:
294 flags |= FLAG_RETURNS_64BITS;
295 break;
297 case FFI_TYPE_STRUCT:
298 if (cif->abi != FFI_GCC_SYSV)
299 if (cif->rtype->size <= 4)
300 break;
301 else if (cif->rtype->size <= 8)
303 flags |= FLAG_RETURNS_64BITS;
304 break;
306 /* else fall through. */
307 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
308 case FFI_TYPE_LONGDOUBLE:
309 #endif
310 intarg_count++;
311 flags |= FLAG_RETVAL_REFERENCE;
312 /* Fall through. */
313 case FFI_TYPE_VOID:
314 flags |= FLAG_RETURNS_NOTHING;
315 break;
317 default:
318 /* Returns 32-bit integer, or similar. Nothing to do here. */
319 break;
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)
331 case FFI_TYPE_FLOAT:
332 fparg_count++;
333 /* floating singles are not 8-aligned on stack */
334 break;
336 case FFI_TYPE_DOUBLE:
337 fparg_count++;
338 /* If this FP arg is going on the stack, it must be
339 8-byte-aligned. */
340 if (fparg_count > NUM_FPR_ARG_REGISTERS
341 && intarg_count%2 != 0)
342 intarg_count++;
343 break;
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)
353 intarg_count++;
354 intarg_count += 2;
355 break;
357 case FFI_TYPE_STRUCT:
358 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
359 case FFI_TYPE_LONGDOUBLE:
360 #endif
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
364 the SYSV ABI). */
365 struct_copy_size += ((*ptr)->size + 15) & ~0xF;
366 /* Fall through (allocate space for the pointer). */
368 default:
369 /* Everything else is passed as a 4-byte word in a GPR, either
370 the object itself or a pointer to it. */
371 intarg_count++;
372 break;
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);
387 /* Stack space. */
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;
399 cif->flags = flags;
400 cif->bytes = bytes;
402 return FFI_OK;
405 /*@-declundef@*/
406 /*@-exportheader@*/
407 extern void ffi_call_SYSV(/*@out@*/ extended_cif *,
408 unsigned, unsigned,
409 /*@out@*/ unsigned *,
410 void (*fn)());
411 /*@=declundef@*/
412 /*@=exportheader@*/
414 void ffi_call(/*@dependent@*/ ffi_cif *cif,
415 void (*fn)(),
416 /*@out@*/ void *rvalue,
417 /*@dependent@*/ void **avalue)
419 extended_cif ecif;
421 ecif.cif = cif;
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))
430 /*@-sysunrecog@*/
431 ecif.rvalue = alloca(cif->rtype->size);
432 /*@=sysunrecog@*/
434 else
435 ecif.rvalue = rvalue;
438 switch (cif->abi)
440 case FFI_SYSV:
441 case FFI_GCC_SYSV:
442 /*@-usedef@*/
443 ffi_call_SYSV(&ecif, -cif->bytes,
444 cif->flags, ecif.rvalue, fn);
445 /*@=usedef@*/
446 break;
447 default:
448 FFI_ASSERT(0);
449 break;
454 static void flush_icache(char *, int);
456 ffi_status
457 ffi_prep_closure (ffi_closure* closure,
458 ffi_cif* cif,
459 void (*fun)(ffi_cif*, void*, void**, void*),
460 void *user_data)
462 unsigned int *tramp;
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 */
478 closure->cif = cif;
479 closure->fun = fun;
480 closure->user_data = user_data;
482 /* Flush the icache. */
483 flush_icache(&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
485 return FFI_OK;
489 #define MIN_CACHE_LINE_SIZE 8
491 static void flush_icache(char * addr1, int size)
493 int i;
494 char * addr;
495 for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) {
496 addr = addr1 + i;
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,
518 unsigned long * pst)
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 */
525 void ** avalue;
526 ffi_type ** arg_types;
527 long i, avn;
528 long nf; /* number of floating registers already used */
529 long ng; /* number of general registers already used */
530 ffi_cif * cif;
531 double temp;
533 cif = closure->cif;
534 avalue = alloca(cif->nargs * sizeof(void *));
536 nf = 0;
537 ng = 0;
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)
543 rvalue = *pgr;
544 ng++;
545 pgr++;
548 i = 0;
549 avn = cif->nargs;
550 arg_types = cif->arg_types;
552 /* Grab the addresses of the arguments from the stack frame. */
553 while (i < avn)
555 switch (arg_types[i]->type)
557 case FFI_TYPE_SINT8:
558 case FFI_TYPE_UINT8:
559 /* there are 8 gpr registers used to pass values */
560 if (ng < 8) {
561 avalue[i] = (((char *)pgr)+3);
562 ng++;
563 pgr++;
564 } else {
565 avalue[i] = (((char *)pst)+3);
566 pst++;
568 break;
570 case FFI_TYPE_SINT16:
571 case FFI_TYPE_UINT16:
572 /* there are 8 gpr registers used to pass values */
573 if (ng < 8) {
574 avalue[i] = (((char *)pgr)+2);
575 ng++;
576 pgr++;
577 } else {
578 avalue[i] = (((char *)pst)+2);
579 pst++;
581 break;
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 */
588 if (ng < 8) {
589 avalue[i] = pgr;
590 ng++;
591 pgr++;
592 } else {
593 avalue[i] = pst;
594 pst++;
596 break;
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
607 * of parameter.
609 if (ng < 7) {
610 if (ng & 0x01) {
611 /* skip r4, r6, r8 as starting points */
612 ng++;
613 pgr++;
615 avalue[i] = pgr;
616 ng+=2;
617 pgr+=2;
618 } else {
619 if (((long)pst) & 4) pst++;
620 avalue[i] = pst;
621 pst+=2;
623 break;
625 case FFI_TYPE_FLOAT:
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 */
633 if (nf < 8) {
634 temp = *(double*)pfr;
635 *(float*)pfr = (float)temp;
636 avalue[i] = pfr;
637 nf++;
638 pfr+=2;
639 } else {
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...
645 avalue[i] = pst;
646 nf++;
647 pst+=1;
649 break;
651 case FFI_TYPE_DOUBLE:
652 /* On the outgoing stack all values are aligned to 8 */
653 /* there are 8 64bit floating point registers */
655 if (nf < 8) {
656 avalue[i] = pfr;
657 nf++;
658 pfr+=2;
659 } else {
660 if (((long)pst) & 4) pst++;
661 avalue[i] = pst;
662 nf++;
663 pst+=2;
665 break;
667 default:
668 FFI_ASSERT(0);
671 i++;
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;