OSDN Git Service

* configure.in (powerpc64*-*-linux*): 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       | |     gorws   |
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               unsigned int 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 = rest + words * 8 - first;
384             }
385           else
386             {
387               /* Structures with 1, 2 and 4 byte sizes are passed left-padded
388                  if they are in the first 8 arguments.  */
389               if (next_arg >= gpr_base
390                   && (*ptr)->size < 8
391                   && ((*ptr)->size & ~((*ptr)->size - 1)) == (*ptr)->size)
392                 memcpy((char *) next_arg + 8 - (*ptr)->size,
393                        (char *) *p_argv, (*ptr)->size);
394               else
395                 memcpy((char *) next_arg, (char *) *p_argv, (*ptr)->size);
396               next_arg += words;
397               if (next_arg == gpr_end)
398                 next_arg = rest;
399             }
400           break;
401
402         case FFI_TYPE_UINT8:
403           gprvalue = *(unsigned char *)*p_argv;
404           goto putgpr;
405         case FFI_TYPE_SINT8:
406           gprvalue = *(signed char *)*p_argv;
407           goto putgpr;
408         case FFI_TYPE_UINT16:
409           gprvalue = *(unsigned short *)*p_argv;
410           goto putgpr;
411         case FFI_TYPE_SINT16:
412           gprvalue = *(signed short *)*p_argv;
413           goto putgpr;
414         case FFI_TYPE_UINT32:
415           gprvalue = *(unsigned int *)*p_argv;
416           goto putgpr;
417         case FFI_TYPE_INT:
418         case FFI_TYPE_SINT32:
419           gprvalue = *(signed int *)*p_argv;
420           goto putgpr;
421         
422         case FFI_TYPE_UINT64:
423         case FFI_TYPE_SINT64:
424         case FFI_TYPE_POINTER:
425           gprvalue = *(unsigned long *)*p_argv;
426         putgpr:
427           *next_arg++ = gprvalue;
428           if (next_arg == gpr_end)
429             next_arg = rest;
430           break;
431         }
432     }
433
434   FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS
435              || (next_arg >= gpr_base && next_arg <= gpr_base + 4));
436 }
437
438
439
440 /* Perform machine dependent cif processing */
441 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
442 {
443   /* All this is for the SYSV and LINUX64 ABI.  */
444   int i;
445   ffi_type **ptr;
446   unsigned bytes;
447   int fparg_count = 0, intarg_count = 0;
448   unsigned flags = 0;
449   unsigned struct_copy_size = 0;
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
474   /* Return value handling.  The rules for SYSV are as follows:
475      - 32-bit (or less) integer values are returned in gpr3;
476      - Structures of size <= 4 bytes also returned in gpr3;
477      - 64-bit integer values and structures between 5 and 8 bytes are returned
478        in gpr3 and gpr4;
479      - Single/double FP values are returned in fpr1;
480      - Larger structures and long double (if not equivalent to double) values
481        are allocated space and a pointer is passed as the first argument.
482      For LINUX64:
483      - integer values in gpr3;
484      - Structures/Unions and long double by reference;
485      - Single/double FP values in fpr1.  */
486   switch (cif->rtype->type)
487     {
488     case FFI_TYPE_DOUBLE:
489       flags |= FLAG_RETURNS_64BITS;
490       /* Fall through.  */
491     case FFI_TYPE_FLOAT:
492       flags |= FLAG_RETURNS_FP;
493       break;
494
495     case FFI_TYPE_UINT64:
496     case FFI_TYPE_SINT64:
497       flags |= FLAG_RETURNS_64BITS;
498       break;
499
500     case FFI_TYPE_STRUCT:
501       if (cif->abi != FFI_GCC_SYSV && cif->abi != FFI_LINUX64)
502         if (cif->rtype->size <= 4)
503           break;
504         else if (cif->rtype->size <= 8)
505           {
506             flags |= FLAG_RETURNS_64BITS;
507             break;
508           }
509       /* else fall through.  */
510 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
511     case FFI_TYPE_LONGDOUBLE:
512 #endif
513       intarg_count++;
514       flags |= FLAG_RETVAL_REFERENCE;
515       /* Fall through.  */
516     case FFI_TYPE_VOID:
517       flags |= FLAG_RETURNS_NOTHING;
518       break;
519
520     default:
521       /* Returns 32-bit integer, or similar.  Nothing to do here.  */
522       break;
523     }
524
525   if (cif->abi != FFI_LINUX64)
526     /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
527        first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
528        goes on the stack.  Structures and long doubles (if not equivalent
529        to double) are passed as a pointer to a copy of the structure.
530        Stuff on the stack needs to keep proper alignment.  */
531     for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
532       {
533         switch ((*ptr)->type)
534           {
535           case FFI_TYPE_FLOAT:
536             fparg_count++;
537             /* floating singles are not 8-aligned on stack */
538             break;
539
540           case FFI_TYPE_DOUBLE:
541             fparg_count++;
542             /* If this FP arg is going on the stack, it must be
543                8-byte-aligned.  */
544             if (fparg_count > NUM_FPR_ARG_REGISTERS
545                 && intarg_count%2 != 0)
546               intarg_count++;
547             break;
548
549           case FFI_TYPE_UINT64:
550           case FFI_TYPE_SINT64:
551             /* 'long long' arguments are passed as two words, but
552                either both words must fit in registers or both go
553                on the stack.  If they go on the stack, they must
554                be 8-byte-aligned.  */
555             if (intarg_count == NUM_GPR_ARG_REGISTERS-1
556                 || (intarg_count >= NUM_GPR_ARG_REGISTERS
557                     && intarg_count%2 != 0))
558               intarg_count++;
559             intarg_count += 2;
560             break;
561
562           case FFI_TYPE_STRUCT:
563 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
564           case FFI_TYPE_LONGDOUBLE:
565 #endif
566             /* We must allocate space for a copy of these to enforce
567                pass-by-value.  Pad the space up to a multiple of 16
568                bytes (the maximum alignment required for anything under
569                the SYSV ABI).  */
570             struct_copy_size += ((*ptr)->size + 15) & ~0xF;
571             /* Fall through (allocate space for the pointer).  */
572
573           default:
574             /* Everything else is passed as a 4-byte word in a GPR, either
575                the object itself or a pointer to it.  */
576             intarg_count++;
577             break;
578           }
579       }
580   else
581     for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
582       {
583         switch ((*ptr)->type)
584           {
585           case FFI_TYPE_FLOAT:
586           case FFI_TYPE_DOUBLE:
587             fparg_count++;
588             intarg_count++;
589             break;
590
591           case FFI_TYPE_STRUCT:
592 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
593           case FFI_TYPE_LONGDOUBLE:
594 #endif
595             intarg_count += ((*ptr)->size + 7) & ~7;
596             break;
597
598           default:
599             /* Everything else is passed as a 8-byte word in a GPR, either
600                the object itself or a pointer to it.  */
601             intarg_count++;
602             break;
603           }
604       }
605
606   if (fparg_count != 0)
607     flags |= FLAG_FP_ARGUMENTS;
608   if (intarg_count > 4)
609     flags |= FLAG_4_GPR_ARGUMENTS;
610   if (struct_copy_size != 0)
611     flags |= FLAG_ARG_NEEDS_COPY;
612
613   if (cif->abi != FFI_LINUX64)
614     {
615       /* Space for the FPR registers, if needed.  */
616       if (fparg_count != 0)
617         bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
618
619       /* Stack space.  */
620       if (intarg_count > NUM_GPR_ARG_REGISTERS)
621         bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof(int);
622       if (fparg_count > NUM_FPR_ARG_REGISTERS)
623         bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof(double);
624     }
625   else
626     {
627       /* Space for the FPR registers, if needed.  */
628       if (fparg_count != 0)
629         bytes += NUM_FPR_ARG_REGISTERS64 * sizeof(double);
630
631       /* Stack space.  */
632       if (intarg_count > NUM_GPR_ARG_REGISTERS64)
633         bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof(long);
634     }
635
636   /* The stack space allocated needs to be a multiple of 16 bytes.  */
637   bytes = (bytes + 15) & ~0xF;
638
639   /* Add in the space for the copied structures.  */
640   bytes += struct_copy_size;
641
642   cif->flags = flags;
643   cif->bytes = bytes;
644
645   return FFI_OK;
646 }
647
648 /*@-declundef@*/
649 /*@-exportheader@*/
650 extern void ffi_call_SYSV(/*@out@*/ extended_cif *, 
651                           unsigned, unsigned, 
652                           /*@out@*/ unsigned *, 
653                           void (*fn)());
654 extern void hidden ffi_call_LINUX64(/*@out@*/ extended_cif *, 
655                                     unsigned long, unsigned long,
656                                     /*@out@*/ unsigned long *, 
657                                     void (*fn)());
658 /*@=declundef@*/
659 /*@=exportheader@*/
660
661 void ffi_call(/*@dependent@*/ ffi_cif *cif, 
662               void (*fn)(), 
663               /*@out@*/ void *rvalue, 
664               /*@dependent@*/ void **avalue)
665 {
666   extended_cif ecif;
667
668   ecif.cif = cif;
669   ecif.avalue = avalue;
670   
671   /* If the return value is a struct and we don't have a return */
672   /* value address then we need to make one                     */
673
674   if ((rvalue == NULL) && 
675       (cif->rtype->type == FFI_TYPE_STRUCT))
676     {
677       /*@-sysunrecog@*/
678       ecif.rvalue = alloca(cif->rtype->size);
679       /*@=sysunrecog@*/
680     }
681   else
682     ecif.rvalue = rvalue;
683     
684   
685   switch (cif->abi) 
686     {
687 #ifndef POWERPC64
688     case FFI_SYSV:
689     case FFI_GCC_SYSV:
690       /*@-usedef@*/
691       ffi_call_SYSV(&ecif, -cif->bytes, 
692                     cif->flags, ecif.rvalue, fn);
693       /*@=usedef@*/
694       break;
695 #else
696     case FFI_LINUX64:
697       /*@-usedef@*/
698       ffi_call_LINUX64(&ecif, -(long) cif->bytes,
699                        cif->flags, ecif.rvalue, fn);
700       /*@=usedef@*/
701       break;
702 #endif
703     default:
704       FFI_ASSERT(0);
705       break;
706     }
707 }
708
709
710 #ifndef POWERPC64
711 static void flush_icache(char *, int);
712
713 #define MIN_CACHE_LINE_SIZE 8
714
715 static void flush_icache(char * addr1, int size)
716 {
717   int i;
718   char * addr;
719   for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) {
720      addr = addr1 + i;
721      __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" : : "r"(addr) : "memory");
722   }
723   addr = addr1 + size - 1;
724   __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" "sync;" "isync;" : : "r"(addr) : "memory");
725 }
726 #endif
727
728 ffi_status
729 ffi_prep_closure (ffi_closure* closure,
730                   ffi_cif* cif,
731                   void (*fun)(ffi_cif*, void*, void**, void*),
732                   void *user_data)
733 {
734 #ifdef POWERPC64
735   void **tramp = (void **) &closure->tramp[0];
736
737   FFI_ASSERT (cif->abi == FFI_LINUX64);
738   /* Copy function address and TOC from ffi_closure_LINUX64.  */
739   memcpy (tramp, (char *) ffi_closure_LINUX64, 16);
740   tramp[2] = (void *) closure;
741 #else
742   unsigned int *tramp;
743
744   FFI_ASSERT (cif->abi == FFI_GCC_SYSV);
745
746   tramp = (unsigned int *) &closure->tramp[0];
747   tramp[0] = 0x7c0802a6;  /*   mflr    r0 */
748   tramp[1] = 0x4800000d;  /*   bl      10 <trampoline_initial+0x10> */
749   tramp[4] = 0x7d6802a6;  /*   mflr    r11 */
750   tramp[5] = 0x7c0803a6;  /*   mtlr    r0 */
751   tramp[6] = 0x800b0000;  /*   lwz     r0,0(r11) */
752   tramp[7] = 0x816b0004;  /*   lwz     r11,4(r11) */
753   tramp[8] = 0x7c0903a6;  /*   mtctr   r0 */
754   tramp[9] = 0x4e800420;  /*   bctr */
755   *(void **) &tramp[2] = (void *)ffi_closure_SYSV; /* function */
756   *(void **) &tramp[3] = (void *)closure;          /* context */
757
758   /* Flush the icache.  */
759   flush_icache(&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
760 #endif
761
762   closure->cif = cif;
763   closure->fun = fun;
764   closure->user_data = user_data;
765
766   return FFI_OK;
767 }
768
769 typedef union
770 {
771   float f;
772   double d;
773 } ffi_dblfl;
774
775 int ffi_closure_helper_SYSV (ffi_closure*, void*, unsigned long*, 
776                              ffi_dblfl*, unsigned long*);
777
778 /* Basically the trampoline invokes ffi_closure_SYSV, and on 
779  * entry, r11 holds the address of the closure.
780  * After storing the registers that could possibly contain
781  * parameters to be passed into the stack frame and setting
782  * up space for a return value, ffi_closure_SYSV invokes the 
783  * following helper function to do most of the work
784  */
785
786 int
787 ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, 
788             unsigned long * pgr, ffi_dblfl * pfr, 
789             unsigned long * pst)
790 {
791   /* rvalue is the pointer to space for return value in closure assembly */
792   /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
793   /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV  */
794   /* pst is the pointer to outgoing parameter stack in original caller */
795
796   void **          avalue;
797   ffi_type **      arg_types;
798   long             i, avn;
799   long             nf;   /* number of floating registers already used */
800   long             ng;   /* number of general registers already used */
801   ffi_cif *        cif; 
802   double           temp; 
803
804   cif = closure->cif;
805   avalue = alloca(cif->nargs * sizeof(void *));
806
807   nf = 0;
808   ng = 0;
809
810   /* Copy the caller's structure return value address so that the closure
811      returns the data directly to the caller.  */
812   if (cif->rtype->type == FFI_TYPE_STRUCT)
813     {
814       rvalue = (void *) *pgr;
815       ng++;
816       pgr++;
817     }
818
819   i = 0;
820   avn = cif->nargs;
821   arg_types = cif->arg_types;
822   
823   /* Grab the addresses of the arguments from the stack frame.  */
824   while (i < avn)
825     {
826       switch (arg_types[i]->type)
827         {
828         case FFI_TYPE_SINT8:
829         case FFI_TYPE_UINT8:
830         /* there are 8 gpr registers used to pass values */
831           if (ng < 8) {
832              avalue[i] = (((char *)pgr)+3);
833              ng++;
834              pgr++;
835           } else {
836              avalue[i] = (((char *)pst)+3);
837              pst++;
838           }
839           break;
840            
841         case FFI_TYPE_SINT16:
842         case FFI_TYPE_UINT16:
843         /* there are 8 gpr registers used to pass values */
844           if (ng < 8) {
845              avalue[i] = (((char *)pgr)+2);
846              ng++;
847              pgr++;
848           } else {
849              avalue[i] = (((char *)pst)+2);
850              pst++;
851           }
852           break;
853
854         case FFI_TYPE_SINT32:
855         case FFI_TYPE_UINT32:
856         case FFI_TYPE_POINTER:
857         case FFI_TYPE_STRUCT:
858         /* there are 8 gpr registers used to pass values */
859           if (ng < 8) {
860              avalue[i] = pgr;
861              ng++;
862              pgr++;
863           } else {
864              avalue[i] = pst;
865              pst++;
866           }
867           break;
868
869         case FFI_TYPE_SINT64:
870         case FFI_TYPE_UINT64:
871           /* passing long long ints are complex, they must
872            * be passed in suitable register pairs such as
873            * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
874            * and if the entire pair aren't available then the outgoing
875            * parameter stack is used for both but an alignment of 8
876            * must will be kept.  So we must either look in pgr
877            * or pst to find the correct address for this type
878            * of parameter.
879            */
880            if (ng < 7) {
881               if (ng & 0x01) {
882                 /* skip r4, r6, r8 as starting points */
883                   ng++;
884                   pgr++;
885               }
886               avalue[i] = pgr;
887               ng+=2;
888               pgr+=2;
889            } else {
890               if (((long)pst) & 4) pst++;
891               avalue[i] = pst;
892               pst+=2;
893            }
894            break;
895
896         case FFI_TYPE_FLOAT:
897             /* unfortunately float values are stored as doubles
898              * in the ffi_closure_SYSV code (since we don't check
899              * the type in that routine).
900              */
901
902           /* there are 8 64bit floating point registers */
903
904           if (nf < 8) {
905              temp = pfr->d;
906              pfr->f = (float)temp;
907              avalue[i] = pfr;
908              nf++;
909              pfr++;
910           } else {
911             /* FIXME? here we are really changing the values
912              * stored in the original calling routines outgoing
913              * parameter stack.  This is probably a really
914              * naughty thing to do but...
915              */
916              avalue[i] = pst;
917              nf++;
918              pst+=1;
919           }
920           break;
921
922         case FFI_TYPE_DOUBLE:
923           /* On the outgoing stack all values are aligned to 8 */
924           /* there are 8 64bit floating point registers */
925
926           if (nf < 8) {
927              avalue[i] = pfr;
928              nf++;
929              pfr++;
930           } else {
931              if (((long)pst) & 4) pst++;
932              avalue[i] = pst;
933              nf++;
934              pst+=2;
935           }
936           break;
937
938         default:
939           FFI_ASSERT(0);
940         }
941
942       i++;
943     }
944
945
946   (closure->fun) (cif, rvalue, avalue, closure->user_data);
947
948   /* Tell ffi_closure_SYSV how to perform return type promotions.  */
949   return cif->rtype->type;
950
951 }
952
953 int hidden ffi_closure_helper_LINUX64 (ffi_closure*, void*, unsigned long*,
954                                        ffi_dblfl*);
955
956 int hidden
957 ffi_closure_helper_LINUX64 (ffi_closure* closure, void * rvalue, 
958             unsigned long * pst, ffi_dblfl * pfr)
959 {
960   /* rvalue is the pointer to space for return value in closure assembly */
961   /* pst is the pointer to parameter save area
962      (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */
963   /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */
964
965   void **          avalue;
966   ffi_type **      arg_types;
967   long             i, avn;
968   long             nf;   /* number of floating registers already used */
969   long             ng;   /* number of general registers already used */
970   ffi_cif *        cif; 
971   double           temp; 
972
973   cif = closure->cif;
974   avalue = alloca(cif->nargs * sizeof(void *));
975
976   nf = 0;
977   ng = 0;
978
979   /* Copy the caller's structure return value address so that the closure
980      returns the data directly to the caller.  */
981   if (cif->rtype->type == FFI_TYPE_STRUCT)
982     {
983       rvalue = (void *) *pst;
984       ng++;
985       pst++;
986     }
987
988   i = 0;
989   avn = cif->nargs;
990   arg_types = cif->arg_types;
991   
992   /* Grab the addresses of the arguments from the stack frame.  */
993   while (i < avn)
994     {
995       switch (arg_types[i]->type)
996         {
997         case FFI_TYPE_SINT8:
998         case FFI_TYPE_UINT8:
999           avalue[i] = (char *) pst + 7;
1000           ng++;
1001           pst++;
1002           break;
1003            
1004         case FFI_TYPE_SINT16:
1005         case FFI_TYPE_UINT16:
1006           avalue[i] = (char *) pst + 6;
1007           ng++;
1008           pst++;
1009           break;
1010
1011         case FFI_TYPE_SINT32:
1012         case FFI_TYPE_UINT32:
1013           avalue[i] = (char *) pst + 4;
1014           ng++;
1015           pst++;
1016           break;
1017
1018         case FFI_TYPE_SINT64:
1019         case FFI_TYPE_UINT64:
1020         case FFI_TYPE_POINTER:
1021           avalue[i] = pst;
1022           ng++;
1023           pst++;
1024           break;
1025
1026         case FFI_TYPE_STRUCT:
1027 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1028         case FFI_TYPE_LONGDOUBLE:
1029 #endif
1030           /* Structures with 1, 2 and 4 byte sizes are passed left-padded
1031              if they are in the first 8 arguments.  */
1032           if (ng < NUM_GPR_ARG_REGISTERS64
1033               && arg_types[i]->size < 8
1034               && ((arg_types[i]->size & ~(arg_types[i]->size - 1))
1035                   == arg_types[i]->size))
1036             avalue[i] = (char *) pst + 8 - arg_types[i]->size;
1037           else
1038             avalue[i] = pst;
1039           ng += (arg_types[i]->size + 7) / 8;
1040           pst += (arg_types[i]->size + 7) / 8;
1041           break;
1042
1043         case FFI_TYPE_FLOAT:
1044           /* unfortunately float values are stored as doubles
1045            * in the ffi_closure_LINUX64 code (since we don't check
1046            * the type in that routine).
1047            */
1048
1049           /* there are 13 64bit floating point registers */
1050
1051           if (nf < NUM_FPR_ARG_REGISTERS64) {
1052              temp = pfr->d;
1053              pfr->f = (float)temp;
1054              avalue[i] = pfr;
1055              pfr++;
1056           } else {
1057              avalue[i] = pst;
1058           }
1059           nf++;
1060           ng++;
1061           pst++;
1062           break;
1063
1064         case FFI_TYPE_DOUBLE:
1065           /* On the outgoing stack all values are aligned to 8 */
1066           /* there are 13 64bit floating point registers */
1067
1068           if (nf < NUM_FPR_ARG_REGISTERS64) {
1069              avalue[i] = pfr;
1070              pfr++;
1071           } else {
1072              avalue[i] = pst;
1073           }
1074           nf++;
1075           ng++;
1076           pst++;
1077           break;
1078
1079         default:
1080           FFI_ASSERT(0);
1081         }
1082
1083       i++;
1084     }
1085
1086
1087   (closure->fun) (cif, rvalue, avalue, closure->user_data);
1088
1089   /* Tell ffi_closure_LINUX64 how to perform return type promotions.  */
1090   return cif->rtype->type;
1091
1092 }