OSDN Git Service

2004-08-23 David Daney <daney@avtrex.com>
[pf3gnuchains/gcc-fork.git] / libffi / src / mips / ffi.c
1 /* -----------------------------------------------------------------------
2    ffi.c - Copyright (c) 1996 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   register int i;
54   register void **p_argv;
55   register char *argp;
56   register 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 * FFI_SIZEOF_ARG)
63     argp = &stack[bytes - (8 * FFI_SIZEOF_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 short a;
89
90       /* Align if necessary */
91       a = (*p_arg)->alignment;
92       if (a < FFI_SIZEOF_ARG)
93         a = FFI_SIZEOF_ARG;
94       
95       if ((a - 1) & (unsigned) argp) {
96         argp = (char *) ALIGN(argp, a);
97         FIX_ARGP;
98       }
99
100 #if _MIPS_SIM == _ABIO32
101 #define OFFSET 0
102 #else
103 #define OFFSET sizeof(int)
104 #endif      
105
106           z = (*p_arg)->size;
107           if (z < sizeof(ffi_arg))
108             {
109               z = sizeof(ffi_arg);
110
111               switch ((*p_arg)->type)
112                 {
113                 case FFI_TYPE_SINT8:
114                   *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT8 *)(* p_argv);
115                   break;
116                   
117                 case FFI_TYPE_UINT8:
118                   *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT8 *)(* p_argv);
119                   break;
120                   
121                 case FFI_TYPE_SINT16:
122                   *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT16 *)(* p_argv);
123                   break;
124                   
125                 case FFI_TYPE_UINT16:
126                   *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT16 *)(* p_argv);
127                   break;
128                   
129                 case FFI_TYPE_SINT32:
130                   *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT32 *)(* p_argv);
131                   break;
132                   
133                 case FFI_TYPE_UINT32:
134                 case FFI_TYPE_POINTER:
135                   *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT32 *)(* p_argv);
136                   break;
137
138                   /* This can only happen with 64bit slots */
139                 case FFI_TYPE_FLOAT:
140                   *(float *) argp = *(float *)(* p_argv);
141                   break;
142
143                   /* Handle small structures */
144                 case FFI_TYPE_STRUCT:
145                   memcpy(argp, *p_argv, (*p_arg)->size);
146                   break;
147
148                 default:
149                   FFI_ASSERT(0);
150                 }
151             }
152           else
153             {
154 #if _MIPS_SIM == _ABIO32              
155               memcpy(argp, *p_argv, z);
156 #else
157               {
158                 unsigned end = (unsigned) argp+z;
159                 unsigned cap = (unsigned) stack+bytes;
160
161                 /* Check if the data will fit within the register
162                    space. Handle it if it doesn't. */
163
164                 if (end <= cap)
165                   memcpy(argp, *p_argv, z);
166                 else
167                   {
168                     unsigned portion = end - cap;
169
170                     memcpy(argp, *p_argv, portion);
171                     argp = stack;
172                     memcpy(argp, 
173                            (void*)((unsigned)(*p_argv)+portion), z - portion);
174                   }
175               }
176 #endif
177             }
178           p_argv++;
179           argp += z;
180           FIX_ARGP;
181     }
182   
183   return;
184 }
185
186 #if _MIPS_SIM == _ABIN32
187
188 /* The n32 spec says that if "a chunk consists solely of a double 
189    float field (but not a double, which is part of a union), it
190    is passed in a floating point register. Any other chunk is
191    passed in an integer register". This code traverses structure
192    definitions and generates the appropriate flags. */
193
194 unsigned calc_n32_struct_flags(ffi_type *arg, unsigned *shift)
195 {
196   unsigned flags = 0;
197   unsigned index = 0;
198
199   ffi_type *e;
200
201   while (e = arg->elements[index])
202     {
203       if (e->type == FFI_TYPE_DOUBLE)
204         {
205           flags += (FFI_TYPE_DOUBLE << *shift);
206           *shift += FFI_FLAG_BITS;
207         }
208       else if (e->type == FFI_TYPE_STRUCT)
209           flags += calc_n32_struct_flags(e, shift);
210       else
211         *shift += FFI_FLAG_BITS;
212
213       index++;
214     }
215
216   return flags;
217 }
218
219 unsigned calc_n32_return_struct_flags(ffi_type *arg)
220 {
221   unsigned flags = 0;
222   unsigned index = 0;
223   unsigned small = FFI_TYPE_SMALLSTRUCT;
224   ffi_type *e;
225
226   /* Returning structures under n32 is a tricky thing.
227      A struct with only one or two floating point fields 
228      is returned in $f0 (and $f2 if necessary). Any other
229      struct results at most 128 bits are returned in $2
230      (the first 64 bits) and $3 (remainder, if necessary).
231      Larger structs are handled normally. */
232   
233   if (arg->size > 16)
234     return 0;
235
236   if (arg->size > 8)
237     small = FFI_TYPE_SMALLSTRUCT2;
238
239   e = arg->elements[0];
240   if (e->type == FFI_TYPE_DOUBLE)
241     flags = FFI_TYPE_DOUBLE << FFI_FLAG_BITS;
242   else if (e->type == FFI_TYPE_FLOAT)
243     flags = FFI_TYPE_FLOAT << FFI_FLAG_BITS;
244
245   if (flags && (e = arg->elements[1]))
246     {
247       if (e->type == FFI_TYPE_DOUBLE)
248         flags += FFI_TYPE_DOUBLE;
249       else if (e->type == FFI_TYPE_FLOAT)
250         flags += FFI_TYPE_FLOAT;
251       else 
252         return small;
253
254       if (flags && (arg->elements[2]))
255         {
256           /* There are three arguments and the first two are 
257              floats! This must be passed the old way. */
258           return small;
259         }
260     }
261   else
262     if (!flags)
263       return small;
264
265   return flags;
266 }
267
268 #endif
269
270 /* Perform machine dependent cif processing */
271 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
272 {
273   cif->flags = 0;
274
275 #if _MIPS_SIM == _ABIO32
276   /* Set the flags necessary for O32 processing.  FFI_O32_SOFT_FLOAT
277    * does not have special handling for floating point args.
278    */
279
280   if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32)
281     {
282       if (cif->nargs > 0)
283         {
284           switch ((cif->arg_types)[0]->type)
285             {
286             case FFI_TYPE_FLOAT:
287             case FFI_TYPE_DOUBLE:
288               cif->flags += (cif->arg_types)[0]->type;
289               break;
290               
291             default:
292               break;
293             }
294
295           if (cif->nargs > 1)
296             {
297               /* Only handle the second argument if the first
298                  is a float or double. */
299               if (cif->flags)
300                 {
301                   switch ((cif->arg_types)[1]->type)
302                     {
303                     case FFI_TYPE_FLOAT:
304                     case FFI_TYPE_DOUBLE:
305                       cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS;
306                       break;
307                       
308                     default:
309                       break;
310                     }
311                 }
312             }
313         }
314     }
315       
316   /* Set the return type flag */
317
318   if (cif->abi == FFI_O32_SOFT_FLOAT)
319     {
320       switch (cif->rtype->type)
321         {
322         case FFI_TYPE_VOID:
323         case FFI_TYPE_STRUCT:
324           cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
325           break;
326
327         case FFI_TYPE_SINT64:
328         case FFI_TYPE_UINT64:
329         case FFI_TYPE_DOUBLE:
330           cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
331           break;
332       
333         case FFI_TYPE_FLOAT:
334         default:
335           cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
336           break;
337         }
338     }
339   else
340     {
341       /* FFI_O32 */      
342       switch (cif->rtype->type)
343         {
344         case FFI_TYPE_VOID:
345         case FFI_TYPE_STRUCT:
346         case FFI_TYPE_FLOAT:
347         case FFI_TYPE_DOUBLE:
348           cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
349           break;
350
351         case FFI_TYPE_SINT64:
352         case FFI_TYPE_UINT64:
353           cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
354           break;
355       
356         default:
357           cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
358           break;
359         }
360     }
361 #endif
362
363 #if _MIPS_SIM == _ABIN32
364   /* Set the flags necessary for N32 processing */
365   {
366     unsigned shift = 0;
367     unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
368     unsigned index = 0;
369
370     unsigned struct_flags = 0;
371
372     if (cif->rtype->type == FFI_TYPE_STRUCT)
373       {
374         struct_flags = calc_n32_return_struct_flags(cif->rtype);
375
376         if (struct_flags == 0)
377           {
378             /* This means that the structure is being passed as
379                a hidden argument */
380
381             shift = FFI_FLAG_BITS;
382             count = (cif->nargs < 7) ? cif->nargs : 7;
383
384             cif->rstruct_flag = !0;
385           }
386         else
387             cif->rstruct_flag = 0;
388       }
389     else
390       cif->rstruct_flag = 0;
391
392     while (count-- > 0)
393       {
394         switch ((cif->arg_types)[index]->type)
395           {
396           case FFI_TYPE_FLOAT:
397           case FFI_TYPE_DOUBLE:
398             cif->flags += ((cif->arg_types)[index]->type << shift);
399             shift += FFI_FLAG_BITS;
400             break;
401
402           case FFI_TYPE_STRUCT:
403             cif->flags += calc_n32_struct_flags((cif->arg_types)[index],
404                                                 &shift);
405             break;
406
407           default:
408             shift += FFI_FLAG_BITS;
409           }
410
411         index++;
412       }
413
414   /* Set the return type flag */
415     switch (cif->rtype->type)
416       {
417       case FFI_TYPE_STRUCT:
418         {
419           if (struct_flags == 0)
420             {
421               /* The structure is returned through a hidden
422                  first argument. Do nothing, 'cause FFI_TYPE_VOID 
423                  is 0 */
424             }
425           else
426             {
427               /* The structure is returned via some tricky
428                  mechanism */
429               cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
430               cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8));
431             }
432           break;
433         }
434       
435       case FFI_TYPE_VOID:
436         /* Do nothing, 'cause FFI_TYPE_VOID is 0 */
437         break;
438         
439       case FFI_TYPE_FLOAT:
440       case FFI_TYPE_DOUBLE:
441         cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
442         break;
443         
444       default:
445         cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
446         break;
447       }
448   }
449 #endif
450   
451   return FFI_OK;
452 }
453
454 /* Low level routine for calling O32 functions */
455 extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int), 
456                         extended_cif *, unsigned, 
457                         unsigned, unsigned *, void (*)());
458
459 /* Low level routine for calling N32 functions */
460 extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int), 
461                         extended_cif *, unsigned, 
462                         unsigned, unsigned *, void (*)());
463
464 void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
465 {
466   extended_cif ecif;
467
468   ecif.cif = cif;
469   ecif.avalue = avalue;
470   
471   /* If the return value is a struct and we don't have a return */
472   /* value address then we need to make one                     */
473   
474   if ((rvalue == NULL) && 
475       (cif->rtype->type == FFI_TYPE_STRUCT))
476     ecif.rvalue = alloca(cif->rtype->size);
477   else
478     ecif.rvalue = rvalue;
479     
480   switch (cif->abi) 
481     {
482 #if _MIPS_SIM == _ABIO32
483     case FFI_O32:
484     case FFI_O32_SOFT_FLOAT:
485       ffi_call_O32(ffi_prep_args, &ecif, cif->bytes, 
486                    cif->flags, ecif.rvalue, fn);
487       break;
488 #endif
489
490 #if _MIPS_SIM == _ABIN32
491     case FFI_N32:
492       ffi_call_N32(ffi_prep_args, &ecif, cif->bytes, 
493                    cif->flags, ecif.rvalue, fn);
494       break;
495 #endif
496
497     default:
498       FFI_ASSERT(0);
499       break;
500     }
501 }
502
503 #if FFI_CLOSURES  /* N32 not implemented yet, FFI_CLOSURES not defined */
504 #if defined(FFI_MIPS_O32)
505 extern void ffi_closure_O32(void);
506 #endif /* FFI_MIPS_O32 */
507
508 ffi_status
509 ffi_prep_closure (ffi_closure *closure,
510                   ffi_cif *cif,
511                   void (*fun)(ffi_cif*,void*,void**,void*),
512                   void *user_data)
513 {
514   unsigned int *tramp = (unsigned int *) &closure->tramp[0];
515   unsigned int fn;
516   unsigned int ctx = (unsigned int) closure;
517
518 #if defined(FFI_MIPS_O32)
519   FFI_ASSERT(cif->abi == FFI_O32 || cif->abi == FFI_O32_SOFT_FLOAT);
520   fn = (unsigned int) ffi_closure_O32;
521 #else /* FFI_MIPS_N32 */
522   FFI_ASSERT(cif->abi == FFI_N32);
523   FFI_ASSERT(!"not implemented");
524 #endif /* FFI_MIPS_O32 */
525
526   tramp[0] = 0x3c190000 | (fn >> 16);     /* lui  $25,high(fn) */
527   tramp[1] = 0x3c080000 | (ctx >> 16);    /* lui  $8,high(ctx) */
528   tramp[2] = 0x37390000 | (fn & 0xffff);  /* ori  $25,low(fn)  */
529   tramp[3] = 0x03200008;                  /* jr   $25          */
530   tramp[4] = 0x35080000 | (ctx & 0xffff); /* ori  $8,low(ctx)  */
531
532   closure->cif = cif;
533   closure->fun = fun;
534   closure->user_data = user_data;
535
536   /* XXX this is available on Linux, but anything else? */
537   cacheflush (tramp, FFI_TRAMPOLINE_SIZE, ICACHE);
538
539   return FFI_OK;
540 }
541
542 /*
543  * Decodes the arguments to a function, which will be stored on the
544  * stack. AR is the pointer to the beginning of the integer arguments
545  * (and, depending upon the arguments, some floating-point arguments
546  * as well). FPR is a pointer to the area where floating point
547  * registers have been saved, if any.
548  *
549  * RVALUE is the location where the function return value will be
550  * stored. CLOSURE is the prepared closure to invoke.
551  *
552  * This function should only be called from assembly, which is in
553  * turn called from a trampoline.
554  *
555  * Returns the function return type.
556  *
557  * Based on the similar routine for sparc.
558  */
559 int
560 ffi_closure_mips_inner_O32 (ffi_closure *closure,
561                             void *rvalue, unsigned long *ar,
562                             double *fpr)
563 {
564   ffi_cif *cif;
565   void **avalue;
566   ffi_type **arg_types;
567   int i, avn, argn, seen_int;
568
569   cif = closure->cif;
570   avalue = alloca (cif->nargs * sizeof (void *));
571
572   seen_int = (cif->abi == FFI_O32_SOFT_FLOAT);
573   argn = 0;
574
575   if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)
576     {
577       rvalue = (void *) ar[0];
578       argn = 1;
579     }
580
581   i = 0;
582   avn = cif->nargs;
583   arg_types = cif->arg_types;
584
585   while (i < avn)
586     {
587       if (i < 2 && !seen_int &&
588           (arg_types[i]->type == FFI_TYPE_FLOAT ||
589            arg_types[i]->type == FFI_TYPE_DOUBLE))
590         {
591           avalue[i] = ((char *) &fpr[i]);
592         }
593       else
594         {
595           if (arg_types[i]->alignment == 8 && (argn & 0x1))
596             argn++;
597           avalue[i] = ((char *) &ar[argn]);
598           seen_int = 1;
599         }
600       argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
601       i++;
602     }
603
604   /* Invoke the closure. */
605   (closure->fun) (cif, rvalue, avalue, closure->user_data);
606
607   if (cif->abi == FFI_O32_SOFT_FLOAT)
608     {
609       switch (cif->rtype->type)
610         {
611         case FFI_TYPE_FLOAT:
612           return FFI_TYPE_INT;
613         case FFI_TYPE_DOUBLE:
614           return FFI_TYPE_UINT64;
615         default:
616           return cif->rtype->type;
617         }
618     }
619   else
620     {
621       return cif->rtype->type;
622     }
623 }
624
625 #endif /* FFI_CLOSURES */