Home | History | Annotate | Download | only in mips
      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 
     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
    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
    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 */
    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 
    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
    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
    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
    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
    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