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