OSDN Git Service

ea1a14e8f65dc1a32c2146b5f54181c23114940f
[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           double_tmp = *(float *)*p_argv;
141           if (fparg_count >= NUM_FPR_ARG_REGISTERS)
142             {
143               *(float *)next_arg = (float)double_tmp;
144               next_arg += 1;
145             }
146           else
147             *fpr_base++ = double_tmp;
148           fparg_count++;
149           FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
150           break;
151
152         case FFI_TYPE_DOUBLE:
153           double_tmp = *(double *)*p_argv;
154
155           if (fparg_count >= NUM_FPR_ARG_REGISTERS)
156             {
157               if (intarg_count%2 != 0)
158                 {
159                   intarg_count++;
160                   next_arg++;
161                 }
162               *(double *)next_arg = double_tmp;
163               next_arg += 2;
164             }
165           else
166             *fpr_base++ = double_tmp;
167           fparg_count++;
168           FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
169           break;
170
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)
176             {
177               if (intarg_count%2 != 0)
178                 {
179                   intarg_count++;
180                   next_arg++;
181                 }
182               *(long long *)next_arg = *(long long *)*p_argv;
183               next_arg += 2;
184             }
185           else
186             {
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
193                */
194               if (intarg_count%2 != 0)
195                 {
196                   intarg_count ++;
197                   gpr_base++;
198                 }
199               *(long long *)gpr_base = *(long long *)*p_argv;
200               gpr_base += 2;
201             }
202           intarg_count += 2;
203           break;
204
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);
212           
213           gprvalue = (unsigned)copy_space;
214
215           FFI_ASSERT(copy_space > (char *)next_arg);
216           FFI_ASSERT(flags & FLAG_ARG_NEEDS_COPY);
217           goto putgpr;
218
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;
231
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;
244         }
245     }
246
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);
253 }
254
255 /* Perform machine dependent cif processing */
256 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
257 {
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;
265   
266   /* All the machine-independent calculation of cif->bytes will be wrong.
267      Redo the calculation for SYSV.  */
268
269   /* Space for the frame pointer, callee's LR, and the asm's temp regs.  */
270   bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof(int);
271
272   /* Space for the GPR registers.  */
273   bytes += NUM_GPR_ARG_REGISTERS * sizeof(int);
274
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)
284     {
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;
291
292     case FFI_TYPE_UINT64:
293     case FFI_TYPE_SINT64:
294       flags |= FLAG_RETURNS_64BITS;
295       break;
296
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)
302           {
303             flags |= FLAG_RETURNS_64BITS;
304             break;
305           }
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;
316
317     default:
318       /* Returns 32-bit integer, or similar.  Nothing to do here.  */
319       break;
320     }
321
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++)
328     {
329       switch ((*ptr)->type)
330         {
331         case FFI_TYPE_FLOAT:
332           fparg_count++;
333           /* floating singles are not 8-aligned on stack */
334           break;
335
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;
344
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;
356
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).  */
367
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;
373         }
374     }
375
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;
382   
383   /* Space for the FPR registers, if needed.  */
384   if (fparg_count != 0)
385     bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
386
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);
392
393   /* The stack space allocated needs to be a multiple of 16 bytes.  */
394   bytes = (bytes + 15) & ~0xF;
395
396   /* Add in the space for the copied structures.  */
397   bytes += struct_copy_size;
398
399   cif->flags = flags;
400   cif->bytes = bytes;
401
402   return FFI_OK;
403 }
404
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@*/
413
414 void ffi_call(/*@dependent@*/ ffi_cif *cif, 
415               void (*fn)(), 
416               /*@out@*/ void *rvalue, 
417               /*@dependent@*/ void **avalue)
418 {
419   extended_cif ecif;
420
421   ecif.cif = cif;
422   ecif.avalue = avalue;
423   
424   /* If the return value is a struct and we don't have a return */
425   /* value address then we need to make one                     */
426
427   if ((rvalue == NULL) && 
428       (cif->rtype->type == FFI_TYPE_STRUCT))
429     {
430       /*@-sysunrecog@*/
431       ecif.rvalue = alloca(cif->rtype->size);
432       /*@=sysunrecog@*/
433     }
434   else
435     ecif.rvalue = rvalue;
436     
437   
438   switch (cif->abi) 
439     {
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;
450     }
451 }
452
453
454 static void flush_icache(char *, int);
455
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)
461 {
462   unsigned int *tramp;
463
464   FFI_ASSERT (cif->abi == FFI_GCC_SYSV);
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] = 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 */
477
478   closure->cif = cif;
479   closure->fun = fun;
480   closure->user_data = user_data;
481
482   /* Flush the icache.  */
483   flush_icache(&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
484
485   return FFI_OK;
486 }
487
488
489 #define MIN_CACHE_LINE_SIZE 8
490
491 static void flush_icache(char * addr1, int size)
492 {
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");
498   }
499   addr = addr1 + size - 1;
500   __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" "sync;" "isync;" : : "r"(addr) : "memory");
501 }
502
503
504 int ffi_closure_helper_SYSV (ffi_closure*, void*, unsigned long*, 
505                                      unsigned long*, unsigned long*);
506
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
513  */
514
515 int
516 ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, 
517             unsigned long * pgr, unsigned long * pfr, 
518             unsigned long * pst)
519 {
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 */
524
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; 
532
533   cif = closure->cif;
534   avalue = alloca(cif->nargs * sizeof(void *));
535
536   nf = 0;
537   ng = 0;
538
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)
542     {
543       rvalue = *pgr;
544       ng++;
545       pgr++;
546     }
547
548   i = 0;
549   avn = cif->nargs;
550   arg_types = cif->arg_types;
551   
552   /* Grab the addresses of the arguments from the stack frame.  */
553   while (i < avn)
554     {
555       switch (arg_types[i]->type)
556         {
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++;
567           }
568           break;
569            
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++;
580           }
581           break;
582
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++;
595           }
596           break;
597
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.
608            */
609            if (ng < 7) {
610               if (ng & 0x01) {
611                 /* skip r4, r6, r8 as starting points */
612                   ng++;
613                   pgr++;
614               }
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;
622            }
623            break;
624
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).
629              */
630
631           /* there are 8 64bit floating point registers */
632
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...
644              */
645              avalue[i] = pst;
646              nf++;
647              pst+=1;
648           }
649           break;
650
651         case FFI_TYPE_DOUBLE:
652           /* On the outgoing stack all values are aligned to 8 */
653           /* there are 8 64bit floating point registers */
654
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;
664           }
665           break;
666
667         default:
668           FFI_ASSERT(0);
669         }
670
671       i++;
672     }
673
674
675   (closure->fun) (cif, rvalue, avalue, closure->user_data);
676
677   /* Tell ffi_closure_osf how to perform return type promotions.  */
678   return cif->rtype->type;
679
680 }
681
682
683
684
685