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