OSDN Git Service

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