OSDN Git Service

cc2a42e7a9f5e9072348b4880a58ac7dd5d79e7b
[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
466       default:
467         cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
468         break;
469       }
470   }
471 #endif
472   
473   return FFI_OK;
474 }
475
476 /* Low level routine for calling O32 functions */
477 extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int), 
478                         extended_cif *, unsigned, 
479                         unsigned, unsigned *, void (*)());
480
481 /* Low level routine for calling N32 functions */
482 extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int), 
483                         extended_cif *, unsigned, 
484                         unsigned, unsigned *, void (*)());
485
486 void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
487 {
488   extended_cif ecif;
489
490   ecif.cif = cif;
491   ecif.avalue = avalue;
492   
493   /* If the return value is a struct and we don't have a return */
494   /* value address then we need to make one                     */
495   
496   if ((rvalue == NULL) && 
497       (cif->rtype->type == FFI_TYPE_STRUCT))
498     ecif.rvalue = alloca(cif->rtype->size);
499   else
500     ecif.rvalue = rvalue;
501     
502   switch (cif->abi) 
503     {
504 #ifdef FFI_MIPS_O32
505     case FFI_O32:
506     case FFI_O32_SOFT_FLOAT:
507       ffi_call_O32(ffi_prep_args, &ecif, cif->bytes, 
508                    cif->flags, ecif.rvalue, fn);
509       break;
510 #endif
511
512 #ifdef FFI_MIPS_N32
513     case FFI_N32:
514     case FFI_N64:
515       {
516         int copy_rvalue = 0;
517         void *rvalue_copy = ecif.rvalue;
518         if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16)
519           {
520             /* For structures smaller than 16 bytes we clobber memory
521                in 8 byte increments.  Make a copy so we don't clobber
522                the callers memory outside of the struct bounds.  */
523             rvalue_copy = alloca(16);
524             copy_rvalue = 1;
525           }
526         ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
527                      cif->flags, rvalue_copy, fn);
528         if (copy_rvalue)
529           memcpy(ecif.rvalue, rvalue_copy, cif->rtype->size);
530       }
531       break;
532 #endif
533
534     default:
535       FFI_ASSERT(0);
536       break;
537     }
538 }
539
540 #if FFI_CLOSURES
541 #if defined(FFI_MIPS_O32)
542 extern void ffi_closure_O32(void);
543 #else
544 extern void ffi_closure_N32(void);
545 #endif /* FFI_MIPS_O32 */
546
547 ffi_status
548 ffi_prep_closure_loc (ffi_closure *closure,
549                       ffi_cif *cif,
550                       void (*fun)(ffi_cif*,void*,void**,void*),
551                       void *user_data,
552                       void *codeloc)
553 {
554   unsigned int *tramp = (unsigned int *) &closure->tramp[0];
555   void * fn;
556   char *clear_location = (char *) codeloc;
557
558 #if defined(FFI_MIPS_O32)
559   FFI_ASSERT(cif->abi == FFI_O32 || cif->abi == FFI_O32_SOFT_FLOAT);
560   fn = ffi_closure_O32;
561 #else /* FFI_MIPS_N32 */
562   FFI_ASSERT(cif->abi == FFI_N32 || cif->abi == FFI_N64);
563   fn = ffi_closure_N32;
564 #endif /* FFI_MIPS_O32 */
565
566 #if defined(FFI_MIPS_O32) || (_MIPS_SIM ==_ABIN32)
567   /* lui  $25,high(fn) */
568   tramp[0] = 0x3c190000 | ((unsigned)fn >> 16);
569   /* ori  $25,low(fn)  */
570   tramp[1] = 0x37390000 | ((unsigned)fn & 0xffff);
571   /* lui  $12,high(codeloc) */
572   tramp[2] = 0x3c0c0000 | ((unsigned)codeloc >> 16);
573   /* jr   $25          */
574   tramp[3] = 0x03200008;
575   /* ori  $12,low(codeloc)  */
576   tramp[4] = 0x358c0000 | ((unsigned)codeloc & 0xffff);
577 #else
578   /* N64 has a somewhat larger trampoline.  */
579   /* lui  $25,high(fn) */
580   tramp[0] = 0x3c190000 | ((unsigned long)fn >> 48);
581   /* lui  $12,high(codeloc) */
582   tramp[1] = 0x3c0c0000 | ((unsigned long)codeloc >> 48);
583   /* ori  $25,mid-high(fn)  */
584   tramp[2] = 0x37390000 | (((unsigned long)fn >> 32 ) & 0xffff);
585   /* ori  $12,mid-high(codeloc)  */
586   tramp[3] = 0x358c0000 | (((unsigned long)codeloc >> 32) & 0xffff);
587   /* dsll $25,$25,16 */
588   tramp[4] = 0x0019cc38;
589   /* dsll $12,$12,16 */
590   tramp[5] = 0x000c6438;
591   /* ori  $25,mid-low(fn)  */
592   tramp[6] = 0x37390000 | (((unsigned long)fn >> 16 ) & 0xffff);
593   /* ori  $12,mid-low(codeloc)  */
594   tramp[7] = 0x358c0000 | (((unsigned long)codeloc >> 16) & 0xffff);
595   /* dsll $25,$25,16 */
596   tramp[8] = 0x0019cc38;
597   /* dsll $12,$12,16 */
598   tramp[9] = 0x000c6438;
599   /* ori  $25,low(fn)  */
600   tramp[10] = 0x37390000 | ((unsigned long)fn  & 0xffff);
601   /* jr   $25          */
602   tramp[11] = 0x03200008;
603   /* ori  $12,low(codeloc)  */
604   tramp[12] = 0x358c0000 | ((unsigned long)codeloc & 0xffff);
605
606 #endif
607
608   closure->cif = cif;
609   closure->fun = fun;
610   closure->user_data = user_data;
611
612   __builtin___clear_cache(clear_location, clear_location + FFI_TRAMPOLINE_SIZE);
613
614   return FFI_OK;
615 }
616
617 /*
618  * Decodes the arguments to a function, which will be stored on the
619  * stack. AR is the pointer to the beginning of the integer arguments
620  * (and, depending upon the arguments, some floating-point arguments
621  * as well). FPR is a pointer to the area where floating point
622  * registers have been saved, if any.
623  *
624  * RVALUE is the location where the function return value will be
625  * stored. CLOSURE is the prepared closure to invoke.
626  *
627  * This function should only be called from assembly, which is in
628  * turn called from a trampoline.
629  *
630  * Returns the function return type.
631  *
632  * Based on the similar routine for sparc.
633  */
634 int
635 ffi_closure_mips_inner_O32 (ffi_closure *closure,
636                             void *rvalue, ffi_arg *ar,
637                             double *fpr)
638 {
639   ffi_cif *cif;
640   void **avaluep;
641   ffi_arg *avalue;
642   ffi_type **arg_types;
643   int i, avn, argn, seen_int;
644
645   cif = closure->cif;
646   avalue = alloca (cif->nargs * sizeof (ffi_arg));
647   avaluep = alloca (cif->nargs * sizeof (ffi_arg));
648
649   seen_int = (cif->abi == FFI_O32_SOFT_FLOAT);
650   argn = 0;
651
652   if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)
653     {
654       rvalue = (void *)(UINT32)ar[0];
655       argn = 1;
656     }
657
658   i = 0;
659   avn = cif->nargs;
660   arg_types = cif->arg_types;
661
662   while (i < avn)
663     {
664       if (i < 2 && !seen_int &&
665           (arg_types[i]->type == FFI_TYPE_FLOAT ||
666            arg_types[i]->type == FFI_TYPE_DOUBLE))
667         {
668 #ifdef __MIPSEB__
669           if (arg_types[i]->type == FFI_TYPE_FLOAT)
670             avaluep[i] = ((char *) &fpr[i]) + sizeof (float);
671           else
672 #endif
673             avaluep[i] = (char *) &fpr[i];
674         }
675       else
676         {
677           if (arg_types[i]->alignment == 8 && (argn & 0x1))
678             argn++;
679           switch (arg_types[i]->type)
680             {
681               case FFI_TYPE_SINT8:
682                 avaluep[i] = &avalue[i];
683                 *(SINT8 *) &avalue[i] = (SINT8) ar[argn];
684                 break;
685
686               case FFI_TYPE_UINT8:
687                 avaluep[i] = &avalue[i];
688                 *(UINT8 *) &avalue[i] = (UINT8) ar[argn];
689                 break;
690                   
691               case FFI_TYPE_SINT16:
692                 avaluep[i] = &avalue[i];
693                 *(SINT16 *) &avalue[i] = (SINT16) ar[argn];
694                 break;
695                   
696               case FFI_TYPE_UINT16:
697                 avaluep[i] = &avalue[i];
698                 *(UINT16 *) &avalue[i] = (UINT16) ar[argn];
699                 break;
700
701               default:
702                 avaluep[i] = (char *) &ar[argn];
703                 break;
704             }
705           seen_int = 1;
706         }
707       argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
708       i++;
709     }
710
711   /* Invoke the closure. */
712   (closure->fun) (cif, rvalue, avaluep, closure->user_data);
713
714   if (cif->abi == FFI_O32_SOFT_FLOAT)
715     {
716       switch (cif->rtype->type)
717         {
718         case FFI_TYPE_FLOAT:
719           return FFI_TYPE_INT;
720         case FFI_TYPE_DOUBLE:
721           return FFI_TYPE_UINT64;
722         default:
723           return cif->rtype->type;
724         }
725     }
726   else
727     {
728       return cif->rtype->type;
729     }
730 }
731
732 #if defined(FFI_MIPS_N32)
733
734 static void
735 copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,
736                 int argn, unsigned arg_offset, ffi_arg *ar,
737                 ffi_arg *fpr)
738 {
739   ffi_type **elt_typep = type->elements;
740   while(*elt_typep)
741     {
742       ffi_type *elt_type = *elt_typep;
743       unsigned o;
744       char *tp;
745       char *argp;
746       char *fpp;
747
748       o = ALIGN(offset, elt_type->alignment);
749       arg_offset += o - offset;
750       offset = o;
751       argn += arg_offset / sizeof(ffi_arg);
752       arg_offset = arg_offset % sizeof(ffi_arg);
753
754       argp = (char *)(ar + argn);
755       fpp = (char *)(argn >= 8 ? ar + argn : fpr + argn);
756
757       tp = target + offset;
758
759       if (elt_type->type == FFI_TYPE_DOUBLE)
760         *(double *)tp = *(double *)fpp;
761       else
762         memcpy(tp, argp + arg_offset, elt_type->size);
763
764       offset += elt_type->size;
765       arg_offset += elt_type->size;
766       elt_typep++;
767       argn += arg_offset / sizeof(ffi_arg);
768       arg_offset = arg_offset % sizeof(ffi_arg);
769     }
770 }
771
772 /*
773  * Decodes the arguments to a function, which will be stored on the
774  * stack. AR is the pointer to the beginning of the integer
775  * arguments. FPR is a pointer to the area where floating point
776  * registers have been saved.
777  *
778  * RVALUE is the location where the function return value will be
779  * stored. CLOSURE is the prepared closure to invoke.
780  *
781  * This function should only be called from assembly, which is in
782  * turn called from a trampoline.
783  *
784  * Returns the function return flags.
785  *
786  */
787 int
788 ffi_closure_mips_inner_N32 (ffi_closure *closure,
789                             void *rvalue, ffi_arg *ar,
790                             ffi_arg *fpr)
791 {
792   ffi_cif *cif;
793   void **avaluep;
794   ffi_arg *avalue;
795   ffi_type **arg_types;
796   int i, avn, argn;
797
798   cif = closure->cif;
799   avalue = alloca (cif->nargs * sizeof (ffi_arg));
800   avaluep = alloca (cif->nargs * sizeof (ffi_arg));
801
802   argn = 0;
803
804   if (cif->rstruct_flag)
805     {
806 #if _MIPS_SIM==_ABIN32
807       rvalue = (void *)(UINT32)ar[0];
808 #else /* N64 */
809       rvalue = (void *)ar[0];
810 #endif
811       argn = 1;
812     }
813
814   i = 0;
815   avn = cif->nargs;
816   arg_types = cif->arg_types;
817
818   while (i < avn)
819     {
820       if (arg_types[i]->type == FFI_TYPE_FLOAT
821           || arg_types[i]->type == FFI_TYPE_DOUBLE)
822         {
823           ffi_arg *argp = argn >= 8 ? ar + argn : fpr + argn;
824 #ifdef __MIPSEB__
825           if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8)
826             avaluep[i] = ((char *) argp) + sizeof (float);
827           else
828 #endif
829             avaluep[i] = (char *) argp;
830         }
831       else
832         {
833           unsigned type = arg_types[i]->type;
834
835           if (arg_types[i]->alignment > sizeof(ffi_arg))
836             argn = ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg));
837
838           ffi_arg *argp = ar + argn;
839
840           /* The size of a pointer depends on the ABI */
841           if (type == FFI_TYPE_POINTER)
842             type = (cif->abi == FFI_N64) ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
843
844           switch (type)
845             {
846             case FFI_TYPE_SINT8:
847               avaluep[i] = &avalue[i];
848               *(SINT8 *) &avalue[i] = (SINT8) *argp;
849               break;
850
851             case FFI_TYPE_UINT8:
852               avaluep[i] = &avalue[i];
853               *(UINT8 *) &avalue[i] = (UINT8) *argp;
854               break;
855
856             case FFI_TYPE_SINT16:
857               avaluep[i] = &avalue[i];
858               *(SINT16 *) &avalue[i] = (SINT16) *argp;
859               break;
860
861             case FFI_TYPE_UINT16:
862               avaluep[i] = &avalue[i];
863               *(UINT16 *) &avalue[i] = (UINT16) *argp;
864               break;
865
866             case FFI_TYPE_SINT32:
867               avaluep[i] = &avalue[i];
868               *(SINT32 *) &avalue[i] = (SINT32) *argp;
869               break;
870
871             case FFI_TYPE_UINT32:
872               avaluep[i] = &avalue[i];
873               *(UINT32 *) &avalue[i] = (UINT32) *argp;
874               break;
875
876             case FFI_TYPE_STRUCT:
877               if (argn < 8)
878                 {
879                   /* Allocate space for the struct as at least part of
880                      it was passed in registers.  */
881                   avaluep[i] = alloca(arg_types[i]->size);
882                   copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i],
883                                   argn, 0, ar, fpr);
884
885                   break;
886                 }
887               /* Else fall through.  */
888             default:
889               avaluep[i] = (char *) argp;
890               break;
891             }
892         }
893       argn += ALIGN(arg_types[i]->size, sizeof(ffi_arg)) / sizeof(ffi_arg);
894       i++;
895     }
896
897   /* Invoke the closure. */
898   (closure->fun) (cif, rvalue, avaluep, closure->user_data);
899
900   return cif->flags >> (FFI_FLAG_BITS * 8);
901 }
902
903 #endif /* FFI_MIPS_N32 */
904
905 #endif /* FFI_CLOSURES */