OSDN Git Service

e5446807c09ec930553bddbcb36dc0fa07a1b32f
[pf3gnuchains/gcc-fork.git] / libffi / src / mips / ffi.c
1 /* -----------------------------------------------------------------------
2    ffi.c - Copyright (c) 1996, 2007 Red Hat, Inc.
3    
4    MIPS Foreign Function Interface 
5
6    Permission is hereby granted, free of charge, to any person obtaining
7    a copy of this software and associated documentation files (the
8    ``Software''), to deal in the Software without restriction, including
9    without limitation the rights to use, copy, modify, merge, publish,
10    distribute, sublicense, and/or sell copies of the Software, and to
11    permit persons to whom the Software is furnished to do so, subject to
12    the following conditions:
13
14    The above copyright notice and this permission notice shall be included
15    in all copies or substantial portions of the Software.
16
17    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
18    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20    IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23    OTHER DEALINGS IN THE SOFTWARE.
24    ----------------------------------------------------------------------- */
25
26 #include <ffi.h>
27 #include <ffi_common.h>
28
29 #include <stdlib.h>
30 #include <sys/cachectl.h>
31
32 #if _MIPS_SIM == _ABIN32
33 #define FIX_ARGP \
34 FFI_ASSERT(argp <= &stack[bytes]); \
35 if (argp == &stack[bytes]) \
36 { \
37   argp = stack; \
38   ffi_stop_here(); \
39 }
40 #else
41 #define FIX_ARGP 
42 #endif
43
44
45 /* ffi_prep_args is called by the assembly routine once stack space
46    has been allocated for the function's arguments */
47
48 static void ffi_prep_args(char *stack, 
49                           extended_cif *ecif,
50                           int bytes,
51                           int flags)
52 {
53   int i;
54   void **p_argv;
55   char *argp;
56   ffi_type **p_arg;
57
58 #if _MIPS_SIM == _ABIN32
59   /* If more than 8 double words are used, the remainder go
60      on the stack. We reorder stuff on the stack here to 
61      support this easily. */
62   if (bytes > 8 * sizeof(ffi_arg))
63     argp = &stack[bytes - (8 * sizeof(ffi_arg))];
64   else
65     argp = stack;
66 #else
67   argp = stack;
68 #endif
69
70   memset(stack, 0, bytes);
71
72 #if _MIPS_SIM == _ABIN32
73   if ( ecif->cif->rstruct_flag != 0 )
74 #else
75   if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT )
76 #endif  
77     {
78       *(ffi_arg *) argp = (ffi_arg) ecif->rvalue;
79       argp += sizeof(ffi_arg);
80       FIX_ARGP;
81     }
82
83   p_argv = ecif->avalue;
84
85   for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
86     {
87       size_t z;
88       unsigned int a;
89
90       /* Align if necessary.  */
91       a = (*p_arg)->alignment;
92       if (a < sizeof(ffi_arg))
93         a = sizeof(ffi_arg);
94       
95       if ((a - 1) & (unsigned int) argp)
96         {
97           argp = (char *) ALIGN(argp, a);
98           FIX_ARGP;
99         }
100
101       z = (*p_arg)->size;
102       if (z <= sizeof(ffi_arg))
103         {
104           z = sizeof(ffi_arg);
105
106           switch ((*p_arg)->type)
107             {
108               case FFI_TYPE_SINT8:
109                 *(ffi_arg *)argp = *(SINT8 *)(* p_argv);
110                 break;
111
112               case FFI_TYPE_UINT8:
113                 *(ffi_arg *)argp = *(UINT8 *)(* p_argv);
114                 break;
115                   
116               case FFI_TYPE_SINT16:
117                 *(ffi_arg *)argp = *(SINT16 *)(* p_argv);
118                 break;
119                   
120               case FFI_TYPE_UINT16:
121                 *(ffi_arg *)argp = *(UINT16 *)(* p_argv);
122                 break;
123                   
124               case FFI_TYPE_SINT32:
125                 *(ffi_arg *)argp = *(SINT32 *)(* p_argv);
126                 break;
127                   
128               case FFI_TYPE_UINT32:
129               case FFI_TYPE_POINTER:
130                 *(ffi_arg *)argp = *(UINT32 *)(* p_argv);
131                 break;
132
133               /* This can only happen with 64bit slots.  */
134               case FFI_TYPE_FLOAT:
135                 *(float *) argp = *(float *)(* p_argv);
136                 break;
137
138               /* Handle small structures.  */
139               case FFI_TYPE_STRUCT:
140               default:
141                 memcpy(argp, *p_argv, (*p_arg)->size);
142                 break;
143             }
144         }
145       else
146         {
147 #if _MIPS_SIM == _ABIO32
148           memcpy(argp, *p_argv, z);
149 #else
150           {
151             unsigned end = (unsigned) argp+z;
152             unsigned cap = (unsigned) stack+bytes;
153
154             /* Check if the data will fit within the register space.
155                Handle it if it doesn't.  */
156
157             if (end <= cap)
158               memcpy(argp, *p_argv, z);
159             else
160               {
161                 unsigned portion = end - cap;
162
163                 memcpy(argp, *p_argv, portion);
164                 argp = stack;
165                 memcpy(argp,
166                        (void*)((unsigned)(*p_argv)+portion), z - portion);
167               }
168           }
169 #endif
170       }
171       p_argv++;
172       argp += z;
173       FIX_ARGP;
174     }
175 }
176
177 #if _MIPS_SIM == _ABIN32
178
179 /* The n32 spec says that if "a chunk consists solely of a double 
180    float field (but not a double, which is part of a union), it
181    is passed in a floating point register. Any other chunk is
182    passed in an integer register". This code traverses structure
183    definitions and generates the appropriate flags. */
184
185 unsigned calc_n32_struct_flags(ffi_type *arg, unsigned *shift)
186 {
187   unsigned flags = 0;
188   unsigned index = 0;
189
190   ffi_type *e;
191
192   while (e = arg->elements[index])
193     {
194       if (e->type == FFI_TYPE_DOUBLE)
195         {
196           flags += (FFI_TYPE_DOUBLE << *shift);
197           *shift += FFI_FLAG_BITS;
198         }
199       else if (e->type == FFI_TYPE_STRUCT)
200           flags += calc_n32_struct_flags(e, shift);
201       else
202         *shift += FFI_FLAG_BITS;
203
204       index++;
205     }
206
207   return flags;
208 }
209
210 unsigned calc_n32_return_struct_flags(ffi_type *arg)
211 {
212   unsigned flags = 0;
213   unsigned index = 0;
214   unsigned small = FFI_TYPE_SMALLSTRUCT;
215   ffi_type *e;
216
217   /* Returning structures under n32 is a tricky thing.
218      A struct with only one or two floating point fields 
219      is returned in $f0 (and $f2 if necessary). Any other
220      struct results at most 128 bits are returned in $2
221      (the first 64 bits) and $3 (remainder, if necessary).
222      Larger structs are handled normally. */
223   
224   if (arg->size > 16)
225     return 0;
226
227   if (arg->size > 8)
228     small = FFI_TYPE_SMALLSTRUCT2;
229
230   e = arg->elements[0];
231   if (e->type == FFI_TYPE_DOUBLE)
232     flags = FFI_TYPE_DOUBLE << FFI_FLAG_BITS;
233   else if (e->type == FFI_TYPE_FLOAT)
234     flags = FFI_TYPE_FLOAT << FFI_FLAG_BITS;
235
236   if (flags && (e = arg->elements[1]))
237     {
238       if (e->type == FFI_TYPE_DOUBLE)
239         flags += FFI_TYPE_DOUBLE;
240       else if (e->type == FFI_TYPE_FLOAT)
241         flags += FFI_TYPE_FLOAT;
242       else 
243         return small;
244
245       if (flags && (arg->elements[2]))
246         {
247           /* There are three arguments and the first two are 
248              floats! This must be passed the old way. */
249           return small;
250         }
251     }
252   else
253     if (!flags)
254       return small;
255
256   return flags;
257 }
258
259 #endif
260
261 /* Perform machine dependent cif processing */
262 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
263 {
264   cif->flags = 0;
265
266 #if _MIPS_SIM == _ABIO32
267   /* Set the flags necessary for O32 processing.  FFI_O32_SOFT_FLOAT
268    * does not have special handling for floating point args.
269    */
270
271   if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32)
272     {
273       if (cif->nargs > 0)
274         {
275           switch ((cif->arg_types)[0]->type)
276             {
277             case FFI_TYPE_FLOAT:
278             case FFI_TYPE_DOUBLE:
279               cif->flags += (cif->arg_types)[0]->type;
280               break;
281               
282             default:
283               break;
284             }
285
286           if (cif->nargs > 1)
287             {
288               /* Only handle the second argument if the first
289                  is a float or double. */
290               if (cif->flags)
291                 {
292                   switch ((cif->arg_types)[1]->type)
293                     {
294                     case FFI_TYPE_FLOAT:
295                     case FFI_TYPE_DOUBLE:
296                       cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS;
297                       break;
298                       
299                     default:
300                       break;
301                     }
302                 }
303             }
304         }
305     }
306       
307   /* Set the return type flag */
308
309   if (cif->abi == FFI_O32_SOFT_FLOAT)
310     {
311       switch (cif->rtype->type)
312         {
313         case FFI_TYPE_VOID:
314         case FFI_TYPE_STRUCT:
315           cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
316           break;
317
318         case FFI_TYPE_SINT64:
319         case FFI_TYPE_UINT64:
320         case FFI_TYPE_DOUBLE:
321           cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
322           break;
323       
324         case FFI_TYPE_FLOAT:
325         default:
326           cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
327           break;
328         }
329     }
330   else
331     {
332       /* FFI_O32 */      
333       switch (cif->rtype->type)
334         {
335         case FFI_TYPE_VOID:
336         case FFI_TYPE_STRUCT:
337         case FFI_TYPE_FLOAT:
338         case FFI_TYPE_DOUBLE:
339           cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
340           break;
341
342         case FFI_TYPE_SINT64:
343         case FFI_TYPE_UINT64:
344           cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
345           break;
346       
347         default:
348           cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
349           break;
350         }
351     }
352 #endif
353
354 #if _MIPS_SIM == _ABIN32
355   /* Set the flags necessary for N32 processing */
356   {
357     unsigned shift = 0;
358     unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
359     unsigned index = 0;
360
361     unsigned struct_flags = 0;
362
363     if (cif->rtype->type == FFI_TYPE_STRUCT)
364       {
365         struct_flags = calc_n32_return_struct_flags(cif->rtype);
366
367         if (struct_flags == 0)
368           {
369             /* This means that the structure is being passed as
370                a hidden argument */
371
372             shift = FFI_FLAG_BITS;
373             count = (cif->nargs < 7) ? cif->nargs : 7;
374
375             cif->rstruct_flag = !0;
376           }
377         else
378             cif->rstruct_flag = 0;
379       }
380     else
381       cif->rstruct_flag = 0;
382
383     while (count-- > 0)
384       {
385         switch ((cif->arg_types)[index]->type)
386           {
387           case FFI_TYPE_FLOAT:
388           case FFI_TYPE_DOUBLE:
389             cif->flags += ((cif->arg_types)[index]->type << shift);
390             shift += FFI_FLAG_BITS;
391             break;
392
393           case FFI_TYPE_STRUCT:
394             cif->flags += calc_n32_struct_flags((cif->arg_types)[index],
395                                                 &shift);
396             break;
397
398           default:
399             shift += FFI_FLAG_BITS;
400           }
401
402         index++;
403       }
404
405   /* Set the return type flag */
406     switch (cif->rtype->type)
407       {
408       case FFI_TYPE_STRUCT:
409         {
410           if (struct_flags == 0)
411             {
412               /* The structure is returned through a hidden
413                  first argument. Do nothing, 'cause FFI_TYPE_VOID 
414                  is 0 */
415             }
416           else
417             {
418               /* The structure is returned via some tricky
419                  mechanism */
420               cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
421               cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8));
422             }
423           break;
424         }
425       
426       case FFI_TYPE_VOID:
427         /* Do nothing, 'cause FFI_TYPE_VOID is 0 */
428         break;
429         
430       case FFI_TYPE_FLOAT:
431       case FFI_TYPE_DOUBLE:
432         cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
433         break;
434         
435       default:
436         cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
437         break;
438       }
439   }
440 #endif
441   
442   return FFI_OK;
443 }
444
445 /* Low level routine for calling O32 functions */
446 extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int), 
447                         extended_cif *, unsigned, 
448                         unsigned, unsigned *, void (*)());
449
450 /* Low level routine for calling N32 functions */
451 extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int), 
452                         extended_cif *, unsigned, 
453                         unsigned, unsigned *, void (*)());
454
455 void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
456 {
457   extended_cif ecif;
458
459   ecif.cif = cif;
460   ecif.avalue = avalue;
461   
462   /* If the return value is a struct and we don't have a return */
463   /* value address then we need to make one                     */
464   
465   if ((rvalue == NULL) && 
466       (cif->rtype->type == FFI_TYPE_STRUCT))
467     ecif.rvalue = alloca(cif->rtype->size);
468   else
469     ecif.rvalue = rvalue;
470     
471   switch (cif->abi) 
472     {
473 #if _MIPS_SIM == _ABIO32
474     case FFI_O32:
475     case FFI_O32_SOFT_FLOAT:
476       ffi_call_O32(ffi_prep_args, &ecif, cif->bytes, 
477                    cif->flags, ecif.rvalue, fn);
478       break;
479 #endif
480
481 #if _MIPS_SIM == _ABIN32
482     case FFI_N32:
483       ffi_call_N32(ffi_prep_args, &ecif, cif->bytes, 
484                    cif->flags, ecif.rvalue, fn);
485       break;
486 #endif
487
488     default:
489       FFI_ASSERT(0);
490       break;
491     }
492 }
493
494 #if FFI_CLOSURES  /* N32 not implemented yet, FFI_CLOSURES not defined */
495 #if defined(FFI_MIPS_O32)
496 extern void ffi_closure_O32(void);
497 #endif /* FFI_MIPS_O32 */
498
499 ffi_status
500 ffi_prep_closure_loc (ffi_closure *closure,
501                       ffi_cif *cif,
502                       void (*fun)(ffi_cif*,void*,void**,void*),
503                       void *user_data,
504                       void *codeloc)
505 {
506   unsigned int *tramp = (unsigned int *) &closure->tramp[0];
507   unsigned int fn;
508   unsigned int ctx = (unsigned int) codeloc;
509
510 #if defined(FFI_MIPS_O32)
511   FFI_ASSERT(cif->abi == FFI_O32 || cif->abi == FFI_O32_SOFT_FLOAT);
512   fn = (unsigned int) ffi_closure_O32;
513 #else /* FFI_MIPS_N32 */
514   FFI_ASSERT(cif->abi == FFI_N32);
515   FFI_ASSERT(!"not implemented");
516 #endif /* FFI_MIPS_O32 */
517
518   tramp[0] = 0x3c190000 | (fn >> 16);     /* lui  $25,high(fn) */
519   tramp[1] = 0x37390000 | (fn & 0xffff);  /* ori  $25,low(fn)  */
520   tramp[2] = 0x3c080000 | (ctx >> 16);    /* lui  $8,high(ctx) */
521   tramp[3] = 0x03200008;                  /* jr   $25          */
522   tramp[4] = 0x35080000 | (ctx & 0xffff); /* ori  $8,low(ctx)  */
523
524   closure->cif = cif;
525   closure->fun = fun;
526   closure->user_data = user_data;
527
528   /* XXX this is available on Linux, but anything else? */
529   cacheflush (codeloc, FFI_TRAMPOLINE_SIZE, ICACHE);
530
531   return FFI_OK;
532 }
533
534 /*
535  * Decodes the arguments to a function, which will be stored on the
536  * stack. AR is the pointer to the beginning of the integer arguments
537  * (and, depending upon the arguments, some floating-point arguments
538  * as well). FPR is a pointer to the area where floating point
539  * registers have been saved, if any.
540  *
541  * RVALUE is the location where the function return value will be
542  * stored. CLOSURE is the prepared closure to invoke.
543  *
544  * This function should only be called from assembly, which is in
545  * turn called from a trampoline.
546  *
547  * Returns the function return type.
548  *
549  * Based on the similar routine for sparc.
550  */
551 int
552 ffi_closure_mips_inner_O32 (ffi_closure *closure,
553                             void *rvalue, ffi_arg *ar,
554                             double *fpr)
555 {
556   ffi_cif *cif;
557   void **avaluep;
558   ffi_arg *avalue;
559   ffi_type **arg_types;
560   int i, avn, argn, seen_int;
561
562   cif = closure->cif;
563   avalue = alloca (cif->nargs * sizeof (ffi_arg));
564   avaluep = alloca (cif->nargs * sizeof (ffi_arg));
565
566   seen_int = (cif->abi == FFI_O32_SOFT_FLOAT);
567   argn = 0;
568
569   if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)
570     {
571       rvalue = (void *) ar[0];
572       argn = 1;
573     }
574
575   i = 0;
576   avn = cif->nargs;
577   arg_types = cif->arg_types;
578
579   while (i < avn)
580     {
581       if (i < 2 && !seen_int &&
582           (arg_types[i]->type == FFI_TYPE_FLOAT ||
583            arg_types[i]->type == FFI_TYPE_DOUBLE))
584         {
585 #ifdef __MIPSEB__
586           if (arg_types[i]->type == FFI_TYPE_FLOAT)
587             avaluep[i] = ((char *) &fpr[i]) + sizeof (float);
588           else
589 #endif
590             avaluep[i] = (char *) &fpr[i];
591         }
592       else
593         {
594           if (arg_types[i]->alignment == 8 && (argn & 0x1))
595             argn++;
596           switch (arg_types[i]->type)
597             {
598               case FFI_TYPE_SINT8:
599                 avaluep[i] = &avalue[i];
600                 *(SINT8 *) &avalue[i] = (SINT8) ar[argn];
601                 break;
602
603               case FFI_TYPE_UINT8:
604                 avaluep[i] = &avalue[i];
605                 *(UINT8 *) &avalue[i] = (UINT8) ar[argn];
606                 break;
607                   
608               case FFI_TYPE_SINT16:
609                 avaluep[i] = &avalue[i];
610                 *(SINT16 *) &avalue[i] = (SINT16) ar[argn];
611                 break;
612                   
613               case FFI_TYPE_UINT16:
614                 avaluep[i] = &avalue[i];
615                 *(UINT16 *) &avalue[i] = (UINT16) ar[argn];
616                 break;
617
618               default:
619                 avaluep[i] = (char *) &ar[argn];
620                 break;
621             }
622           seen_int = 1;
623         }
624       argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
625       i++;
626     }
627
628   /* Invoke the closure. */
629   (closure->fun) (cif, rvalue, avaluep, closure->user_data);
630
631   if (cif->abi == FFI_O32_SOFT_FLOAT)
632     {
633       switch (cif->rtype->type)
634         {
635         case FFI_TYPE_FLOAT:
636           return FFI_TYPE_INT;
637         case FFI_TYPE_DOUBLE:
638           return FFI_TYPE_UINT64;
639         default:
640           return cif->rtype->type;
641         }
642     }
643   else
644     {
645       return cif->rtype->type;
646     }
647 }
648
649 #endif /* FFI_CLOSURES */