github.com/prattmic/llgo-embedded@v0.0.0-20150820070356-41cfecea0e1e/third_party/gofrontend/libffi/src/powerpc/ffi_sysv.c (about)

     1  /* -----------------------------------------------------------------------
     2     ffi_sysv.c - Copyright (C) 2013 IBM
     3                  Copyright (C) 2011 Anthony Green
     4                  Copyright (C) 2011 Kyle Moffett
     5                  Copyright (C) 2008 Red Hat, Inc
     6                  Copyright (C) 2007, 2008 Free Software Foundation, Inc
     7                  Copyright (c) 1998 Geoffrey Keating
     8  
     9     PowerPC Foreign Function Interface
    10  
    11     Permission is hereby granted, free of charge, to any person obtaining
    12     a copy of this software and associated documentation files (the
    13     ``Software''), to deal in the Software without restriction, including
    14     without limitation the rights to use, copy, modify, merge, publish,
    15     distribute, sublicense, and/or sell copies of the Software, and to
    16     permit persons to whom the Software is furnished to do so, subject to
    17     the following conditions:
    18  
    19     The above copyright notice and this permission notice shall be included
    20     in all copies or substantial portions of the Software.
    21  
    22     THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
    23     OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    24     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    25     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
    26     OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
    27     ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    28     OTHER DEALINGS IN THE SOFTWARE.
    29     ----------------------------------------------------------------------- */
    30  
    31  #include "ffi.h"
    32  
    33  #ifndef POWERPC64
    34  #include "ffi_common.h"
    35  #include "ffi_powerpc.h"
    36  
    37  
    38  /* About the SYSV ABI.  */
    39  #define ASM_NEEDS_REGISTERS 6
    40  #define NUM_GPR_ARG_REGISTERS 8
    41  #define NUM_FPR_ARG_REGISTERS 8
    42  
    43  
    44  #if HAVE_LONG_DOUBLE_VARIANT && FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
    45  /* Adjust size of ffi_type_longdouble.  */
    46  void FFI_HIDDEN
    47  ffi_prep_types_sysv (ffi_abi abi)
    48  {
    49    if ((abi & (FFI_SYSV | FFI_SYSV_LONG_DOUBLE_128)) == FFI_SYSV)
    50      {
    51        ffi_type_longdouble.size = 8;
    52        ffi_type_longdouble.alignment = 8;
    53      }
    54    else
    55      {
    56        ffi_type_longdouble.size = 16;
    57        ffi_type_longdouble.alignment = 16;
    58      }
    59  }
    60  #endif
    61  
    62  /* Transform long double, double and float to other types as per abi.  */
    63  static int
    64  translate_float (int abi, int type)
    65  {
    66  #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
    67    if (type == FFI_TYPE_LONGDOUBLE
    68        && (abi & FFI_SYSV_LONG_DOUBLE_128) == 0)
    69      type = FFI_TYPE_DOUBLE;
    70  #endif
    71    if ((abi & FFI_SYSV_SOFT_FLOAT) != 0)
    72      {
    73        if (type == FFI_TYPE_FLOAT)
    74  	type = FFI_TYPE_UINT32;
    75        else if (type == FFI_TYPE_DOUBLE)
    76  	type = FFI_TYPE_UINT64;
    77  #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
    78        else if (type == FFI_TYPE_LONGDOUBLE)
    79  	type = FFI_TYPE_UINT128;
    80      }
    81    else if ((abi & FFI_SYSV_IBM_LONG_DOUBLE) == 0)
    82      {
    83        if (type == FFI_TYPE_LONGDOUBLE)
    84  	type = FFI_TYPE_STRUCT;
    85  #endif
    86      }
    87    return type;
    88  }
    89  
    90  /* Perform machine dependent cif processing */
    91  static ffi_status
    92  ffi_prep_cif_sysv_core (ffi_cif *cif)
    93  {
    94    ffi_type **ptr;
    95    unsigned bytes;
    96    unsigned i, fparg_count = 0, intarg_count = 0;
    97    unsigned flags = cif->flags;
    98    unsigned struct_copy_size = 0;
    99    unsigned type = cif->rtype->type;
   100    unsigned size = cif->rtype->size;
   101  
   102    /* The machine-independent calculation of cif->bytes doesn't work
   103       for us.  Redo the calculation.  */
   104  
   105    /* Space for the frame pointer, callee's LR, and the asm's temp regs.  */
   106    bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int);
   107  
   108    /* Space for the GPR registers.  */
   109    bytes += NUM_GPR_ARG_REGISTERS * sizeof (int);
   110  
   111    /* Return value handling.  The rules for SYSV are as follows:
   112       - 32-bit (or less) integer values are returned in gpr3;
   113       - Structures of size <= 4 bytes also returned in gpr3;
   114       - 64-bit integer values and structures between 5 and 8 bytes are returned
   115       in gpr3 and gpr4;
   116       - Larger structures are allocated space and a pointer is passed as
   117       the first argument.
   118       - Single/double FP values are returned in fpr1;
   119       - long doubles (if not equivalent to double) are returned in
   120       fpr1,fpr2 for Linux and as for large structs for SysV.  */
   121  
   122    type = translate_float (cif->abi, type);
   123  
   124    switch (type)
   125      {
   126  #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
   127      case FFI_TYPE_LONGDOUBLE:
   128        flags |= FLAG_RETURNS_128BITS;
   129        /* Fall through.  */
   130  #endif
   131      case FFI_TYPE_DOUBLE:
   132        flags |= FLAG_RETURNS_64BITS;
   133        /* Fall through.  */
   134      case FFI_TYPE_FLOAT:
   135        flags |= FLAG_RETURNS_FP;
   136  #ifdef __NO_FPRS__
   137        return FFI_BAD_ABI;
   138  #endif
   139        break;
   140  
   141      case FFI_TYPE_UINT128:
   142        flags |= FLAG_RETURNS_128BITS;
   143        /* Fall through.  */
   144      case FFI_TYPE_UINT64:
   145      case FFI_TYPE_SINT64:
   146        flags |= FLAG_RETURNS_64BITS;
   147        break;
   148  
   149      case FFI_TYPE_STRUCT:
   150        /* The final SYSV ABI says that structures smaller or equal 8 bytes
   151  	 are returned in r3/r4.  A draft ABI used by linux instead
   152  	 returns them in memory.  */
   153        if ((cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8)
   154  	{
   155  	  flags |= FLAG_RETURNS_SMST;
   156  	  break;
   157  	}
   158        intarg_count++;
   159        flags |= FLAG_RETVAL_REFERENCE;
   160        /* Fall through.  */
   161      case FFI_TYPE_VOID:
   162        flags |= FLAG_RETURNS_NOTHING;
   163        break;
   164  
   165      default:
   166        /* Returns 32-bit integer, or similar.  Nothing to do here.  */
   167        break;
   168      }
   169  
   170    /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
   171       first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
   172       goes on the stack.  Structures and long doubles (if not equivalent
   173       to double) are passed as a pointer to a copy of the structure.
   174       Stuff on the stack needs to keep proper alignment.  */
   175    for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
   176      {
   177        unsigned short typenum = (*ptr)->type;
   178  
   179        typenum = translate_float (cif->abi, typenum);
   180  
   181        switch (typenum)
   182  	{
   183  #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
   184  	case FFI_TYPE_LONGDOUBLE:
   185  	  fparg_count++;
   186  	  /* Fall thru */
   187  #endif
   188  	case FFI_TYPE_DOUBLE:
   189  	  fparg_count++;
   190  	  /* If this FP arg is going on the stack, it must be
   191  	     8-byte-aligned.  */
   192  	  if (fparg_count > NUM_FPR_ARG_REGISTERS
   193  	      && intarg_count >= NUM_GPR_ARG_REGISTERS
   194  	      && intarg_count % 2 != 0)
   195  	    intarg_count++;
   196  #ifdef __NO_FPRS__
   197  	  return FFI_BAD_ABI;
   198  #endif
   199  	  break;
   200  
   201  	case FFI_TYPE_FLOAT:
   202  	  fparg_count++;
   203  #ifdef __NO_FPRS__
   204  	  return FFI_BAD_ABI;
   205  #endif
   206  	  break;
   207  
   208  	case FFI_TYPE_UINT128:
   209  	  /* A long double in FFI_LINUX_SOFT_FLOAT can use only a set
   210  	     of four consecutive gprs. If we do not have enough, we
   211  	     have to adjust the intarg_count value.  */
   212  	  if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3
   213  	      && intarg_count < NUM_GPR_ARG_REGISTERS)
   214  	    intarg_count = NUM_GPR_ARG_REGISTERS;
   215  	  intarg_count += 4;
   216  	  break;
   217  
   218  	case FFI_TYPE_UINT64:
   219  	case FFI_TYPE_SINT64:
   220  	  /* 'long long' arguments are passed as two words, but
   221  	     either both words must fit in registers or both go
   222  	     on the stack.  If they go on the stack, they must
   223  	     be 8-byte-aligned.
   224  
   225  	     Also, only certain register pairs can be used for
   226  	     passing long long int -- specifically (r3,r4), (r5,r6),
   227  	     (r7,r8), (r9,r10).  */
   228  	  if (intarg_count == NUM_GPR_ARG_REGISTERS-1
   229  	      || intarg_count % 2 != 0)
   230  	    intarg_count++;
   231  	  intarg_count += 2;
   232  	  break;
   233  
   234  	case FFI_TYPE_STRUCT:
   235  	  /* We must allocate space for a copy of these to enforce
   236  	     pass-by-value.  Pad the space up to a multiple of 16
   237  	     bytes (the maximum alignment required for anything under
   238  	     the SYSV ABI).  */
   239  	  struct_copy_size += ((*ptr)->size + 15) & ~0xF;
   240  	  /* Fall through (allocate space for the pointer).  */
   241  
   242  	case FFI_TYPE_POINTER:
   243  	case FFI_TYPE_INT:
   244  	case FFI_TYPE_UINT32:
   245  	case FFI_TYPE_SINT32:
   246  	case FFI_TYPE_UINT16:
   247  	case FFI_TYPE_SINT16:
   248  	case FFI_TYPE_UINT8:
   249  	case FFI_TYPE_SINT8:
   250  	  /* Everything else is passed as a 4-byte word in a GPR, either
   251  	     the object itself or a pointer to it.  */
   252  	  intarg_count++;
   253  	  break;
   254  
   255  	default:
   256  	  FFI_ASSERT (0);
   257  	}
   258      }
   259  
   260    if (fparg_count != 0)
   261      flags |= FLAG_FP_ARGUMENTS;
   262    if (intarg_count > 4)
   263      flags |= FLAG_4_GPR_ARGUMENTS;
   264    if (struct_copy_size != 0)
   265      flags |= FLAG_ARG_NEEDS_COPY;
   266  
   267    /* Space for the FPR registers, if needed.  */
   268    if (fparg_count != 0)
   269      bytes += NUM_FPR_ARG_REGISTERS * sizeof (double);
   270  
   271    /* Stack space.  */
   272    if (intarg_count > NUM_GPR_ARG_REGISTERS)
   273      bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int);
   274    if (fparg_count > NUM_FPR_ARG_REGISTERS)
   275      bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double);
   276  
   277    /* The stack space allocated needs to be a multiple of 16 bytes.  */
   278    bytes = (bytes + 15) & ~0xF;
   279  
   280    /* Add in the space for the copied structures.  */
   281    bytes += struct_copy_size;
   282  
   283    cif->flags = flags;
   284    cif->bytes = bytes;
   285  
   286    return FFI_OK;
   287  }
   288  
   289  ffi_status FFI_HIDDEN
   290  ffi_prep_cif_sysv (ffi_cif *cif)
   291  {
   292    if ((cif->abi & FFI_SYSV) == 0)
   293      {
   294        /* This call is from old code.  Translate to new ABI values.  */
   295        cif->flags |= FLAG_COMPAT;
   296        switch (cif->abi)
   297  	{
   298  	default:
   299  	  return FFI_BAD_ABI;
   300  
   301  	case FFI_COMPAT_SYSV:
   302  	  cif->abi = FFI_SYSV | FFI_SYSV_STRUCT_RET | FFI_SYSV_LONG_DOUBLE_128;
   303  	  break;
   304  
   305  	case FFI_COMPAT_GCC_SYSV:
   306  	  cif->abi = FFI_SYSV | FFI_SYSV_LONG_DOUBLE_128;
   307  	  break;
   308  
   309  	case FFI_COMPAT_LINUX:
   310  	  cif->abi = (FFI_SYSV | FFI_SYSV_IBM_LONG_DOUBLE
   311  		      | FFI_SYSV_LONG_DOUBLE_128);
   312  	  break;
   313  
   314  	case FFI_COMPAT_LINUX_SOFT_FLOAT:
   315  	  cif->abi = (FFI_SYSV | FFI_SYSV_SOFT_FLOAT | FFI_SYSV_IBM_LONG_DOUBLE
   316  		      | FFI_SYSV_LONG_DOUBLE_128);
   317  	  break;
   318  	}
   319      }
   320    return ffi_prep_cif_sysv_core (cif);
   321  }
   322  
   323  /* ffi_prep_args_SYSV is called by the assembly routine once stack space
   324     has been allocated for the function's arguments.
   325  
   326     The stack layout we want looks like this:
   327  
   328     |   Return address from ffi_call_SYSV 4bytes	|	higher addresses
   329     |--------------------------------------------|
   330     |   Previous backchain pointer	4	|       stack pointer here
   331     |--------------------------------------------|<+ <<<	on entry to
   332     |   Saved r28-r31			4*4	| |	ffi_call_SYSV
   333     |--------------------------------------------| |
   334     |   GPR registers r3-r10		8*4	| |	ffi_call_SYSV
   335     |--------------------------------------------| |
   336     |   FPR registers f1-f8 (optional)	8*8	| |
   337     |--------------------------------------------| |	stack	|
   338     |   Space for copied structures		| |	grows	|
   339     |--------------------------------------------| |	down    V
   340     |   Parameters that didn't fit in registers  | |
   341     |--------------------------------------------| |	lower addresses
   342     |   Space for callee's LR		4	| |
   343     |--------------------------------------------| |	stack pointer here
   344     |   Current backchain pointer	4	|-/	during
   345     |--------------------------------------------|   <<<	ffi_call_SYSV
   346  
   347  */
   348  
   349  void FFI_HIDDEN
   350  ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack)
   351  {
   352    const unsigned bytes = ecif->cif->bytes;
   353    const unsigned flags = ecif->cif->flags;
   354  
   355    typedef union
   356    {
   357      char *c;
   358      unsigned *u;
   359      long long *ll;
   360      float *f;
   361      double *d;
   362    } valp;
   363  
   364    /* 'stacktop' points at the previous backchain pointer.  */
   365    valp stacktop;
   366  
   367    /* 'gpr_base' points at the space for gpr3, and grows upwards as
   368       we use GPR registers.  */
   369    valp gpr_base;
   370    int intarg_count;
   371  
   372  #ifndef __NO_FPRS__
   373    /* 'fpr_base' points at the space for fpr1, and grows upwards as
   374       we use FPR registers.  */
   375    valp fpr_base;
   376    int fparg_count;
   377  #endif
   378  
   379    /* 'copy_space' grows down as we put structures in it.  It should
   380       stay 16-byte aligned.  */
   381    valp copy_space;
   382  
   383    /* 'next_arg' grows up as we put parameters in it.  */
   384    valp next_arg;
   385  
   386    int i;
   387    ffi_type **ptr;
   388  #ifndef __NO_FPRS__
   389    double double_tmp;
   390  #endif
   391    union
   392    {
   393      void **v;
   394      char **c;
   395      signed char **sc;
   396      unsigned char **uc;
   397      signed short **ss;
   398      unsigned short **us;
   399      unsigned int **ui;
   400      long long **ll;
   401      float **f;
   402      double **d;
   403    } p_argv;
   404    size_t struct_copy_size;
   405    unsigned gprvalue;
   406  
   407    stacktop.c = (char *) stack + bytes;
   408    gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
   409    intarg_count = 0;
   410  #ifndef __NO_FPRS__
   411    fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS;
   412    fparg_count = 0;
   413    copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c);
   414  #else
   415    copy_space.c = gpr_base.c;
   416  #endif
   417    next_arg.u = stack + 2;
   418  
   419    /* Check that everything starts aligned properly.  */
   420    FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
   421    FFI_ASSERT (((unsigned long) copy_space.c & 0xF) == 0);
   422    FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
   423    FFI_ASSERT ((bytes & 0xF) == 0);
   424    FFI_ASSERT (copy_space.c >= next_arg.c);
   425  
   426    /* Deal with return values that are actually pass-by-reference.  */
   427    if (flags & FLAG_RETVAL_REFERENCE)
   428      {
   429        *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue;
   430        intarg_count++;
   431      }
   432  
   433    /* Now for the arguments.  */
   434    p_argv.v = ecif->avalue;
   435    for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
   436         i > 0;
   437         i--, ptr++, p_argv.v++)
   438      {
   439        unsigned int typenum = (*ptr)->type;
   440  
   441        typenum = translate_float (ecif->cif->abi, typenum);
   442  
   443        /* Now test the translated value */
   444        switch (typenum)
   445  	{
   446  #ifndef __NO_FPRS__
   447  # if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
   448  	case FFI_TYPE_LONGDOUBLE:
   449  	  double_tmp = (*p_argv.d)[0];
   450  
   451  	  if (fparg_count >= NUM_FPR_ARG_REGISTERS - 1)
   452  	    {
   453  	      if (intarg_count >= NUM_GPR_ARG_REGISTERS
   454  		  && intarg_count % 2 != 0)
   455  		{
   456  		  intarg_count++;
   457  		  next_arg.u++;
   458  		}
   459  	      *next_arg.d = double_tmp;
   460  	      next_arg.u += 2;
   461  	      double_tmp = (*p_argv.d)[1];
   462  	      *next_arg.d = double_tmp;
   463  	      next_arg.u += 2;
   464  	    }
   465  	  else
   466  	    {
   467  	      *fpr_base.d++ = double_tmp;
   468  	      double_tmp = (*p_argv.d)[1];
   469  	      *fpr_base.d++ = double_tmp;
   470  	    }
   471  
   472  	  fparg_count += 2;
   473  	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
   474  	  break;
   475  # endif
   476  	case FFI_TYPE_DOUBLE:
   477  	  double_tmp = **p_argv.d;
   478  
   479  	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
   480  	    {
   481  	      if (intarg_count >= NUM_GPR_ARG_REGISTERS
   482  		  && intarg_count % 2 != 0)
   483  		{
   484  		  intarg_count++;
   485  		  next_arg.u++;
   486  		}
   487  	      *next_arg.d = double_tmp;
   488  	      next_arg.u += 2;
   489  	    }
   490  	  else
   491  	    *fpr_base.d++ = double_tmp;
   492  	  fparg_count++;
   493  	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
   494  	  break;
   495  
   496  	case FFI_TYPE_FLOAT:
   497  	  double_tmp = **p_argv.f;
   498  	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
   499  	    {
   500  	      *next_arg.f = (float) double_tmp;
   501  	      next_arg.u += 1;
   502  	      intarg_count++;
   503  	    }
   504  	  else
   505  	    *fpr_base.d++ = double_tmp;
   506  	  fparg_count++;
   507  	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
   508  	  break;
   509  #endif /* have FPRs */
   510  
   511  	case FFI_TYPE_UINT128:
   512  	  /* The soft float ABI for long doubles works like this, a long double
   513  	     is passed in four consecutive GPRs if available.  A maximum of 2
   514  	     long doubles can be passed in gprs.  If we do not have 4 GPRs
   515  	     left, the long double is passed on the stack, 4-byte aligned.  */
   516  	  {
   517  	    unsigned int int_tmp;
   518  	    unsigned int ii;
   519  	    if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3)
   520  	      {
   521  		if (intarg_count < NUM_GPR_ARG_REGISTERS)
   522  		  intarg_count = NUM_GPR_ARG_REGISTERS;
   523  		for (ii = 0; ii < 4; ii++)
   524  		  {
   525  		    int_tmp = (*p_argv.ui)[ii];
   526  		    *next_arg.u++ = int_tmp;
   527  		  }
   528  	      }
   529  	    else
   530  	      {
   531  		for (ii = 0; ii < 4; ii++)
   532  		  {
   533  		    int_tmp = (*p_argv.ui)[ii];
   534  		    *gpr_base.u++ = int_tmp;
   535  		  }
   536  	      }
   537  	    intarg_count += 4;
   538  	    break;
   539  	  }
   540  
   541  	case FFI_TYPE_UINT64:
   542  	case FFI_TYPE_SINT64:
   543  	  if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
   544  	    intarg_count++;
   545  	  if (intarg_count >= NUM_GPR_ARG_REGISTERS)
   546  	    {
   547  	      if (intarg_count % 2 != 0)
   548  		{
   549  		  intarg_count++;
   550  		  next_arg.u++;
   551  		}
   552  	      *next_arg.ll = **p_argv.ll;
   553  	      next_arg.u += 2;
   554  	    }
   555  	  else
   556  	    {
   557  	      /* The abi states only certain register pairs can be
   558  		 used for passing long long int specifically (r3,r4),
   559  		 (r5,r6), (r7,r8), (r9,r10).  If next arg is long long
   560  		 but not correct starting register of pair then skip
   561  		 until the proper starting register.  */
   562  	      if (intarg_count % 2 != 0)
   563  		{
   564  		  intarg_count ++;
   565  		  gpr_base.u++;
   566  		}
   567  	      *gpr_base.ll++ = **p_argv.ll;
   568  	    }
   569  	  intarg_count += 2;
   570  	  break;
   571  
   572  	case FFI_TYPE_STRUCT:
   573  	  struct_copy_size = ((*ptr)->size + 15) & ~0xF;
   574  	  copy_space.c -= struct_copy_size;
   575  	  memcpy (copy_space.c, *p_argv.c, (*ptr)->size);
   576  
   577  	  gprvalue = (unsigned long) copy_space.c;
   578  
   579  	  FFI_ASSERT (copy_space.c > next_arg.c);
   580  	  FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY);
   581  	  goto putgpr;
   582  
   583  	case FFI_TYPE_UINT8:
   584  	  gprvalue = **p_argv.uc;
   585  	  goto putgpr;
   586  	case FFI_TYPE_SINT8:
   587  	  gprvalue = **p_argv.sc;
   588  	  goto putgpr;
   589  	case FFI_TYPE_UINT16:
   590  	  gprvalue = **p_argv.us;
   591  	  goto putgpr;
   592  	case FFI_TYPE_SINT16:
   593  	  gprvalue = **p_argv.ss;
   594  	  goto putgpr;
   595  
   596  	case FFI_TYPE_INT:
   597  	case FFI_TYPE_UINT32:
   598  	case FFI_TYPE_SINT32:
   599  	case FFI_TYPE_POINTER:
   600  
   601  	  gprvalue = **p_argv.ui;
   602  
   603  	putgpr:
   604  	  if (intarg_count >= NUM_GPR_ARG_REGISTERS)
   605  	    *next_arg.u++ = gprvalue;
   606  	  else
   607  	    *gpr_base.u++ = gprvalue;
   608  	  intarg_count++;
   609  	  break;
   610  	}
   611      }
   612  
   613    /* Check that we didn't overrun the stack...  */
   614    FFI_ASSERT (copy_space.c >= next_arg.c);
   615    FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS);
   616    /* The assert below is testing that the number of integer arguments agrees
   617       with the number found in ffi_prep_cif_machdep().  However, intarg_count
   618       is incremented whenever we place an FP arg on the stack, so account for
   619       that before our assert test.  */
   620  #ifndef __NO_FPRS__
   621    if (fparg_count > NUM_FPR_ARG_REGISTERS)
   622      intarg_count -= fparg_count - NUM_FPR_ARG_REGISTERS;
   623    FFI_ASSERT (fpr_base.u
   624  	      <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
   625  #endif
   626    FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
   627  }
   628  
   629  #define MIN_CACHE_LINE_SIZE 8
   630  
   631  static void
   632  flush_icache (char *wraddr, char *xaddr, int size)
   633  {
   634    int i;
   635    for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE)
   636      __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;"
   637  		      : : "r" (xaddr + i), "r" (wraddr + i) : "memory");
   638    __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;"
   639  		    : : "r"(xaddr + size - 1), "r"(wraddr + size - 1)
   640  		    : "memory");
   641  }
   642  
   643  ffi_status FFI_HIDDEN
   644  ffi_prep_closure_loc_sysv (ffi_closure *closure,
   645  			   ffi_cif *cif,
   646  			   void (*fun) (ffi_cif *, void *, void **, void *),
   647  			   void *user_data,
   648  			   void *codeloc)
   649  {
   650    unsigned int *tramp;
   651  
   652    if (cif->abi < FFI_SYSV || cif->abi >= FFI_LAST_ABI)
   653      return FFI_BAD_ABI;
   654  
   655    tramp = (unsigned int *) &closure->tramp[0];
   656    tramp[0] = 0x7c0802a6;  /*   mflr    r0 */
   657    tramp[1] = 0x429f0005;  /*   bcl     20,31,.+4 */
   658    tramp[2] = 0x7d6802a6;  /*   mflr    r11 */
   659    tramp[3] = 0x7c0803a6;  /*   mtlr    r0 */
   660    tramp[4] = 0x800b0018;  /*   lwz     r0,24(r11) */
   661    tramp[5] = 0x816b001c;  /*   lwz     r11,28(r11) */
   662    tramp[6] = 0x7c0903a6;  /*   mtctr   r0 */
   663    tramp[7] = 0x4e800420;  /*   bctr */
   664    *(void **) &tramp[8] = (void *) ffi_closure_SYSV; /* function */
   665    *(void **) &tramp[9] = codeloc;                   /* context */
   666  
   667    /* Flush the icache.  */
   668    flush_icache ((char *)tramp, (char *)codeloc, 8 * 4);
   669  
   670    closure->cif = cif;
   671    closure->fun = fun;
   672    closure->user_data = user_data;
   673  
   674    return FFI_OK;
   675  }
   676  
   677  /* Basically the trampoline invokes ffi_closure_SYSV, and on
   678     entry, r11 holds the address of the closure.
   679     After storing the registers that could possibly contain
   680     parameters to be passed into the stack frame and setting
   681     up space for a return value, ffi_closure_SYSV invokes the
   682     following helper function to do most of the work.  */
   683  
   684  int
   685  ffi_closure_helper_SYSV (ffi_cif *cif,
   686  			 void (*fun) (ffi_cif *, void *, void **, void *),
   687  			 void *user_data,
   688  			 void *rvalue,
   689  			 unsigned long *pgr,
   690  			 ffi_dblfl *pfr,
   691  			 unsigned long *pst)
   692  {
   693    /* rvalue is the pointer to space for return value in closure assembly */
   694    /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
   695    /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV  */
   696    /* pst is the pointer to outgoing parameter stack in original caller */
   697  
   698    void **          avalue;
   699    ffi_type **      arg_types;
   700    long             i, avn;
   701  #ifndef __NO_FPRS__
   702    long             nf = 0;   /* number of floating registers already used */
   703  #endif
   704    long             ng = 0;   /* number of general registers already used */
   705  
   706    unsigned       size     = cif->rtype->size;
   707    unsigned short rtypenum = cif->rtype->type;
   708  
   709    avalue = alloca (cif->nargs * sizeof (void *));
   710  
   711    /* First translate for softfloat/nonlinux */
   712    rtypenum = translate_float (cif->abi, rtypenum);
   713  
   714    /* Copy the caller's structure return value address so that the closure
   715       returns the data directly to the caller.
   716       For FFI_SYSV the result is passed in r3/r4 if the struct size is less
   717       or equal 8 bytes.  */
   718    if (rtypenum == FFI_TYPE_STRUCT
   719        && !((cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8))
   720      {
   721        rvalue = (void *) *pgr;
   722        ng++;
   723        pgr++;
   724      }
   725  
   726    i = 0;
   727    avn = cif->nargs;
   728    arg_types = cif->arg_types;
   729  
   730    /* Grab the addresses of the arguments from the stack frame.  */
   731    while (i < avn) {
   732      unsigned short typenum = arg_types[i]->type;
   733  
   734      /* We may need to handle some values depending on ABI.  */
   735      typenum = translate_float (cif->abi, typenum);
   736  
   737      switch (typenum)
   738        {
   739  #ifndef __NO_FPRS__
   740        case FFI_TYPE_FLOAT:
   741  	/* Unfortunately float values are stored as doubles
   742  	   in the ffi_closure_SYSV code (since we don't check
   743  	   the type in that routine).  */
   744  	if (nf < NUM_FPR_ARG_REGISTERS)
   745  	  {
   746  	    /* FIXME? here we are really changing the values
   747  	       stored in the original calling routines outgoing
   748  	       parameter stack.  This is probably a really
   749  	       naughty thing to do but...  */
   750  	    double temp = pfr->d;
   751  	    pfr->f = (float) temp;
   752  	    avalue[i] = pfr;
   753  	    nf++;
   754  	    pfr++;
   755  	  }
   756  	else
   757  	  {
   758  	    avalue[i] = pst;
   759  	    pst += 1;
   760  	  }
   761  	break;
   762  
   763        case FFI_TYPE_DOUBLE:
   764  	if (nf < NUM_FPR_ARG_REGISTERS)
   765  	  {
   766  	    avalue[i] = pfr;
   767  	    nf++;
   768  	    pfr++;
   769  	  }
   770  	else
   771  	  {
   772  	    if (((long) pst) & 4)
   773  	      pst++;
   774  	    avalue[i] = pst;
   775  	    pst += 2;
   776  	  }
   777  	break;
   778  
   779  # if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
   780        case FFI_TYPE_LONGDOUBLE:
   781  	if (nf < NUM_FPR_ARG_REGISTERS - 1)
   782  	  {
   783  	    avalue[i] = pfr;
   784  	    pfr += 2;
   785  	    nf += 2;
   786  	  }
   787  	else
   788  	  {
   789  	    if (((long) pst) & 4)
   790  	      pst++;
   791  	    avalue[i] = pst;
   792  	    pst += 4;
   793  	    nf = 8;
   794  	  }
   795  	break;
   796  # endif
   797  #endif
   798  
   799        case FFI_TYPE_UINT128:
   800  	/* Test if for the whole long double, 4 gprs are available.
   801  	   otherwise the stuff ends up on the stack.  */
   802  	if (ng < NUM_GPR_ARG_REGISTERS - 3)
   803  	  {
   804  	    avalue[i] = pgr;
   805  	    pgr += 4;
   806  	    ng += 4;
   807  	  }
   808  	else
   809  	  {
   810  	    avalue[i] = pst;
   811  	    pst += 4;
   812  	    ng = 8+4;
   813  	  }
   814  	break;
   815  
   816        case FFI_TYPE_SINT8:
   817        case FFI_TYPE_UINT8:
   818  #ifndef __LITTLE_ENDIAN__
   819  	if (ng < NUM_GPR_ARG_REGISTERS)
   820  	  {
   821  	    avalue[i] = (char *) pgr + 3;
   822  	    ng++;
   823  	    pgr++;
   824  	  }
   825  	else
   826  	  {
   827  	    avalue[i] = (char *) pst + 3;
   828  	    pst++;
   829  	  }
   830  	break;
   831  #endif
   832  
   833        case FFI_TYPE_SINT16:
   834        case FFI_TYPE_UINT16:
   835  #ifndef __LITTLE_ENDIAN__
   836  	if (ng < NUM_GPR_ARG_REGISTERS)
   837  	  {
   838  	    avalue[i] = (char *) pgr + 2;
   839  	    ng++;
   840  	    pgr++;
   841  	  }
   842  	else
   843  	  {
   844  	    avalue[i] = (char *) pst + 2;
   845  	    pst++;
   846  	  }
   847  	break;
   848  #endif
   849  
   850        case FFI_TYPE_SINT32:
   851        case FFI_TYPE_UINT32:
   852        case FFI_TYPE_POINTER:
   853  	if (ng < NUM_GPR_ARG_REGISTERS)
   854  	  {
   855  	    avalue[i] = pgr;
   856  	    ng++;
   857  	    pgr++;
   858  	  }
   859  	else
   860  	  {
   861  	    avalue[i] = pst;
   862  	    pst++;
   863  	  }
   864  	break;
   865  
   866        case FFI_TYPE_STRUCT:
   867  	/* Structs are passed by reference. The address will appear in a
   868  	   gpr if it is one of the first 8 arguments.  */
   869  	if (ng < NUM_GPR_ARG_REGISTERS)
   870  	  {
   871  	    avalue[i] = (void *) *pgr;
   872  	    ng++;
   873  	    pgr++;
   874  	  }
   875  	else
   876  	  {
   877  	    avalue[i] = (void *) *pst;
   878  	    pst++;
   879  	  }
   880  	break;
   881  
   882        case FFI_TYPE_SINT64:
   883        case FFI_TYPE_UINT64:
   884  	/* Passing long long ints are complex, they must
   885  	   be passed in suitable register pairs such as
   886  	   (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
   887  	   and if the entire pair aren't available then the outgoing
   888  	   parameter stack is used for both but an alignment of 8
   889  	   must will be kept.  So we must either look in pgr
   890  	   or pst to find the correct address for this type
   891  	   of parameter.  */
   892  	if (ng < NUM_GPR_ARG_REGISTERS - 1)
   893  	  {
   894  	    if (ng & 1)
   895  	      {
   896  		/* skip r4, r6, r8 as starting points */
   897  		ng++;
   898  		pgr++;
   899  	      }
   900  	    avalue[i] = pgr;
   901  	    ng += 2;
   902  	    pgr += 2;
   903  	  }
   904  	else
   905  	  {
   906  	    if (((long) pst) & 4)
   907  	      pst++;
   908  	    avalue[i] = pst;
   909  	    pst += 2;
   910  	    ng = NUM_GPR_ARG_REGISTERS;
   911  	  }
   912  	break;
   913  
   914        default:
   915  	FFI_ASSERT (0);
   916        }
   917  
   918      i++;
   919    }
   920  
   921    (*fun) (cif, rvalue, avalue, user_data);
   922  
   923    /* Tell ffi_closure_SYSV how to perform return type promotions.
   924       Because the FFI_SYSV ABI returns the structures <= 8 bytes in
   925       r3/r4 we have to tell ffi_closure_SYSV how to treat them.  We
   926       combine the base type FFI_SYSV_TYPE_SMALL_STRUCT with the size of
   927       the struct less one.  We never have a struct with size zero.
   928       See the comment in ffitarget.h about ordering.  */
   929    if (rtypenum == FFI_TYPE_STRUCT
   930        && (cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8)
   931      return FFI_SYSV_TYPE_SMALL_STRUCT - 1 + size;
   932    return rtypenum;
   933  }
   934  #endif