OSDN Git Service

2009-09-15 David Daney <ddaney@caviumnetworks.com>
[pf3gnuchains/gcc-fork.git] / libffi / src / mips / ffi.c
1 /* -----------------------------------------------------------------------
2    ffi.c - Copyright (c) 1996, 2007, 2008  Red Hat, Inc.
3            Copyright (c) 2008       David Daney
4    
5    MIPS Foreign Function Interface 
6
7    Permission is hereby granted, free of charge, to any person obtaining
8    a copy of this software and associated documentation files (the
9    ``Software''), to deal in the Software without restriction, including
10    without limitation the rights to use, copy, modify, merge, publish,
11    distribute, sublicense, and/or sell copies of the Software, and to
12    permit persons to whom the Software is furnished to do so, subject to
13    the following conditions:
14
15    The above copyright notice and this permission notice shall be included
16    in all copies or substantial portions of the Software.
17
18    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
19    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21    NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25    DEALINGS IN THE SOFTWARE.
26    ----------------------------------------------------------------------- */
27
28 #include <ffi.h>
29 #include <ffi_common.h>
30
31 #include <stdlib.h>
32
33 #ifdef __GNUC__
34 #  if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))
35 #    define USE__BUILTIN___CLEAR_CACHE 1
36 #  endif
37 #endif
38
39 #ifndef USE__BUILTIN___CLEAR_CACHE
40 #include <sys/cachectl.h>
41 #endif
42
43 #ifdef FFI_DEBUG
44 # define FFI_MIPS_STOP_HERE() ffi_stop_here()
45 #else
46 # define FFI_MIPS_STOP_HERE() do {} while(0)
47 #endif
48
49 #ifdef FFI_MIPS_N32
50 #define FIX_ARGP \
51 FFI_ASSERT(argp <= &stack[bytes]); \
52 if (argp == &stack[bytes]) \
53 { \
54   argp = stack; \
55   FFI_MIPS_STOP_HERE(); \
56 }
57 #else
58 #define FIX_ARGP 
59 #endif
60
61
62 /* ffi_prep_args is called by the assembly routine once stack space
63    has been allocated for the function's arguments */
64
65 static void ffi_prep_args(char *stack, 
66                           extended_cif *ecif,
67                           int bytes,
68                           int flags)
69 {
70   int i;
71   void **p_argv;
72   char *argp;
73   ffi_type **p_arg;
74
75 #ifdef FFI_MIPS_N32
76   /* If more than 8 double words are used, the remainder go
77      on the stack. We reorder stuff on the stack here to 
78      support this easily. */
79   if (bytes > 8 * sizeof(ffi_arg))
80     argp = &stack[bytes - (8 * sizeof(ffi_arg))];
81   else
82     argp = stack;
83 #else
84   argp = stack;
85 #endif
86
87   memset(stack, 0, bytes);
88
89 #ifdef FFI_MIPS_N32
90   if ( ecif->cif->rstruct_flag != 0 )
91 #else
92   if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT )
93 #endif  
94     {
95       *(ffi_arg *) argp = (ffi_arg) ecif->rvalue;
96       argp += sizeof(ffi_arg);
97       FIX_ARGP;
98     }
99
100   p_argv = ecif->avalue;
101
102   for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs; i++, p_arg++)
103     {
104       size_t z;
105       unsigned int a;
106
107       /* Align if necessary.  */
108       a = (*p_arg)->alignment;
109       if (a < sizeof(ffi_arg))
110         a = sizeof(ffi_arg);
111       
112       if ((a - 1) & (unsigned long) argp)
113         {
114           argp = (char *) ALIGN(argp, a);
115           FIX_ARGP;
116         }
117
118       z = (*p_arg)->size;
119       if (z <= sizeof(ffi_arg))
120         {
121           int type = (*p_arg)->type;
122           z = sizeof(ffi_arg);
123
124           /* The size of a pointer depends on the ABI */
125           if (type == FFI_TYPE_POINTER)
126             type = (ecif->cif->abi == FFI_N64
127                     || ecif->cif->abi == FFI_N64_SOFT_FLOAT)
128               ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
129
130         if (i < 8 && (ecif->cif->abi == FFI_N32_SOFT_FLOAT
131                       || ecif->cif->abi == FFI_N64_SOFT_FLOAT))
132           {
133             switch (type)
134               {
135               case FFI_TYPE_FLOAT:
136                 type = FFI_TYPE_UINT32;
137                 break;
138               case FFI_TYPE_DOUBLE:
139                 type = FFI_TYPE_UINT64;
140                 break;
141               default:
142                 break;
143               }
144           }
145           switch (type)
146             {
147               case FFI_TYPE_SINT8:
148                 *(ffi_arg *)argp = *(SINT8 *)(* p_argv);
149                 break;
150
151               case FFI_TYPE_UINT8:
152                 *(ffi_arg *)argp = *(UINT8 *)(* p_argv);
153                 break;
154                   
155               case FFI_TYPE_SINT16:
156                 *(ffi_arg *)argp = *(SINT16 *)(* p_argv);
157                 break;
158                   
159               case FFI_TYPE_UINT16:
160                 *(ffi_arg *)argp = *(UINT16 *)(* p_argv);
161                 break;
162                   
163               case FFI_TYPE_SINT32:
164                 *(ffi_arg *)argp = *(SINT32 *)(* p_argv);
165                 break;
166                   
167               case FFI_TYPE_UINT32:
168                 *(ffi_arg *)argp = *(UINT32 *)(* p_argv);
169                 break;
170
171               /* This can only happen with 64bit slots.  */
172               case FFI_TYPE_FLOAT:
173                 *(float *) argp = *(float *)(* p_argv);
174                 break;
175
176               /* Handle structures.  */
177               default:
178                 memcpy(argp, *p_argv, (*p_arg)->size);
179                 break;
180             }
181         }
182       else
183         {
184 #ifdef FFI_MIPS_O32
185           memcpy(argp, *p_argv, z);
186 #else
187           {
188             unsigned long end = (unsigned long) argp + z;
189             unsigned long cap = (unsigned long) stack + bytes;
190
191             /* Check if the data will fit within the register space.
192                Handle it if it doesn't.  */
193
194             if (end <= cap)
195               memcpy(argp, *p_argv, z);
196             else
197               {
198                 unsigned long portion = cap - (unsigned long)argp;
199
200                 memcpy(argp, *p_argv, portion);
201                 argp = stack;
202                 z -= portion;
203                 memcpy(argp, (void*)((unsigned long)(*p_argv) + portion),
204                        z);
205               }
206           }
207 #endif
208       }
209       p_argv++;
210       argp += z;
211       FIX_ARGP;
212     }
213 }
214
215 #ifdef FFI_MIPS_N32
216
217 /* The n32 spec says that if "a chunk consists solely of a double 
218    float field (but not a double, which is part of a union), it
219    is passed in a floating point register. Any other chunk is
220    passed in an integer register". This code traverses structure
221    definitions and generates the appropriate flags. */
222
223 static unsigned
224 calc_n32_struct_flags(int soft_float, ffi_type *arg,
225                       unsigned *loc, unsigned *arg_reg)
226 {
227   unsigned flags = 0;
228   unsigned index = 0;
229
230   ffi_type *e;
231
232   if (soft_float)
233     return 0;
234
235   while ((e = arg->elements[index]))
236     {
237       /* Align this object.  */
238       *loc = ALIGN(*loc, e->alignment);
239       if (e->type == FFI_TYPE_DOUBLE)
240         {
241           /* Already aligned to FFI_SIZEOF_ARG.  */
242           *arg_reg = *loc / FFI_SIZEOF_ARG;
243           if (*arg_reg > 7)
244             break;
245           flags += (FFI_TYPE_DOUBLE << (*arg_reg * FFI_FLAG_BITS));
246           *loc += e->size;
247         }
248       else
249         *loc += e->size;
250       index++;
251     }
252   /* Next Argument register at alignment of FFI_SIZEOF_ARG.  */
253   *arg_reg = ALIGN(*loc, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
254
255   return flags;
256 }
257
258 static unsigned
259 calc_n32_return_struct_flags(int soft_float, ffi_type *arg)
260 {
261   unsigned flags = 0;
262   unsigned small = FFI_TYPE_SMALLSTRUCT;
263   ffi_type *e;
264
265   /* Returning structures under n32 is a tricky thing.
266      A struct with only one or two floating point fields 
267      is returned in $f0 (and $f2 if necessary). Any other
268      struct results at most 128 bits are returned in $2
269      (the first 64 bits) and $3 (remainder, if necessary).
270      Larger structs are handled normally. */
271   
272   if (arg->size > 16)
273     return 0;
274
275   if (arg->size > 8)
276     small = FFI_TYPE_SMALLSTRUCT2;
277
278   e = arg->elements[0];
279
280   if (e->type == FFI_TYPE_DOUBLE)
281     flags = FFI_TYPE_DOUBLE;
282   else if (e->type == FFI_TYPE_FLOAT)
283     flags = FFI_TYPE_FLOAT;
284
285   if (flags && (e = arg->elements[1]))
286     {
287       if (e->type == FFI_TYPE_DOUBLE)
288         flags += FFI_TYPE_DOUBLE << FFI_FLAG_BITS;
289       else if (e->type == FFI_TYPE_FLOAT)
290         flags += FFI_TYPE_FLOAT << FFI_FLAG_BITS;
291       else 
292         return small;
293
294       if (flags && (arg->elements[2]))
295         {
296           /* There are three arguments and the first two are 
297              floats! This must be passed the old way. */
298           return small;
299         }
300       if (soft_float)
301         flags += FFI_TYPE_STRUCT_SOFT;
302     }
303   else
304     if (!flags)
305       return small;
306
307   return flags;
308 }
309
310 #endif
311
312 /* Perform machine dependent cif processing */
313 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
314 {
315   cif->flags = 0;
316
317 #ifdef FFI_MIPS_O32
318   /* Set the flags necessary for O32 processing.  FFI_O32_SOFT_FLOAT
319    * does not have special handling for floating point args.
320    */
321
322   if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32)
323     {
324       if (cif->nargs > 0)
325         {
326           switch ((cif->arg_types)[0]->type)
327             {
328             case FFI_TYPE_FLOAT:
329             case FFI_TYPE_DOUBLE:
330               cif->flags += (cif->arg_types)[0]->type;
331               break;
332               
333             default:
334               break;
335             }
336
337           if (cif->nargs > 1)
338             {
339               /* Only handle the second argument if the first
340                  is a float or double. */
341               if (cif->flags)
342                 {
343                   switch ((cif->arg_types)[1]->type)
344                     {
345                     case FFI_TYPE_FLOAT:
346                     case FFI_TYPE_DOUBLE:
347                       cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS;
348                       break;
349                       
350                     default:
351                       break;
352                     }
353                 }
354             }
355         }
356     }
357       
358   /* Set the return type flag */
359
360   if (cif->abi == FFI_O32_SOFT_FLOAT)
361     {
362       switch (cif->rtype->type)
363         {
364         case FFI_TYPE_VOID:
365         case FFI_TYPE_STRUCT:
366           cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
367           break;
368
369         case FFI_TYPE_SINT64:
370         case FFI_TYPE_UINT64:
371         case FFI_TYPE_DOUBLE:
372           cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
373           break;
374       
375         case FFI_TYPE_FLOAT:
376         default:
377           cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
378           break;
379         }
380     }
381   else
382     {
383       /* FFI_O32 */      
384       switch (cif->rtype->type)
385         {
386         case FFI_TYPE_VOID:
387         case FFI_TYPE_STRUCT:
388         case FFI_TYPE_FLOAT:
389         case FFI_TYPE_DOUBLE:
390           cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
391           break;
392
393         case FFI_TYPE_SINT64:
394         case FFI_TYPE_UINT64:
395           cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
396           break;
397       
398         default:
399           cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
400           break;
401         }
402     }
403 #endif
404
405 #ifdef FFI_MIPS_N32
406   /* Set the flags necessary for N32 processing */
407   {
408     int type;
409     unsigned arg_reg = 0;
410     unsigned loc = 0;
411     unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
412     unsigned index = 0;
413
414     unsigned struct_flags = 0;
415     int soft_float = (cif->abi == FFI_N32_SOFT_FLOAT
416                       || cif->abi == FFI_N64_SOFT_FLOAT);
417
418     if (cif->rtype->type == FFI_TYPE_STRUCT)
419       {
420         struct_flags = calc_n32_return_struct_flags(soft_float, cif->rtype);
421
422         if (struct_flags == 0)
423           {
424             /* This means that the structure is being passed as
425                a hidden argument */
426
427             arg_reg = 1;
428             count = (cif->nargs < 7) ? cif->nargs : 7;
429
430             cif->rstruct_flag = !0;
431           }
432         else
433             cif->rstruct_flag = 0;
434       }
435     else
436       cif->rstruct_flag = 0;
437
438     while (count-- > 0 && arg_reg < 8)
439       {
440         type = (cif->arg_types)[index]->type;
441         if (soft_float)
442           {
443             switch (type)
444               {
445               case FFI_TYPE_FLOAT:
446                 type = FFI_TYPE_UINT32;
447                 break;
448               case FFI_TYPE_DOUBLE:
449                 type = FFI_TYPE_UINT64;
450                 break;
451               default:
452                 break;
453               }
454           }
455         switch (type)
456           {
457           case FFI_TYPE_FLOAT:
458           case FFI_TYPE_DOUBLE:
459             cif->flags +=
460               ((cif->arg_types)[index]->type << (arg_reg * FFI_FLAG_BITS));
461             arg_reg++;
462             break;
463           case FFI_TYPE_LONGDOUBLE:
464             /* Align it.  */
465             arg_reg = ALIGN(arg_reg, 2);
466             /* Treat it as two adjacent doubles.  */
467             if (soft_float) 
468               {
469                 arg_reg += 2;
470               }
471             else
472               {
473                 cif->flags +=
474                   (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
475                 arg_reg++;
476                 cif->flags +=
477                   (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
478                 arg_reg++;
479               }
480             break;
481
482           case FFI_TYPE_STRUCT:
483             loc = arg_reg * FFI_SIZEOF_ARG;
484             cif->flags += calc_n32_struct_flags(soft_float,
485                                                 (cif->arg_types)[index],
486                                                 &loc, &arg_reg);
487             break;
488
489           default:
490             arg_reg++;
491             break;
492           }
493
494         index++;
495       }
496
497   /* Set the return type flag */
498     switch (cif->rtype->type)
499       {
500       case FFI_TYPE_STRUCT:
501         {
502           if (struct_flags == 0)
503             {
504               /* The structure is returned through a hidden
505                  first argument. Do nothing, 'cause FFI_TYPE_VOID 
506                  is 0 */
507             }
508           else
509             {
510               /* The structure is returned via some tricky
511                  mechanism */
512               cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
513               cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8));
514             }
515           break;
516         }
517       
518       case FFI_TYPE_VOID:
519         /* Do nothing, 'cause FFI_TYPE_VOID is 0 */
520         break;
521
522       case FFI_TYPE_POINTER:
523         if (cif->abi == FFI_N32_SOFT_FLOAT || cif->abi == FFI_N32)
524           cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);
525         else
526           cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
527         break;
528
529       case FFI_TYPE_FLOAT:
530         if (soft_float)
531           {
532             cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);
533             break;
534           }
535         /* else fall through */
536       case FFI_TYPE_DOUBLE:
537         if (soft_float)
538           cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
539         else
540           cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
541         break;
542
543       case FFI_TYPE_LONGDOUBLE:
544         /* Long double is returned as if it were a struct containing
545            two doubles.  */
546         if (soft_float)
547           {
548             cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
549             cif->flags += FFI_TYPE_SMALLSTRUCT2 << (4 + (FFI_FLAG_BITS * 8));
550           }
551         else
552           {
553             cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
554             cif->flags += (FFI_TYPE_DOUBLE
555                            + (FFI_TYPE_DOUBLE << FFI_FLAG_BITS))
556                                               << (4 + (FFI_FLAG_BITS * 8));
557           }
558         break;
559       default:
560         cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
561         break;
562       }
563   }
564 #endif
565   
566   return FFI_OK;
567 }
568
569 /* Low level routine for calling O32 functions */
570 extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int), 
571                         extended_cif *, unsigned, 
572                         unsigned, unsigned *, void (*)(void));
573
574 /* Low level routine for calling N32 functions */
575 extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int), 
576                         extended_cif *, unsigned, 
577                         unsigned, void *, void (*)(void));
578
579 void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
580 {
581   extended_cif ecif;
582
583   ecif.cif = cif;
584   ecif.avalue = avalue;
585   
586   /* If the return value is a struct and we don't have a return */
587   /* value address then we need to make one                     */
588   
589   if ((rvalue == NULL) && 
590       (cif->rtype->type == FFI_TYPE_STRUCT))
591     ecif.rvalue = alloca(cif->rtype->size);
592   else
593     ecif.rvalue = rvalue;
594     
595   switch (cif->abi) 
596     {
597 #ifdef FFI_MIPS_O32
598     case FFI_O32:
599     case FFI_O32_SOFT_FLOAT:
600       ffi_call_O32(ffi_prep_args, &ecif, cif->bytes, 
601                    cif->flags, ecif.rvalue, fn);
602       break;
603 #endif
604
605 #ifdef FFI_MIPS_N32
606     case FFI_N32:
607     case FFI_N32_SOFT_FLOAT:
608     case FFI_N64:
609     case FFI_N64_SOFT_FLOAT:
610       {
611         int copy_rvalue = 0;
612         int copy_offset = 0;
613         char *rvalue_copy = ecif.rvalue;
614         if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16)
615           {
616             /* For structures smaller than 16 bytes we clobber memory
617                in 8 byte increments.  Make a copy so we don't clobber
618                the callers memory outside of the struct bounds.  */
619             rvalue_copy = alloca(16);
620             copy_rvalue = 1;
621           }
622         else if (cif->rtype->type == FFI_TYPE_FLOAT
623                  && (cif->abi == FFI_N64_SOFT_FLOAT
624                      || cif->abi == FFI_N32_SOFT_FLOAT))
625           {
626             rvalue_copy = alloca (8);
627             copy_rvalue = 1;
628 #ifdef __MIPSEB__
629             copy_offset = 4;
630 #endif
631           }
632         ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
633                      cif->flags, rvalue_copy, fn);
634         if (copy_rvalue)
635           memcpy(ecif.rvalue, rvalue_copy + copy_offset, cif->rtype->size);
636       }
637       break;
638 #endif
639
640     default:
641       FFI_ASSERT(0);
642       break;
643     }
644 }
645
646 #if FFI_CLOSURES
647 #if defined(FFI_MIPS_O32)
648 extern void ffi_closure_O32(void);
649 #else
650 extern void ffi_closure_N32(void);
651 #endif /* FFI_MIPS_O32 */
652
653 ffi_status
654 ffi_prep_closure_loc (ffi_closure *closure,
655                       ffi_cif *cif,
656                       void (*fun)(ffi_cif*,void*,void**,void*),
657                       void *user_data,
658                       void *codeloc)
659 {
660   unsigned int *tramp = (unsigned int *) &closure->tramp[0];
661   void * fn;
662   char *clear_location = (char *) codeloc;
663
664 #if defined(FFI_MIPS_O32)
665   FFI_ASSERT(cif->abi == FFI_O32 || cif->abi == FFI_O32_SOFT_FLOAT);
666   fn = ffi_closure_O32;
667 #else /* FFI_MIPS_N32 */
668   FFI_ASSERT(cif->abi == FFI_N32 || cif->abi == FFI_N64);
669   fn = ffi_closure_N32;
670 #endif /* FFI_MIPS_O32 */
671
672 #if defined(FFI_MIPS_O32) || (_MIPS_SIM ==_ABIN32)
673   /* lui  $25,high(fn) */
674   tramp[0] = 0x3c190000 | ((unsigned)fn >> 16);
675   /* ori  $25,low(fn)  */
676   tramp[1] = 0x37390000 | ((unsigned)fn & 0xffff);
677   /* lui  $12,high(codeloc) */
678   tramp[2] = 0x3c0c0000 | ((unsigned)codeloc >> 16);
679   /* jr   $25          */
680   tramp[3] = 0x03200008;
681   /* ori  $12,low(codeloc)  */
682   tramp[4] = 0x358c0000 | ((unsigned)codeloc & 0xffff);
683 #else
684   /* N64 has a somewhat larger trampoline.  */
685   /* lui  $25,high(fn) */
686   tramp[0] = 0x3c190000 | ((unsigned long)fn >> 48);
687   /* lui  $12,high(codeloc) */
688   tramp[1] = 0x3c0c0000 | ((unsigned long)codeloc >> 48);
689   /* ori  $25,mid-high(fn)  */
690   tramp[2] = 0x37390000 | (((unsigned long)fn >> 32 ) & 0xffff);
691   /* ori  $12,mid-high(codeloc)  */
692   tramp[3] = 0x358c0000 | (((unsigned long)codeloc >> 32) & 0xffff);
693   /* dsll $25,$25,16 */
694   tramp[4] = 0x0019cc38;
695   /* dsll $12,$12,16 */
696   tramp[5] = 0x000c6438;
697   /* ori  $25,mid-low(fn)  */
698   tramp[6] = 0x37390000 | (((unsigned long)fn >> 16 ) & 0xffff);
699   /* ori  $12,mid-low(codeloc)  */
700   tramp[7] = 0x358c0000 | (((unsigned long)codeloc >> 16) & 0xffff);
701   /* dsll $25,$25,16 */
702   tramp[8] = 0x0019cc38;
703   /* dsll $12,$12,16 */
704   tramp[9] = 0x000c6438;
705   /* ori  $25,low(fn)  */
706   tramp[10] = 0x37390000 | ((unsigned long)fn  & 0xffff);
707   /* jr   $25          */
708   tramp[11] = 0x03200008;
709   /* ori  $12,low(codeloc)  */
710   tramp[12] = 0x358c0000 | ((unsigned long)codeloc & 0xffff);
711
712 #endif
713
714   closure->cif = cif;
715   closure->fun = fun;
716   closure->user_data = user_data;
717
718 #ifdef USE__BUILTIN___CLEAR_CACHE
719   __builtin___clear_cache(clear_location, clear_location + FFI_TRAMPOLINE_SIZE);
720 #else
721   cacheflush (clear_location, FFI_TRAMPOLINE_SIZE, ICACHE);
722 #endif
723   return FFI_OK;
724 }
725
726 /*
727  * Decodes the arguments to a function, which will be stored on the
728  * stack. AR is the pointer to the beginning of the integer arguments
729  * (and, depending upon the arguments, some floating-point arguments
730  * as well). FPR is a pointer to the area where floating point
731  * registers have been saved, if any.
732  *
733  * RVALUE is the location where the function return value will be
734  * stored. CLOSURE is the prepared closure to invoke.
735  *
736  * This function should only be called from assembly, which is in
737  * turn called from a trampoline.
738  *
739  * Returns the function return type.
740  *
741  * Based on the similar routine for sparc.
742  */
743 int
744 ffi_closure_mips_inner_O32 (ffi_closure *closure,
745                             void *rvalue, ffi_arg *ar,
746                             double *fpr)
747 {
748   ffi_cif *cif;
749   void **avaluep;
750   ffi_arg *avalue;
751   ffi_type **arg_types;
752   int i, avn, argn, seen_int;
753
754   cif = closure->cif;
755   avalue = alloca (cif->nargs * sizeof (ffi_arg));
756   avaluep = alloca (cif->nargs * sizeof (ffi_arg));
757
758   seen_int = (cif->abi == FFI_O32_SOFT_FLOAT);
759   argn = 0;
760
761   if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)
762     {
763       rvalue = (void *)(UINT32)ar[0];
764       argn = 1;
765     }
766
767   i = 0;
768   avn = cif->nargs;
769   arg_types = cif->arg_types;
770
771   while (i < avn)
772     {
773       if (i < 2 && !seen_int &&
774           (arg_types[i]->type == FFI_TYPE_FLOAT ||
775            arg_types[i]->type == FFI_TYPE_DOUBLE))
776         {
777 #ifdef __MIPSEB__
778           if (arg_types[i]->type == FFI_TYPE_FLOAT)
779             avaluep[i] = ((char *) &fpr[i]) + sizeof (float);
780           else
781 #endif
782             avaluep[i] = (char *) &fpr[i];
783         }
784       else
785         {
786           if (arg_types[i]->alignment == 8 && (argn & 0x1))
787             argn++;
788           switch (arg_types[i]->type)
789             {
790               case FFI_TYPE_SINT8:
791                 avaluep[i] = &avalue[i];
792                 *(SINT8 *) &avalue[i] = (SINT8) ar[argn];
793                 break;
794
795               case FFI_TYPE_UINT8:
796                 avaluep[i] = &avalue[i];
797                 *(UINT8 *) &avalue[i] = (UINT8) ar[argn];
798                 break;
799                   
800               case FFI_TYPE_SINT16:
801                 avaluep[i] = &avalue[i];
802                 *(SINT16 *) &avalue[i] = (SINT16) ar[argn];
803                 break;
804                   
805               case FFI_TYPE_UINT16:
806                 avaluep[i] = &avalue[i];
807                 *(UINT16 *) &avalue[i] = (UINT16) ar[argn];
808                 break;
809
810               default:
811                 avaluep[i] = (char *) &ar[argn];
812                 break;
813             }
814           seen_int = 1;
815         }
816       argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
817       i++;
818     }
819
820   /* Invoke the closure. */
821   (closure->fun) (cif, rvalue, avaluep, closure->user_data);
822
823   if (cif->abi == FFI_O32_SOFT_FLOAT)
824     {
825       switch (cif->rtype->type)
826         {
827         case FFI_TYPE_FLOAT:
828           return FFI_TYPE_INT;
829         case FFI_TYPE_DOUBLE:
830           return FFI_TYPE_UINT64;
831         default:
832           return cif->rtype->type;
833         }
834     }
835   else
836     {
837       return cif->rtype->type;
838     }
839 }
840
841 #if defined(FFI_MIPS_N32)
842
843 static void
844 copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,
845                 int argn, unsigned arg_offset, ffi_arg *ar,
846                 ffi_arg *fpr, int soft_float)
847 {
848   ffi_type **elt_typep = type->elements;
849   while(*elt_typep)
850     {
851       ffi_type *elt_type = *elt_typep;
852       unsigned o;
853       char *tp;
854       char *argp;
855       char *fpp;
856
857       o = ALIGN(offset, elt_type->alignment);
858       arg_offset += o - offset;
859       offset = o;
860       argn += arg_offset / sizeof(ffi_arg);
861       arg_offset = arg_offset % sizeof(ffi_arg);
862
863       argp = (char *)(ar + argn);
864       fpp = (char *)(argn >= 8 ? ar + argn : fpr + argn);
865
866       tp = target + offset;
867
868       if (elt_type->type == FFI_TYPE_DOUBLE && !soft_float)
869         *(double *)tp = *(double *)fpp;
870       else
871         memcpy(tp, argp + arg_offset, elt_type->size);
872
873       offset += elt_type->size;
874       arg_offset += elt_type->size;
875       elt_typep++;
876       argn += arg_offset / sizeof(ffi_arg);
877       arg_offset = arg_offset % sizeof(ffi_arg);
878     }
879 }
880
881 /*
882  * Decodes the arguments to a function, which will be stored on the
883  * stack. AR is the pointer to the beginning of the integer
884  * arguments. FPR is a pointer to the area where floating point
885  * registers have been saved.
886  *
887  * RVALUE is the location where the function return value will be
888  * stored. CLOSURE is the prepared closure to invoke.
889  *
890  * This function should only be called from assembly, which is in
891  * turn called from a trampoline.
892  *
893  * Returns the function return flags.
894  *
895  */
896 int
897 ffi_closure_mips_inner_N32 (ffi_closure *closure,
898                             void *rvalue, ffi_arg *ar,
899                             ffi_arg *fpr)
900 {
901   ffi_cif *cif;
902   void **avaluep;
903   ffi_arg *avalue;
904   ffi_type **arg_types;
905   int i, avn, argn;
906   int soft_float;
907   ffi_arg *argp;
908
909   cif = closure->cif;
910   soft_float = cif->abi == FFI_N64_SOFT_FLOAT
911     || cif->abi == FFI_N32_SOFT_FLOAT;
912   avalue = alloca (cif->nargs * sizeof (ffi_arg));
913   avaluep = alloca (cif->nargs * sizeof (ffi_arg));
914
915   argn = 0;
916
917   if (cif->rstruct_flag)
918     {
919 #if _MIPS_SIM==_ABIN32
920       rvalue = (void *)(UINT32)ar[0];
921 #else /* N64 */
922       rvalue = (void *)ar[0];
923 #endif
924       argn = 1;
925     }
926
927   i = 0;
928   avn = cif->nargs;
929   arg_types = cif->arg_types;
930
931   while (i < avn)
932     {
933       if (arg_types[i]->type == FFI_TYPE_FLOAT
934           || arg_types[i]->type == FFI_TYPE_DOUBLE)
935         {
936           argp = (argn >= 8 || soft_float) ? ar + argn : fpr + argn;
937 #ifdef __MIPSEB__
938           if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8)
939             avaluep[i] = ((char *) argp) + sizeof (float);
940           else
941 #endif
942             avaluep[i] = (char *) argp;
943         }
944       else
945         {
946           unsigned type = arg_types[i]->type;
947
948           if (arg_types[i]->alignment > sizeof(ffi_arg))
949             argn = ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg));
950
951           argp = ar + argn;
952
953           /* The size of a pointer depends on the ABI */
954           if (type == FFI_TYPE_POINTER)
955             type = (cif->abi == FFI_N64 || cif->abi == FFI_N64_SOFT_FLOAT)
956               ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
957
958           if (soft_float && type ==  FFI_TYPE_FLOAT)
959             type = FFI_TYPE_UINT32;
960
961           switch (type)
962             {
963             case FFI_TYPE_SINT8:
964               avaluep[i] = &avalue[i];
965               *(SINT8 *) &avalue[i] = (SINT8) *argp;
966               break;
967
968             case FFI_TYPE_UINT8:
969               avaluep[i] = &avalue[i];
970               *(UINT8 *) &avalue[i] = (UINT8) *argp;
971               break;
972
973             case FFI_TYPE_SINT16:
974               avaluep[i] = &avalue[i];
975               *(SINT16 *) &avalue[i] = (SINT16) *argp;
976               break;
977
978             case FFI_TYPE_UINT16:
979               avaluep[i] = &avalue[i];
980               *(UINT16 *) &avalue[i] = (UINT16) *argp;
981               break;
982
983             case FFI_TYPE_SINT32:
984               avaluep[i] = &avalue[i];
985               *(SINT32 *) &avalue[i] = (SINT32) *argp;
986               break;
987
988             case FFI_TYPE_UINT32:
989               avaluep[i] = &avalue[i];
990               *(UINT32 *) &avalue[i] = (UINT32) *argp;
991               break;
992
993             case FFI_TYPE_STRUCT:
994               if (argn < 8)
995                 {
996                   /* Allocate space for the struct as at least part of
997                      it was passed in registers.  */
998                   avaluep[i] = alloca(arg_types[i]->size);
999                   copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i],
1000                                   argn, 0, ar, fpr, soft_float);
1001
1002                   break;
1003                 }
1004               /* Else fall through.  */
1005             default:
1006               avaluep[i] = (char *) argp;
1007               break;
1008             }
1009         }
1010       argn += ALIGN(arg_types[i]->size, sizeof(ffi_arg)) / sizeof(ffi_arg);
1011       i++;
1012     }
1013
1014   /* Invoke the closure. */
1015   (closure->fun) (cif, rvalue, avaluep, closure->user_data);
1016
1017   return cif->flags >> (FFI_FLAG_BITS * 8);
1018 }
1019
1020 #endif /* FFI_MIPS_N32 */
1021
1022 #endif /* FFI_CLOSURES */