OSDN Git Service

2008-08-25 Andreas Tobler <a.tobler@schweiz.org>
[pf3gnuchains/gcc-fork.git] / libffi / src / powerpc / ffi.c
1 /* -----------------------------------------------------------------------
2    ffi.c - Copyright (c) 1998 Geoffrey Keating
3    Copyright (C) 2007, 2008 Free Software Foundation, Inc
4
5    PowerPC Foreign Function Interface
6
7    Permission is hereby granted, free of charge, to any person obtaining
8    a copy of this software and associated documentation files (the
9    ``Software''), to deal in the Software without restriction, including
10    without limitation the rights to use, copy, modify, merge, publish,
11    distribute, sublicense, and/or sell copies of the Software, and to
12    permit persons to whom the Software is furnished to do so, subject to
13    the following conditions:
14
15    The above copyright notice and this permission notice shall be included
16    in all copies or substantial portions of the Software.
17
18    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
19    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
22    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24    OTHER DEALINGS IN THE SOFTWARE.
25    ----------------------------------------------------------------------- */
26
27 #include <ffi.h>
28 #include <ffi_common.h>
29
30 #include <stdlib.h>
31 #include <stdio.h>
32
33
34 extern void ffi_closure_SYSV (void);
35 extern void FFI_HIDDEN ffi_closure_LINUX64 (void);
36
37 enum {
38   /* The assembly depends on these exact flags.  */
39   FLAG_RETURNS_SMST     = 1 << (31-31), /* Used for FFI_SYSV small structs.  */
40   FLAG_RETURNS_NOTHING  = 1 << (31-30), /* These go in cr7 */
41   FLAG_RETURNS_FP       = 1 << (31-29),
42   FLAG_RETURNS_64BITS   = 1 << (31-28),
43
44   FLAG_RETURNS_128BITS  = 1 << (31-27), /* cr6  */
45
46   FLAG_SYSV_SMST_R4     = 1 << (31-16), /* cr4, use r4 for FFI_SYSV 8 byte
47                                            structs.  */
48   FLAG_SYSV_SMST_R3     = 1 << (31-15), /* cr3, use r3 for FFI_SYSV 4 byte
49                                            structs.  */
50   FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
51   FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI */
52   FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
53   FLAG_RETVAL_REFERENCE = 1 << (31- 4)
54 };
55
56 /* About the SYSV ABI.  */
57 unsigned int NUM_GPR_ARG_REGISTERS = 8;
58 #ifndef __NO_FPRS__
59 unsigned int NUM_FPR_ARG_REGISTERS = 8;
60 #else
61 unsigned int NUM_FPR_ARG_REGISTERS = 0;
62 #endif
63
64 enum { ASM_NEEDS_REGISTERS = 4 };
65
66 /* ffi_prep_args_SYSV is called by the assembly routine once stack space
67    has been allocated for the function's arguments.
68
69    The stack layout we want looks like this:
70
71    |   Return address from ffi_call_SYSV 4bytes |       higher addresses
72    |--------------------------------------------|
73    |   Previous backchain pointer       4       |       stack pointer here
74    |--------------------------------------------|<+ <<< on entry to
75    |   Saved r28-r31                    4*4     | |     ffi_call_SYSV
76    |--------------------------------------------| |
77    |   GPR registers r3-r10             8*4     | |     ffi_call_SYSV
78    |--------------------------------------------| |
79    |   FPR registers f1-f8 (optional)   8*8     | |
80    |--------------------------------------------| |     stack   |
81    |   Space for copied structures              | |     grows   |
82    |--------------------------------------------| |     down    V
83    |   Parameters that didn't fit in registers  | |
84    |--------------------------------------------| |     lower addresses
85    |   Space for callee's LR            4       | |
86    |--------------------------------------------| |     stack pointer here
87    |   Current backchain pointer        4       |-/     during
88    |--------------------------------------------|   <<< ffi_call_SYSV
89
90 */
91
92 void
93 ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack)
94 {
95   const unsigned bytes = ecif->cif->bytes;
96   const unsigned flags = ecif->cif->flags;
97
98   typedef union {
99     char *c;
100     unsigned *u;
101     long long *ll;
102     float *f;
103     double *d;
104   } valp;
105
106   /* 'stacktop' points at the previous backchain pointer.  */
107   valp stacktop;
108
109   /* 'gpr_base' points at the space for gpr3, and grows upwards as
110      we use GPR registers.  */
111   valp gpr_base;
112   int intarg_count;
113
114   /* 'fpr_base' points at the space for fpr1, and grows upwards as
115      we use FPR registers.  */
116   valp fpr_base;
117   int fparg_count;
118
119   /* 'copy_space' grows down as we put structures in it.  It should
120      stay 16-byte aligned.  */
121   valp copy_space;
122
123   /* 'next_arg' grows up as we put parameters in it.  */
124   valp next_arg;
125
126   int i, ii MAYBE_UNUSED;
127   ffi_type **ptr;
128   double double_tmp;
129   union {
130     void **v;
131     char **c;
132     signed char **sc;
133     unsigned char **uc;
134     signed short **ss;
135     unsigned short **us;
136     unsigned int **ui;
137     long long **ll;
138     float **f;
139     double **d;
140   } p_argv;
141   size_t struct_copy_size;
142   unsigned gprvalue;
143
144   if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
145     NUM_FPR_ARG_REGISTERS = 0;
146
147   stacktop.c = (char *) stack + bytes;
148   gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
149   intarg_count = 0;
150   fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS;
151   fparg_count = 0;
152   copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c);
153   next_arg.u = stack + 2;
154
155   /* Check that everything starts aligned properly.  */
156   FFI_ASSERT (((unsigned) (char *) stack & 0xF) == 0);
157   FFI_ASSERT (((unsigned) copy_space.c & 0xF) == 0);
158   FFI_ASSERT (((unsigned) stacktop.c & 0xF) == 0);
159   FFI_ASSERT ((bytes & 0xF) == 0);
160   FFI_ASSERT (copy_space.c >= next_arg.c);
161
162   /* Deal with return values that are actually pass-by-reference.  */
163   if (flags & FLAG_RETVAL_REFERENCE)
164     {
165       *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue;
166       intarg_count++;
167     }
168
169   /* Now for the arguments.  */
170   p_argv.v = ecif->avalue;
171   for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
172        i > 0;
173        i--, ptr++, p_argv.v++)
174     {
175       switch ((*ptr)->type)
176         {
177         case FFI_TYPE_FLOAT:
178           /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
179           if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
180             goto soft_float_prep;
181           double_tmp = **p_argv.f;
182           if (fparg_count >= NUM_FPR_ARG_REGISTERS)
183             {
184               *next_arg.f = (float) double_tmp;
185               next_arg.u += 1;
186             }
187           else
188             *fpr_base.d++ = double_tmp;
189           fparg_count++;
190           FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
191           break;
192
193         case FFI_TYPE_DOUBLE:
194           /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
195           if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
196             goto soft_double_prep;
197           double_tmp = **p_argv.d;
198
199           if (fparg_count >= NUM_FPR_ARG_REGISTERS)
200             {
201               if (intarg_count >= NUM_GPR_ARG_REGISTERS
202                   && intarg_count % 2 != 0)
203                 {
204                   intarg_count++;
205                   next_arg.u++;
206                 }
207               *next_arg.d = double_tmp;
208               next_arg.u += 2;
209             }
210           else
211             *fpr_base.d++ = double_tmp;
212           fparg_count++;
213           FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
214           break;
215
216 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
217         case FFI_TYPE_LONGDOUBLE:
218           if ((ecif->cif->abi != FFI_LINUX)
219                 && (ecif->cif->abi != FFI_LINUX_SOFT_FLOAT))
220             goto do_struct;
221           /* The soft float ABI for long doubles works like this,
222              a long double is passed in four consecutive gprs if available.
223              A maximum of 2 long doubles can be passed in gprs.
224              If we do not have 4 gprs left, the long double is passed on the
225              stack, 4-byte aligned.  */
226           if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
227             {
228               unsigned int int_tmp = (*p_argv.ui)[0];
229               if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3)
230                 {
231                   if (intarg_count < NUM_GPR_ARG_REGISTERS)
232                     intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
233                   *next_arg.u = int_tmp;
234                   next_arg.u++;
235                   for (ii = 1; ii < 4; ii++)
236                     {
237                       int_tmp = (*p_argv.ui)[ii];
238                       *next_arg.u = int_tmp;
239                       next_arg.u++;
240                     }
241                 }
242               else
243                 {
244                   *gpr_base.u++ = int_tmp;
245                   for (ii = 1; ii < 4; ii++)
246                     {
247                       int_tmp = (*p_argv.ui)[ii];
248                       *gpr_base.u++ = int_tmp;
249                     }
250                 }
251               intarg_count +=4;
252             }
253           else
254             {
255               double_tmp = (*p_argv.d)[0];
256
257               if (fparg_count >= NUM_FPR_ARG_REGISTERS - 1)
258                 {
259                   if (intarg_count >= NUM_GPR_ARG_REGISTERS
260                       && intarg_count % 2 != 0)
261                     {
262                       intarg_count++;
263                       next_arg.u++;
264                     }
265                   *next_arg.d = double_tmp;
266                   next_arg.u += 2;
267                   double_tmp = (*p_argv.d)[1];
268                   *next_arg.d = double_tmp;
269                   next_arg.u += 2;
270                 }
271               else
272                 {
273                   *fpr_base.d++ = double_tmp;
274                   double_tmp = (*p_argv.d)[1];
275                   *fpr_base.d++ = double_tmp;
276                 }
277
278               fparg_count += 2;
279               FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
280             }
281           break;
282 #endif
283
284         case FFI_TYPE_UINT64:
285         case FFI_TYPE_SINT64:
286         soft_double_prep:
287           if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
288             intarg_count++;
289           if (intarg_count >= NUM_GPR_ARG_REGISTERS)
290             {
291               if (intarg_count % 2 != 0)
292                 {
293                   intarg_count++;
294                   next_arg.u++;
295                 }
296               *next_arg.ll = **p_argv.ll;
297               next_arg.u += 2;
298             }
299           else
300             {
301               /* whoops: abi states only certain register pairs
302                * can be used for passing long long int
303                * specifically (r3,r4), (r5,r6), (r7,r8),
304                * (r9,r10) and if next arg is long long but
305                * not correct starting register of pair then skip
306                * until the proper starting register
307                */
308               if (intarg_count % 2 != 0)
309                 {
310                   intarg_count ++;
311                   gpr_base.u++;
312                 }
313               *gpr_base.ll++ = **p_argv.ll;
314             }
315           intarg_count += 2;
316           break;
317
318         case FFI_TYPE_STRUCT:
319 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
320         do_struct:
321 #endif
322           struct_copy_size = ((*ptr)->size + 15) & ~0xF;
323           copy_space.c -= struct_copy_size;
324           memcpy (copy_space.c, *p_argv.c, (*ptr)->size);
325
326           gprvalue = (unsigned long) copy_space.c;
327
328           FFI_ASSERT (copy_space.c > next_arg.c);
329           FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY);
330           goto putgpr;
331
332         case FFI_TYPE_UINT8:
333           gprvalue = **p_argv.uc;
334           goto putgpr;
335         case FFI_TYPE_SINT8:
336           gprvalue = **p_argv.sc;
337           goto putgpr;
338         case FFI_TYPE_UINT16:
339           gprvalue = **p_argv.us;
340           goto putgpr;
341         case FFI_TYPE_SINT16:
342           gprvalue = **p_argv.ss;
343           goto putgpr;
344
345         case FFI_TYPE_INT:
346         case FFI_TYPE_UINT32:
347         case FFI_TYPE_SINT32:
348         case FFI_TYPE_POINTER:
349         soft_float_prep:
350
351           gprvalue = **p_argv.ui;
352
353         putgpr:
354           if (intarg_count >= NUM_GPR_ARG_REGISTERS)
355             *next_arg.u++ = gprvalue;
356           else
357             *gpr_base.u++ = gprvalue;
358           intarg_count++;
359           break;
360         }
361     }
362
363   /* Check that we didn't overrun the stack...  */
364   FFI_ASSERT (copy_space.c >= next_arg.c);
365   FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS);
366   FFI_ASSERT (fpr_base.u
367               <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
368   FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
369 }
370
371 /* About the LINUX64 ABI.  */
372 enum {
373   NUM_GPR_ARG_REGISTERS64 = 8,
374   NUM_FPR_ARG_REGISTERS64 = 13
375 };
376 enum { ASM_NEEDS_REGISTERS64 = 4 };
377
378 /* ffi_prep_args64 is called by the assembly routine once stack space
379    has been allocated for the function's arguments.
380
381    The stack layout we want looks like this:
382
383    |   Ret addr from ffi_call_LINUX64   8bytes  |       higher addresses
384    |--------------------------------------------|
385    |   CR save area                     8bytes  |
386    |--------------------------------------------|
387    |   Previous backchain pointer       8       |       stack pointer here
388    |--------------------------------------------|<+ <<< on entry to
389    |   Saved r28-r31                    4*8     | |     ffi_call_LINUX64
390    |--------------------------------------------| |
391    |   GPR registers r3-r10             8*8     | |
392    |--------------------------------------------| |
393    |   FPR registers f1-f13 (optional)  13*8    | |
394    |--------------------------------------------| |
395    |   Parameter save area                      | |
396    |--------------------------------------------| |
397    |   TOC save area                    8       | |
398    |--------------------------------------------| |     stack   |
399    |   Linker doubleword                8       | |     grows   |
400    |--------------------------------------------| |     down    V
401    |   Compiler doubleword              8       | |
402    |--------------------------------------------| |     lower addresses
403    |   Space for callee's LR            8       | |
404    |--------------------------------------------| |
405    |   CR save area                     8       | |
406    |--------------------------------------------| |     stack pointer here
407    |   Current backchain pointer        8       |-/     during
408    |--------------------------------------------|   <<< ffi_call_LINUX64
409
410 */
411
412 void FFI_HIDDEN
413 ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
414 {
415   const unsigned long bytes = ecif->cif->bytes;
416   const unsigned long flags = ecif->cif->flags;
417
418   typedef union {
419     char *c;
420     unsigned long *ul;
421     float *f;
422     double *d;
423   } valp;
424
425   /* 'stacktop' points at the previous backchain pointer.  */
426   valp stacktop;
427
428   /* 'next_arg' points at the space for gpr3, and grows upwards as
429      we use GPR registers, then continues at rest.  */
430   valp gpr_base;
431   valp gpr_end;
432   valp rest;
433   valp next_arg;
434
435   /* 'fpr_base' points at the space for fpr3, and grows upwards as
436      we use FPR registers.  */
437   valp fpr_base;
438   int fparg_count;
439
440   int i, words;
441   ffi_type **ptr;
442   double double_tmp;
443   union {
444     void **v;
445     char **c;
446     signed char **sc;
447     unsigned char **uc;
448     signed short **ss;
449     unsigned short **us;
450     signed int **si;
451     unsigned int **ui;
452     unsigned long **ul;
453     float **f;
454     double **d;
455   } p_argv;
456   unsigned long gprvalue;
457
458   stacktop.c = (char *) stack + bytes;
459   gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64;
460   gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64;
461   rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64;
462   fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64;
463   fparg_count = 0;
464   next_arg.ul = gpr_base.ul;
465
466   /* Check that everything starts aligned properly.  */
467   FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
468   FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
469   FFI_ASSERT ((bytes & 0xF) == 0);
470
471   /* Deal with return values that are actually pass-by-reference.  */
472   if (flags & FLAG_RETVAL_REFERENCE)
473     *next_arg.ul++ = (unsigned long) (char *) ecif->rvalue;
474
475   /* Now for the arguments.  */
476   p_argv.v = ecif->avalue;
477   for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
478        i > 0;
479        i--, ptr++, p_argv.v++)
480     {
481       switch ((*ptr)->type)
482         {
483         case FFI_TYPE_FLOAT:
484           double_tmp = **p_argv.f;
485           *next_arg.f = (float) double_tmp;
486           if (++next_arg.ul == gpr_end.ul)
487             next_arg.ul = rest.ul;
488           if (fparg_count < NUM_FPR_ARG_REGISTERS64)
489             *fpr_base.d++ = double_tmp;
490           fparg_count++;
491           FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
492           break;
493
494         case FFI_TYPE_DOUBLE:
495           double_tmp = **p_argv.d;
496           *next_arg.d = double_tmp;
497           if (++next_arg.ul == gpr_end.ul)
498             next_arg.ul = rest.ul;
499           if (fparg_count < NUM_FPR_ARG_REGISTERS64)
500             *fpr_base.d++ = double_tmp;
501           fparg_count++;
502           FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
503           break;
504
505 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
506         case FFI_TYPE_LONGDOUBLE:
507           double_tmp = (*p_argv.d)[0];
508           *next_arg.d = double_tmp;
509           if (++next_arg.ul == gpr_end.ul)
510             next_arg.ul = rest.ul;
511           if (fparg_count < NUM_FPR_ARG_REGISTERS64)
512             *fpr_base.d++ = double_tmp;
513           fparg_count++;
514           double_tmp = (*p_argv.d)[1];
515           *next_arg.d = double_tmp;
516           if (++next_arg.ul == gpr_end.ul)
517             next_arg.ul = rest.ul;
518           if (fparg_count < NUM_FPR_ARG_REGISTERS64)
519             *fpr_base.d++ = double_tmp;
520           fparg_count++;
521           FFI_ASSERT (__LDBL_MANT_DIG__ == 106);
522           FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
523           break;
524 #endif
525
526         case FFI_TYPE_STRUCT:
527           words = ((*ptr)->size + 7) / 8;
528           if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
529             {
530               size_t first = gpr_end.c - next_arg.c;
531               memcpy (next_arg.c, *p_argv.c, first);
532               memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first);
533               next_arg.c = rest.c + words * 8 - first;
534             }
535           else
536             {
537               char *where = next_arg.c;
538
539               /* Structures with size less than eight bytes are passed
540                  left-padded.  */
541               if ((*ptr)->size < 8)
542                 where += 8 - (*ptr)->size;
543
544               memcpy (where, *p_argv.c, (*ptr)->size);
545               next_arg.ul += words;
546               if (next_arg.ul == gpr_end.ul)
547                 next_arg.ul = rest.ul;
548             }
549           break;
550
551         case FFI_TYPE_UINT8:
552           gprvalue = **p_argv.uc;
553           goto putgpr;
554         case FFI_TYPE_SINT8:
555           gprvalue = **p_argv.sc;
556           goto putgpr;
557         case FFI_TYPE_UINT16:
558           gprvalue = **p_argv.us;
559           goto putgpr;
560         case FFI_TYPE_SINT16:
561           gprvalue = **p_argv.ss;
562           goto putgpr;
563         case FFI_TYPE_UINT32:
564           gprvalue = **p_argv.ui;
565           goto putgpr;
566         case FFI_TYPE_INT:
567         case FFI_TYPE_SINT32:
568           gprvalue = **p_argv.si;
569           goto putgpr;
570
571         case FFI_TYPE_UINT64:
572         case FFI_TYPE_SINT64:
573         case FFI_TYPE_POINTER:
574           gprvalue = **p_argv.ul;
575         putgpr:
576           *next_arg.ul++ = gprvalue;
577           if (next_arg.ul == gpr_end.ul)
578             next_arg.ul = rest.ul;
579           break;
580         }
581     }
582
583   FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS
584               || (next_arg.ul >= gpr_base.ul
585                   && next_arg.ul <= gpr_base.ul + 4));
586 }
587
588
589
590 /* Perform machine dependent cif processing */
591 ffi_status
592 ffi_prep_cif_machdep (ffi_cif *cif)
593 {
594   /* All this is for the SYSV and LINUX64 ABI.  */
595   int i;
596   ffi_type **ptr;
597   unsigned bytes;
598   int fparg_count = 0, intarg_count = 0;
599   unsigned flags = 0;
600   unsigned struct_copy_size = 0;
601   unsigned type = cif->rtype->type;
602   unsigned size = cif->rtype->size;
603
604   if (cif->abi == FFI_LINUX_SOFT_FLOAT)
605     NUM_FPR_ARG_REGISTERS = 0;
606
607   if (cif->abi != FFI_LINUX64)
608     {
609       /* All the machine-independent calculation of cif->bytes will be wrong.
610          Redo the calculation for SYSV.  */
611
612       /* Space for the frame pointer, callee's LR, and the asm's temp regs.  */
613       bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int);
614
615       /* Space for the GPR registers.  */
616       bytes += NUM_GPR_ARG_REGISTERS * sizeof (int);
617     }
618   else
619     {
620       /* 64-bit ABI.  */
621
622       /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp
623          regs.  */
624       bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long);
625
626       /* Space for the mandatory parm save area and general registers.  */
627       bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long);
628     }
629
630   /* Return value handling.  The rules for SYSV are as follows:
631      - 32-bit (or less) integer values are returned in gpr3;
632      - Structures of size <= 4 bytes also returned in gpr3;
633      - 64-bit integer values and structures between 5 and 8 bytes are returned
634      in gpr3 and gpr4;
635      - Single/double FP values are returned in fpr1;
636      - Larger structures are allocated space and a pointer is passed as
637      the first argument.
638      - long doubles (if not equivalent to double) are returned in
639      fpr1,fpr2 for Linux and as for large structs for SysV.
640      For LINUX64:
641      - integer values in gpr3;
642      - Structures/Unions by reference;
643      - Single/double FP values in fpr1, long double in fpr1,fpr2.
644      - soft-float float/doubles are treated as UINT32/UINT64 respectivley.
645      - soft-float long doubles are returned in gpr3-gpr6.  */
646   switch (type)
647     {
648 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
649     case FFI_TYPE_LONGDOUBLE:
650       if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64
651         && cif->abi != FFI_LINUX_SOFT_FLOAT)
652         goto byref;
653       flags |= FLAG_RETURNS_128BITS;
654       /* Fall through.  */
655 #endif
656     case FFI_TYPE_DOUBLE:
657       flags |= FLAG_RETURNS_64BITS;
658       /* Fall through.  */
659     case FFI_TYPE_FLOAT:
660       /* With FFI_LINUX_SOFT_FLOAT no fp registers are used.  */
661       if (cif->abi != FFI_LINUX_SOFT_FLOAT)
662         flags |= FLAG_RETURNS_FP;
663       break;
664
665     case FFI_TYPE_UINT64:
666     case FFI_TYPE_SINT64:
667       flags |= FLAG_RETURNS_64BITS;
668       break;
669
670     case FFI_TYPE_STRUCT:
671       if (cif->abi == FFI_SYSV)
672         {
673           /* The final SYSV ABI says that structures smaller or equal 8 bytes
674              are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them
675              in memory.  */
676
677           /* Treat structs with size <= 8 bytes.  */
678           if (size <= 8)
679             {
680               flags |= FLAG_RETURNS_SMST;
681               /* These structs are returned in r3. We pack the type and the
682                  precalculated shift value (needed in the sysv.S) into flags.
683                  The same applies for the structs returned in r3/r4.  */
684               if (size <= 4)
685                 {
686                   flags |= FLAG_SYSV_SMST_R3;
687                   flags |= 8 * (4 - size) << 4;
688                   break;
689                 }
690               /* These structs are returned in r3 and r4. See above.   */
691               if  (size <= 8)
692                 {
693                   flags |= FLAG_SYSV_SMST_R4;
694                   flags |= 8 * (8 - size) << 4;
695                   break;
696                 }
697             }
698         }
699 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
700     byref:
701 #endif
702       intarg_count++;
703       flags |= FLAG_RETVAL_REFERENCE;
704       /* Fall through.  */
705     case FFI_TYPE_VOID:
706       flags |= FLAG_RETURNS_NOTHING;
707       break;
708
709     default:
710       /* Returns 32-bit integer, or similar.  Nothing to do here.  */
711       break;
712     }
713
714   if (cif->abi != FFI_LINUX64)
715     /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
716        first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
717        goes on the stack.  Structures and long doubles (if not equivalent
718        to double) are passed as a pointer to a copy of the structure.
719        Stuff on the stack needs to keep proper alignment.  */
720     for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
721       {
722         switch ((*ptr)->type)
723           {
724           case FFI_TYPE_FLOAT:
725             /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
726             if (cif->abi == FFI_LINUX_SOFT_FLOAT)
727               goto soft_float_cif;
728             fparg_count++;
729             /* floating singles are not 8-aligned on stack */
730             break;
731
732 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
733           case FFI_TYPE_LONGDOUBLE:
734             if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
735               goto do_struct;
736             if (cif->abi == FFI_LINUX_SOFT_FLOAT)
737               {
738                 if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3
739                   || intarg_count < NUM_GPR_ARG_REGISTERS)
740                   /* A long double in FFI_LINUX_SOFT_FLOAT can use only
741                      a set of four consecutive gprs. If we have not enough,
742                      we have to adjust the intarg_count value.  */
743                   intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
744                 intarg_count += 4;
745                 break;
746               }
747             else
748               fparg_count++;
749             /* Fall thru */
750 #endif
751           case FFI_TYPE_DOUBLE:
752             /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
753             if (cif->abi == FFI_LINUX_SOFT_FLOAT)
754               goto soft_double_cif;
755             fparg_count++;
756             /* If this FP arg is going on the stack, it must be
757                8-byte-aligned.  */
758             if (fparg_count > NUM_FPR_ARG_REGISTERS
759                 && intarg_count >= NUM_GPR_ARG_REGISTERS
760                 && intarg_count % 2 != 0)
761               intarg_count++;
762             break;
763
764           case FFI_TYPE_UINT64:
765           case FFI_TYPE_SINT64:
766           soft_double_cif:
767             /* 'long long' arguments are passed as two words, but
768                either both words must fit in registers or both go
769                on the stack.  If they go on the stack, they must
770                be 8-byte-aligned.
771
772                Also, only certain register pairs can be used for
773                passing long long int -- specifically (r3,r4), (r5,r6),
774                (r7,r8), (r9,r10).
775             */
776             if (intarg_count == NUM_GPR_ARG_REGISTERS-1
777                 || intarg_count % 2 != 0)
778               intarg_count++;
779             intarg_count += 2;
780             break;
781
782           case FFI_TYPE_STRUCT:
783 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
784           do_struct:
785 #endif
786             /* We must allocate space for a copy of these to enforce
787                pass-by-value.  Pad the space up to a multiple of 16
788                bytes (the maximum alignment required for anything under
789                the SYSV ABI).  */
790             struct_copy_size += ((*ptr)->size + 15) & ~0xF;
791             /* Fall through (allocate space for the pointer).  */
792
793           default:
794           soft_float_cif:
795             /* Everything else is passed as a 4-byte word in a GPR, either
796                the object itself or a pointer to it.  */
797             intarg_count++;
798             break;
799           }
800       }
801   else
802     for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
803       {
804         switch ((*ptr)->type)
805           {
806 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
807           case FFI_TYPE_LONGDOUBLE:
808             if (cif->abi == FFI_LINUX_SOFT_FLOAT)
809               intarg_count += 4;
810             else
811               {
812                 fparg_count += 2;
813                 intarg_count += 2;
814               }
815             break;
816 #endif
817           case FFI_TYPE_FLOAT:
818           case FFI_TYPE_DOUBLE:
819             fparg_count++;
820             intarg_count++;
821             break;
822
823           case FFI_TYPE_STRUCT:
824             intarg_count += ((*ptr)->size + 7) / 8;
825             break;
826
827           default:
828             /* Everything else is passed as a 8-byte word in a GPR, either
829                the object itself or a pointer to it.  */
830             intarg_count++;
831             break;
832           }
833       }
834
835   if (fparg_count != 0)
836     flags |= FLAG_FP_ARGUMENTS;
837   if (intarg_count > 4)
838     flags |= FLAG_4_GPR_ARGUMENTS;
839   if (struct_copy_size != 0)
840     flags |= FLAG_ARG_NEEDS_COPY;
841
842   if (cif->abi != FFI_LINUX64)
843     {
844       /* Space for the FPR registers, if needed.  */
845       if (fparg_count != 0)
846         bytes += NUM_FPR_ARG_REGISTERS * sizeof (double);
847
848       /* Stack space.  */
849       if (intarg_count > NUM_GPR_ARG_REGISTERS)
850         bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int);
851       if (fparg_count > NUM_FPR_ARG_REGISTERS)
852         bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double);
853     }
854   else
855     {
856       /* Space for the FPR registers, if needed.  */
857       if (fparg_count != 0)
858         bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double);
859
860       /* Stack space.  */
861       if (intarg_count > NUM_GPR_ARG_REGISTERS64)
862         bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long);
863     }
864
865   /* The stack space allocated needs to be a multiple of 16 bytes.  */
866   bytes = (bytes + 15) & ~0xF;
867
868   /* Add in the space for the copied structures.  */
869   bytes += struct_copy_size;
870
871   cif->flags = flags;
872   cif->bytes = bytes;
873
874   return FFI_OK;
875 }
876
877 extern void ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *,
878                           void (*fn)());
879 extern void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long,
880                                         unsigned long, unsigned long *,
881                                         void (*fn)());
882
883 void
884 ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
885 {
886   extended_cif ecif;
887
888   ecif.cif = cif;
889   ecif.avalue = avalue;
890
891   /* If the return value is a struct and we don't have a return */
892   /* value address then we need to make one                     */
893
894   if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
895     {
896       ecif.rvalue = alloca(cif->rtype->size);
897     }
898   else
899     ecif.rvalue = rvalue;
900
901
902   switch (cif->abi)
903     {
904 #ifndef POWERPC64
905     case FFI_SYSV:
906     case FFI_GCC_SYSV:
907     case FFI_LINUX:
908     case FFI_LINUX_SOFT_FLOAT:
909       ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn);
910       break;
911 #else
912     case FFI_LINUX64:
913       ffi_call_LINUX64 (&ecif, -(long) cif->bytes, cif->flags, ecif.rvalue, fn);
914       break;
915 #endif
916     default:
917       FFI_ASSERT (0);
918       break;
919     }
920 }
921
922
923 #ifndef POWERPC64
924 #define MIN_CACHE_LINE_SIZE 8
925
926 static void
927 flush_icache (char *wraddr, char *xaddr, int size)
928 {
929   int i;
930   for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE)
931     __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;"
932                       : : "r" (xaddr + i), "r" (wraddr + i) : "memory");
933   __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;"
934                     : : "r"(xaddr + size - 1), "r"(wraddr + size - 1)
935                     : "memory");
936 }
937 #endif
938
939 ffi_status
940 ffi_prep_closure_loc (ffi_closure *closure,
941                       ffi_cif *cif,
942                       void (*fun) (ffi_cif *, void *, void **, void *),
943                       void *user_data,
944                       void *codeloc)
945 {
946 #ifdef POWERPC64
947   void **tramp = (void **) &closure->tramp[0];
948
949   FFI_ASSERT (cif->abi == FFI_LINUX64);
950   /* Copy function address and TOC from ffi_closure_LINUX64.  */
951   memcpy (tramp, (char *) ffi_closure_LINUX64, 16);
952   tramp[2] = codeloc;
953 #else
954   unsigned int *tramp;
955
956   FFI_ASSERT (cif->abi == FFI_GCC_SYSV || cif->abi == FFI_SYSV);
957
958   tramp = (unsigned int *) &closure->tramp[0];
959   tramp[0] = 0x7c0802a6;  /*   mflr    r0 */
960   tramp[1] = 0x4800000d;  /*   bl      10 <trampoline_initial+0x10> */
961   tramp[4] = 0x7d6802a6;  /*   mflr    r11 */
962   tramp[5] = 0x7c0803a6;  /*   mtlr    r0 */
963   tramp[6] = 0x800b0000;  /*   lwz     r0,0(r11) */
964   tramp[7] = 0x816b0004;  /*   lwz     r11,4(r11) */
965   tramp[8] = 0x7c0903a6;  /*   mtctr   r0 */
966   tramp[9] = 0x4e800420;  /*   bctr */
967   *(void **) &tramp[2] = (void *) ffi_closure_SYSV; /* function */
968   *(void **) &tramp[3] = codeloc;                   /* context */
969
970   /* Flush the icache.  */
971   flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE);
972 #endif
973
974   closure->cif = cif;
975   closure->fun = fun;
976   closure->user_data = user_data;
977
978   return FFI_OK;
979 }
980
981 typedef union
982 {
983   float f;
984   double d;
985 } ffi_dblfl;
986
987 int ffi_closure_helper_SYSV (ffi_closure *, void *, unsigned long *,
988                              ffi_dblfl *, unsigned long *);
989
990 /* Basically the trampoline invokes ffi_closure_SYSV, and on
991  * entry, r11 holds the address of the closure.
992  * After storing the registers that could possibly contain
993  * parameters to be passed into the stack frame and setting
994  * up space for a return value, ffi_closure_SYSV invokes the
995  * following helper function to do most of the work
996  */
997
998 int
999 ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue,
1000                          unsigned long *pgr, ffi_dblfl *pfr,
1001                          unsigned long *pst)
1002 {
1003   /* rvalue is the pointer to space for return value in closure assembly */
1004   /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
1005   /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV  */
1006   /* pst is the pointer to outgoing parameter stack in original caller */
1007
1008   void **          avalue;
1009   ffi_type **      arg_types;
1010   long             i, avn;
1011   long             nf;   /* number of floating registers already used */
1012   long             ng;   /* number of general registers already used */
1013   ffi_cif *        cif;
1014   double           temp;
1015   unsigned         size;
1016
1017   cif = closure->cif;
1018   avalue = alloca (cif->nargs * sizeof (void *));
1019   size = cif->rtype->size;
1020
1021   nf = 0;
1022   ng = 0;
1023
1024   /* Copy the caller's structure return value address so that the closure
1025      returns the data directly to the caller.
1026      For FFI_SYSV the result is passed in r3/r4 if the struct size is less
1027      or equal 8 bytes.  */
1028
1029   if ((cif->rtype->type == FFI_TYPE_STRUCT
1030        && !((cif->abi == FFI_SYSV) && (size <= 8)))
1031 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1032       || (cif->rtype->type == FFI_TYPE_LONGDOUBLE
1033           && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
1034 #endif
1035       )
1036     {
1037       rvalue = (void *) *pgr;
1038       ng++;
1039       pgr++;
1040     }
1041
1042   i = 0;
1043   avn = cif->nargs;
1044   arg_types = cif->arg_types;
1045
1046   /* Grab the addresses of the arguments from the stack frame.  */
1047   while (i < avn)
1048     {
1049       switch (arg_types[i]->type)
1050         {
1051         case FFI_TYPE_SINT8:
1052         case FFI_TYPE_UINT8:
1053           /* there are 8 gpr registers used to pass values */
1054           if (ng < 8)
1055             {
1056               avalue[i] = (char *) pgr + 3;
1057               ng++;
1058               pgr++;
1059             }
1060           else
1061             {
1062               avalue[i] = (char *) pst + 3;
1063               pst++;
1064             }
1065           break;
1066
1067         case FFI_TYPE_SINT16:
1068         case FFI_TYPE_UINT16:
1069           /* there are 8 gpr registers used to pass values */
1070           if (ng < 8)
1071             {
1072               avalue[i] = (char *) pgr + 2;
1073               ng++;
1074               pgr++;
1075             }
1076           else
1077             {
1078               avalue[i] = (char *) pst + 2;
1079               pst++;
1080             }
1081           break;
1082
1083         case FFI_TYPE_SINT32:
1084         case FFI_TYPE_UINT32:
1085         case FFI_TYPE_POINTER:
1086         soft_float_closure:
1087           /* there are 8 gpr registers used to pass values */
1088           if (ng < 8)
1089             {
1090               avalue[i] = pgr;
1091               ng++;
1092               pgr++;
1093             }
1094           else
1095             {
1096               avalue[i] = pst;
1097               pst++;
1098             }
1099           break;
1100
1101         case FFI_TYPE_STRUCT:
1102 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1103         do_struct:
1104 #endif
1105           /* Structs are passed by reference. The address will appear in a
1106              gpr if it is one of the first 8 arguments.  */
1107           if (ng < 8)
1108             {
1109               avalue[i] = (void *) *pgr;
1110               ng++;
1111               pgr++;
1112             }
1113           else
1114             {
1115               avalue[i] = (void *) *pst;
1116               pst++;
1117             }
1118           break;
1119
1120         case FFI_TYPE_SINT64:
1121         case FFI_TYPE_UINT64:
1122         soft_double_closure:
1123           /* passing long long ints are complex, they must
1124            * be passed in suitable register pairs such as
1125            * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
1126            * and if the entire pair aren't available then the outgoing
1127            * parameter stack is used for both but an alignment of 8
1128            * must will be kept.  So we must either look in pgr
1129            * or pst to find the correct address for this type
1130            * of parameter.
1131            */
1132           if (ng < 7)
1133             {
1134               if (ng & 0x01)
1135                 {
1136                   /* skip r4, r6, r8 as starting points */
1137                   ng++;
1138                   pgr++;
1139                 }
1140               avalue[i] = pgr;
1141               ng += 2;
1142               pgr += 2;
1143             }
1144           else
1145             {
1146               if (((long) pst) & 4)
1147                 pst++;
1148               avalue[i] = pst;
1149               pst += 2;
1150             }
1151           break;
1152
1153         case FFI_TYPE_FLOAT:
1154           /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
1155           if (cif->abi == FFI_LINUX_SOFT_FLOAT)
1156             goto soft_float_closure;
1157           /* unfortunately float values are stored as doubles
1158            * in the ffi_closure_SYSV code (since we don't check
1159            * the type in that routine).
1160            */
1161
1162           /* there are 8 64bit floating point registers */
1163
1164           if (nf < 8)
1165             {
1166               temp = pfr->d;
1167               pfr->f = (float) temp;
1168               avalue[i] = pfr;
1169               nf++;
1170               pfr++;
1171             }
1172           else
1173             {
1174               /* FIXME? here we are really changing the values
1175                * stored in the original calling routines outgoing
1176                * parameter stack.  This is probably a really
1177                * naughty thing to do but...
1178                */
1179               avalue[i] = pst;
1180               pst += 1;
1181             }
1182           break;
1183
1184         case FFI_TYPE_DOUBLE:
1185           /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
1186           if (cif->abi == FFI_LINUX_SOFT_FLOAT)
1187             goto soft_double_closure;
1188           /* On the outgoing stack all values are aligned to 8 */
1189           /* there are 8 64bit floating point registers */
1190
1191           if (nf < 8)
1192             {
1193               avalue[i] = pfr;
1194               nf++;
1195               pfr++;
1196             }
1197           else
1198             {
1199               if (((long) pst) & 4)
1200                 pst++;
1201               avalue[i] = pst;
1202               pst += 2;
1203             }
1204           break;
1205
1206 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1207         case FFI_TYPE_LONGDOUBLE:
1208           if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
1209             goto do_struct;
1210           if (cif->abi == FFI_LINUX_SOFT_FLOAT)
1211             { /* Test if for the whole long double, 4 gprs are available.
1212                  otherwise the stuff ends up on the stack.  */
1213               if (ng < 5)
1214                 {
1215                   avalue[i] = pgr;
1216                   pgr += 4;
1217                   ng += 4;
1218                 }
1219               else
1220                 {
1221                   avalue[i] = pst;
1222                   pst += 4;
1223                 }
1224               break;
1225             }
1226           if (nf < 7)
1227             {
1228               avalue[i] = pfr;
1229               pfr += 2;
1230               nf += 2;
1231             }
1232           else
1233             {
1234               if (((long) pst) & 4)
1235                 pst++;
1236               avalue[i] = pst;
1237               pst += 4;
1238               nf = 8;
1239             }
1240           break;
1241 #endif
1242
1243         default:
1244           FFI_ASSERT (0);
1245         }
1246
1247       i++;
1248     }
1249
1250
1251   (closure->fun) (cif, rvalue, avalue, closure->user_data);
1252
1253   /* Tell ffi_closure_SYSV how to perform return type promotions.
1254      Because the FFI_SYSV ABI returns the structures <= 8 bytes in r3/r4
1255      we have to tell ffi_closure_SYSV how to treat them. We combine the base
1256      type FFI_SYSV_TYPE_SMALL_STRUCT - 1  with the size of the struct.
1257      So a one byte struct gets the return type 16. Return type 1 to 15 are
1258      already used and we never have a struct with size zero. That is the reason
1259      for the subtraction of 1. See the comment in ffitarget.h about ordering.
1260   */
1261   if (cif->abi == FFI_SYSV && cif->rtype->type == FFI_TYPE_STRUCT
1262       && size <= 8)
1263     return (FFI_SYSV_TYPE_SMALL_STRUCT - 1) + size;
1264 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1265   else if (cif->rtype->type == FFI_TYPE_LONGDOUBLE
1266            && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
1267     return FFI_TYPE_STRUCT;
1268 #endif
1269   /* With FFI_LINUX_SOFT_FLOAT floats and doubles are handled like UINT32
1270      respectivley UINT64.  */
1271   if (cif->abi == FFI_LINUX_SOFT_FLOAT)
1272     {
1273       switch (cif->rtype->type)
1274         {
1275         case FFI_TYPE_FLOAT:
1276           return FFI_TYPE_UINT32;
1277           break;
1278         case FFI_TYPE_DOUBLE:
1279           return FFI_TYPE_UINT64;
1280           break;
1281 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1282         case FFI_TYPE_LONGDOUBLE:
1283           return FFI_TYPE_UINT128;
1284           break;
1285 #endif
1286         default:
1287           return cif->rtype->type;
1288         }
1289     }
1290   else
1291     {
1292       return cif->rtype->type;
1293     }
1294 }
1295
1296 int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *,
1297                                            unsigned long *, ffi_dblfl *);
1298
1299 int FFI_HIDDEN
1300 ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
1301                             unsigned long *pst, ffi_dblfl *pfr)
1302 {
1303   /* rvalue is the pointer to space for return value in closure assembly */
1304   /* pst is the pointer to parameter save area
1305      (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */
1306   /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */
1307
1308   void **avalue;
1309   ffi_type **arg_types;
1310   long i, avn;
1311   ffi_cif *cif;
1312   ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;
1313
1314   cif = closure->cif;
1315   avalue = alloca (cif->nargs * sizeof (void *));
1316
1317   /* Copy the caller's structure return value address so that the closure
1318      returns the data directly to the caller.  */
1319   if (cif->rtype->type == FFI_TYPE_STRUCT)
1320     {
1321       rvalue = (void *) *pst;
1322       pst++;
1323     }
1324
1325   i = 0;
1326   avn = cif->nargs;
1327   arg_types = cif->arg_types;
1328
1329   /* Grab the addresses of the arguments from the stack frame.  */
1330   while (i < avn)
1331     {
1332       switch (arg_types[i]->type)
1333         {
1334         case FFI_TYPE_SINT8:
1335         case FFI_TYPE_UINT8:
1336           avalue[i] = (char *) pst + 7;
1337           pst++;
1338           break;
1339
1340         case FFI_TYPE_SINT16:
1341         case FFI_TYPE_UINT16:
1342           avalue[i] = (char *) pst + 6;
1343           pst++;
1344           break;
1345
1346         case FFI_TYPE_SINT32:
1347         case FFI_TYPE_UINT32:
1348           avalue[i] = (char *) pst + 4;
1349           pst++;
1350           break;
1351
1352         case FFI_TYPE_SINT64:
1353         case FFI_TYPE_UINT64:
1354         case FFI_TYPE_POINTER:
1355           avalue[i] = pst;
1356           pst++;
1357           break;
1358
1359         case FFI_TYPE_STRUCT:
1360           /* Structures with size less than eight bytes are passed
1361              left-padded.  */
1362           if (arg_types[i]->size < 8)
1363             avalue[i] = (char *) pst + 8 - arg_types[i]->size;
1364           else
1365             avalue[i] = pst;
1366           pst += (arg_types[i]->size + 7) / 8;
1367           break;
1368
1369         case FFI_TYPE_FLOAT:
1370           /* unfortunately float values are stored as doubles
1371            * in the ffi_closure_LINUX64 code (since we don't check
1372            * the type in that routine).
1373            */
1374
1375           /* there are 13 64bit floating point registers */
1376
1377           if (pfr < end_pfr)
1378             {
1379               double temp = pfr->d;
1380               pfr->f = (float) temp;
1381               avalue[i] = pfr;
1382               pfr++;
1383             }
1384           else
1385             avalue[i] = pst;
1386           pst++;
1387           break;
1388
1389         case FFI_TYPE_DOUBLE:
1390           /* On the outgoing stack all values are aligned to 8 */
1391           /* there are 13 64bit floating point registers */
1392
1393           if (pfr < end_pfr)
1394             {
1395               avalue[i] = pfr;
1396               pfr++;
1397             }
1398           else
1399             avalue[i] = pst;
1400           pst++;
1401           break;
1402
1403 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1404         case FFI_TYPE_LONGDOUBLE:
1405           if (pfr + 1 < end_pfr)
1406             {
1407               avalue[i] = pfr;
1408               pfr += 2;
1409             }
1410           else
1411             {
1412               if (pfr < end_pfr)
1413                 {
1414                   /* Passed partly in f13 and partly on the stack.
1415                      Move it all to the stack.  */
1416                   *pst = *(unsigned long *) pfr;
1417                   pfr++;
1418                 }
1419               avalue[i] = pst;
1420             }
1421           pst += 2;
1422           break;
1423 #endif
1424
1425         default:
1426           FFI_ASSERT (0);
1427         }
1428
1429       i++;
1430     }
1431
1432
1433   (closure->fun) (cif, rvalue, avalue, closure->user_data);
1434
1435   /* Tell ffi_closure_LINUX64 how to perform return type promotions.  */
1436   return cif->rtype->type;
1437 }