OSDN Git Service

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