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