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