source: trunk/gcc/libffi/src/powerpc/ffi_darwin.c

Last change on this file was 1392, checked in by bird, 21 years ago

This commit was generated by cvs2svn to compensate for changes in r1391,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 21.7 KB
Line 
1/* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 1998 Geoffrey Keating
3
4 PowerPC Foreign Function Interface
5
6 Darwin ABI support (c) 2001 John Hornkvist
7 AIX ABI support (c) 2002 Free Software Foundation, Inc.
8
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:
16
17 The above copyright notice and this permission notice shall be included
18 in all copies or substantial portions of the Software.
19
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>
30
31#include <stdlib.h>
32
33extern void ffi_closure_ASM(void);
34
35enum {
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),
40
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)
45};
46
47/* About the DARWIN ABI. */
48enum {
49 NUM_GPR_ARG_REGISTERS = 8,
50 NUM_FPR_ARG_REGISTERS = 13
51};
52enum { ASM_NEEDS_REGISTERS = 4 };
53
54/* ffi_prep_args is called by the assembly routine once stack space
55 has been allocated for the function's arguments.
56
57 The stack layout we want looks like this:
58
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
77
78 */
79
80/*@-exportheader@*/
81void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
82/*@=exportheader@*/
83{
84 const unsigned bytes = ecif->cif->bytes;
85 const unsigned flags = ecif->cif->flags;
86
87 /* 'stacktop' points at the previous backchain pointer. */
88 unsigned *const stacktop = stack + (ecif->cif->bytes / sizeof(unsigned));
89
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;
94
95
96 /* 'next_arg' grows up as we put parameters in it. */
97 unsigned *next_arg = stack + 6; // 6 reserved posistions.
98
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;
105
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);
110
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;
116
117 /* Now for the arguments. */
118 for (;
119 i > 0;
120 i--, ptr++, p_argv++)
121 {
122 switch ((*ptr)->type)
123 {
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;
147
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;
165
166 case FFI_TYPE_STRUCT:
167
168#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
169 case FFI_TYPE_LONGDOUBLE:
170#endif
171
172 memcpy((char*)next_arg, (char *)*p_argv, (*ptr)->size);
173 next_arg+=(((((*ptr)->size) + 3) & ~0x3)/4);
174 break;
175
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;
186 }
187 }
188
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);
195}
196
197/* Perform machine dependent cif processing */
198ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
199{
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;
207
208 /* All the machine-independent calculation of cif->bytes will be wrong.
209 Redo the calculation for DARWIN. */
210
211 /* Space for the frame pointer, callee's LR, CR, etc, and for
212 the asm's temp regs. */
213
214 bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(long);
215
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)
227 {
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;
238
239 case FFI_TYPE_UINT64:
240 case FFI_TYPE_SINT64:
241 flags |= FLAG_RETURNS_64BITS;
242 break;
243
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;
252
253 default:
254 /* Returns 32-bit integer, or similar. Nothing to do here. */
255 break;
256 }
257
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++)
264 {
265 switch ((*ptr)->type)
266 {
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;
276
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;
288
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;
295
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;
301 }
302 }
303
304 if (fparg_count != 0)
305 flags |= FLAG_FP_ARGUMENTS;
306 if (struct_copy_size != 0)
307 flags |= FLAG_ARG_NEEDS_COPY;
308
309 /* Space for the FPR registers, if needed. */
310 if (fparg_count != 0)
311 bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
312
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);
318
319 /* The stack space allocated needs to be a multiple of 16 bytes. */
320 bytes = (bytes + 15) & ~0xF;
321
322 cif->flags = flags;
323 cif->bytes = bytes;
324
325 return FFI_OK;
326}
327
328/*@-declundef@*/
329/*@-exportheader@*/
330extern void ffi_call_AIX(/*@out@*/ extended_cif *,
331 unsigned, unsigned,
332 /*@out@*/ unsigned *,
333 void (*fn)(),
334 void (*fn2)());
335extern void ffi_call_DARWIN(/*@out@*/ extended_cif *,
336 unsigned, unsigned,
337 /*@out@*/ unsigned *,
338 void (*fn)(),
339 void (*fn2)());
340/*@=declundef@*/
341/*@=exportheader@*/
342
343void ffi_call(/*@dependent@*/ ffi_cif *cif,
344 void (*fn)(),
345 /*@out@*/ void *rvalue,
346 /*@dependent@*/ void **avalue)
347{
348 extended_cif ecif;
349
350 ecif.cif = cif;
351 ecif.avalue = avalue;
352
353 /* If the return value is a struct and we don't have a return */
354 /* value address then we need to make one */
355
356 if ((rvalue == NULL) &&
357 (cif->rtype->type == FFI_TYPE_STRUCT))
358 {
359 /*@-sysunrecog@*/
360 ecif.rvalue = alloca(cif->rtype->size);
361 /*@=sysunrecog@*/
362 }
363 else
364 ecif.rvalue = rvalue;
365
366 switch (cif->abi)
367 {
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;
383 }
384}
385
386static void flush_icache(char *);
387static void flush_range(char *, int);
388
389/* The layout of a function descriptor. A C function pointer really */
390/* points to one of these. */
391
392typedef struct aix_fd_struct {
393 void *code_pointer;
394 void *toc;
395} aix_fd;
396
397/* here I'd like to add the stack frame layout we use in darwin_closure.S
398 * and aix_clsoure.S
399 *
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 |
425SP 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
448
449*/
450ffi_status
451ffi_prep_closure (ffi_closure* closure,
452 ffi_cif* cif,
453 void (*fun)(ffi_cif*, void*, void**, void*),
454 void *user_data)
455{
456 unsigned int *tramp;
457 struct ffi_aix_trampoline_struct *tramp_aix;
458 aix_fd *fd;
459
460 switch (cif->abi)
461 {
462 case FFI_DARWIN:
463
464 FFI_ASSERT (cif->abi == FFI_DARWIN);
465
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 */
477
478 closure->cif = cif;
479 closure->fun = fun;
480 closure->user_data = user_data;
481
482 /* Flush the icache. Only necessary on Darwin */
483 flush_range(&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
484
485 break;
486
487 case FFI_AIX:
488
489 tramp_aix = (struct ffi_aix_trampoline_struct *) (closure->tramp);
490 fd = (aix_fd *)(void *)ffi_closure_ASM;
491
492 FFI_ASSERT (cif->abi == FFI_AIX);
493
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;
500
501 default:
502
503 FFI_ASSERT(0);
504 break;
505 }
506 return FFI_OK;
507}
508
509static void
510flush_icache(char *addr)
511{
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
521}
522
523static void
524flush_range(char * addr1, int size)
525{
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);
531}
532
533int ffi_closure_helper_DARWIN (ffi_closure*, void*, unsigned long*,
534 unsigned long*, unsigned long*);
535
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
542 */
543
544int
545ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
546 unsigned long * pgr, unsigned long * pfr,
547 unsigned long * pst)
548{
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 */
553
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;
561
562 cif = closure->cif;
563 avalue = alloca(cif->nargs * sizeof(void *));
564
565 nf = 0;
566 ng = 0;
567
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)
571 {
572 rvalue = (void *)pgr;
573 ng++;
574 pgr++;
575 }
576
577 i = 0;
578 avn = cif->nargs;
579 arg_types = cif->arg_types;
580
581 /* Grab the addresses of the arguments from the stack frame. */
582 while (i < avn)
583 {
584 switch (arg_types[i]->type)
585 {
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++;
596 }
597 break;
598
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++;
609 }
610 break;
611
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++;
624 }
625 break;
626
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.
633 */
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;
646 }
647 break;
648
649 case FFI_TYPE_FLOAT:
650 /* a float value consumes a GPR
651 *
652 * there are 13 64bit floating point registers
653 */
654
655 if ((ng > 7) && (nf < 13)) {
656 pst++;
657 }
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++;
666
667 } else {
668 avalue[i] = pst;
669 nf++;
670 pst++;
671 }
672 break;
673
674 case FFI_TYPE_DOUBLE:
675 /* a double value consumes two GPRs
676 *
677 * there are 13 64bit floating point registers
678 */
679
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 */
684 }
685 if (nf < 13) {
686 avalue[i] = pfr;
687 nf++;
688 pfr+=2;
689 ng+=2;
690 pgr+=2;
691
692 } else {
693 avalue[i] = pst;
694 nf++;
695 pst+=2;
696 }
697 break;
698
699 default:
700 FFI_ASSERT(0);
701
702 }
703
704 i++;
705 }
706
707 (closure->fun) (cif, rvalue, avalue, closure->user_data);
708
709 /* Tell ffi_closure_ASM to perform return type promotions. */
710 return cif->rtype->type;
711
712}
Note: See TracBrowser for help on using the repository browser.