OSDN Git Service

fee5243db71f86fe22149a1526c0f7738e9e7182
[pf3gnuchains/gcc-fork.git] / libffi / src / powerpc / ffi_darwin.c
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
33 extern void ffi_closure_ASM(void);
34
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),
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.  */
48 enum {
49   NUM_GPR_ARG_REGISTERS = 8,
50   NUM_FPR_ARG_REGISTERS = 13
51 };
52 enum { 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@*/
81 void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
82 /*@=exportheader@*/
83 {
84   const unsigned flags = ecif->cif->flags;
85
86   /* 'stacktop' points at the previous backchain pointer.  */
87   unsigned *const stacktop = stack + (ecif->cif->bytes / sizeof(unsigned));
88
89   /* 'fpr_base' points at the space for fpr1, and grows upwards as
90      we use FPR registers.  */
91   double *fpr_base = (double*) (stacktop - ASM_NEEDS_REGISTERS) - NUM_FPR_ARG_REGISTERS;
92   int fparg_count = 0;
93
94
95   /* 'next_arg' grows up as we put parameters in it.  */
96   unsigned *next_arg = stack + 6; // 6 reserved posistions. 
97
98   int i = ecif->cif->nargs;
99   double double_tmp;
100   void **p_argv = ecif->avalue;
101   unsigned gprvalue;
102   ffi_type** ptr = ecif->cif->arg_types;
103   char *dest_cpy;
104   unsigned size_al = 0;
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           dest_cpy = (char *) next_arg;
172
173           /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
174              SI 4 bytes) are aligned as if they were those modes.
175              Structures with 3 byte in size are padded upwards.  */
176           size_al = (*ptr)->size;
177           /* If the first member of the struct is a double, then align
178              the struct to double-word.
179              Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3.  */
180           if ((*ptr)->elements[0]->type == 3)
181             size_al = ALIGN((*ptr)->size, 8);
182           if (size_al < 3 && ecif->cif->abi == FFI_DARWIN)
183             dest_cpy += 4 - size_al;
184
185           memcpy((char *)dest_cpy, (char *)*p_argv, size_al);
186           next_arg += (size_al + 3) / 4;
187           break;
188
189         case FFI_TYPE_INT:
190         case FFI_TYPE_UINT32:
191         case FFI_TYPE_SINT32:
192         case FFI_TYPE_POINTER:
193           gprvalue = *(unsigned *)*p_argv;
194         putgpr:
195           *next_arg++ = gprvalue;
196           break;
197         default:
198           break;
199         }
200     }
201
202   /* Check that we didn't overrun the stack...  */
203   //FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
204   //FFI_ASSERT((unsigned *)fpr_base
205   //         <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
206   //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
207 }
208
209 /* Perform machine dependent cif processing */
210 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
211 {
212   /* All this is for the DARWIN ABI.  */
213   int i;
214   ffi_type **ptr;
215   unsigned bytes;
216   int fparg_count = 0, intarg_count = 0;
217   unsigned flags = 0;
218   unsigned size_al = 0;
219
220   /* All the machine-independent calculation of cif->bytes will be wrong.
221      Redo the calculation for DARWIN.  */
222
223   /* Space for the frame pointer, callee's LR, CR, etc, and for 
224      the asm's temp regs.  */
225
226   bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(long);
227
228   /* Return value handling.  The rules are as follows:
229      - 32-bit (or less) integer values are returned in gpr3;
230      - Structures of size <= 4 bytes also returned in gpr3;
231      - 64-bit integer values and structures between 5 and 8 bytes are returned
232        in gpr3 and gpr4;
233      - Single/double FP values are returned in fpr1;
234      - Long double FP (if not equivalent to double) values are returned in
235        fpr1 and fpr2;
236      - Larger structures values are allocated space and a pointer is passed
237        as the first argument.  */
238   switch (cif->rtype->type)
239     {
240 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
241     case FFI_TYPE_LONGDOUBLE:
242 #endif
243       /* Fall through.  */
244     case FFI_TYPE_DOUBLE:
245       flags |= FLAG_RETURNS_64BITS;
246       /* Fall through.  */
247     case FFI_TYPE_FLOAT:
248       flags |= FLAG_RETURNS_FP;
249       break;
250
251     case FFI_TYPE_UINT64:
252     case FFI_TYPE_SINT64:
253       flags |= FLAG_RETURNS_64BITS;
254       break;
255
256     case FFI_TYPE_STRUCT:
257       flags |= FLAG_RETVAL_REFERENCE;
258       flags |= FLAG_RETURNS_NOTHING;
259       intarg_count++;
260       break;
261     case FFI_TYPE_VOID:
262       flags |= FLAG_RETURNS_NOTHING;
263       break;
264
265     default:
266       /* Returns 32-bit integer, or similar.  Nothing to do here.  */
267       break;
268     }
269
270   /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
271      first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
272      goes on the stack.  Structures and long doubles (if not equivalent
273      to double) are passed as a pointer to a copy of the structure.
274      Stuff on the stack needs to keep proper alignment.  */
275   for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
276     {
277       switch ((*ptr)->type)
278         {
279         case FFI_TYPE_FLOAT:
280         case FFI_TYPE_DOUBLE:
281           fparg_count++;
282           /* If this FP arg is going on the stack, it must be
283              8-byte-aligned.  */
284           if (fparg_count > NUM_FPR_ARG_REGISTERS
285               && intarg_count%2 != 0)
286             intarg_count++;
287           break;
288
289         case FFI_TYPE_UINT64:
290         case FFI_TYPE_SINT64:
291           /* 'long long' arguments are passed as two words, but
292              either both words must fit in registers or both go
293              on the stack.  If they go on the stack, they must
294              be 8-byte-aligned.  */
295           if (intarg_count == NUM_GPR_ARG_REGISTERS-1
296               || (intarg_count >= NUM_GPR_ARG_REGISTERS && intarg_count%2 != 0))
297             intarg_count++;
298           intarg_count += 2;
299           break;
300
301         case FFI_TYPE_STRUCT:
302 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
303         case FFI_TYPE_LONGDOUBLE:
304 #endif
305           size_al = (*ptr)->size;
306           /* If the first member of the struct is a double, then align
307              the struct to double-word.
308              Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3.  */
309           if ((*ptr)->elements[0]->type == 3)
310             size_al = ALIGN((*ptr)->size, 8);
311           intarg_count += (size_al + 3) / 4;
312           break;
313
314         default:
315           /* Everything else is passed as a 4-byte word in a GPR, either
316              the object itself or a pointer to it.  */
317           intarg_count++;
318           break;
319         }
320     }
321
322   if (fparg_count != 0)
323     flags |= FLAG_FP_ARGUMENTS;
324
325   /* Space for the FPR registers, if needed.  */
326   if (fparg_count != 0)
327     bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
328
329   /* Stack space.  */
330   if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)
331     bytes += (intarg_count + 2 * fparg_count) * sizeof(long);
332   else
333     bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
334
335   /* The stack space allocated needs to be a multiple of 16 bytes.  */
336   bytes = (bytes + 15) & ~0xF;
337
338   cif->flags = flags;
339   cif->bytes = bytes;
340
341   return FFI_OK;
342 }
343
344 /*@-declundef@*/
345 /*@-exportheader@*/
346 extern void ffi_call_AIX(/*@out@*/ extended_cif *, 
347                          unsigned, unsigned, 
348                          /*@out@*/ unsigned *, 
349                          void (*fn)(),
350                          void (*fn2)());
351 extern void ffi_call_DARWIN(/*@out@*/ extended_cif *, 
352                             unsigned, unsigned, 
353                             /*@out@*/ unsigned *, 
354                             void (*fn)(),
355                             void (*fn2)());
356 /*@=declundef@*/
357 /*@=exportheader@*/
358
359 void ffi_call(/*@dependent@*/ ffi_cif *cif, 
360               void (*fn)(), 
361               /*@out@*/ void *rvalue, 
362               /*@dependent@*/ void **avalue)
363 {
364   extended_cif ecif;
365
366   ecif.cif = cif;
367   ecif.avalue = avalue;
368
369   /* If the return value is a struct and we don't have a return */
370   /* value address then we need to make one                     */
371
372   if ((rvalue == NULL) && 
373       (cif->rtype->type == FFI_TYPE_STRUCT))
374     {
375       /*@-sysunrecog@*/
376       ecif.rvalue = alloca(cif->rtype->size);
377       /*@=sysunrecog@*/
378     }
379   else
380     ecif.rvalue = rvalue;
381
382   switch (cif->abi) 
383     {
384     case FFI_AIX:
385       /*@-usedef@*/
386       ffi_call_AIX(&ecif, -cif->bytes, 
387                    cif->flags, ecif.rvalue, fn, ffi_prep_args);
388       /*@=usedef@*/
389       break;
390     case FFI_DARWIN:
391       /*@-usedef@*/
392       ffi_call_DARWIN(&ecif, -cif->bytes, 
393                       cif->flags, ecif.rvalue, fn, ffi_prep_args);
394       /*@=usedef@*/
395       break;
396     default:
397       FFI_ASSERT(0);
398       break;
399     }
400 }
401
402 static void flush_icache(char *);
403 static void flush_range(char *, int);
404
405 /* The layout of a function descriptor.  A C function pointer really    */
406 /* points to one of these.                                              */
407
408 typedef struct aix_fd_struct {
409     void *code_pointer;
410     void *toc;
411 } aix_fd;
412
413 /* here I'd like to add the stack frame layout we use in darwin_closure.S
414  * and aix_clsoure.S
415  *
416  * SP previous -> +---------------------------------------+ <--- child frame
417                   | back chain to caller 4                | 
418                   +---------------------------------------+ 4
419                   | saved CR 4                            | 
420                   +---------------------------------------+ 8 
421                   | saved LR 4                            | 
422                   +---------------------------------------+ 12
423                   | reserved for compilers 4              | 
424                   +---------------------------------------+ 16
425                   | reserved for binders 4                | 
426                   +---------------------------------------+ 20
427                   | saved TOC pointer 4                   | 
428                   +---------------------------------------+ 24
429                   | always reserved 8*4=32 (previous GPRs)| 
430                   | according to the linkage convention   |
431                   | from AIX                              |
432                   +---------------------------------------+ 56
433                   | our FPR area 13*8=104                 |
434                   | f1                                    |
435                   | .                                     |
436                   | f13                                   | 
437                   +---------------------------------------+ 160
438                   | result area 8                         |
439                   +---------------------------------------+ 168
440                   | alignement to the next multiple of 16 |
441 SP current -->    +---------------------------------------+ 176 <- parent frame
442                   | back chain to caller 4                | 
443                   +---------------------------------------+ 180
444                   | saved CR 4                            | 
445                   +---------------------------------------+ 184
446                   | saved LR 4                            | 
447                   +---------------------------------------+ 188
448                   | reserved for compilers 4              | 
449                   +---------------------------------------+ 192
450                   | reserved for binders 4                | 
451                   +---------------------------------------+ 196
452                   | saved TOC pointer 4                   | 
453                   +---------------------------------------+ 200
454                   | always reserved 8*4=32  we store our  |
455                   | GPRs here                             |
456                   | r3                                    |
457                   | .                                     |
458                   | r10                                   |
459                   +---------------------------------------+ 232
460                   | overflow part                         | 
461                   +---------------------------------------+ xxx
462                   | ????                                  | 
463                   +---------------------------------------+ xxx
464
465 */
466 ffi_status
467 ffi_prep_closure (ffi_closure* closure,    
468                   ffi_cif* cif,
469                   void (*fun)(ffi_cif*, void*, void**, void*),
470                   void *user_data)
471 {
472   unsigned int *tramp;
473   struct ffi_aix_trampoline_struct *tramp_aix;
474   aix_fd *fd;
475
476   switch (cif->abi)
477     {  
478     case FFI_DARWIN:
479
480       FFI_ASSERT (cif->abi == FFI_DARWIN);
481
482       tramp = (unsigned int *) &closure->tramp[0];
483       tramp[0] = 0x7c0802a6;  /*   mflr    r0  */
484       tramp[1] = 0x429f000d;  /*   bcl-    20,4*cr7+so,0x10  */
485       tramp[4] = 0x7d6802a6;  /*   mflr    r11  */
486       tramp[5] = 0x818b0000;  /*   lwz     r12,0(r11) function address  */
487       tramp[6] = 0x7c0803a6;  /*   mtlr    r0   */
488       tramp[7] = 0x7d8903a6;  /*   mtctr   r12  */
489       tramp[8] = 0x816b0004;  /*   lwz     r11,4(r11) static chain  */
490       tramp[9] = 0x4e800420;  /*   bctr  */
491       tramp[2] = (unsigned long) ffi_closure_ASM; /* function  */
492       tramp[3] = (unsigned long) closure; /* context  */
493
494       closure->cif = cif;
495       closure->fun = fun;
496       closure->user_data = user_data;
497
498       /* Flush the icache. Only necessary on Darwin.  */
499       flush_range(&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
500
501       break;
502
503     case FFI_AIX:
504
505       tramp_aix = (struct ffi_aix_trampoline_struct *) (closure->tramp);
506       fd = (aix_fd *)(void *)ffi_closure_ASM;
507
508       FFI_ASSERT (cif->abi == FFI_AIX);
509
510       tramp_aix->code_pointer = fd->code_pointer;
511       tramp_aix->toc = fd->toc;
512       tramp_aix->static_chain = closure;
513       closure->cif = cif;
514       closure->fun = fun;
515       closure->user_data = user_data;
516
517     default:
518
519       FFI_ASSERT(0);
520       break;
521     }
522   return FFI_OK;
523 }
524
525 static void
526 flush_icache(char *addr)
527 {
528 #ifndef _AIX
529   __asm__ volatile (
530                 "dcbf 0,%0;"
531                 "sync;"
532                 "icbi 0,%0;"
533                 "sync;"
534                 "isync;"
535                 : : "r"(addr) : "memory");
536 #endif
537 }
538
539 static void
540 flush_range(char * addr1, int size)
541 {
542 #define MIN_LINE_SIZE 32
543   int i;
544   for (i = 0; i < size; i += MIN_LINE_SIZE)
545     flush_icache(addr1+i);
546   flush_icache(addr1+size-1);
547 }
548
549 typedef union
550 {
551   float f;
552   double d;
553 } ffi_dblfl;
554
555 int ffi_closure_helper_DARWIN (ffi_closure*, void*,
556                                unsigned long*, ffi_dblfl*);
557
558 /* Basically the trampoline invokes ffi_closure_ASM, and on
559  * entry, r11 holds the address of the closure.
560  * After storing the registers that could possibly contain
561  * parameters to be passed into the stack frame and setting
562  * up space for a return value, ffi_closure_ASM invokes the
563  * following helper function to do most of the work
564  */
565
566 int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
567                                unsigned long * pgr, ffi_dblfl * pfr)
568 {
569   /* rvalue is the pointer to space for return value in closure assembly
570      pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM
571      pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM.  */
572
573
574   void **          avalue;
575   ffi_type **      arg_types;
576   long             i, avn;
577   long             nf;   /* number of floating registers already used */
578   long             ng;   /* number of general registers already used */
579   ffi_cif *        cif;
580   double           temp;
581   unsigned         size_al;
582
583   cif = closure->cif;
584   avalue = alloca(cif->nargs * sizeof(void *));
585
586   nf = 0;
587   ng = 0;
588
589   /* Copy the caller's structure return value address so that the closure
590      returns the data directly to the caller.  */
591   if (cif->rtype->type == FFI_TYPE_STRUCT)
592     {
593       rvalue = (void *) *pgr;
594       pgr++;
595       ng++;
596     }
597
598   i = 0;
599   avn = cif->nargs;
600   arg_types = cif->arg_types;
601
602   /* Grab the addresses of the arguments from the stack frame.  */
603   while (i < avn)
604     {
605       switch (arg_types[i]->type)
606         {
607         case FFI_TYPE_SINT8:
608         case FFI_TYPE_UINT8:
609           avalue[i] = (char *) pgr + 3;
610           ng++;
611           pgr++;
612           break;
613
614         case FFI_TYPE_SINT16:
615         case FFI_TYPE_UINT16:
616           avalue[i] = (char *) pgr + 2;
617           ng++;
618           pgr++;
619           break;
620
621         case FFI_TYPE_SINT32:
622         case FFI_TYPE_UINT32:
623         case FFI_TYPE_POINTER:
624           avalue[i] = pgr;
625           ng++;
626           pgr++;
627           break;
628
629         case FFI_TYPE_STRUCT:
630           /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
631              SI 4 bytes) are aligned as if they were those modes.  */
632           size_al = arg_types[i]->size;
633           /* If the first member of the struct is a double, then align
634              the struct to double-word.
635              Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3.  */
636           if (arg_types[i]->elements[0]->type == 3)
637             size_al = ALIGN(arg_types[i]->size, 8);
638           if (size_al < 3 && cif->abi == FFI_DARWIN)
639             avalue[i] = (void*) pgr + 4 - size_al;
640           else
641             avalue[i] = (void*) pgr;
642           ng += (size_al + 3) / 4;
643           pgr += (size_al + 3) / 4;
644           break;
645
646         case FFI_TYPE_SINT64:
647         case FFI_TYPE_UINT64:
648           /* Long long ints are passed in two gpr's.  */
649           avalue[i] = pgr;
650           ng += 2;
651           pgr += 2;
652           break;
653
654         case FFI_TYPE_FLOAT:
655           /* a float value consumes a GPR
656            *
657            * here are 13 64bit floating point registers.
658            */
659           if (nf < NUM_FPR_ARG_REGISTERS)
660             {
661               temp = pfr->d;
662               pfr->f = (float)temp;
663               avalue[i] = pfr;
664               pfr++;
665             }
666           else
667             {
668               avalue[i] = pgr;
669             }
670           nf++;
671           ng++;
672           pgr++;
673           break;
674
675         case FFI_TYPE_DOUBLE:
676           /* a double value consumes two GPRs
677            *
678            * There are 13 64bit floating point registers.
679            */
680           if (nf < NUM_FPR_ARG_REGISTERS)
681             {
682               avalue[i] = pfr;
683               pfr++;
684             }
685           else
686             {
687               avalue[i] = pgr;
688             }
689           nf++;
690           ng += 2;
691           pgr += 2;
692           break;
693
694         default:
695           FFI_ASSERT(0);
696         }
697       i++;
698     }
699
700   (closure->fun) (cif, rvalue, avalue, closure->user_data);
701
702   /* Tell ffi_closure_ASM to perform return type promotions.  */
703   return cif->rtype->type;
704 }