OSDN Git Service

* src/powerpc/ppc_closure.S: New file.
[pf3gnuchains/gcc-fork.git] / libffi / src / powerpc / ffi.c
1 /* -----------------------------------------------------------------------
2    ffi.c - Copyright (c) 1998 Geoffrey Keating
3    
4    PowerPC Foreign Function Interface 
5
6    $Id: ffi.c,v 1.1.1.1 1998/11/29 16:48:16 green Exp $
7
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:
15
16    The above copyright notice and this permission notice shall be included
17    in all copies or substantial portions of the Software.
18
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    ----------------------------------------------------------------------- */
27
28 #include <ffi.h>
29 #include <ffi_common.h>
30
31 #include <stdlib.h>
32 #include <stdio.h>
33
34 extern void ffi_closure_SYSV(void);
35
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),
41
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)
46 };
47
48 /* About the SYSV ABI.  */
49 enum {
50   NUM_GPR_ARG_REGISTERS = 8,
51   NUM_FPR_ARG_REGISTERS = 8
52 };
53 enum { ASM_NEEDS_REGISTERS = 4 };
54
55 /* ffi_prep_args is called by the assembly routine once stack space
56    has been allocated for the function's arguments.
57
58    The stack layout we want looks like this:
59
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
78
79    */
80
81 /*@-exportheader@*/
82 void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
83 /*@=exportheader@*/
84 {
85   const unsigned bytes = ecif->cif->bytes;
86   const unsigned flags = ecif->cif->flags;
87   
88   /* 'stacktop' points at the previous backchain pointer.  */
89   unsigned *const stacktop = stack + (ecif->cif->bytes / sizeof(unsigned));
90
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;
95
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;
100
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);
106
107   /* 'next_arg' grows up as we put parameters in it.  */
108   unsigned *next_arg = stack + 2;
109
110   int i;
111   ffi_type **ptr;
112   double double_tmp;
113   void **p_argv;
114   size_t struct_copy_size;
115   unsigned gprvalue;
116
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);
123
124   /* Deal with return values that are actually pass-by-reference.  */
125   if (flags & FLAG_RETVAL_REFERENCE)
126   {
127     *gpr_base++ = (unsigned)(char *)ecif->rvalue;
128     intarg_count++;
129   }
130
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++)
136     {
137       switch ((*ptr)->type)
138         {
139         case FFI_TYPE_FLOAT:
140         case FFI_TYPE_DOUBLE:
141           if ((*ptr)->type == FFI_TYPE_FLOAT)
142             double_tmp = *(float *)*p_argv;
143           else
144             double_tmp = *(double *)*p_argv;
145
146           if (fparg_count >= NUM_FPR_ARG_REGISTERS)
147             {
148               if (intarg_count%2 != 0)
149                 {
150                   intarg_count++;
151                   next_arg++;
152                 }
153               *(double *)next_arg = double_tmp;
154               next_arg += 2;
155             }
156           else
157             *fpr_base++ = double_tmp;
158           fparg_count++;
159           FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
160           break;
161
162         case FFI_TYPE_UINT64:
163         case FFI_TYPE_SINT64:
164           if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
165             intarg_count++;
166           if (intarg_count >= NUM_GPR_ARG_REGISTERS)
167             {
168               if (intarg_count%2 != 0)
169                 {
170                   intarg_count++;
171                   next_arg++;
172                 }
173               *(long long *)next_arg = *(long long *)*p_argv;
174               next_arg += 2;
175             }
176           else
177             {
178               /* whoops: abi states only certain register pairs
179                * can be used for passing long long int
180                * specifically (r3,r4), (r5,r6), (r7,r8), 
181                * (r9,r10) and if next arg is long long but
182                * not correct starting register of pair then skip
183                * until the proper starting register
184                */
185               if (intarg_count%2 != 0)
186                 {
187                   intarg_count ++;
188                   gpr_base++;
189                 }
190               *(long long *)gpr_base = *(long long *)*p_argv;
191               gpr_base += 2;
192             }
193           intarg_count += 2;
194           break;
195
196         case FFI_TYPE_STRUCT:
197 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
198         case FFI_TYPE_LONGDOUBLE:
199 #endif
200           struct_copy_size = ((*ptr)->size + 15) & ~0xF;
201           copy_space -= struct_copy_size;
202           memcpy(copy_space, (char *)*p_argv, (*ptr)->size);
203           
204           gprvalue = (unsigned)copy_space;
205
206           FFI_ASSERT(copy_space > (char *)next_arg);
207           FFI_ASSERT(flags & FLAG_ARG_NEEDS_COPY);
208           goto putgpr;
209
210         case FFI_TYPE_UINT8:
211           gprvalue = *(unsigned char *)*p_argv;
212           goto putgpr;
213         case FFI_TYPE_SINT8:
214           gprvalue = *(signed char *)*p_argv;
215           goto putgpr;
216         case FFI_TYPE_UINT16:
217           gprvalue = *(unsigned short *)*p_argv;
218           goto putgpr;
219         case FFI_TYPE_SINT16:
220           gprvalue = *(signed short *)*p_argv;
221           goto putgpr;
222
223         case FFI_TYPE_INT:
224         case FFI_TYPE_UINT32:
225         case FFI_TYPE_SINT32:
226         case FFI_TYPE_POINTER:
227           gprvalue = *(unsigned *)*p_argv;
228         putgpr:
229           if (intarg_count >= NUM_GPR_ARG_REGISTERS)
230             *next_arg++ = gprvalue;
231           else
232             *gpr_base++ = gprvalue;
233           intarg_count++;
234           break;
235         }
236     }
237
238   /* Check that we didn't overrun the stack...  */
239   FFI_ASSERT(copy_space >= (char *)next_arg);
240   FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
241   FFI_ASSERT((unsigned *)fpr_base
242              <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
243   FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
244 }
245
246 /* Perform machine dependent cif processing */
247 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
248 {
249   /* All this is for the SYSV ABI.  */
250   int i;
251   ffi_type **ptr;
252   unsigned bytes;
253   int fparg_count = 0, intarg_count = 0;
254   unsigned flags = 0;
255   unsigned struct_copy_size = 0;
256   
257   /* All the machine-independent calculation of cif->bytes will be wrong.
258      Redo the calculation for SYSV.  */
259
260   /* Space for the frame pointer, callee's LR, and the asm's temp regs.  */
261   bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof(int);
262
263   /* Space for the GPR registers.  */
264   bytes += NUM_GPR_ARG_REGISTERS * sizeof(int);
265
266   /* Return value handling.  The rules are as follows:
267      - 32-bit (or less) integer values are returned in gpr3;
268      - Structures of size <= 4 bytes also returned in gpr3;
269      - 64-bit integer values and structures between 5 and 8 bytes are returned
270        in gpr3 and gpr4;
271      - Single/double FP values are returned in fpr1;
272      - Larger structures and long double (if not equivalent to double) values
273        are allocated space and a pointer is passed as the first argument.  */
274   switch (cif->rtype->type)
275     {
276     case FFI_TYPE_DOUBLE:
277       flags |= FLAG_RETURNS_64BITS;
278       /* Fall through.  */
279     case FFI_TYPE_FLOAT:
280       flags |= FLAG_RETURNS_FP;
281       break;
282
283     case FFI_TYPE_UINT64:
284     case FFI_TYPE_SINT64:
285       flags |= FLAG_RETURNS_64BITS;
286       break;
287
288     case FFI_TYPE_STRUCT:
289       if (cif->abi != FFI_GCC_SYSV)
290         if (cif->rtype->size <= 4)
291           break;
292         else if (cif->rtype->size <= 8)
293           {
294             flags |= FLAG_RETURNS_64BITS;
295             break;
296           }
297       /* else fall through.  */
298 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
299     case FFI_TYPE_LONGDOUBLE:
300 #endif
301       intarg_count++;
302       flags |= FLAG_RETVAL_REFERENCE;
303       /* Fall through.  */
304     case FFI_TYPE_VOID:
305       flags |= FLAG_RETURNS_NOTHING;
306       break;
307
308     default:
309       /* Returns 32-bit integer, or similar.  Nothing to do here.  */
310       break;
311     }
312
313   /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
314      first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
315      goes on the stack.  Structures and long doubles (if not equivalent
316      to double) are passed as a pointer to a copy of the structure.
317      Stuff on the stack needs to keep proper alignment.  */
318   for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
319     {
320       switch ((*ptr)->type)
321         {
322         case FFI_TYPE_FLOAT:
323         case FFI_TYPE_DOUBLE:
324           fparg_count++;
325           /* If this FP arg is going on the stack, it must be
326              8-byte-aligned.  */
327           if (fparg_count > NUM_FPR_ARG_REGISTERS
328               && intarg_count%2 != 0)
329             intarg_count++;
330           break;
331
332         case FFI_TYPE_UINT64:
333         case FFI_TYPE_SINT64:
334           /* 'long long' arguments are passed as two words, but
335              either both words must fit in registers or both go
336              on the stack.  If they go on the stack, they must
337              be 8-byte-aligned.  */
338           if (intarg_count == NUM_GPR_ARG_REGISTERS-1
339               || intarg_count >= NUM_GPR_ARG_REGISTERS && intarg_count%2 != 0)
340             intarg_count++;
341           intarg_count += 2;
342           break;
343
344         case FFI_TYPE_STRUCT:
345 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
346         case FFI_TYPE_LONGDOUBLE:
347 #endif
348           /* We must allocate space for a copy of these to enforce
349              pass-by-value.  Pad the space up to a multiple of 16
350              bytes (the maximum alignment required for anything under
351              the SYSV ABI).  */
352           struct_copy_size += ((*ptr)->size + 15) & ~0xF;
353           /* Fall through (allocate space for the pointer).  */
354
355         default:
356           /* Everything else is passed as a 4-byte word in a GPR, either
357              the object itself or a pointer to it.  */
358           intarg_count++;
359           break;
360         }
361     }
362
363   if (fparg_count != 0)
364     flags |= FLAG_FP_ARGUMENTS;
365   if (intarg_count > 4)
366     flags |= FLAG_4_GPR_ARGUMENTS;
367   if (struct_copy_size != 0)
368     flags |= FLAG_ARG_NEEDS_COPY;
369   
370   /* Space for the FPR registers, if needed.  */
371   if (fparg_count != 0)
372     bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
373
374   /* Stack space.  */
375   if (intarg_count > NUM_GPR_ARG_REGISTERS)
376     bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof(int);
377   if (fparg_count > NUM_FPR_ARG_REGISTERS)
378     bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof(double);
379
380   /* The stack space allocated needs to be a multiple of 16 bytes.  */
381   bytes = (bytes + 15) & ~0xF;
382
383   /* Add in the space for the copied structures.  */
384   bytes += struct_copy_size;
385
386   cif->flags = flags;
387   cif->bytes = bytes;
388
389   return FFI_OK;
390 }
391
392 /*@-declundef@*/
393 /*@-exportheader@*/
394 extern void ffi_call_SYSV(/*@out@*/ extended_cif *, 
395                           unsigned, unsigned, 
396                           /*@out@*/ unsigned *, 
397                           void (*fn)());
398 /*@=declundef@*/
399 /*@=exportheader@*/
400
401 void ffi_call(/*@dependent@*/ ffi_cif *cif, 
402               void (*fn)(), 
403               /*@out@*/ void *rvalue, 
404               /*@dependent@*/ void **avalue)
405 {
406   extended_cif ecif;
407
408   ecif.cif = cif;
409   ecif.avalue = avalue;
410   
411   /* If the return value is a struct and we don't have a return */
412   /* value address then we need to make one                     */
413
414   if ((rvalue == NULL) && 
415       (cif->rtype->type == FFI_TYPE_STRUCT))
416     {
417       /*@-sysunrecog@*/
418       ecif.rvalue = alloca(cif->rtype->size);
419       /*@=sysunrecog@*/
420     }
421   else
422     ecif.rvalue = rvalue;
423     
424   
425   switch (cif->abi) 
426     {
427     case FFI_SYSV:
428     case FFI_GCC_SYSV:
429       /*@-usedef@*/
430       ffi_call_SYSV(&ecif, -cif->bytes, 
431                     cif->flags, ecif.rvalue, fn);
432       /*@=usedef@*/
433       break;
434     default:
435       FFI_ASSERT(0);
436       break;
437     }
438 }
439
440
441 static void flush_icache(char *, int);
442
443 ffi_status
444 ffi_prep_closure (ffi_closure* closure,
445                   ffi_cif* cif,
446                   void (*fun)(ffi_cif*, void*, void**, void*),
447                   void *user_data)
448 {
449   unsigned int *tramp;
450
451   FFI_ASSERT (cif->abi == FFI_GCC_SYSV);
452
453   tramp = (unsigned int *) &closure->tramp[0];
454   tramp[0] = 0x7c0802a6;  /*   mflr    r0 */
455   tramp[1] = 0x4800000d;  /*   bl      10 <trampoline_initial+0x10> */
456   tramp[4] = 0x7d6802a6;  /*   mflr    r11 */
457   tramp[5] = 0x7c0803a6;  /*   mtlr    r0 */
458   tramp[6] = 0x800b0000;  /*   lwz     r0,0(r11) */
459   tramp[7] = 0x816b0004;  /*   lwz     r11,4(r11) */
460   tramp[8] = 0x7c0903a6;  /*   mtctr   r0 */
461   tramp[9] = 0x4e800420;  /*   bctr */
462   *(void **) &tramp[2] = (void *)ffi_closure_SYSV; /* function */
463   *(void **) &tramp[3] = (void *)closure;          /* context */
464
465   closure->cif = cif;
466   closure->fun = fun;
467   closure->user_data = user_data;
468
469   /* Flush the icache.  */
470   flush_icache(&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
471
472   return FFI_OK;
473 }
474
475
476 #define MIN_CACHE_LINE_SIZE 8
477
478 static void flush_icache(char * addr1, int size)
479 {
480   int i;
481   char * addr;
482   for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) {
483      addr = addr1 + i;
484      __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" : : "r"(addr) : "memory");
485   }
486   addr = addr1 + size - 1;
487   __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" "sync;" "isync;" : : "r"(addr) : "memory");
488 }
489
490
491 int ffi_closure_helper_SYSV (ffi_closure*, void*, unsigned long*, 
492                                      unsigned long*, unsigned long*);
493
494 /* Basically the trampoline invokes ffi_closure_SYSV, and on 
495  * entry, r11 holds the address of the closure.
496  * After storing the registers that could possibly contain
497  * parameters to be passed into the stack frame and setting
498  * up space for a return value, ffi_closure_SYSV invokes the 
499  * following helper function to do most of the work
500  */
501
502 int
503 ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, 
504             unsigned long * pgr, unsigned long * pfr, 
505             unsigned long * pst)
506 {
507   /* rvalue is the pointer to space for return value in closure assembly */
508   /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
509   /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV  */
510   /* pst is the pointer to outgoing parameter stack in original caller */
511
512   void **          avalue;
513   ffi_type **      arg_types;
514   long             i, avn;
515   long             nf;   /* number of floating registers already used */
516   long             ng;   /* number of general registers already used */
517   ffi_cif *        cif; 
518   double           temp; 
519
520   cif = closure->cif;
521   avalue = alloca(cif->nargs * sizeof(void *));
522
523   nf = 0;
524   ng = 0;
525
526   /* Copy the caller's structure return value address so that the closure
527      returns the data directly to the caller.  */
528   if (cif->rtype->type == FFI_TYPE_STRUCT)
529     {
530       rvalue = *pgr;
531       ng++;
532       pgr++;
533     }
534
535   i = 0;
536   avn = cif->nargs;
537   arg_types = cif->arg_types;
538   
539   /* Grab the addresses of the arguments from the stack frame.  */
540   while (i < avn)
541     {
542       switch (arg_types[i]->type)
543         {
544         case FFI_TYPE_SINT8:
545         case FFI_TYPE_UINT8:
546         /* there are 8 gpr registers used to pass values */
547           if (ng < 8) {
548              avalue[i] = (((char *)pgr)+3);
549              ng++;
550              pgr++;
551           } else {
552              avalue[i] = (((char *)pst)+3);
553              pst++;
554           }
555           break;
556            
557         case FFI_TYPE_SINT16:
558         case FFI_TYPE_UINT16:
559         /* there are 8 gpr registers used to pass values */
560           if (ng < 8) {
561              avalue[i] = (((char *)pgr)+2);
562              ng++;
563              pgr++;
564           } else {
565              avalue[i] = (((char *)pst)+2);
566              pst++;
567           }
568           break;
569
570         case FFI_TYPE_SINT32:
571         case FFI_TYPE_UINT32:
572         case FFI_TYPE_POINTER:
573         case FFI_TYPE_STRUCT:
574         /* there are 8 gpr registers used to pass values */
575           if (ng < 8) {
576              avalue[i] = pgr;
577              ng++;
578              pgr++;
579           } else {
580              avalue[i] = pst;
581              pst++;
582           }
583           break;
584
585         case FFI_TYPE_SINT64:
586         case FFI_TYPE_UINT64:
587           /* passing long long ints are complex, they must
588            * be passed in suitable register pairs such as
589            * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
590            * and if the entire pair aren't available then the outgoing
591            * parameter stack is used for both but an alignment of 8
592            * must will be kept.  So we must either look in pgr
593            * or pst to find the correct address for this type
594            * of parameter.
595            */
596            if (ng < 7) {
597               if (ng & 0x01) {
598                 /* skip r4, r6, r8 as starting points */
599                   ng++;
600                   pgr++;
601               }
602               avalue[i] = pgr;
603               ng+=2;
604               pgr+=2;
605            } else {
606               if (((long)pst) & 4) pst++;
607               avalue[i] = pst;
608               pst+=2;
609            }
610            break;
611
612         case FFI_TYPE_FLOAT:
613             /* unfortunately float values are stored as doubles
614              * in the ffi_closure_SYSV code (since we don't check
615              * the type in that routine).  This is also true
616              * of floats passed on the outgoing parameter stack.
617              * Also, on the outgoing stack all values are aligned
618              * to 8
619              *
620              * Don't you just love the simplicity of this ABI!
621              */
622
623           /* there are 8 64bit floating point registers */
624
625           if (nf < 8) {
626              temp = *(double*)pfr;
627              *(float*)pfr = (float)temp;
628              avalue[i] = pfr;
629              nf++;
630              pfr+=2;
631           } else {
632             /* FIXME? here we are really changing the values
633              * stored in the original calling routines outgoing
634              * parameter stack.  This is probably a really
635              * naughty thing to do but...
636              */
637              if (((long)pst) & 4) pst++;
638              temp = *(double*)pst;
639              *(float*)pst = (float)temp;
640              avalue[i] = pst;
641              nf++;
642              pst+=2;
643           }
644           break;
645
646         case FFI_TYPE_DOUBLE:
647           /* On the outgoing stack all values are aligned to 8 */
648           /* there are 8 64bit floating point registers */
649
650           if (nf < 8) {
651              avalue[i] = pfr;
652              nf++;
653              pfr+=2;
654           } else {
655              if (((long)pst) & 4) pst++;
656              avalue[i] = pst;
657              nf++;
658              pst+=2;
659           }
660           break;
661
662         default:
663           FFI_ASSERT(0);
664         }
665
666       i++;
667     }
668
669
670   (closure->fun) (cif, rvalue, avalue, closure->user_data);
671
672   /* Tell ffi_closure_osf how to perform return type promotions.  */
673   return cif->rtype->type;
674
675 }
676
677
678
679
680