OSDN Git Service

* config/m68k/m68k.c, config/m68k/m68k.md (SGS, SGS_CMP_ORDER): Remove
[pf3gnuchains/gcc-fork.git] / libffi / src / powerpc / ffi.c
1 /* -----------------------------------------------------------------------
2    ffi.c - Copyright (c) 1998 Geoffrey Keating
3    
4    PowerPC Foreign Function Interface 
5
6    $Id: ffi.c,v 1.1.1.1 1998/11/29 16:48:16 green Exp $
7
8    Permission is hereby granted, free of charge, to any person obtaining
9    a copy of this software and associated documentation files (the
10    ``Software''), to deal in the Software without restriction, including
11    without limitation the rights to use, copy, modify, merge, publish,
12    distribute, sublicense, and/or sell copies of the Software, and to
13    permit persons to whom the Software is furnished to do so, subject to
14    the following conditions:
15
16    The above copyright notice and this permission notice shall be included
17    in all copies or substantial portions of the Software.
18
19    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
20    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
23    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25    OTHER DEALINGS IN THE SOFTWARE.
26    ----------------------------------------------------------------------- */
27
28 #include <ffi.h>
29 #include <ffi_common.h>
30
31 #include <stdlib.h>
32 #include <stdio.h>
33
34 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 1)
35 # define hidden __attribute__ ((visibility ("hidden")))
36 #else
37 # define hidden
38 #endif
39
40
41 extern void ffi_closure_SYSV(void);
42 extern void hidden ffi_closure_LINUX64(void);
43
44 enum {
45   /* The assembly depends on these exact flags.  */
46   FLAG_RETURNS_NOTHING  = 1 << (31-30), /* These go in cr7 */
47   FLAG_RETURNS_FP       = 1 << (31-29),
48   FLAG_RETURNS_64BITS   = 1 << (31-28),
49
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 enum {
58   NUM_GPR_ARG_REGISTERS = 8,
59   NUM_FPR_ARG_REGISTERS = 8
60 };
61 enum { ASM_NEEDS_REGISTERS = 4 };
62
63 /* ffi_prep_args_SYSV is called by the assembly routine once stack space
64    has been allocated for the function's arguments.
65
66    The stack layout we want looks like this:
67
68    |   Return address from ffi_call_SYSV 4bytes |       higher addresses
69    |--------------------------------------------|
70    |   Previous backchain pointer       4       |       stack pointer here
71    |--------------------------------------------|<+ <<< on entry to
72    |   Saved r28-r31                    4*4     | |     ffi_call_SYSV
73    |--------------------------------------------| |
74    |   GPR registers r3-r10             8*4     | |     ffi_call_SYSV
75    |--------------------------------------------| |
76    |   FPR registers f1-f8 (optional)   8*8     | |
77    |--------------------------------------------| |     stack   |
78    |   Space for copied structures              | |     grows   |
79    |--------------------------------------------| |     down    V
80    |   Parameters that didn't fit in registers  | |
81    |--------------------------------------------| |     lower addresses
82    |   Space for callee's LR            4       | |
83    |--------------------------------------------| |     stack pointer here
84    |   Current backchain pointer        4       |-/     during
85    |--------------------------------------------|   <<< ffi_call_SYSV
86
87    */
88
89 /*@-exportheader@*/
90 void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack)
91 /*@=exportheader@*/
92 {
93   const unsigned bytes = ecif->cif->bytes;
94   const unsigned flags = ecif->cif->flags;
95   
96   /* 'stacktop' points at the previous backchain pointer.  */
97   unsigned *const stacktop = stack + (ecif->cif->bytes / sizeof(unsigned));
98
99   /* 'gpr_base' points at the space for gpr3, and grows upwards as
100      we use GPR registers.  */
101   unsigned *gpr_base = stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
102   int intarg_count = 0;
103
104   /* 'fpr_base' points at the space for fpr1, and grows upwards as
105      we use FPR registers.  */
106   double *fpr_base = (double *)gpr_base - NUM_FPR_ARG_REGISTERS;
107   int fparg_count = 0;
108
109   /* 'copy_space' grows down as we put structures in it.  It should
110      stay 16-byte aligned.  */
111   char *copy_space = ((flags & FLAG_FP_ARGUMENTS)
112                       ? (char *)fpr_base
113                       : (char *)gpr_base);
114
115   /* 'next_arg' grows up as we put parameters in it.  */
116   unsigned *next_arg = stack + 2;
117
118   int i;
119   ffi_type **ptr;
120   double double_tmp;
121   void **p_argv;
122   size_t struct_copy_size;
123   unsigned gprvalue;
124
125   /* Check that everything starts aligned properly.  */
126   FFI_ASSERT(((unsigned)(char *)stack & 0xF) == 0);
127   FFI_ASSERT(((unsigned)(char *)copy_space & 0xF) == 0);
128   FFI_ASSERT(((unsigned)(char *)stacktop & 0xF) == 0);
129   FFI_ASSERT((bytes & 0xF) == 0);
130   FFI_ASSERT(copy_space >= (char *)next_arg);
131
132   /* Deal with return values that are actually pass-by-reference.  */
133   if (flags & FLAG_RETVAL_REFERENCE)
134   {
135     *gpr_base++ = (unsigned long)(char *)ecif->rvalue;
136     intarg_count++;
137   }
138
139   /* Now for the arguments.  */
140   p_argv = ecif->avalue;
141   for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
142        i > 0;
143        i--, ptr++, p_argv++)
144     {
145       switch ((*ptr)->type)
146         {
147         case FFI_TYPE_FLOAT:
148           double_tmp = *(float *)*p_argv;
149           if (fparg_count >= NUM_FPR_ARG_REGISTERS)
150             {
151               *(float *)next_arg = (float)double_tmp;
152               next_arg += 1;
153             }
154           else
155             *fpr_base++ = double_tmp;
156           fparg_count++;
157           FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
158           break;
159
160         case FFI_TYPE_DOUBLE:
161           double_tmp = *(double *)*p_argv;
162
163           if (fparg_count >= NUM_FPR_ARG_REGISTERS)
164             {
165               if (intarg_count%2 != 0)
166                 {
167                   intarg_count++;
168                   next_arg++;
169                 }
170               *(double *)next_arg = double_tmp;
171               next_arg += 2;
172             }
173           else
174             *fpr_base++ = double_tmp;
175           fparg_count++;
176           FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
177           break;
178
179         case FFI_TYPE_UINT64:
180         case FFI_TYPE_SINT64:
181           if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
182             intarg_count++;
183           if (intarg_count >= NUM_GPR_ARG_REGISTERS)
184             {
185               if (intarg_count%2 != 0)
186                 {
187                   intarg_count++;
188                   next_arg++;
189                 }
190               *(long long *)next_arg = *(long long *)*p_argv;
191               next_arg += 2;
192             }
193           else
194             {
195               /* whoops: abi states only certain register pairs
196                * can be used for passing long long int
197                * specifically (r3,r4), (r5,r6), (r7,r8), 
198                * (r9,r10) and if next arg is long long but
199                * not correct starting register of pair then skip
200                * until the proper starting register
201                */
202               if (intarg_count%2 != 0)
203                 {
204                   intarg_count ++;
205                   gpr_base++;
206                 }
207               *(long long *)gpr_base = *(long long *)*p_argv;
208               gpr_base += 2;
209             }
210           intarg_count += 2;
211           break;
212
213         case FFI_TYPE_STRUCT:
214 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
215         case FFI_TYPE_LONGDOUBLE:
216 #endif
217           struct_copy_size = ((*ptr)->size + 15) & ~0xF;
218           copy_space -= struct_copy_size;
219           memcpy(copy_space, (char *)*p_argv, (*ptr)->size);
220           
221           gprvalue = (unsigned long)copy_space;
222
223           FFI_ASSERT(copy_space > (char *)next_arg);
224           FFI_ASSERT(flags & FLAG_ARG_NEEDS_COPY);
225           goto putgpr;
226
227         case FFI_TYPE_UINT8:
228           gprvalue = *(unsigned char *)*p_argv;
229           goto putgpr;
230         case FFI_TYPE_SINT8:
231           gprvalue = *(signed char *)*p_argv;
232           goto putgpr;
233         case FFI_TYPE_UINT16:
234           gprvalue = *(unsigned short *)*p_argv;
235           goto putgpr;
236         case FFI_TYPE_SINT16:
237           gprvalue = *(signed short *)*p_argv;
238           goto putgpr;
239
240         case FFI_TYPE_INT:
241         case FFI_TYPE_UINT32:
242         case FFI_TYPE_SINT32:
243         case FFI_TYPE_POINTER:
244           gprvalue = *(unsigned *)*p_argv;
245         putgpr:
246           if (intarg_count >= NUM_GPR_ARG_REGISTERS)
247             *next_arg++ = gprvalue;
248           else
249             *gpr_base++ = gprvalue;
250           intarg_count++;
251           break;
252         }
253     }
254
255   /* Check that we didn't overrun the stack...  */
256   FFI_ASSERT(copy_space >= (char *)next_arg);
257   FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
258   FFI_ASSERT((unsigned *)fpr_base
259              <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
260   FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
261 }
262
263 /* About the LINUX64 ABI.  */
264 enum {
265   NUM_GPR_ARG_REGISTERS64 = 8,
266   NUM_FPR_ARG_REGISTERS64 = 13
267 };
268 enum { ASM_NEEDS_REGISTERS64 = 4 };
269
270 /* ffi_prep_args64 is called by the assembly routine once stack space
271    has been allocated for the function's arguments.
272
273    The stack layout we want looks like this:
274
275    |   Ret addr from ffi_call_LINUX64   8bytes  |       higher addresses
276    |--------------------------------------------|
277    |   CR save area                     8bytes  |
278    |--------------------------------------------|
279    |   Previous backchain pointer       8       |       stack pointer here
280    |--------------------------------------------|<+ <<< on entry to
281    |   Saved r28-r31                    4*8     | |     ffi_call_LINUX64
282    |--------------------------------------------| |
283    |   GPR registers r3-r10             8*8     | |
284    |--------------------------------------------| |
285    |   FPR registers f1-f13 (optional)  13*8    | |
286    |--------------------------------------------| |
287    |   Parameter save area                      | |
288    |--------------------------------------------| |
289    |   TOC save area                    8       | |
290    |--------------------------------------------| |     stack   |
291    |   Linker doubleword                8       | |     grows   |
292    |--------------------------------------------| |     down    V
293    |   Compiler doubleword              8       | |
294    |--------------------------------------------| |     lower addresses
295    |   Space for callee's LR            8       | |
296    |--------------------------------------------| |
297    |   CR save area                     8       | |
298    |--------------------------------------------| |     stack pointer here
299    |   Current backchain pointer        8       |-/     during
300    |--------------------------------------------|   <<< ffi_call_LINUX64
301
302    */
303
304 /*@-exportheader@*/
305 void hidden ffi_prep_args64(extended_cif *ecif, unsigned long *const stack)
306 /*@=exportheader@*/
307 {
308   const unsigned long bytes = ecif->cif->bytes;
309   const unsigned long flags = ecif->cif->flags;
310
311   /* 'stacktop' points at the previous backchain pointer.  */
312   unsigned long *const stacktop = stack + (bytes / sizeof(unsigned long));
313
314   /* 'next_arg' points at the space for gpr3, and grows upwards as
315      we use GPR registers, then continues at rest.  */
316   unsigned long *const gpr_base = stacktop - ASM_NEEDS_REGISTERS64
317                                   - NUM_GPR_ARG_REGISTERS64;
318   unsigned long *const gpr_end = gpr_base + NUM_GPR_ARG_REGISTERS64;
319   unsigned long *const rest = stack + 6 + NUM_GPR_ARG_REGISTERS64;
320   unsigned long *next_arg = gpr_base;
321
322   /* 'fpr_base' points at the space for fpr3, and grows upwards as
323      we use FPR registers.  */
324   double *fpr_base = (double *)gpr_base - NUM_FPR_ARG_REGISTERS64;
325   int fparg_count = 0;
326
327   int i, words;
328   ffi_type **ptr;
329   double double_tmp;
330   void **p_argv;
331   unsigned long gprvalue;
332
333   /* Check that everything starts aligned properly.  */
334   FFI_ASSERT(((unsigned long)(char *)stack & 0xF) == 0);
335   FFI_ASSERT(((unsigned long)(char *)stacktop & 0xF) == 0);
336   FFI_ASSERT((bytes & 0xF) == 0);
337
338   /* Deal with return values that are actually pass-by-reference.  */
339   if (flags & FLAG_RETVAL_REFERENCE)
340     *next_arg++ = (unsigned long)(char *)ecif->rvalue;
341
342   /* Now for the arguments.  */
343   p_argv = ecif->avalue;
344   for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
345        i > 0;
346        i--, ptr++, p_argv++)
347     {
348       switch ((*ptr)->type)
349         {
350         case FFI_TYPE_FLOAT:
351           double_tmp = *(float *)*p_argv;
352           *(float *)next_arg = (float)double_tmp;
353           if (++next_arg == gpr_end)
354             next_arg = rest;
355           if (fparg_count < NUM_FPR_ARG_REGISTERS64)
356             *fpr_base++ = double_tmp;
357           fparg_count++;
358           FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
359           break;
360
361         case FFI_TYPE_DOUBLE:
362           double_tmp = *(double *)*p_argv;
363           *(double *)next_arg = double_tmp;
364           if (++next_arg == gpr_end)
365             next_arg = rest;
366           if (fparg_count < NUM_FPR_ARG_REGISTERS64)
367             *fpr_base++ = double_tmp;
368           fparg_count++;
369           FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
370           break;
371
372         case FFI_TYPE_STRUCT:
373 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
374         case FFI_TYPE_LONGDOUBLE:
375 #endif
376           words = ((*ptr)->size + 7) / 8;
377           if (next_arg >= gpr_base && next_arg + words > gpr_end)
378             {
379               size_t first = (char *) gpr_end - (char *) next_arg;
380               memcpy((char *) next_arg, (char *) *p_argv, first);
381               memcpy((char *) rest, (char *) *p_argv + first,
382                      (*ptr)->size - first);
383               next_arg = (unsigned long *) ((char *) rest + words * 8 - first);
384             }
385           else
386             {
387               char *where = (char *) next_arg;
388
389               /* Structures with size less than eight bytes are passed
390                  left-padded.  */
391               if ((*ptr)->size < 8)
392                 where += 8 - (*ptr)->size;
393
394               memcpy (where, (char *) *p_argv, (*ptr)->size);
395               next_arg += words;
396               if (next_arg == gpr_end)
397                 next_arg = rest;
398             }
399           break;
400
401         case FFI_TYPE_UINT8:
402           gprvalue = *(unsigned char *)*p_argv;
403           goto putgpr;
404         case FFI_TYPE_SINT8:
405           gprvalue = *(signed char *)*p_argv;
406           goto putgpr;
407         case FFI_TYPE_UINT16:
408           gprvalue = *(unsigned short *)*p_argv;
409           goto putgpr;
410         case FFI_TYPE_SINT16:
411           gprvalue = *(signed short *)*p_argv;
412           goto putgpr;
413         case FFI_TYPE_UINT32:
414           gprvalue = *(unsigned int *)*p_argv;
415           goto putgpr;
416         case FFI_TYPE_INT:
417         case FFI_TYPE_SINT32:
418           gprvalue = *(signed int *)*p_argv;
419           goto putgpr;
420         
421         case FFI_TYPE_UINT64:
422         case FFI_TYPE_SINT64:
423         case FFI_TYPE_POINTER:
424           gprvalue = *(unsigned long *)*p_argv;
425         putgpr:
426           *next_arg++ = gprvalue;
427           if (next_arg == gpr_end)
428             next_arg = rest;
429           break;
430         }
431     }
432
433   FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS
434              || (next_arg >= gpr_base && next_arg <= gpr_base + 4));
435 }
436
437
438
439 /* Perform machine dependent cif processing */
440 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
441 {
442   /* All this is for the SYSV and LINUX64 ABI.  */
443   int i;
444   ffi_type **ptr;
445   unsigned bytes;
446   int fparg_count = 0, intarg_count = 0;
447   unsigned flags = 0;
448   unsigned struct_copy_size = 0;
449   unsigned type = cif->rtype->type;
450
451   if (cif->abi != FFI_LINUX64)
452     {    
453       /* All the machine-independent calculation of cif->bytes will be wrong.
454          Redo the calculation for SYSV.  */
455
456       /* Space for the frame pointer, callee's LR, and the asm's temp regs.  */
457       bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof(int);
458
459       /* Space for the GPR registers.  */
460       bytes += NUM_GPR_ARG_REGISTERS * sizeof(int);
461     }
462   else
463     {
464       /* 64-bit ABI.  */
465
466       /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp
467          regs.  */
468       bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof(long);
469
470       /* Space for the mandatory parm save area and general registers.  */
471       bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof(long);
472
473 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
474       if (type == FFI_TYPE_LONGDOUBLE)
475         type = FFI_TYPE_DOUBLE;
476 #endif
477     }
478
479   /* Return value handling.  The rules for SYSV are as follows:
480      - 32-bit (or less) integer values are returned in gpr3;
481      - Structures of size <= 4 bytes also returned in gpr3;
482      - 64-bit integer values and structures between 5 and 8 bytes are returned
483        in gpr3 and gpr4;
484      - Single/double FP values are returned in fpr1;
485      - Larger structures and long double (if not equivalent to double) values
486        are allocated space and a pointer is passed as the first argument.
487      For LINUX64:
488      - integer values in gpr3;
489      - Structures/Unions by reference;
490      - Single/double FP values in fpr1, long double in fpr1,fpr2.  */
491   switch (type)
492     {
493     case FFI_TYPE_DOUBLE:
494       flags |= FLAG_RETURNS_64BITS;
495       /* Fall through.  */
496     case FFI_TYPE_FLOAT:
497       flags |= FLAG_RETURNS_FP;
498       break;
499
500     case FFI_TYPE_UINT64:
501     case FFI_TYPE_SINT64:
502       flags |= FLAG_RETURNS_64BITS;
503       break;
504
505     case FFI_TYPE_STRUCT:
506       if (cif->abi != FFI_GCC_SYSV && cif->abi != FFI_LINUX64)
507         if (cif->rtype->size <= 4)
508           break;
509         else if (cif->rtype->size <= 8)
510           {
511             flags |= FLAG_RETURNS_64BITS;
512             break;
513           }
514       /* else fall through.  */
515 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
516     case FFI_TYPE_LONGDOUBLE:
517 #endif
518       intarg_count++;
519       flags |= FLAG_RETVAL_REFERENCE;
520       /* Fall through.  */
521     case FFI_TYPE_VOID:
522       flags |= FLAG_RETURNS_NOTHING;
523       break;
524
525     default:
526       /* Returns 32-bit integer, or similar.  Nothing to do here.  */
527       break;
528     }
529
530   if (cif->abi != FFI_LINUX64)
531     /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
532        first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
533        goes on the stack.  Structures and long doubles (if not equivalent
534        to double) are passed as a pointer to a copy of the structure.
535        Stuff on the stack needs to keep proper alignment.  */
536     for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
537       {
538         switch ((*ptr)->type)
539           {
540           case FFI_TYPE_FLOAT:
541             fparg_count++;
542             /* floating singles are not 8-aligned on stack */
543             break;
544
545           case FFI_TYPE_DOUBLE:
546             fparg_count++;
547             /* If this FP arg is going on the stack, it must be
548                8-byte-aligned.  */
549             if (fparg_count > NUM_FPR_ARG_REGISTERS
550                 && intarg_count%2 != 0)
551               intarg_count++;
552             break;
553
554           case FFI_TYPE_UINT64:
555           case FFI_TYPE_SINT64:
556             /* 'long long' arguments are passed as two words, but
557                either both words must fit in registers or both go
558                on the stack.  If they go on the stack, they must
559                be 8-byte-aligned.  */
560             if (intarg_count == NUM_GPR_ARG_REGISTERS-1
561                 || (intarg_count >= NUM_GPR_ARG_REGISTERS
562                     && intarg_count%2 != 0))
563               intarg_count++;
564             intarg_count += 2;
565             break;
566
567           case FFI_TYPE_STRUCT:
568 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
569           case FFI_TYPE_LONGDOUBLE:
570 #endif
571             /* We must allocate space for a copy of these to enforce
572                pass-by-value.  Pad the space up to a multiple of 16
573                bytes (the maximum alignment required for anything under
574                the SYSV ABI).  */
575             struct_copy_size += ((*ptr)->size + 15) & ~0xF;
576             /* Fall through (allocate space for the pointer).  */
577
578           default:
579             /* Everything else is passed as a 4-byte word in a GPR, either
580                the object itself or a pointer to it.  */
581             intarg_count++;
582             break;
583           }
584       }
585   else
586     for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
587       {
588         switch ((*ptr)->type)
589           {
590 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
591           case FFI_TYPE_LONGDOUBLE:
592             fparg_count += 2;
593             intarg_count += 2;
594             break;
595 #endif
596           case FFI_TYPE_FLOAT:
597           case FFI_TYPE_DOUBLE:
598             fparg_count++;
599             intarg_count++;
600             break;
601
602           case FFI_TYPE_STRUCT:
603             intarg_count += ((*ptr)->size + 7) / 8;
604             break;
605
606           default:
607             /* Everything else is passed as a 8-byte word in a GPR, either
608                the object itself or a pointer to it.  */
609             intarg_count++;
610             break;
611           }
612       }
613
614   if (fparg_count != 0)
615     flags |= FLAG_FP_ARGUMENTS;
616   if (intarg_count > 4)
617     flags |= FLAG_4_GPR_ARGUMENTS;
618   if (struct_copy_size != 0)
619     flags |= FLAG_ARG_NEEDS_COPY;
620
621   if (cif->abi != FFI_LINUX64)
622     {
623       /* Space for the FPR registers, if needed.  */
624       if (fparg_count != 0)
625         bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
626
627       /* Stack space.  */
628       if (intarg_count > NUM_GPR_ARG_REGISTERS)
629         bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof(int);
630       if (fparg_count > NUM_FPR_ARG_REGISTERS)
631         bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof(double);
632     }
633   else
634     {
635       /* Space for the FPR registers, if needed.  */
636       if (fparg_count != 0)
637         bytes += NUM_FPR_ARG_REGISTERS64 * sizeof(double);
638
639       /* Stack space.  */
640       if (intarg_count > NUM_GPR_ARG_REGISTERS64)
641         bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof(long);
642     }
643
644   /* The stack space allocated needs to be a multiple of 16 bytes.  */
645   bytes = (bytes + 15) & ~0xF;
646
647   /* Add in the space for the copied structures.  */
648   bytes += struct_copy_size;
649
650   cif->flags = flags;
651   cif->bytes = bytes;
652
653   return FFI_OK;
654 }
655
656 /*@-declundef@*/
657 /*@-exportheader@*/
658 extern void ffi_call_SYSV(/*@out@*/ extended_cif *, 
659                           unsigned, unsigned, 
660                           /*@out@*/ unsigned *, 
661                           void (*fn)());
662 extern void hidden ffi_call_LINUX64(/*@out@*/ extended_cif *, 
663                                     unsigned long, unsigned long,
664                                     /*@out@*/ unsigned long *, 
665                                     void (*fn)());
666 /*@=declundef@*/
667 /*@=exportheader@*/
668
669 void ffi_call(/*@dependent@*/ ffi_cif *cif, 
670               void (*fn)(), 
671               /*@out@*/ void *rvalue, 
672               /*@dependent@*/ void **avalue)
673 {
674   extended_cif ecif;
675
676   ecif.cif = cif;
677   ecif.avalue = avalue;
678   
679   /* If the return value is a struct and we don't have a return */
680   /* value address then we need to make one                     */
681
682   if ((rvalue == NULL) && 
683       (cif->rtype->type == FFI_TYPE_STRUCT))
684     {
685       /*@-sysunrecog@*/
686       ecif.rvalue = alloca(cif->rtype->size);
687       /*@=sysunrecog@*/
688     }
689   else
690     ecif.rvalue = rvalue;
691     
692   
693   switch (cif->abi) 
694     {
695 #ifndef POWERPC64
696     case FFI_SYSV:
697     case FFI_GCC_SYSV:
698       /*@-usedef@*/
699       ffi_call_SYSV(&ecif, -cif->bytes, 
700                     cif->flags, ecif.rvalue, fn);
701       /*@=usedef@*/
702       break;
703 #else
704     case FFI_LINUX64:
705       /*@-usedef@*/
706       ffi_call_LINUX64(&ecif, -(long) cif->bytes,
707                        cif->flags, ecif.rvalue, fn);
708       /*@=usedef@*/
709       break;
710 #endif
711     default:
712       FFI_ASSERT(0);
713       break;
714     }
715 }
716
717
718 #ifndef POWERPC64
719 static void flush_icache(char *, int);
720
721 #define MIN_CACHE_LINE_SIZE 8
722
723 static void flush_icache(char * addr1, int size)
724 {
725   int i;
726   char * addr;
727   for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) {
728      addr = addr1 + i;
729      __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" : : "r"(addr) : "memory");
730   }
731   addr = addr1 + size - 1;
732   __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" "sync;" "isync;" : : "r"(addr) : "memory");
733 }
734 #endif
735
736 ffi_status
737 ffi_prep_closure (ffi_closure* closure,
738                   ffi_cif* cif,
739                   void (*fun)(ffi_cif*, void*, void**, void*),
740                   void *user_data)
741 {
742 #ifdef POWERPC64
743   void **tramp = (void **) &closure->tramp[0];
744
745   FFI_ASSERT (cif->abi == FFI_LINUX64);
746   /* Copy function address and TOC from ffi_closure_LINUX64.  */
747   memcpy (tramp, (char *) ffi_closure_LINUX64, 16);
748   tramp[2] = (void *) closure;
749 #else
750   unsigned int *tramp;
751
752   FFI_ASSERT (cif->abi == FFI_GCC_SYSV);
753
754   tramp = (unsigned int *) &closure->tramp[0];
755   tramp[0] = 0x7c0802a6;  /*   mflr    r0 */
756   tramp[1] = 0x4800000d;  /*   bl      10 <trampoline_initial+0x10> */
757   tramp[4] = 0x7d6802a6;  /*   mflr    r11 */
758   tramp[5] = 0x7c0803a6;  /*   mtlr    r0 */
759   tramp[6] = 0x800b0000;  /*   lwz     r0,0(r11) */
760   tramp[7] = 0x816b0004;  /*   lwz     r11,4(r11) */
761   tramp[8] = 0x7c0903a6;  /*   mtctr   r0 */
762   tramp[9] = 0x4e800420;  /*   bctr */
763   *(void **) &tramp[2] = (void *)ffi_closure_SYSV; /* function */
764   *(void **) &tramp[3] = (void *)closure;          /* context */
765
766   /* Flush the icache.  */
767   flush_icache(&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
768 #endif
769
770   closure->cif = cif;
771   closure->fun = fun;
772   closure->user_data = user_data;
773
774   return FFI_OK;
775 }
776
777 typedef union
778 {
779   float f;
780   double d;
781 } ffi_dblfl;
782
783 int ffi_closure_helper_SYSV (ffi_closure*, void*, unsigned long*, 
784                              ffi_dblfl*, unsigned long*);
785
786 /* Basically the trampoline invokes ffi_closure_SYSV, and on 
787  * entry, r11 holds the address of the closure.
788  * After storing the registers that could possibly contain
789  * parameters to be passed into the stack frame and setting
790  * up space for a return value, ffi_closure_SYSV invokes the 
791  * following helper function to do most of the work
792  */
793
794 int
795 ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, 
796             unsigned long * pgr, ffi_dblfl * pfr, 
797             unsigned long * pst)
798 {
799   /* rvalue is the pointer to space for return value in closure assembly */
800   /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
801   /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV  */
802   /* pst is the pointer to outgoing parameter stack in original caller */
803
804   void **          avalue;
805   ffi_type **      arg_types;
806   long             i, avn;
807   long             nf;   /* number of floating registers already used */
808   long             ng;   /* number of general registers already used */
809   ffi_cif *        cif; 
810   double           temp; 
811
812   cif = closure->cif;
813   avalue = alloca(cif->nargs * sizeof(void *));
814
815   nf = 0;
816   ng = 0;
817
818   /* Copy the caller's structure return value address so that the closure
819      returns the data directly to the caller.  */
820   if (cif->rtype->type == FFI_TYPE_STRUCT)
821     {
822       rvalue = (void *) *pgr;
823       ng++;
824       pgr++;
825     }
826
827   i = 0;
828   avn = cif->nargs;
829   arg_types = cif->arg_types;
830   
831   /* Grab the addresses of the arguments from the stack frame.  */
832   while (i < avn)
833     {
834       switch (arg_types[i]->type)
835         {
836         case FFI_TYPE_SINT8:
837         case FFI_TYPE_UINT8:
838         /* there are 8 gpr registers used to pass values */
839           if (ng < 8) {
840              avalue[i] = (((char *)pgr)+3);
841              ng++;
842              pgr++;
843           } else {
844              avalue[i] = (((char *)pst)+3);
845              pst++;
846           }
847           break;
848            
849         case FFI_TYPE_SINT16:
850         case FFI_TYPE_UINT16:
851         /* there are 8 gpr registers used to pass values */
852           if (ng < 8) {
853              avalue[i] = (((char *)pgr)+2);
854              ng++;
855              pgr++;
856           } else {
857              avalue[i] = (((char *)pst)+2);
858              pst++;
859           }
860           break;
861
862         case FFI_TYPE_SINT32:
863         case FFI_TYPE_UINT32:
864         case FFI_TYPE_POINTER:
865           /* there are 8 gpr registers used to pass values */
866           if (ng < 8) {
867              avalue[i] = pgr;
868              ng++;
869              pgr++;
870           } else {
871              avalue[i] = pst;
872              pst++;
873           }
874           break;
875
876         case FFI_TYPE_STRUCT:
877           /* Structs are passed by reference. The address will appear in a 
878              gpr if it is one of the first 8 arguments.  */
879           if (ng < 8) {
880              avalue[i] = (void *) *pgr;
881              ng++;
882              pgr++;
883           } else {
884              avalue[i] = (void *) *pst;
885              pst++;
886           }
887           break;
888
889         case FFI_TYPE_SINT64:
890         case FFI_TYPE_UINT64:
891           /* passing long long ints are complex, they must
892            * be passed in suitable register pairs such as
893            * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
894            * and if the entire pair aren't available then the outgoing
895            * parameter stack is used for both but an alignment of 8
896            * must will be kept.  So we must either look in pgr
897            * or pst to find the correct address for this type
898            * of parameter.
899            */
900            if (ng < 7) {
901               if (ng & 0x01) {
902                 /* skip r4, r6, r8 as starting points */
903                   ng++;
904                   pgr++;
905               }
906               avalue[i] = pgr;
907               ng+=2;
908               pgr+=2;
909            } else {
910               if (((long)pst) & 4) pst++;
911               avalue[i] = pst;
912               pst+=2;
913            }
914            break;
915
916         case FFI_TYPE_FLOAT:
917             /* unfortunately float values are stored as doubles
918              * in the ffi_closure_SYSV code (since we don't check
919              * the type in that routine).
920              */
921
922           /* there are 8 64bit floating point registers */
923
924           if (nf < 8) {
925              temp = pfr->d;
926              pfr->f = (float)temp;
927              avalue[i] = pfr;
928              nf++;
929              pfr++;
930           } else {
931             /* FIXME? here we are really changing the values
932              * stored in the original calling routines outgoing
933              * parameter stack.  This is probably a really
934              * naughty thing to do but...
935              */
936              avalue[i] = pst;
937              nf++;
938              pst+=1;
939           }
940           break;
941
942         case FFI_TYPE_DOUBLE:
943           /* On the outgoing stack all values are aligned to 8 */
944           /* there are 8 64bit floating point registers */
945
946           if (nf < 8) {
947              avalue[i] = pfr;
948              nf++;
949              pfr++;
950           } else {
951              if (((long)pst) & 4) pst++;
952              avalue[i] = pst;
953              nf++;
954              pst+=2;
955           }
956           break;
957
958         default:
959           FFI_ASSERT(0);
960         }
961
962       i++;
963     }
964
965
966   (closure->fun) (cif, rvalue, avalue, closure->user_data);
967
968   /* Tell ffi_closure_SYSV how to perform return type promotions.  */
969   return cif->rtype->type;
970
971 }
972
973 int hidden ffi_closure_helper_LINUX64 (ffi_closure*, void*, unsigned long*,
974                                        ffi_dblfl*);
975
976 int hidden
977 ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue, 
978                             unsigned long *pst, ffi_dblfl *pfr)
979 {
980   /* rvalue is the pointer to space for return value in closure assembly */
981   /* pst is the pointer to parameter save area
982      (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */
983   /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */
984
985   void **avalue;
986   ffi_type **arg_types;
987   long i, avn;
988   ffi_cif *cif; 
989   ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;
990
991   cif = closure->cif;
992   avalue = alloca (cif->nargs * sizeof (void *));
993
994   /* Copy the caller's structure return value address so that the closure
995      returns the data directly to the caller.  */
996   if (cif->rtype->type == FFI_TYPE_STRUCT)
997     {
998       rvalue = (void *) *pst;
999       pst++;
1000     }
1001
1002   i = 0;
1003   avn = cif->nargs;
1004   arg_types = cif->arg_types;
1005   
1006   /* Grab the addresses of the arguments from the stack frame.  */
1007   while (i < avn)
1008     {
1009       switch (arg_types[i]->type)
1010         {
1011         case FFI_TYPE_SINT8:
1012         case FFI_TYPE_UINT8:
1013           avalue[i] = (char *) pst + 7;
1014           pst++;
1015           break;
1016            
1017         case FFI_TYPE_SINT16:
1018         case FFI_TYPE_UINT16:
1019           avalue[i] = (char *) pst + 6;
1020           pst++;
1021           break;
1022
1023         case FFI_TYPE_SINT32:
1024         case FFI_TYPE_UINT32:
1025           avalue[i] = (char *) pst + 4;
1026           pst++;
1027           break;
1028
1029         case FFI_TYPE_SINT64:
1030         case FFI_TYPE_UINT64:
1031         case FFI_TYPE_POINTER:
1032           avalue[i] = pst;
1033           pst++;
1034           break;
1035
1036         case FFI_TYPE_STRUCT:
1037           /* Structures with size less than eight bytes are passed
1038              left-padded.  */
1039           if (arg_types[i]->size < 8)
1040             avalue[i] = (char *) pst + 8 - arg_types[i]->size;
1041           else
1042             avalue[i] = pst;
1043           pst += (arg_types[i]->size + 7) / 8;
1044           break;
1045
1046         case FFI_TYPE_FLOAT:
1047           /* unfortunately float values are stored as doubles
1048            * in the ffi_closure_LINUX64 code (since we don't check
1049            * the type in that routine).
1050            */
1051
1052           /* there are 13 64bit floating point registers */
1053
1054           if (pfr < end_pfr)
1055             {
1056               double temp = pfr->d;
1057               pfr->f = (float) temp;
1058               avalue[i] = pfr;
1059               pfr++;
1060             }
1061           else
1062             avalue[i] = pst;
1063           pst++;
1064           break;
1065
1066         case FFI_TYPE_DOUBLE:
1067           /* On the outgoing stack all values are aligned to 8 */
1068           /* there are 13 64bit floating point registers */
1069
1070           if (pfr < end_pfr)
1071             {
1072               avalue[i] = pfr;
1073               pfr++;
1074             }
1075           else
1076             avalue[i] = pst;
1077           pst++;
1078           break;
1079
1080 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1081         case FFI_TYPE_LONGDOUBLE:
1082           if (prf + 1 < end_pfr)
1083             {
1084               avalue[i] = pfr;
1085               pfr += 2;
1086             }
1087           else
1088             {
1089               if (pfr < end_pfr)
1090                 {
1091                   /* Passed partly in f13 and partly on the stack.
1092                      Move it all to the stack.  */
1093                   *pst = *(unsigned long *) pfr;
1094                   pfr++;
1095                 }
1096               avalue[i] = pst;
1097             }
1098           pst += 2;
1099           break;
1100 #endif
1101
1102         default:
1103           FFI_ASSERT(0);
1104         }
1105
1106       i++;
1107     }
1108
1109
1110   (closure->fun) (cif, rvalue, avalue, closure->user_data);
1111
1112   /* Tell ffi_closure_LINUX64 how to perform return type promotions.  */
1113   return cif->rtype->type;
1114 }