FSF GCC merge 02/23/03
[official-gcc.git] / libffi / src / powerpc / ffi_darwin.c
blob3f705275c5f37207d7808f15b44c6918218dd600
1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 1998 Geoffrey Keating
4 PowerPC Foreign Function Interface
6 Darwin ABI support (c) 2001 John Hornkvist
7 AIX ABI support (c) 2002 Free Software Foundation, Inc.
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 ``Software''), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice shall be included
18 in all copies or substantial portions of the Software.
20 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26 OTHER DEALINGS IN THE SOFTWARE.
27 ----------------------------------------------------------------------- */
28 #include <ffi.h>
29 #include <ffi_common.h>
31 #include <stdlib.h>
33 extern void ffi_closure_ASM(void);
35 enum {
36 /* The assembly depends on these exact flags. */
37 FLAG_RETURNS_NOTHING = 1 << (31-30), /* These go in cr7 */
38 FLAG_RETURNS_FP = 1 << (31-29),
39 FLAG_RETURNS_64BITS = 1 << (31-28),
41 FLAG_ARG_NEEDS_COPY = 1 << (31- 7),
42 FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */
43 FLAG_4_GPR_ARGUMENTS = 1 << (31- 5),
44 FLAG_RETVAL_REFERENCE = 1 << (31- 4)
47 /* About the DARWIN ABI. */
48 enum {
49 NUM_GPR_ARG_REGISTERS = 8,
50 NUM_FPR_ARG_REGISTERS = 13
52 enum { ASM_NEEDS_REGISTERS = 4 };
54 /* ffi_prep_args is called by the assembly routine once stack space
55 has been allocated for the function's arguments.
57 The stack layout we want looks like this:
59 | Return address from ffi_call_DARWIN | higher addresses
60 |--------------------------------------------|
61 | Previous backchain pointer 4 | stack pointer here
62 |--------------------------------------------|<+ <<< on entry to
63 | Saved r28-r31 4*4 | | ffi_call_DARWIN
64 |--------------------------------------------| |
65 | Parameters (at least 8*4=32) | |
66 |--------------------------------------------| |
67 | Space for GPR2 4 | |
68 |--------------------------------------------| | stack |
69 | Reserved 2*4 | | grows |
70 |--------------------------------------------| | down V
71 | Space for callee's LR 4 | |
72 |--------------------------------------------| | lower addresses
73 | Saved CR 4 | |
74 |--------------------------------------------| | stack pointer here
75 | Current backchain pointer 4 |-/ during
76 |--------------------------------------------| <<< ffi_call_DARWIN
80 /*@-exportheader@*/
81 void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
82 /*@=exportheader@*/
84 const unsigned bytes = ecif->cif->bytes;
85 const unsigned flags = ecif->cif->flags;
87 /* 'stacktop' points at the previous backchain pointer. */
88 unsigned *const stacktop = stack + (ecif->cif->bytes / sizeof(unsigned));
90 /* 'fpr_base' points at the space for fpr1, and grows upwards as
91 we use FPR registers. */
92 double *fpr_base = (double*) (stacktop - ASM_NEEDS_REGISTERS) - NUM_FPR_ARG_REGISTERS;
93 int fparg_count = 0;
96 /* 'next_arg' grows up as we put parameters in it. */
97 unsigned *next_arg = stack + 6; // 6 reserved posistions.
99 int i=ecif->cif->nargs;
100 double double_tmp;
101 float float_tmp;
102 void **p_argv = ecif->avalue;
103 unsigned gprvalue;
104 ffi_type** ptr = ecif->cif->arg_types;
106 /* Check that everything starts aligned properly. */
107 FFI_ASSERT(((unsigned)(char *)stack & 0xF) == 0);
108 FFI_ASSERT(((unsigned)(char *)stacktop & 0xF) == 0);
109 FFI_ASSERT((bytes & 0xF) == 0);
111 /* Deal with return values that are actually pass-by-reference. */
112 // Rule:
113 // Return values are referenced by r3, so r4 is the first parameter.
114 if (flags & FLAG_RETVAL_REFERENCE)
115 *next_arg++ = (unsigned)(char *)ecif->rvalue;
117 /* Now for the arguments. */
118 for (;
119 i > 0;
120 i--, ptr++, p_argv++)
122 switch ((*ptr)->type)
124 /* If a floating-point parameter appears before all of the general-
125 purpose registers are filled, the corresponding GPRs that match
126 the size of the floating-point parameter are skipped. */
127 case FFI_TYPE_FLOAT:
128 double_tmp = *(float *)*p_argv;
129 if (fparg_count >= NUM_FPR_ARG_REGISTERS)
130 *(double *)next_arg = double_tmp;
131 else
132 *fpr_base++ = double_tmp;
133 next_arg++;
134 fparg_count++;
135 FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
136 break;
137 case FFI_TYPE_DOUBLE:
138 double_tmp = *(double *)*p_argv;
139 if (fparg_count >= NUM_FPR_ARG_REGISTERS)
140 *(double *)next_arg = double_tmp;
141 else
142 *fpr_base++ = double_tmp;
143 next_arg += 2;
144 fparg_count++;
145 FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
146 break;
148 case FFI_TYPE_UINT64:
149 case FFI_TYPE_SINT64:
150 *(long long *)next_arg = *(long long *)*p_argv;
151 next_arg+=2;
152 break;
153 case FFI_TYPE_UINT8:
154 gprvalue = *(unsigned char *)*p_argv;
155 goto putgpr;
156 case FFI_TYPE_SINT8:
157 gprvalue = *(signed char *)*p_argv;
158 goto putgpr;
159 case FFI_TYPE_UINT16:
160 gprvalue = *(unsigned short *)*p_argv;
161 goto putgpr;
162 case FFI_TYPE_SINT16:
163 gprvalue = *(signed short *)*p_argv;
164 goto putgpr;
166 case FFI_TYPE_STRUCT:
168 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
169 case FFI_TYPE_LONGDOUBLE:
170 #endif
172 memcpy((char*)next_arg, (char *)*p_argv, (*ptr)->size);
173 next_arg+=(((((*ptr)->size) + 3) & ~0x3)/4);
174 break;
176 case FFI_TYPE_INT:
177 case FFI_TYPE_UINT32:
178 case FFI_TYPE_SINT32:
179 case FFI_TYPE_POINTER:
180 gprvalue = *(unsigned *)*p_argv;
181 putgpr:
182 *next_arg++ = gprvalue;
183 break;
184 default:
185 break;
189 /* Check that we didn't overrun the stack... */
190 //FFI_ASSERT(copy_space >= (char *)next_arg);
191 //FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
192 //FFI_ASSERT((unsigned *)fpr_base
193 // <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
194 //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
197 /* Perform machine dependent cif processing */
198 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
200 /* All this is for the DARWIN ABI. */
201 int i;
202 ffi_type **ptr;
203 unsigned bytes;
204 int fparg_count = 0, intarg_count = 0;
205 unsigned flags = 0;
206 unsigned struct_copy_size = 0;
208 /* All the machine-independent calculation of cif->bytes will be wrong.
209 Redo the calculation for DARWIN. */
211 /* Space for the frame pointer, callee's LR, CR, etc, and for
212 the asm's temp regs. */
214 bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(long);
216 /* Return value handling. The rules are as follows:
217 - 32-bit (or less) integer values are returned in gpr3;
218 - Structures of size <= 4 bytes also returned in gpr3;
219 - 64-bit integer values and structures between 5 and 8 bytes are returned
220 in gpr3 and gpr4;
221 - Single/double FP values are returned in fpr1;
222 - Long double FP (if not equivalent to double) values are returned in
223 fpr1 and fpr2;
224 - Larger structures values are allocated space and a pointer is passed
225 as the first argument. */
226 switch (cif->rtype->type)
228 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
229 case FFI_TYPE_LONGDOUBLE:
230 #endif
231 /* Fall through. */
232 case FFI_TYPE_DOUBLE:
233 flags |= FLAG_RETURNS_64BITS;
234 /* Fall through. */
235 case FFI_TYPE_FLOAT:
236 flags |= FLAG_RETURNS_FP;
237 break;
239 case FFI_TYPE_UINT64:
240 case FFI_TYPE_SINT64:
241 flags |= FLAG_RETURNS_64BITS;
242 break;
244 case FFI_TYPE_STRUCT:
245 flags |= FLAG_RETVAL_REFERENCE;
246 flags |= FLAG_RETURNS_NOTHING;
247 intarg_count++;
248 break;
249 case FFI_TYPE_VOID:
250 flags |= FLAG_RETURNS_NOTHING;
251 break;
253 default:
254 /* Returns 32-bit integer, or similar. Nothing to do here. */
255 break;
258 /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
259 first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
260 goes on the stack. Structures and long doubles (if not equivalent
261 to double) are passed as a pointer to a copy of the structure.
262 Stuff on the stack needs to keep proper alignment. */
263 for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
265 switch ((*ptr)->type)
267 case FFI_TYPE_FLOAT:
268 case FFI_TYPE_DOUBLE:
269 fparg_count++;
270 /* If this FP arg is going on the stack, it must be
271 8-byte-aligned. */
272 if (fparg_count > NUM_FPR_ARG_REGISTERS
273 && intarg_count%2 != 0)
274 intarg_count++;
275 break;
277 case FFI_TYPE_UINT64:
278 case FFI_TYPE_SINT64:
279 /* 'long long' arguments are passed as two words, but
280 either both words must fit in registers or both go
281 on the stack. If they go on the stack, they must
282 be 8-byte-aligned. */
283 if (intarg_count == NUM_GPR_ARG_REGISTERS-1
284 || intarg_count >= NUM_GPR_ARG_REGISTERS && intarg_count%2 != 0)
285 intarg_count++;
286 intarg_count += 2;
287 break;
289 case FFI_TYPE_STRUCT:
290 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
291 case FFI_TYPE_LONGDOUBLE:
292 #endif
293 intarg_count+=(((*ptr)->size + 3) & ~0x3)/4;
294 break;
296 default:
297 /* Everything else is passed as a 4-byte word in a GPR, either
298 the object itself or a pointer to it. */
299 intarg_count++;
300 break;
304 if (fparg_count != 0)
305 flags |= FLAG_FP_ARGUMENTS;
306 if (struct_copy_size != 0)
307 flags |= FLAG_ARG_NEEDS_COPY;
309 /* Space for the FPR registers, if needed. */
310 if (fparg_count != 0)
311 bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
313 /* Stack space. */
314 if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)
315 bytes += (intarg_count + 2 * fparg_count) * sizeof(long);
316 else
317 bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
319 /* The stack space allocated needs to be a multiple of 16 bytes. */
320 bytes = (bytes + 15) & ~0xF;
322 cif->flags = flags;
323 cif->bytes = bytes;
325 return FFI_OK;
328 /*@-declundef@*/
329 /*@-exportheader@*/
330 extern void ffi_call_AIX(/*@out@*/ extended_cif *,
331 unsigned, unsigned,
332 /*@out@*/ unsigned *,
333 void (*fn)(),
334 void (*fn2)());
335 extern void ffi_call_DARWIN(/*@out@*/ extended_cif *,
336 unsigned, unsigned,
337 /*@out@*/ unsigned *,
338 void (*fn)(),
339 void (*fn2)());
340 /*@=declundef@*/
341 /*@=exportheader@*/
343 void ffi_call(/*@dependent@*/ ffi_cif *cif,
344 void (*fn)(),
345 /*@out@*/ void *rvalue,
346 /*@dependent@*/ void **avalue)
348 extended_cif ecif;
350 ecif.cif = cif;
351 ecif.avalue = avalue;
353 /* If the return value is a struct and we don't have a return */
354 /* value address then we need to make one */
356 if ((rvalue == NULL) &&
357 (cif->rtype->type == FFI_TYPE_STRUCT))
359 /*@-sysunrecog@*/
360 ecif.rvalue = alloca(cif->rtype->size);
361 /*@=sysunrecog@*/
363 else
364 ecif.rvalue = rvalue;
366 switch (cif->abi)
368 case FFI_AIX:
369 /*@-usedef@*/
370 ffi_call_AIX(&ecif, -cif->bytes,
371 cif->flags, ecif.rvalue, fn, ffi_prep_args);
372 /*@=usedef@*/
373 break;
374 case FFI_DARWIN:
375 /*@-usedef@*/
376 ffi_call_DARWIN(&ecif, -cif->bytes,
377 cif->flags, ecif.rvalue, fn, ffi_prep_args);
378 /*@=usedef@*/
379 break;
380 default:
381 FFI_ASSERT(0);
382 break;
386 static void flush_icache(char *);
387 static void flush_range(char *, int);
389 /* The layout of a function descriptor. A C function pointer really */
390 /* points to one of these. */
392 typedef struct aix_fd_struct {
393 void *code_pointer;
394 void *toc;
395 } aix_fd;
397 /* here I'd like to add the stack frame layout we use in darwin_closure.S
398 * and aix_clsoure.S
400 /* SP previous -> +---------------------------------------+ <--- child frame
401 | back chain to caller 4 |
402 +---------------------------------------+ 4
403 | saved CR 4 |
404 +---------------------------------------+ 8
405 | saved LR 4 |
406 +---------------------------------------+ 12
407 | reserved for compilers 4 |
408 +---------------------------------------+ 16
409 | reserved for binders 4 |
410 +---------------------------------------+ 20
411 | saved TOC pointer 4 |
412 +---------------------------------------+ 24
413 | always reserved 8*4=32 (previous GPRs)|
414 | according to the linkage convention |
415 | from AIX |
416 +---------------------------------------+ 56
417 | our FPR area 13*8=104 |
418 | f1 |
419 | . |
420 | f13 |
421 +---------------------------------------+ 160
422 | result area 8 |
423 +---------------------------------------+ 168
424 | alignement to the next multiple of 16 |
425 SP current --> +---------------------------------------+ 176 <- parent frame
426 | back chain to caller 4 |
427 +---------------------------------------+ 180
428 | saved CR 4 |
429 +---------------------------------------+ 184
430 | saved LR 4 |
431 +---------------------------------------+ 188
432 | reserved for compilers 4 |
433 +---------------------------------------+ 192
434 | reserved for binders 4 |
435 +---------------------------------------+ 196
436 | saved TOC pointer 4 |
437 +---------------------------------------+ 200
438 | always reserved 8*4=32 we store our |
439 | GPRs here |
440 | r3 |
441 | . |
442 | r10 |
443 +---------------------------------------+ 232
444 | PST area, overflow part |
445 +---------------------------------------+ xxx
446 | ???? |
447 +---------------------------------------+ xxx
450 ffi_status
451 ffi_prep_closure (ffi_closure* closure,
452 ffi_cif* cif,
453 void (*fun)(ffi_cif*, void*, void**, void*),
454 void *user_data)
456 unsigned int *tramp;
457 struct ffi_aix_trampoline_struct *tramp_aix;
458 aix_fd *fd;
460 switch (cif->abi)
462 case FFI_DARWIN:
464 FFI_ASSERT (cif->abi == FFI_DARWIN);
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] = 0x818b0000; /* lwz r12,0(r11) /* function address */
471 tramp[6] = 0x7c0803a6; /* mtlr r0 */
472 tramp[7] = 0x7d8903a6; /* mtctr r12 */
473 tramp[8] = 0x816b0004; /* lwz r11,4(r11) /* static chain */
474 tramp[9] = 0x4e800420; /* bctr */
475 *(void **) &tramp[2] = (void *)ffi_closure_ASM; /* 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. Only necessary on Darwin */
483 flush_range(&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
485 break;
487 case FFI_AIX:
489 tramp_aix = (struct ffi_aix_trampoline_struct *) (closure->tramp);
490 fd = (aix_fd *)(void *)ffi_closure_ASM;
492 FFI_ASSERT (cif->abi == FFI_AIX);
494 tramp_aix->code_pointer = fd->code_pointer;
495 tramp_aix->toc = fd->toc;
496 tramp_aix->static_chain = closure;
497 closure->cif = cif;
498 closure->fun = fun;
499 closure->user_data = user_data;
501 default:
503 FFI_ASSERT(0);
504 break;
506 return FFI_OK;
509 static void
510 flush_icache(char *addr)
512 #ifndef _AIX
513 __asm__ volatile (
514 "dcbf 0,%0;"
515 "sync;"
516 "icbi 0,%0;"
517 "sync;"
518 "isync;"
519 : : "r"(addr) : "memory");
520 #endif
523 static void
524 flush_range(char * addr1, int size)
526 #define MIN_LINE_SIZE 32
527 int i;
528 for (i = 0; i < size; i += MIN_LINE_SIZE)
529 flush_icache(addr1+i);
530 flush_icache(addr1+size-1);
533 int ffi_closure_helper_DARWIN (ffi_closure*, void*, unsigned long*,
534 unsigned long*, unsigned long*);
536 /* Basically the trampoline invokes ffi_closure_ASM, and on
537 * entry, r11 holds the address of the closure.
538 * After storing the registers that could possibly contain
539 * parameters to be passed into the stack frame and setting
540 * up space for a return value, ffi_closure_ASM invokes the
541 * following helper function to do most of the work
545 ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
546 unsigned long * pgr, unsigned long * pfr,
547 unsigned long * pst)
549 /* rvalue is the pointer to space for return value in closure assembly */
550 /* pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM */
551 /* pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM */
552 /* pst is the pointer to outgoing parameter stack in original caller */
554 void ** avalue;
555 ffi_type ** arg_types;
556 long i, avn;
557 long nf; /* number of floating registers already used */
558 long ng; /* number of general registers already used */
559 ffi_cif * cif;
560 double temp;
562 cif = closure->cif;
563 avalue = alloca(cif->nargs * sizeof(void *));
565 nf = 0;
566 ng = 0;
568 /* Copy the caller's structure return value address so that the closure
569 returns the data directly to the caller. */
570 if (cif->rtype->type == FFI_TYPE_STRUCT)
572 rvalue = (void *)pgr;
573 ng++;
574 pgr++;
577 i = 0;
578 avn = cif->nargs;
579 arg_types = cif->arg_types;
581 /* Grab the addresses of the arguments from the stack frame. */
582 while (i < avn)
584 switch (arg_types[i]->type)
586 case FFI_TYPE_SINT8:
587 case FFI_TYPE_UINT8:
588 /* there are 8 gpr registers used to pass values */
589 if (ng < 8) {
590 avalue[i] = (((char *)pgr)+3);
591 ng++;
592 pgr++;
593 } else {
594 avalue[i] = (((char *)pst)+3);
595 pst++;
597 break;
599 case FFI_TYPE_SINT16:
600 case FFI_TYPE_UINT16:
601 /* there are 8 gpr registers used to pass values */
602 if (ng < 8) {
603 avalue[i] = (((char *)pgr)+2);
604 ng++;
605 pgr++;
606 } else {
607 avalue[i] = (((char *)pst)+2);
608 pst++;
610 break;
612 case FFI_TYPE_SINT32:
613 case FFI_TYPE_UINT32:
614 case FFI_TYPE_POINTER:
615 case FFI_TYPE_STRUCT:
616 /* there are 8 gpr registers used to pass values */
617 if (ng < 8) {
618 avalue[i] = pgr;
619 ng++;
620 pgr++;
621 } else {
622 avalue[i] = pst;
623 pst++;
625 break;
627 case FFI_TYPE_SINT64:
628 case FFI_TYPE_UINT64:
629 /* long long ints are passed in two gpr's if available or in
630 * the pst, one place is a bit odd, when a long long passes
631 * the boundary between gpr and pst area we have to increment
632 * the pst by one.
634 if (ng < 7) {
635 avalue[i] = pgr;
636 ng+=2;
637 pgr+=2;
638 } else if (ng == 7) {
639 avalue[i] = pgr;
640 ng++;
641 pgr++;
642 pst++;
643 } else {
644 avalue[i] = pst;
645 pst+=2;
647 break;
649 case FFI_TYPE_FLOAT:
650 /* a float value consumes a GPR
652 * there are 13 64bit floating point registers
655 if ((ng > 7) && (nf < 13)) {
656 pst++;
658 if (nf < 13) {
659 temp = *(double*)pfr;
660 *(float*)pfr = (float)temp;
661 avalue[i] = pfr;
662 nf++;
663 pfr+=2;
664 ng++;
665 pgr++;
667 } else {
668 avalue[i] = pst;
669 nf++;
670 pst++;
672 break;
674 case FFI_TYPE_DOUBLE:
675 /* a double value consumes two GPRs
677 * there are 13 64bit floating point registers
680 if ((ng == 7) && (nf < 13)) {
681 pst++; /* if only one gpr is left the double steals it */
682 } else if ((ng > 7) && (nf < 13)) {
683 pst+=2; /* a double consumes two GPRs in Darwin/AIX */
685 if (nf < 13) {
686 avalue[i] = pfr;
687 nf++;
688 pfr+=2;
689 ng+=2;
690 pgr+=2;
692 } else {
693 avalue[i] = pst;
694 nf++;
695 pst+=2;
697 break;
699 default:
700 FFI_ASSERT(0);
704 i++;
707 (closure->fun) (cif, rvalue, avalue, closure->user_data);
709 /* Tell ffi_closure_ASM to perform return type promotions. */
710 return cif->rtype->type;