OSDN Git Service

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